Compare commits
450 Commits
v8.1.18
...
#17642-che
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9803e27fc1 | ||
|
|
9b4101855f | ||
|
|
9253d894d3 | ||
|
|
ebd79f22c7 | ||
|
|
c1b139fb9a | ||
|
|
a88bcea8ca | ||
|
|
21566560a7 | ||
|
|
e3ca43bf40 | ||
|
|
61abb8d5cb | ||
|
|
ecad656551 | ||
|
|
615e6d6e4f | ||
|
|
6dceefb96e | ||
|
|
69eff394fd | ||
|
|
a9da3aca81 | ||
|
|
91f3556375 | ||
|
|
aab7c3a840 | ||
|
|
9c823119e3 | ||
|
|
f5128833f6 | ||
|
|
2bc144354a | ||
|
|
e6fec6ec34 | ||
|
|
53389875bf | ||
|
|
3b243b38c8 | ||
|
|
3d9580808b | ||
|
|
2141ee71d4 | ||
|
|
01dd07083e | ||
|
|
42a28ea06b | ||
|
|
180cb6ba8e | ||
|
|
a78762e40b | ||
|
|
9797bb19e2 | ||
|
|
08a9554b3c | ||
|
|
d79bd825ee | ||
|
|
fe3d225cfa | ||
|
|
376e0db66e | ||
|
|
5fdabc1a62 | ||
|
|
dfe2a75d72 | ||
|
|
db58b80d27 | ||
|
|
5cb8aae383 | ||
|
|
817530429b | ||
|
|
4a7b7183d2 | ||
|
|
94bd39cf23 | ||
|
|
4038a22093 | ||
|
|
682baec0c9 | ||
|
|
ff91be491d | ||
|
|
ef35a0f2f1 | ||
|
|
f12a3bb08b | ||
|
|
c8a5065ffa | ||
|
|
23da5573f3 | ||
|
|
b08f985776 | ||
|
|
9b968baaa7 | ||
|
|
07edbe6f1c | ||
|
|
1f55a8b6e3 | ||
|
|
f6b9e11810 | ||
|
|
c18a3e4266 | ||
|
|
5840ef1c6f | ||
|
|
7974baddf5 | ||
|
|
4bf569758f | ||
|
|
f56fd9bb0b | ||
|
|
357ee5fc45 | ||
|
|
c6dea085b2 | ||
|
|
8782c3ecec | ||
|
|
b636cf2ef0 | ||
|
|
6dee2b8601 | ||
|
|
bcf301ac17 | ||
|
|
bf2120fb31 | ||
|
|
de56b74f3e | ||
|
|
2f146abe91 | ||
|
|
543d41b6ff | ||
|
|
8da0dd7563 | ||
|
|
a2217d7dbc | ||
|
|
ea84728a3f | ||
|
|
b2d10f7ccf | ||
|
|
b6af25ce99 | ||
|
|
7a9d2454d4 | ||
|
|
a9254cff02 | ||
|
|
d14b34141c | ||
|
|
14bc2cc1ba | ||
|
|
a91b54b97a | ||
|
|
ead655e1db | ||
|
|
c5f28748f7 | ||
|
|
ee4831cb30 | ||
|
|
deb1afd28b | ||
|
|
9e8eead71e | ||
|
|
3f96f7cbd7 | ||
|
|
dde2e88332 | ||
|
|
ff25015595 | ||
|
|
7d0c695808 | ||
|
|
906385def9 | ||
|
|
a6c6c7eae9 | ||
|
|
205725c767 | ||
|
|
c207efbb35 | ||
|
|
c0211e59b3 | ||
|
|
dd2678cbb9 | ||
|
|
e2c87b664e | ||
|
|
29d4b4dd53 | ||
|
|
3fba307e55 | ||
|
|
7171fa36d8 | ||
|
|
c570f656bf | ||
|
|
a5e37519f5 | ||
|
|
0f88d6eec3 | ||
|
|
651c51bb01 | ||
|
|
0fdbdfd5c2 | ||
|
|
31056ff858 | ||
|
|
8d2643696b | ||
|
|
e7488d19e9 | ||
|
|
2bb3b6d64c | ||
|
|
5744e48ae8 | ||
|
|
82d0a21440 | ||
|
|
58133cffac | ||
|
|
bfd8c2f310 | ||
|
|
30d447c023 | ||
|
|
9a0846b8a6 | ||
|
|
3667fcddd7 | ||
|
|
906741d662 | ||
|
|
12be088c4f | ||
|
|
6737ba80cd | ||
|
|
862a3d938e | ||
|
|
09e82377a5 | ||
|
|
59470864e7 | ||
|
|
c95aeb3730 | ||
|
|
5c55c90d68 | ||
|
|
e47972731b | ||
|
|
5851cc9e41 | ||
|
|
6f615230e9 | ||
|
|
d91598a25e | ||
|
|
9e416778d9 | ||
|
|
860a117567 | ||
|
|
b8fe3b18d4 | ||
|
|
40269a724b | ||
|
|
ec828318d8 | ||
|
|
d31e7ed534 | ||
|
|
5c2dbe438b | ||
|
|
10857635ac | ||
|
|
df2545ef80 | ||
|
|
f6ff729316 | ||
|
|
38678803eb | ||
|
|
67c931f196 | ||
|
|
1c23092d0e | ||
|
|
a90ff21cbf | ||
|
|
0ce0cee81f | ||
|
|
f4be5ffb5d | ||
|
|
19958748bf | ||
|
|
d6ca8468e3 | ||
|
|
7bccb7718b | ||
|
|
f6b63b5e44 | ||
|
|
9a2c5ff195 | ||
|
|
3597f759da | ||
|
|
3ed3b21286 | ||
|
|
b89b636474 | ||
|
|
2afc595452 | ||
|
|
c7262f2885 | ||
|
|
8662aa2277 | ||
|
|
8095e0ab72 | ||
|
|
be3c8ddd5c | ||
|
|
ec5b9ce903 | ||
|
|
bd2acefecc | ||
|
|
18e49e9067 | ||
|
|
a0d65520a3 | ||
|
|
a35731d9d5 | ||
|
|
9d3623cca6 | ||
|
|
2fe08a721f | ||
|
|
7abc3a7d7d | ||
|
|
d4a34f1a3c | ||
|
|
ddda4848d3 | ||
|
|
8516856d37 | ||
|
|
132327594b | ||
|
|
d2a2c63070 | ||
|
|
170a5158fa | ||
|
|
1d8493d388 | ||
|
|
ff39e8bd2c | ||
|
|
c3442033da | ||
|
|
f1dd84edba | ||
|
|
06b040a337 | ||
|
|
fa546ddc5b | ||
|
|
f811352c79 | ||
|
|
7ed8963b9f | ||
|
|
a9fc8b79fd | ||
|
|
afd794b4c7 | ||
|
|
c4a28f0ec4 | ||
|
|
db343bf795 | ||
|
|
0157043dc5 | ||
|
|
a947f9bd32 | ||
|
|
2a4181c7c3 | ||
|
|
30192f5b14 | ||
|
|
c41b5e8844 | ||
|
|
b27928807b | ||
|
|
16f1b5e23e | ||
|
|
ed651b6869 | ||
|
|
b9d925c7aa | ||
|
|
3650a29381 | ||
|
|
de84ee3693 | ||
|
|
42ba31591d | ||
|
|
a78a243e20 | ||
|
|
38924ced4a | ||
|
|
5e8cc66f5c | ||
|
|
1353837584 | ||
|
|
7cb5a89523 | ||
|
|
1db09a7953 | ||
|
|
bc6aa12dd0 | ||
|
|
c3bea88979 | ||
|
|
6e85e466b0 | ||
|
|
3327cc70c9 | ||
|
|
c9eac66a93 | ||
|
|
53e9bd6e48 | ||
|
|
eaa18e1efb | ||
|
|
afa3dacc31 | ||
|
|
c803c4a57a | ||
|
|
2d3a53e449 | ||
|
|
5e076754ce | ||
|
|
927e217961 | ||
|
|
80b48101aa | ||
|
|
08530e6133 | ||
|
|
97130ef6c1 | ||
|
|
da37feae6d | ||
|
|
f96172e61f | ||
|
|
e35477b8db | ||
|
|
cea5560a67 | ||
|
|
311bd5e67e | ||
|
|
1cfddf2a4c | ||
|
|
abe58117fe | ||
|
|
ee5f89f70d | ||
|
|
4f545ed101 | ||
|
|
136de4208e | ||
|
|
7650a2c2a7 | ||
|
|
c3d1987fac | ||
|
|
12ef78bb1c | ||
|
|
16c4241a6e | ||
|
|
4992c77818 | ||
|
|
3a0b1de136 | ||
|
|
1c3ef02c7b | ||
|
|
f268fe9e80 | ||
|
|
2ed98c17d4 | ||
|
|
571ae4fbfd | ||
|
|
6e61e94e02 | ||
|
|
6a7972c5a1 | ||
|
|
db4fbe315a | ||
|
|
f3613d7103 | ||
|
|
cbbed36428 | ||
|
|
e86e9697b3 | ||
|
|
fd6b2d5715 | ||
|
|
fbb36d1665 | ||
|
|
07be1b8192 | ||
|
|
33880393ac | ||
|
|
5123fe7838 | ||
|
|
cbe26a365d | ||
|
|
f1bb72b2a6 | ||
|
|
2c33654395 | ||
|
|
dd86de017e | ||
|
|
3eabde9630 | ||
|
|
640c51af31 | ||
|
|
7167b17d25 | ||
|
|
8a35948678 | ||
|
|
0fe63d3fb9 | ||
|
|
e4302c3e88 | ||
|
|
a7df6fb465 | ||
|
|
133e7598e0 | ||
|
|
c1a52ffa75 | ||
|
|
4f46313388 | ||
|
|
03b2cc9cd2 | ||
|
|
1a2bf8dc95 | ||
|
|
dd63fbeb84 | ||
|
|
59e435c418 | ||
|
|
f89f0a19b5 | ||
|
|
cbc6ef95cb | ||
|
|
0ceecc9e1d | ||
|
|
c816902025 | ||
|
|
cfb03cdca0 | ||
|
|
266f77b08c | ||
|
|
257d58c236 | ||
|
|
015f3d936c | ||
|
|
18d2a0ffd7 | ||
|
|
24afde0e46 | ||
|
|
8499faa55a | ||
|
|
c60dd809b8 | ||
|
|
297b8e33f2 | ||
|
|
d0593c6b8d | ||
|
|
8a40d7e35c | ||
|
|
b670b2014c | ||
|
|
440e969f52 | ||
|
|
14b79f2f1c | ||
|
|
00cf49a61f | ||
|
|
4f534e0e84 | ||
|
|
83a19fbbbf | ||
|
|
610cb884fc | ||
|
|
ba92cec62b | ||
|
|
d92e961a52 | ||
|
|
b13e74756a | ||
|
|
4ef3072766 | ||
|
|
e96e2461d3 | ||
|
|
7a2e2be169 | ||
|
|
8d2a5a7e4a | ||
|
|
b7b0e4fab5 | ||
|
|
a624a79b30 | ||
|
|
313135da6f | ||
|
|
58d27d1247 | ||
|
|
edfb28168f | ||
|
|
8d0e03bb06 | ||
|
|
855f6f77cf | ||
|
|
6236cffe14 | ||
|
|
322a71fbb8 | ||
|
|
4d9f8476f3 | ||
|
|
d7d93b14b2 | ||
|
|
d1af3ece6e | ||
|
|
8153b20984 | ||
|
|
a50f605c29 | ||
|
|
daf23edd10 | ||
|
|
2eaaeb8259 | ||
|
|
a02c62d62c | ||
|
|
e0232a8e84 | ||
|
|
6ea5693b2f | ||
|
|
030c2114d1 | ||
|
|
2cb18e3668 | ||
|
|
cd9f8be563 | ||
|
|
a02792e9bf | ||
|
|
41bb422244 | ||
|
|
54663d3342 | ||
|
|
2529f7369f | ||
|
|
909c33dccf | ||
|
|
1adc9f1aa9 | ||
|
|
e9948f0718 | ||
|
|
49da9e58fd | ||
|
|
2f74a8afe1 | ||
|
|
f3e288d078 | ||
|
|
988000952e | ||
|
|
6537f3794b | ||
|
|
d31718ba8a | ||
|
|
9dd4bc5fa8 | ||
|
|
df5f1bd522 | ||
|
|
ddffab9169 | ||
|
|
0c34073582 | ||
|
|
14674947cb | ||
|
|
51bccdbd66 | ||
|
|
f0fbb3cf36 | ||
|
|
0cc47aacbe | ||
|
|
fafd592290 | ||
|
|
40e754b8c3 | ||
|
|
483301db7a | ||
|
|
218606fbd6 | ||
|
|
c601b8e62c | ||
|
|
2bd68ec991 | ||
|
|
66842648ed | ||
|
|
ce54b9a7b5 | ||
|
|
8a5f6d2a5d | ||
|
|
1d86a5476f | ||
|
|
ca4d3f6bce | ||
|
|
2812f2ce92 | ||
|
|
5c623db798 | ||
|
|
edaf005fe1 | ||
|
|
4f6e407247 | ||
|
|
e30881239c | ||
|
|
bbde2cc4b2 | ||
|
|
16d18c79d7 | ||
|
|
a0d2cb8a03 | ||
|
|
1bb5dc7e69 | ||
|
|
58759acfe4 | ||
|
|
0cd5136052 | ||
|
|
b3c6fe5369 | ||
|
|
599718f84e | ||
|
|
d9a5452388 | ||
|
|
0fe49e04bf | ||
|
|
a98d3fb4dc | ||
|
|
8c670d1832 | ||
|
|
c232f490bc | ||
|
|
c7280953dd | ||
|
|
8f4c606c64 | ||
|
|
6740afab42 | ||
|
|
5df22b3e6a | ||
|
|
3d9d18a0d5 | ||
|
|
0102599708 | ||
|
|
960edd4adf | ||
|
|
3547fa723c | ||
|
|
7a456185c6 | ||
|
|
dd79c3f2d6 | ||
|
|
35682d11f0 | ||
|
|
d04b3f0907 | ||
|
|
c926358e04 | ||
|
|
856ba52f36 | ||
|
|
a5bea31154 | ||
|
|
2afcc1e384 | ||
|
|
fc469707a3 | ||
|
|
77fdc370c7 | ||
|
|
301290fb6d | ||
|
|
07fffe2f79 | ||
|
|
0227a63fa5 | ||
|
|
27764b863c | ||
|
|
032fd75f9e | ||
|
|
0bf4f861f3 | ||
|
|
fd8f90cb52 | ||
|
|
b6c6b025c8 | ||
|
|
3d89e98d1f | ||
|
|
7c5110ed5d | ||
|
|
0a474f48ad | ||
|
|
c409bfd5be | ||
|
|
39d5d5b2e0 | ||
|
|
8a80d9009d | ||
|
|
f62b5df566 | ||
|
|
826521f053 | ||
|
|
f9b05bc8de | ||
|
|
b8239e8ed9 | ||
|
|
214757ab0b | ||
|
|
f130186b37 | ||
|
|
2244eebc3b | ||
|
|
4176792f2d | ||
|
|
1e6cef52c9 | ||
|
|
a0f4f30a50 | ||
|
|
4cbf6ac393 | ||
|
|
af7425d8e6 | ||
|
|
3fea909d3f | ||
|
|
7c37d40677 | ||
|
|
3a97c27350 | ||
|
|
e0516a52a8 | ||
|
|
a85ec6efb3 | ||
|
|
3795c74814 | ||
|
|
27954dc6d3 | ||
|
|
68c4187a09 | ||
|
|
b9834231f3 | ||
|
|
2be343ea1c | ||
|
|
109fe1b62c | ||
|
|
63d691a63c | ||
|
|
6f57d6b876 | ||
|
|
e0bad99ea1 | ||
|
|
e39eb09cfb | ||
|
|
64d397c3f3 | ||
|
|
465ac1d1e1 | ||
|
|
18d6becebc | ||
|
|
943a4093ad | ||
|
|
b0917a5131 | ||
|
|
0972c4e340 | ||
|
|
3bbd0fdbcd | ||
|
|
43a237bf95 | ||
|
|
95f867b267 | ||
|
|
e96daf469a | ||
|
|
f2cdfe9e47 | ||
|
|
929b67e768 | ||
|
|
0573dc136a | ||
|
|
48588f6a9e | ||
|
|
8214b11da5 | ||
|
|
36090bf83e | ||
|
|
bffb2fe82f | ||
|
|
500cbf5d92 | ||
|
|
88579b9bf3 | ||
|
|
e8bb9bde99 | ||
|
|
0ee3cca4da | ||
|
|
f89ee6b7f2 | ||
|
|
aebfb52c85 | ||
|
|
667bd7af0e | ||
|
|
3fd9e3ab56 | ||
|
|
c8b213c190 | ||
|
|
942de9dce5 | ||
|
|
69b9b0bbc0 | ||
|
|
3c1088f030 |
@@ -4189,6 +4189,15 @@
|
|||||||
"contributions": [
|
"contributions": [
|
||||||
"code"
|
"code"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "mckaygerhard",
|
||||||
|
"name": "Герхард PICCORO Lenz McKAY ",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/1571724?v=4",
|
||||||
|
"profile": "https://github-readme-stats.vercel.app/api?username=mckaygerhard",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ PUBLIC_FILESYSTEM_DISK=local_public
|
|||||||
# --------------------------------------------
|
# --------------------------------------------
|
||||||
DB_CONNECTION=mysql
|
DB_CONNECTION=mysql
|
||||||
DB_HOST=db
|
DB_HOST=db
|
||||||
|
DB_SOCKET=null
|
||||||
DB_PORT='3306'
|
DB_PORT='3306'
|
||||||
DB_DATABASE=snipeit
|
DB_DATABASE=snipeit
|
||||||
DB_USERNAME=snipeit
|
DB_USERNAME=snipeit
|
||||||
@@ -168,6 +169,7 @@ AWS_DEFAULT_REGION=null
|
|||||||
LOGIN_MAX_ATTEMPTS=5
|
LOGIN_MAX_ATTEMPTS=5
|
||||||
LOGIN_LOCKOUT_DURATION=60
|
LOGIN_LOCKOUT_DURATION=60
|
||||||
RESET_PASSWORD_LINK_EXPIRES=900
|
RESET_PASSWORD_LINK_EXPIRES=900
|
||||||
|
INVITE_PASSWORD_LINK_EXPIRES=1500
|
||||||
|
|
||||||
# --------------------------------------------
|
# --------------------------------------------
|
||||||
# OPTIONAL: MISC
|
# OPTIONAL: MISC
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ PUBLIC_FILESYSTEM_DISK=local_public
|
|||||||
# --------------------------------------------
|
# --------------------------------------------
|
||||||
DB_CONNECTION=mysql
|
DB_CONNECTION=mysql
|
||||||
DB_HOST=127.0.0.1
|
DB_HOST=127.0.0.1
|
||||||
|
DB_SOCKET=null
|
||||||
DB_PORT=3306
|
DB_PORT=3306
|
||||||
DB_DATABASE=null
|
DB_DATABASE=null
|
||||||
DB_USERNAME=null
|
DB_USERNAME=null
|
||||||
@@ -174,6 +175,7 @@ LOGIN_AUTOCOMPLETE=false
|
|||||||
RESET_PASSWORD_LINK_EXPIRES=15
|
RESET_PASSWORD_LINK_EXPIRES=15
|
||||||
PASSWORD_CONFIRM_TIMEOUT=10800
|
PASSWORD_CONFIRM_TIMEOUT=10800
|
||||||
PASSWORD_RESET_MAX_ATTEMPTS_PER_MIN=50
|
PASSWORD_RESET_MAX_ATTEMPTS_PER_MIN=50
|
||||||
|
INVITE_PASSWORD_LINK_EXPIRES=1500
|
||||||
|
|
||||||
# --------------------------------------------
|
# --------------------------------------------
|
||||||
# OPTIONAL: MISC
|
# OPTIONAL: MISC
|
||||||
|
|||||||
2
.github/workflows/codacy-analysis.yml
vendored
2
.github/workflows/codacy-analysis.yml
vendored
@@ -36,7 +36,7 @@ jobs:
|
|||||||
|
|
||||||
# Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
|
# Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
|
||||||
- name: Run Codacy Analysis CLI
|
- name: Run Codacy Analysis CLI
|
||||||
uses: codacy/codacy-analysis-cli-action@v4.4.5
|
uses: codacy/codacy-analysis-cli-action@v4.4.7
|
||||||
with:
|
with:
|
||||||
# Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository
|
# Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository
|
||||||
# You can also omit the token and run the tools that support default configurations
|
# You can also omit the token and run the tools that support default configurations
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
|
|||||||
| [<img src="https://avatars.githubusercontent.com/u/181059?v=4" width="110px;"/><br /><sub>Juan Font</sub>](https://github.com/juanfont)<br />[💻](https://github.com/snipe/snipe-it/commits?author=juanfont "Code") | [<img src="https://avatars.githubusercontent.com/u/13137708?v=4" width="110px;"/><br /><sub>Juho Taipale</sub>](https://github.com/juhotaipale)<br />[💻](https://github.com/snipe/snipe-it/commits?author=juhotaipale "Code") | [<img src="https://avatars.githubusercontent.com/u/1007419?v=4" width="110px;"/><br /><sub>Korvin Szanto</sub>](https://github.com/KorvinSzanto)<br />[💻](https://github.com/snipe/snipe-it/commits?author=KorvinSzanto "Code") | [<img src="https://avatars.githubusercontent.com/u/8513053?v=4" width="110px;"/><br /><sub>Lewis Foster</sub>](https://lewisfoster.foo/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sniff122 "Code") | [<img src="https://avatars.githubusercontent.com/u/33877541?v=4" width="110px;"/><br /><sub>Logan Swartzendruber</sub>](https://github.com/loganswartz)<br />[💻](https://github.com/snipe/snipe-it/commits?author=loganswartz "Code") | [<img src="https://avatars.githubusercontent.com/u/1156208?v=4" width="110px;"/><br /><sub>Lorenzo P.</sub>](https://github.com/lopezio)<br />[💻](https://github.com/snipe/snipe-it/commits?author=lopezio "Code") | [<img src="https://avatars.githubusercontent.com/u/33946590?v=4" width="110px;"/><br /><sub>Lukas Jung</sub>](https://github.com/m4us1ne)<br />[💻](https://github.com/snipe/snipe-it/commits?author=m4us1ne "Code") |
|
| [<img src="https://avatars.githubusercontent.com/u/181059?v=4" width="110px;"/><br /><sub>Juan Font</sub>](https://github.com/juanfont)<br />[💻](https://github.com/snipe/snipe-it/commits?author=juanfont "Code") | [<img src="https://avatars.githubusercontent.com/u/13137708?v=4" width="110px;"/><br /><sub>Juho Taipale</sub>](https://github.com/juhotaipale)<br />[💻](https://github.com/snipe/snipe-it/commits?author=juhotaipale "Code") | [<img src="https://avatars.githubusercontent.com/u/1007419?v=4" width="110px;"/><br /><sub>Korvin Szanto</sub>](https://github.com/KorvinSzanto)<br />[💻](https://github.com/snipe/snipe-it/commits?author=KorvinSzanto "Code") | [<img src="https://avatars.githubusercontent.com/u/8513053?v=4" width="110px;"/><br /><sub>Lewis Foster</sub>](https://lewisfoster.foo/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sniff122 "Code") | [<img src="https://avatars.githubusercontent.com/u/33877541?v=4" width="110px;"/><br /><sub>Logan Swartzendruber</sub>](https://github.com/loganswartz)<br />[💻](https://github.com/snipe/snipe-it/commits?author=loganswartz "Code") | [<img src="https://avatars.githubusercontent.com/u/1156208?v=4" width="110px;"/><br /><sub>Lorenzo P.</sub>](https://github.com/lopezio)<br />[💻](https://github.com/snipe/snipe-it/commits?author=lopezio "Code") | [<img src="https://avatars.githubusercontent.com/u/33946590?v=4" width="110px;"/><br /><sub>Lukas Jung</sub>](https://github.com/m4us1ne)<br />[💻](https://github.com/snipe/snipe-it/commits?author=m4us1ne "Code") |
|
||||||
| [<img src="https://avatars.githubusercontent.com/u/10965027?v=4" width="110px;"/><br /><sub>Ellie</sub>](https://leafedfox.xyz/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=LeafedFox "Code") | [<img src="https://avatars.githubusercontent.com/u/20960555?v=4" width="110px;"/><br /><sub>GA Stamper</sub>](https://github.com/gastamper)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gastamper "Code") | [<img src="https://avatars.githubusercontent.com/u/206553556?v=4" width="110px;"/><br /><sub>Guillaume Lefranc</sub>](https://github.com/gl-pup)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gl-pup "Code") | [<img src="https://avatars.githubusercontent.com/u/733892?v=4" width="110px;"/><br /><sub>Hajo Möller</sub>](https://github.com/dasjoe)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dasjoe "Code") | [<img src="https://avatars.githubusercontent.com/u/3420063?v=4" width="110px;"/><br /><sub>Istvan Basa</sub>](https://github.com/pottom)<br />[💻](https://github.com/snipe/snipe-it/commits?author=pottom "Code") | [<img src="https://avatars.githubusercontent.com/u/810824?v=4" width="110px;"/><br /><sub>JJ Asghar</sub>](https://jjasghar.github.io/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jjasghar "Code") | [<img src="https://avatars.githubusercontent.com/u/40404495?v=4" width="110px;"/><br /><sub>James E. Msenga</sub>](https://github.com/JemCdo)<br />[💻](https://github.com/snipe/snipe-it/commits?author=JemCdo "Code") |
|
| [<img src="https://avatars.githubusercontent.com/u/10965027?v=4" width="110px;"/><br /><sub>Ellie</sub>](https://leafedfox.xyz/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=LeafedFox "Code") | [<img src="https://avatars.githubusercontent.com/u/20960555?v=4" width="110px;"/><br /><sub>GA Stamper</sub>](https://github.com/gastamper)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gastamper "Code") | [<img src="https://avatars.githubusercontent.com/u/206553556?v=4" width="110px;"/><br /><sub>Guillaume Lefranc</sub>](https://github.com/gl-pup)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gl-pup "Code") | [<img src="https://avatars.githubusercontent.com/u/733892?v=4" width="110px;"/><br /><sub>Hajo Möller</sub>](https://github.com/dasjoe)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dasjoe "Code") | [<img src="https://avatars.githubusercontent.com/u/3420063?v=4" width="110px;"/><br /><sub>Istvan Basa</sub>](https://github.com/pottom)<br />[💻](https://github.com/snipe/snipe-it/commits?author=pottom "Code") | [<img src="https://avatars.githubusercontent.com/u/810824?v=4" width="110px;"/><br /><sub>JJ Asghar</sub>](https://jjasghar.github.io/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jjasghar "Code") | [<img src="https://avatars.githubusercontent.com/u/40404495?v=4" width="110px;"/><br /><sub>James E. Msenga</sub>](https://github.com/JemCdo)<br />[💻](https://github.com/snipe/snipe-it/commits?author=JemCdo "Code") |
|
||||||
| [<img src="https://avatars.githubusercontent.com/u/6865786?v=4" width="110px;"/><br /><sub>Jan Felix Wiebe</sub>](https://github.com/jfwiebe)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jfwiebe "Code") | [<img src="https://avatars.githubusercontent.com/u/43412008?v=4" width="110px;"/><br /><sub>Jo Drexl</sub>](https://www.nfon.com/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=drexljo "Code") | [<img src="https://avatars.githubusercontent.com/u/4807843?v=4" width="110px;"/><br /><sub>Austin Sasko</sub>](https://github.com/austinsasko)<br />[💻](https://github.com/snipe/snipe-it/commits?author=austinsasko "Code") | [<img src="https://avatars.githubusercontent.com/u/4875039?v=4" width="110px;"/><br /><sub>Jasson</sub>](http://jassoncordones.github.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=JassonCordones "Code") | [<img src="https://avatars.githubusercontent.com/u/76069640?v=4" width="110px;"/><br /><sub>Okean</sub>](https://github.com/Tinyblargon)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Tinyblargon "Code") | [<img src="https://avatars.githubusercontent.com/u/6515064?v=4" width="110px;"/><br /><sub>Alejandro Medrano</sub>](https://www.lst.tfo.upm.es/alejandro-medrano/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=amedranogil "Code") | [<img src="https://avatars.githubusercontent.com/u/58696401?v=4" width="110px;"/><br /><sub>Lukas Kraic</sub>](https://github.com/lukaskraic)<br />[💻](https://github.com/snipe/snipe-it/commits?author=lukaskraic "Code") |
|
| [<img src="https://avatars.githubusercontent.com/u/6865786?v=4" width="110px;"/><br /><sub>Jan Felix Wiebe</sub>](https://github.com/jfwiebe)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jfwiebe "Code") | [<img src="https://avatars.githubusercontent.com/u/43412008?v=4" width="110px;"/><br /><sub>Jo Drexl</sub>](https://www.nfon.com/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=drexljo "Code") | [<img src="https://avatars.githubusercontent.com/u/4807843?v=4" width="110px;"/><br /><sub>Austin Sasko</sub>](https://github.com/austinsasko)<br />[💻](https://github.com/snipe/snipe-it/commits?author=austinsasko "Code") | [<img src="https://avatars.githubusercontent.com/u/4875039?v=4" width="110px;"/><br /><sub>Jasson</sub>](http://jassoncordones.github.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=JassonCordones "Code") | [<img src="https://avatars.githubusercontent.com/u/76069640?v=4" width="110px;"/><br /><sub>Okean</sub>](https://github.com/Tinyblargon)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Tinyblargon "Code") | [<img src="https://avatars.githubusercontent.com/u/6515064?v=4" width="110px;"/><br /><sub>Alejandro Medrano</sub>](https://www.lst.tfo.upm.es/alejandro-medrano/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=amedranogil "Code") | [<img src="https://avatars.githubusercontent.com/u/58696401?v=4" width="110px;"/><br /><sub>Lukas Kraic</sub>](https://github.com/lukaskraic)<br />[💻](https://github.com/snipe/snipe-it/commits?author=lukaskraic "Code") |
|
||||||
|
| [<img src="https://avatars.githubusercontent.com/u/1571724?v=4" width="110px;"/><br /><sub>Герхард PICCORO Lenz McKAY </sub>](https://github-readme-stats.vercel.app/api?username=mckaygerhard)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mckaygerhard "Code") |
|
||||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||||
|
|
||||||
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
|
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
|
||||||
|
|||||||
68
app/Console/Commands/CleanIncorrectCheckoutAcceptances.php
Normal file
68
app/Console/Commands/CleanIncorrectCheckoutAcceptances.php
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Models\CheckoutAcceptance;
|
||||||
|
use App\Models\LicenseSeat;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
|
class CleanIncorrectCheckoutAcceptances extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'snipeit:clean-checkout-acceptances';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = "Delete checkout acceptances for checkouts to non-users";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$deletions = 0;
|
||||||
|
$skips = 0;
|
||||||
|
|
||||||
|
// This walks *every* checkoutacceptance. That's gnarly. But necessary
|
||||||
|
$this->withProgressBar(CheckoutAcceptance::all(), function ($checkoutAcceptance) use (&$deletions, &$skips) {
|
||||||
|
$item = $checkoutAcceptance->checkoutable;
|
||||||
|
$checkout_to_id = $checkoutAcceptance->assigned_to_id;
|
||||||
|
if(is_null($item)) {
|
||||||
|
$this->info("'Checkoutable' Item is null, going to next record");
|
||||||
|
return; //'false' allegedly breaks execution entirely, so 'true' maybe doesn't? hrm. just straight return maybe?
|
||||||
|
}
|
||||||
|
if(get_class($item) == LicenseSeat::class) {
|
||||||
|
$item = $item->license;
|
||||||
|
}
|
||||||
|
foreach($item->assetlog()->where('action_type','checkout')->get() as $assetlog) {
|
||||||
|
if ($assetlog->target_id == $checkout_to_id && $assetlog->target_type != User::class) {
|
||||||
|
//We have a checkout-to an ID for a non-User, which matches to an ID in the checkout_acceptances table
|
||||||
|
|
||||||
|
//now, let's compare the _times_ - are they close?
|
||||||
|
//I'm picking `created_at` over `action_date` because I'm more interested in when the actionlogs
|
||||||
|
//were _created_, not when they were alleged to have happened - those created_at times need to be within 'X' seconds of
|
||||||
|
//each other (currently 5)
|
||||||
|
if ($assetlog->created_at->diffInSeconds($checkoutAcceptance->created_at, true) <= 5) { //we're allowing for five _ish_ seconds of slop
|
||||||
|
$deletions++;
|
||||||
|
$checkoutAcceptance->forceDelete(); // HARD delete this record; it should have never been
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
//$this->info("The two records are too far apart");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//$this->info("No match! checkout to id: " . $checkout_to_id." target_id: ".$assetlog->target_id." target_type: ".$assetlog->target_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$skips++;
|
||||||
|
});
|
||||||
|
$this->error("Final deletion count: $deletions, and skip count: $skips");
|
||||||
|
}
|
||||||
|
}
|
||||||
74
app/Console/Commands/CleanOldCheckoutRequests.php
Normal file
74
app/Console/Commands/CleanOldCheckoutRequests.php
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Models\CheckoutRequest;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
|
class CleanOldCheckoutRequests extends Command
|
||||||
|
{
|
||||||
|
private int $deletions = 0;
|
||||||
|
private int $skips = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'snipeit:clean-old-checkout-requests';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Removes checkout requests that reference deleted assets or users.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$requests = CheckoutRequest::with([
|
||||||
|
'user' => function ($query) {
|
||||||
|
$query->withTrashed();
|
||||||
|
},
|
||||||
|
'requestedItem' => function ($query) {
|
||||||
|
$query->withTrashed();
|
||||||
|
},
|
||||||
|
])->get();
|
||||||
|
|
||||||
|
$this->info("Processing {$requests->count()} checkout requests");
|
||||||
|
|
||||||
|
$this->withProgressBar($requests, function ($request) {
|
||||||
|
if ($this->shouldForceDelete($request)) {
|
||||||
|
$request->forceDelete();
|
||||||
|
$this->deletions++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->shouldSoftDelete($request)) {
|
||||||
|
$request->delete();
|
||||||
|
$this->deletions++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->skips++;
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->info("Final deletion count: $this->deletions, and skip count: $this->skips");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function shouldForceDelete(CheckoutRequest $request)
|
||||||
|
{
|
||||||
|
// check if the requestable or user relationship is null
|
||||||
|
return !$request->requestable || !$request->user;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function shouldSoftDelete(CheckoutRequest $request)
|
||||||
|
{
|
||||||
|
return $request->requestable->trashed() || $request->user->trashed();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -96,7 +96,7 @@ class MoveUploadsToNewDisk extends Command
|
|||||||
$private_uploads['assets'] = glob('storage/private_uploads/assets'."/*.*");
|
$private_uploads['assets'] = glob('storage/private_uploads/assets'."/*.*");
|
||||||
$private_uploads['signatures'] = glob('storage/private_uploads/signatures'."/*.*");
|
$private_uploads['signatures'] = glob('storage/private_uploads/signatures'."/*.*");
|
||||||
$private_uploads['audits'] = glob('storage/private_uploads/audits'."/*.*");
|
$private_uploads['audits'] = glob('storage/private_uploads/audits'."/*.*");
|
||||||
$private_uploads['assetmodels'] = glob('storage/private_uploads/assetmodels'."/*.*");
|
$private_uploads['assetmodels'] = glob('storage/private_uploads/models'."/*.*");
|
||||||
$private_uploads['imports'] = glob('storage/private_uploads/imports'."/*.*");
|
$private_uploads['imports'] = glob('storage/private_uploads/imports'."/*.*");
|
||||||
$private_uploads['licenses'] = glob('storage/private_uploads/licenses'."/*.*");
|
$private_uploads['licenses'] = glob('storage/private_uploads/licenses'."/*.*");
|
||||||
$private_uploads['users'] = glob('storage/private_uploads/users'."/*.*");
|
$private_uploads['users'] = glob('storage/private_uploads/users'."/*.*");
|
||||||
|
|||||||
@@ -62,19 +62,19 @@ class Purge extends Command
|
|||||||
$assetcount = $assets->count();
|
$assetcount = $assets->count();
|
||||||
$this->info($assets->count().' assets purged.');
|
$this->info($assets->count().' assets purged.');
|
||||||
$asset_assoc = 0;
|
$asset_assoc = 0;
|
||||||
$asset_maintenances = 0;
|
$maintenances = 0;
|
||||||
|
|
||||||
foreach ($assets as $asset) {
|
foreach ($assets as $asset) {
|
||||||
$this->info('- Asset "'.$asset->present()->name().'" deleted.');
|
$this->info('- Asset "'.$asset->present()->name().'" deleted.');
|
||||||
$asset_assoc += $asset->assetlog()->count();
|
$asset_assoc += $asset->assetlog()->count();
|
||||||
$asset->assetlog()->forceDelete();
|
$asset->assetlog()->forceDelete();
|
||||||
$asset_maintenances += $asset->assetmaintenances()->count();
|
$maintenances += $asset->maintenances()->count();
|
||||||
$asset->assetmaintenances()->forceDelete();
|
$asset->maintenances()->forceDelete();
|
||||||
$asset->forceDelete();
|
$asset->forceDelete();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->info($asset_assoc.' corresponding log records purged.');
|
$this->info($asset_assoc.' corresponding log records purged.');
|
||||||
$this->info($asset_maintenances.' corresponding maintenance records purged.');
|
$this->info($maintenances.' corresponding maintenance records purged.');
|
||||||
|
|
||||||
$locations = Location::whereNotNull('deleted_at')->withTrashed()->get();
|
$locations = Location::whereNotNull('deleted_at')->withTrashed()->get();
|
||||||
$this->info($locations->count().' locations purged.');
|
$this->info($locations->count().' locations purged.');
|
||||||
|
|||||||
@@ -243,6 +243,8 @@ class RestoreFromBackup extends Command
|
|||||||
$private_dirs = [
|
$private_dirs = [
|
||||||
'storage/private_uploads/accessories',
|
'storage/private_uploads/accessories',
|
||||||
'storage/private_uploads/assetmodels',
|
'storage/private_uploads/assetmodels',
|
||||||
|
'storage/private_uploads/maintenances',
|
||||||
|
'storage/private_uploads/models',
|
||||||
'storage/private_uploads/assets', // these are asset _files_, not the pictures.
|
'storage/private_uploads/assets', // these are asset _files_, not the pictures.
|
||||||
'storage/private_uploads/audits',
|
'storage/private_uploads/audits',
|
||||||
'storage/private_uploads/components',
|
'storage/private_uploads/components',
|
||||||
@@ -260,9 +262,10 @@ class RestoreFromBackup extends Command
|
|||||||
];
|
];
|
||||||
$public_dirs = [
|
$public_dirs = [
|
||||||
'public/uploads/accessories',
|
'public/uploads/accessories',
|
||||||
|
'public/uploads/assetmodels',
|
||||||
|
'public/uploads/maintenances',
|
||||||
'public/uploads/assets', // these are asset _pictures_, not asset files
|
'public/uploads/assets', // these are asset _pictures_, not asset files
|
||||||
'public/uploads/avatars',
|
'public/uploads/avatars',
|
||||||
//'public/uploads/barcodes', // we don't want this, let the barcodes be regenerated
|
|
||||||
'public/uploads/categories',
|
'public/uploads/categories',
|
||||||
'public/uploads/companies',
|
'public/uploads/companies',
|
||||||
'public/uploads/components',
|
'public/uploads/components',
|
||||||
|
|||||||
@@ -133,9 +133,18 @@ class Handler extends ExceptionHandler
|
|||||||
// This is traaaaash but it handles models that are not found while using route model binding :(
|
// This is traaaaash but it handles models that are not found while using route model binding :(
|
||||||
// The only alternative is to set that at *each* route, which is crazypants
|
// The only alternative is to set that at *each* route, which is crazypants
|
||||||
if ($e instanceof \Illuminate\Database\Eloquent\ModelNotFoundException) {
|
if ($e instanceof \Illuminate\Database\Eloquent\ModelNotFoundException) {
|
||||||
|
$ids = method_exists($e, 'getIds') ? $e->getIds() : [];
|
||||||
|
|
||||||
|
if (in_array('bulkedit', $ids, true)) {
|
||||||
|
$error_array = session()->get('bulk_asset_errors');
|
||||||
|
return redirect()
|
||||||
|
->route('hardware.index')
|
||||||
|
->withErrors($error_array, 'bulk_asset_errors')
|
||||||
|
->withInput();
|
||||||
|
}
|
||||||
|
|
||||||
// This gets the MVC model name from the exception and formats in a way that's less fugly
|
// This gets the MVC model name from the exception and formats in a way that's less fugly
|
||||||
$model_name = strtolower(implode(" ", preg_split('/(?=[A-Z])/', last(explode('\\', $e->getModel())))));
|
$model_name = trim(strtolower(implode(" ", preg_split('/(?=[A-Z])/', last(explode('\\', $e->getModel()))))));
|
||||||
$route = str_plural(strtolower(last(explode('\\', $e->getModel())))).'.index';
|
$route = str_plural(strtolower(last(explode('\\', $e->getModel())))).'.index';
|
||||||
|
|
||||||
// Sigh.
|
// Sigh.
|
||||||
@@ -151,9 +160,7 @@ class Handler extends ExceptionHandler
|
|||||||
$route = 'maintenances.index';
|
$route = 'maintenances.index';
|
||||||
} elseif ($route === 'licenseseats.index') {
|
} elseif ($route === 'licenseseats.index') {
|
||||||
$route = 'licenses.index';
|
$route = 'licenses.index';
|
||||||
} elseif ($route === 'customfields.index') {
|
} elseif (($route === 'customfieldsets.index') || ($route === 'customfields.index')) {
|
||||||
$route = 'fields.index';
|
|
||||||
} elseif ($route === 'customfieldsets.index') {
|
|
||||||
$route = 'fields.index';
|
$route = 'fields.index';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -870,7 +870,7 @@ class Helper
|
|||||||
$filetype = @finfo_file($finfo, $file);
|
$filetype = @finfo_file($finfo, $file);
|
||||||
finfo_close($finfo);
|
finfo_close($finfo);
|
||||||
|
|
||||||
if (($filetype == 'image/jpeg') || ($filetype == 'image/jpg') || ($filetype == 'image/png') || ($filetype == 'image/bmp') || ($filetype == 'image/gif') || ($filetype == 'image/avif') || ($filetype == 'image/webp') || ($filetype == 'video/mp4') || ($filetype == 'video/quicktime') || ($filetype == 'video/mpeg') || ($filetype == 'video/ogg') || ($filetype == 'video/webm') || ($filetype == 'video/x-msvide')) {
|
if (($filetype == 'image/jpeg') || ($filetype == 'image/jpg') || ($filetype == 'image/png') || ($filetype == 'image/bmp') || ($filetype == 'image/gif') || ($filetype == 'image/avif') || ($filetype == 'image/webp')) {
|
||||||
return $filetype;
|
return $filetype;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -878,12 +878,33 @@ class Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the file is an image, so we can show a preview
|
* Check if the file is a video, so we can show a preview
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @since [v3.0]
|
|
||||||
* @param File $file
|
* @param File $file
|
||||||
* @return string | Boolean
|
* @return string | Boolean
|
||||||
|
* @author [B. Wetherington] [<bwetherington@grokability.com>]
|
||||||
|
* @since [v8.1.18]
|
||||||
|
*/
|
||||||
|
public static function checkUploadIsVideo($file)
|
||||||
|
{
|
||||||
|
$finfo = @finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
|
||||||
|
$filetype = @finfo_file($finfo, $file);
|
||||||
|
finfo_close($finfo);
|
||||||
|
|
||||||
|
if (($filetype == 'video/mp4') || ($filetype == 'video/quicktime') || ($filetype == 'video/mpeg') || ($filetype == 'video/ogg') || ($filetype == 'video/webm') || ($filetype == 'video/x-msvide')) {
|
||||||
|
return $filetype;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the file is audio, so we can show a preview
|
||||||
|
*
|
||||||
|
* @param File $file
|
||||||
|
* @return string | Boolean
|
||||||
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
|
* @since [v3.0]
|
||||||
*/
|
*/
|
||||||
public static function checkUploadIsAudio($file)
|
public static function checkUploadIsAudio($file)
|
||||||
{
|
{
|
||||||
@@ -1522,11 +1543,6 @@ class Helper
|
|||||||
|
|
||||||
// return to previous page
|
// return to previous page
|
||||||
if ($redirect_option === 'back') {
|
if ($redirect_option === 'back') {
|
||||||
if ($backUrl === route('home')) {
|
|
||||||
return redirect()->to($backUrl)
|
|
||||||
->with('warning', trans('general.page_error'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->to($backUrl);
|
return redirect()->to($backUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ class IconHelper
|
|||||||
return 'fa-regular fa-envelope';
|
return 'fa-regular fa-envelope';
|
||||||
case 'phone':
|
case 'phone':
|
||||||
return 'fa-solid fa-phone';
|
return 'fa-solid fa-phone';
|
||||||
|
case 'mobile':
|
||||||
|
return 'fas fa-mobile-screen-button';
|
||||||
case 'long-arrow-right':
|
case 'long-arrow-right':
|
||||||
return 'fas fa-long-arrow-alt-right';
|
return 'fas fa-long-arrow-alt-right';
|
||||||
case 'download':
|
case 'download':
|
||||||
@@ -151,6 +153,7 @@ class IconHelper
|
|||||||
case 'location':
|
case 'location':
|
||||||
return 'fas fa-map-marker-alt';
|
return 'fas fa-map-marker-alt';
|
||||||
case 'superadmin':
|
case 'superadmin':
|
||||||
|
case 'admin':
|
||||||
return 'fas fa-crown';
|
return 'fas fa-crown';
|
||||||
case 'print':
|
case 'print':
|
||||||
return 'fa-solid fa-print';
|
return 'fa-solid fa-print';
|
||||||
|
|||||||
@@ -27,6 +27,36 @@ class StorageHelper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getMediaType($file_with_path) {
|
||||||
|
|
||||||
|
// The file exists and is allowed to be displayed inline
|
||||||
|
if (Storage::exists($file_with_path)) {
|
||||||
|
$fileinfo = pathinfo($file_with_path);
|
||||||
|
$extension = strtolower($fileinfo['extension']);
|
||||||
|
switch ($extension) {
|
||||||
|
case 'avif':
|
||||||
|
case 'jpg':
|
||||||
|
case 'png':
|
||||||
|
case 'gif':
|
||||||
|
case 'svg':
|
||||||
|
case 'webp':
|
||||||
|
return 'image';
|
||||||
|
case 'pdf':
|
||||||
|
return 'pdf';
|
||||||
|
case 'mp3':
|
||||||
|
case 'wav':
|
||||||
|
case 'ogg':
|
||||||
|
return 'audio';
|
||||||
|
case 'mp4':
|
||||||
|
case 'webm':
|
||||||
|
case 'mov':
|
||||||
|
return 'video';
|
||||||
|
default:
|
||||||
|
return $extension; // Default for unknown types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This determines the file types that should be allowed inline and checks their fileinfo extension
|
* This determines the file types that should be allowed inline and checks their fileinfo extension
|
||||||
@@ -52,7 +82,6 @@ class StorageHelper
|
|||||||
'pdf',
|
'pdf',
|
||||||
'png',
|
'png',
|
||||||
'svg',
|
'svg',
|
||||||
'svg',
|
|
||||||
'wav',
|
'wav',
|
||||||
'webm',
|
'webm',
|
||||||
'webp',
|
'webp',
|
||||||
|
|||||||
@@ -77,9 +77,25 @@ class AccessoriesController extends Controller
|
|||||||
$accessory->supplier_id = request('supplier_id');
|
$accessory->supplier_id = request('supplier_id');
|
||||||
$accessory->notes = request('notes');
|
$accessory->notes = request('notes');
|
||||||
|
|
||||||
$accessory = $request->handleImages($accessory);
|
if ($request->has('use_cloned_image')) {
|
||||||
|
$cloned_model_img = Accessory::select('image')->find($request->input('clone_image_from_id'));
|
||||||
|
if ($cloned_model_img) {
|
||||||
|
$new_image_name = 'clone-'.date('U').'-'.$cloned_model_img->image;
|
||||||
|
$new_image = 'accessories/'.$new_image_name;
|
||||||
|
Storage::disk('public')->copy('accessories/'.$cloned_model_img->image, $new_image);
|
||||||
|
$accessory->image = $new_image_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$accessory = $request->handleImages($accessory);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($request->get('redirect_option') === 'back'){
|
||||||
|
session()->put(['redirect_option' => 'index']);
|
||||||
|
} else {
|
||||||
|
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||||
|
}
|
||||||
|
|
||||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
|
||||||
// Was the accessory created?
|
// Was the accessory created?
|
||||||
if ($accessory->save()) {
|
if ($accessory->save()) {
|
||||||
// Redirect to the new accessory page
|
// Redirect to the new accessory page
|
||||||
@@ -114,11 +130,12 @@ class AccessoriesController extends Controller
|
|||||||
|
|
||||||
$this->authorize('create', Accessory::class);
|
$this->authorize('create', Accessory::class);
|
||||||
$cloned = clone $accessory;
|
$cloned = clone $accessory;
|
||||||
|
$accessory_to_clone = $accessory;
|
||||||
$cloned->id = null;
|
$cloned->id = null;
|
||||||
$cloned->deleted_at = '';
|
$cloned->deleted_at = '';
|
||||||
$cloned->location_id = null;
|
|
||||||
|
|
||||||
return view('accessories/edit')
|
return view('accessories/edit')
|
||||||
|
->with('cloned_model', $accessory_to_clone)
|
||||||
->with('item', $cloned);
|
->with('item', $cloned);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,132 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Accessories;
|
|
||||||
|
|
||||||
use App\Helpers\StorageHelper;
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\UploadFileRequest;
|
|
||||||
use App\Models\Actionlog;
|
|
||||||
use App\Models\Accessory;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use \Illuminate\Contracts\View\View;
|
|
||||||
use \Illuminate\Http\RedirectResponse;
|
|
||||||
use Illuminate\Support\Facades\Response;
|
|
||||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
|
||||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
|
||||||
|
|
||||||
class AccessoriesFilesController extends Controller
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Validates and stores files associated with a accessory.
|
|
||||||
*
|
|
||||||
* @param UploadFileRequest $request
|
|
||||||
* @param int $accessoryId
|
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @since [v1.0]
|
|
||||||
* @todo Switch to using the AssetFileRequest form request validator.
|
|
||||||
*/
|
|
||||||
public function store(UploadFileRequest $request, $accessoryId = null) : RedirectResponse
|
|
||||||
{
|
|
||||||
|
|
||||||
if (config('app.lock_passwords')) {
|
|
||||||
return redirect()->route('accessories.show', ['accessory'=>$accessoryId])->with('error', trans('general.feature_disabled'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$accessory = Accessory::find($accessoryId);
|
|
||||||
|
|
||||||
if (isset($accessory->id)) {
|
|
||||||
$this->authorize('accessories.files', $accessory);
|
|
||||||
|
|
||||||
if ($request->hasFile('file')) {
|
|
||||||
if (! Storage::exists('private_uploads/accessories')) {
|
|
||||||
Storage::makeDirectory('private_uploads/accessories', 775);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($request->file('file') as $file) {
|
|
||||||
|
|
||||||
$file_name = $request->handleFile('private_uploads/accessories/', 'accessory-'.$accessory->id, $file);
|
|
||||||
//Log the upload to the log
|
|
||||||
$accessory->logUpload($file_name, e($request->input('notes')));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return redirect()->route('accessories.show', $accessory->id)->withFragment('files')->with('success', trans('general.file_upload_success'));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->route('accessories.show', $accessory->id)->withFragment('files')->with('error', trans('general.no_files_uploaded'));
|
|
||||||
}
|
|
||||||
// Prepare the error message
|
|
||||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes the selected accessory file.
|
|
||||||
*
|
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @since [v1.0]
|
|
||||||
* @param int $accessoryId
|
|
||||||
* @param int $fileId
|
|
||||||
*/
|
|
||||||
public function destroy($accessoryId = null, $fileId = null) : RedirectResponse
|
|
||||||
{
|
|
||||||
if ($accessory = Accessory::find($accessoryId)) {
|
|
||||||
$this->authorize('update', $accessory);
|
|
||||||
|
|
||||||
if ($log = Actionlog::find($fileId)) {
|
|
||||||
|
|
||||||
if (Storage::exists('private_uploads/accessories/'.$log->filename)) {
|
|
||||||
try {
|
|
||||||
Storage::delete('private_uploads/accessories/' . $log->filename);
|
|
||||||
$log->delete();
|
|
||||||
return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success'));
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
Log::debug($e);
|
|
||||||
return redirect()->route('accessories.index')->with('error', trans('general.file_does_not_exist'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return redirect()->route('accessories.show', ['accessory' => $accessory])->withFragment('files')->with('error', trans('general.log_record_not_found'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows the selected file to be viewed.
|
|
||||||
*
|
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @since [v1.4]
|
|
||||||
* @param int $accessoryId
|
|
||||||
* @param int $fileId
|
|
||||||
*/
|
|
||||||
public function show($accessoryId = null, $fileId = null) : View | RedirectResponse | Response | BinaryFileResponse | StreamedResponse
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
// the accessory is valid
|
|
||||||
if ($accessory = Accessory::find($accessoryId)) {
|
|
||||||
$this->authorize('view', $accessory);
|
|
||||||
$this->authorize('accessories.files', $accessory);
|
|
||||||
|
|
||||||
if ($log = Actionlog::whereNotNull('filename')->where('item_id', $accessory->id)->find($fileId)) {
|
|
||||||
$file = 'private_uploads/accessories/'.$log->filename;
|
|
||||||
|
|
||||||
try {
|
|
||||||
return StorageHelper::showOrDownloadFile($file, $log->filename);
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return redirect()->route('accessories.show', ['accessory' => $accessory])->with('error', trans('general.file_not_found'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->route('accessories.show', ['accessory' => $accessory])->withFragment('files')->with('error', trans('general.log_record_not_found'));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -232,6 +232,7 @@ class AcceptanceController extends Controller
|
|||||||
'signature' => ($sig_filename) ? storage_path() . '/private_uploads/signatures/' . $sig_filename : null,
|
'signature' => ($sig_filename) ? storage_path() . '/private_uploads/signatures/' . $sig_filename : null,
|
||||||
'logo' => $path_logo,
|
'logo' => $path_logo,
|
||||||
'date_settings' => $branding_settings->date_display_format,
|
'date_settings' => $branding_settings->date_display_format,
|
||||||
|
'admin' => auth()->user()->present()?->fullName,
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($pdf_view_route!='') {
|
if ($pdf_view_route!='') {
|
||||||
@@ -347,6 +348,7 @@ class AcceptanceController extends Controller
|
|||||||
|
|
||||||
$acceptance->decline($sig_filename, $request->input('note'));
|
$acceptance->decline($sig_filename, $request->input('note'));
|
||||||
$acceptance->notify(new AcceptanceAssetDeclinedNotification($data));
|
$acceptance->notify(new AcceptanceAssetDeclinedNotification($data));
|
||||||
|
Log::debug('New event acceptance.');
|
||||||
event(new CheckoutDeclined($acceptance));
|
event(new CheckoutDeclined($acceptance));
|
||||||
$return_msg = trans('admin/users/message.declined');
|
$return_msg = trans('admin/users/message.declined');
|
||||||
}
|
}
|
||||||
@@ -356,13 +358,16 @@ class AcceptanceController extends Controller
|
|||||||
$recipient = User::find($acceptance->alert_on_response_id);
|
$recipient = User::find($acceptance->alert_on_response_id);
|
||||||
|
|
||||||
if ($recipient) {
|
if ($recipient) {
|
||||||
|
Log::debug('Attempting to send email acceptance.');
|
||||||
Mail::to($recipient)->send(new CheckoutAcceptanceResponseMail(
|
Mail::to($recipient)->send(new CheckoutAcceptanceResponseMail(
|
||||||
$acceptance,
|
$acceptance,
|
||||||
$recipient,
|
$recipient,
|
||||||
$request->input('asset_acceptance') === 'accepted',
|
$request->input('asset_acceptance') === 'accepted',
|
||||||
));
|
));
|
||||||
|
Log::debug('Send email notification sucess on checkout acceptance response.');
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
|
Log::error($e->getMessage());
|
||||||
Log::warning($e);
|
Log::warning($e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ class AssetModelsController extends Controller
|
|||||||
$assetmodel = $request->handleImages($assetmodel);
|
$assetmodel = $request->handleImages($assetmodel);
|
||||||
|
|
||||||
if ($assetmodel->save()) {
|
if ($assetmodel->save()) {
|
||||||
return response()->json(Helper::formatStandardApiResponse('success', $assetmodel, trans('admin/models/message.create.success')));
|
return response()->json(Helper::formatStandardApiResponse('success', (new AssetModelsTransformer)->transformAssetModel($assetmodel), trans('admin/models/message.create.success')));
|
||||||
}
|
}
|
||||||
return response()->json(Helper::formatStandardApiResponse('error', null, $assetmodel->getErrors()));
|
return response()->json(Helper::formatStandardApiResponse('error', null, $assetmodel->getErrors()));
|
||||||
|
|
||||||
@@ -207,7 +207,7 @@ class AssetModelsController extends Controller
|
|||||||
$assetmodel = AssetModel::findOrFail($id);
|
$assetmodel = AssetModel::findOrFail($id);
|
||||||
$assetmodel->fill($request->all());
|
$assetmodel->fill($request->all());
|
||||||
$assetmodel = $request->handleImages($assetmodel);
|
$assetmodel = $request->handleImages($assetmodel);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow custom_fieldset_id to override and populate fieldset_id.
|
* Allow custom_fieldset_id to override and populate fieldset_id.
|
||||||
* This is stupid, but required for legacy API support.
|
* This is stupid, but required for legacy API support.
|
||||||
@@ -222,7 +222,7 @@ class AssetModelsController extends Controller
|
|||||||
|
|
||||||
|
|
||||||
if ($assetmodel->save()) {
|
if ($assetmodel->save()) {
|
||||||
return response()->json(Helper::formatStandardApiResponse('success', $assetmodel, trans('admin/models/message.update.success')));
|
return response()->json(Helper::formatStandardApiResponse('success', (new AssetModelsTransformer)->transformAssetModel($assetmodel), trans('admin/models/message.update.success')));
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json(Helper::formatStandardApiResponse('error', null, $assetmodel->getErrors()));
|
return response()->json(Helper::formatStandardApiResponse('error', null, $assetmodel->getErrors()));
|
||||||
|
|||||||
@@ -117,15 +117,20 @@ class AssetsController extends Controller
|
|||||||
'jobtitle',
|
'jobtitle',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$all_custom_fields = CustomField::all(); //used as a 'cache' of custom fields throughout this page load
|
||||||
|
|
||||||
|
foreach ($all_custom_fields as $field) {
|
||||||
|
$allowed_columns[] = $field->db_column_name();
|
||||||
|
}
|
||||||
|
|
||||||
$filter = [];
|
$filter = [];
|
||||||
|
|
||||||
if ($request->filled('filter')) {
|
if ($request->filled('filter')) {
|
||||||
$filter = json_decode($request->input('filter'), true);
|
$filter = json_decode($request->input('filter'), true);
|
||||||
}
|
|
||||||
|
|
||||||
$all_custom_fields = CustomField::all(); //used as a 'cache' of custom fields throughout this page load
|
$filter = array_filter($filter, function ($key) use ($allowed_columns) {
|
||||||
foreach ($all_custom_fields as $field) {
|
return in_array($key, $allowed_columns);
|
||||||
$allowed_columns[] = $field->db_column_name();
|
}, ARRAY_FILTER_USE_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
$assets = Asset::select('assets.*')
|
$assets = Asset::select('assets.*')
|
||||||
|
|||||||
@@ -228,11 +228,16 @@ class ConsumablesController extends Controller
|
|||||||
foreach ($consumable->consumableAssignments as $consumable_assignment) {
|
foreach ($consumable->consumableAssignments as $consumable_assignment) {
|
||||||
$rows[] = [
|
$rows[] = [
|
||||||
'avatar' => ($consumable_assignment->user) ? e($consumable_assignment->user->present()->gravatar) : '',
|
'avatar' => ($consumable_assignment->user) ? e($consumable_assignment->user->present()->gravatar) : '',
|
||||||
'name' => ($consumable_assignment->user) ? $consumable_assignment->user->present()->nameUrl() : 'Deleted User',
|
'user' => ($consumable_assignment->user) ? [
|
||||||
|
'id' => (int) $consumable_assignment->user->id,
|
||||||
|
'name'=> e($consumable_assignment->user->present()->fullName()),
|
||||||
|
] : null,
|
||||||
'created_at' => Helper::getFormattedDateObject($consumable_assignment->created_at, 'datetime'),
|
'created_at' => Helper::getFormattedDateObject($consumable_assignment->created_at, 'datetime'),
|
||||||
'note' => ($consumable_assignment->note) ? e($consumable_assignment->note) : null,
|
'note' => ($consumable_assignment->note) ? e($consumable_assignment->note) : null,
|
||||||
'admin' => ($consumable_assignment->adminuser) ? $consumable_assignment->adminuser->present()->nameUrl() : null, // legacy, so we don't change the shape of the response
|
'created_by' => ($consumable_assignment->adminuser) ? [
|
||||||
'created_by' => ($consumable_assignment->adminuser) ? $consumable_assignment->adminuser->present()->nameUrl() : null,
|
'id' => (int) $consumable_assignment->adminuser->id,
|
||||||
|
'name'=> e($consumable_assignment->adminuser->present()->fullName()),
|
||||||
|
] : null,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ namespace App\Http\Controllers\Api;
|
|||||||
|
|
||||||
use App\Helpers\Helper;
|
use App\Helpers\Helper;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Transformers\AssetMaintenancesTransformer;
|
use App\Http\Requests\ImageUploadRequest;
|
||||||
|
use App\Http\Transformers\MaintenancesTransformer;
|
||||||
use App\Models\Asset;
|
use App\Models\Asset;
|
||||||
use App\Models\AssetMaintenance;
|
use App\Models\Maintenance;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use Illuminate\Support\Facades\Auth;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
@@ -18,13 +18,13 @@ use Illuminate\Http\JsonResponse;
|
|||||||
*
|
*
|
||||||
* @version v2.0
|
* @version v2.0
|
||||||
*/
|
*/
|
||||||
class AssetMaintenancesController extends Controller
|
class MaintenancesController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates the JSON response for asset maintenances listing view.
|
* Generates the JSON response for asset maintenances listing view.
|
||||||
*
|
*
|
||||||
* @see AssetMaintenancesController::getIndex() method that generates view
|
* @see MaintenancesController::getIndex() method that generates view
|
||||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||||
* @version v1.0
|
* @version v1.0
|
||||||
* @since [v1.8]
|
* @since [v1.8]
|
||||||
@@ -33,7 +33,7 @@ class AssetMaintenancesController extends Controller
|
|||||||
{
|
{
|
||||||
$this->authorize('view', Asset::class);
|
$this->authorize('view', Asset::class);
|
||||||
|
|
||||||
$maintenances = AssetMaintenance::select('asset_maintenances.*')
|
$maintenances = Maintenance::select('maintenances.*')
|
||||||
->with('asset', 'asset.model', 'asset.location', 'asset.defaultLoc', 'supplier', 'asset.company', 'asset.assetstatus', 'adminuser');
|
->with('asset', 'asset.model', 'asset.location', 'asset.defaultLoc', 'supplier', 'asset.company', 'asset.assetstatus', 'adminuser');
|
||||||
|
|
||||||
if ($request->filled('search')) {
|
if ($request->filled('search')) {
|
||||||
@@ -45,11 +45,11 @@ class AssetMaintenancesController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($request->filled('supplier_id')) {
|
if ($request->filled('supplier_id')) {
|
||||||
$maintenances->where('asset_maintenances.supplier_id', '=', $request->input('supplier_id'));
|
$maintenances->where('maintenances.supplier_id', '=', $request->input('supplier_id'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($request->filled('created_by')) {
|
if ($request->filled('created_by')) {
|
||||||
$maintenances->where('asset_maintenances.created_by', '=', $request->input('created_by'));
|
$maintenances->where('maintenances.created_by', '=', $request->input('created_by'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($request->filled('asset_maintenance_type')) {
|
if ($request->filled('asset_maintenance_type')) {
|
||||||
@@ -63,7 +63,7 @@ class AssetMaintenancesController extends Controller
|
|||||||
|
|
||||||
$allowed_columns = [
|
$allowed_columns = [
|
||||||
'id',
|
'id',
|
||||||
'title',
|
'name',
|
||||||
'asset_maintenance_time',
|
'asset_maintenance_time',
|
||||||
'asset_maintenance_type',
|
'asset_maintenance_type',
|
||||||
'cost',
|
'cost',
|
||||||
@@ -112,7 +112,7 @@ class AssetMaintenancesController extends Controller
|
|||||||
|
|
||||||
$total = $maintenances->count();
|
$total = $maintenances->count();
|
||||||
$maintenances = $maintenances->skip($offset)->take($limit)->get();
|
$maintenances = $maintenances->skip($offset)->take($limit)->get();
|
||||||
return (new AssetMaintenancesTransformer())->transformAssetMaintenances($maintenances, $total);
|
return (new MaintenancesTransformer())->transformMaintenances($maintenances, $total);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -121,22 +121,23 @@ class AssetMaintenancesController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Validates and stores the new asset maintenance
|
* Validates and stores the new asset maintenance
|
||||||
*
|
*
|
||||||
* @see AssetMaintenancesController::getCreate() method for the form
|
* @see MaintenancesController::getCreate() method for the form
|
||||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||||
* @version v1.0
|
* @version v1.0
|
||||||
* @since [v1.8]
|
* @since [v1.8]
|
||||||
*/
|
*/
|
||||||
public function store(Request $request) : JsonResponse | array
|
public function store(ImageUploadRequest $request) : JsonResponse | array
|
||||||
{
|
{
|
||||||
$this->authorize('update', Asset::class);
|
$this->authorize('update', Asset::class);
|
||||||
|
|
||||||
// create a new model instance
|
// create a new model instance
|
||||||
$maintenance = new AssetMaintenance();
|
$maintenance = new Maintenance();
|
||||||
$maintenance->fill($request->all());
|
$maintenance->fill($request->all());
|
||||||
$maintenance->created_by = auth()->id();
|
$maintenance->created_by = auth()->id();
|
||||||
|
$maintenance = $request->handleImages($maintenance);
|
||||||
// Was the asset maintenance created?
|
// Was the asset maintenance created?
|
||||||
if ($maintenance->save()) {
|
if ($maintenance->save()) {
|
||||||
return response()->json(Helper::formatStandardApiResponse('success', $maintenance, trans('admin/asset_maintenances/message.create.success')));
|
return response()->json(Helper::formatStandardApiResponse('success', $maintenance, trans('admin/maintenances/message.create.success')));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,11 +158,11 @@ class AssetMaintenancesController extends Controller
|
|||||||
{
|
{
|
||||||
$this->authorize('update', Asset::class);
|
$this->authorize('update', Asset::class);
|
||||||
|
|
||||||
if ($maintenance = AssetMaintenance::with('asset')->find($id)) {
|
if ($maintenance = Maintenance::with('asset')->find($id)) {
|
||||||
|
|
||||||
// Can this user manage this asset?
|
// Can this user manage this asset?
|
||||||
if (! Company::isCurrentUserHasAccess($maintenance->asset)) {
|
if (! Company::isCurrentUserHasAccess($maintenance->asset)) {
|
||||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('general.action_permission_denied', ['item_type' => trans('admin/asset_maintenances/general.maintenance'), 'id' => $id, 'action' => trans('general.edit')])));
|
return response()->json(Helper::formatStandardApiResponse('error', null, trans('general.action_permission_denied', ['item_type' => trans('admin/maintenances/general.maintenance'), 'id' => $id, 'action' => trans('general.edit')])));
|
||||||
}
|
}
|
||||||
|
|
||||||
// The asset this miantenance is attached to is not valid or has been deleted
|
// The asset this miantenance is attached to is not valid or has been deleted
|
||||||
@@ -172,13 +173,13 @@ class AssetMaintenancesController extends Controller
|
|||||||
$maintenance->fill($request->all());
|
$maintenance->fill($request->all());
|
||||||
|
|
||||||
if ($maintenance->save()) {
|
if ($maintenance->save()) {
|
||||||
return response()->json(Helper::formatStandardApiResponse('success', $maintenance, trans('admin/asset_maintenances/message.edit.success')));
|
return response()->json(Helper::formatStandardApiResponse('success', $maintenance, trans('admin/maintenances/message.edit.success')));
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json(Helper::formatStandardApiResponse('error', null, $maintenance->getErrors()));
|
return response()->json(Helper::formatStandardApiResponse('error', null, $maintenance->getErrors()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('general.item_not_found', ['item_type' => trans('admin/asset_maintenances/general.maintenance'), 'id' => $id])));
|
return response()->json(Helper::formatStandardApiResponse('error', null, trans('general.item_not_found', ['item_type' => trans('admin/maintenances/general.maintenance'), 'id' => $id])));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,20 +187,20 @@ class AssetMaintenancesController extends Controller
|
|||||||
* Delete an asset maintenance
|
* Delete an asset maintenance
|
||||||
*
|
*
|
||||||
* @author A. Gianotto <snipe@snipe.net>
|
* @author A. Gianotto <snipe@snipe.net>
|
||||||
* @param int $assetMaintenanceId
|
* @param int $maintenanceId
|
||||||
* @version v1.0
|
* @version v1.0
|
||||||
* @since [v4.0]
|
* @since [v4.0]
|
||||||
*/
|
*/
|
||||||
public function destroy($assetMaintenanceId) : JsonResponse | array
|
public function destroy($maintenanceId) : JsonResponse | array
|
||||||
{
|
{
|
||||||
$this->authorize('update', Asset::class);
|
$this->authorize('update', Asset::class);
|
||||||
// Check if the asset maintenance exists
|
// Check if the asset maintenance exists
|
||||||
|
|
||||||
$assetMaintenance = AssetMaintenance::findOrFail($assetMaintenanceId);
|
$maintenance = Maintenance::findOrFail($maintenanceId);
|
||||||
|
|
||||||
$assetMaintenance->delete();
|
$maintenance->delete();
|
||||||
|
|
||||||
return response()->json(Helper::formatStandardApiResponse('success', $assetMaintenance, trans('admin/asset_maintenances/message.delete.success')));
|
return response()->json(Helper::formatStandardApiResponse('success', $maintenance, trans('admin/maintenances/message.delete.success')));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -208,19 +209,19 @@ class AssetMaintenancesController extends Controller
|
|||||||
* View an asset maintenance
|
* View an asset maintenance
|
||||||
*
|
*
|
||||||
* @author A. Gianotto <snipe@snipe.net>
|
* @author A. Gianotto <snipe@snipe.net>
|
||||||
* @param int $assetMaintenanceId
|
* @param int $maintenanceId
|
||||||
* @version v1.0
|
* @version v1.0
|
||||||
* @since [v4.0]
|
* @since [v4.0]
|
||||||
*/
|
*/
|
||||||
public function show($assetMaintenanceId) : JsonResponse | array
|
public function show($maintenanceId) : JsonResponse | array
|
||||||
{
|
{
|
||||||
$this->authorize('view', Asset::class);
|
$this->authorize('view', Asset::class);
|
||||||
$assetMaintenance = AssetMaintenance::findOrFail($assetMaintenanceId);
|
$maintenance = Maintenance::findOrFail($maintenanceId);
|
||||||
if (! Company::isCurrentUserHasAccess($assetMaintenance->asset)) {
|
if (! Company::isCurrentUserHasAccess($maintenance->asset)) {
|
||||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'You cannot view a maintenance for that asset'));
|
return response()->json(Helper::formatStandardApiResponse('error', null, 'You cannot view a maintenance for that asset'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return (new AssetMaintenancesTransformer())->transformAssetMaintenance($assetMaintenance);
|
return (new MaintenancesTransformer())->transformMaintenance($maintenance);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -150,8 +150,11 @@ class SettingsController extends Controller
|
|||||||
if (!config('app.lock_passwords')) {
|
if (!config('app.lock_passwords')) {
|
||||||
try {
|
try {
|
||||||
Notification::send(Setting::first(), new MailTest());
|
Notification::send(Setting::first(), new MailTest());
|
||||||
|
Log::debug('Attempting to sending to '.config('mail.reply_to.address'));
|
||||||
return response()->json(['message' => 'Mail sent to '.config('mail.reply_to.address')], 200);
|
return response()->json(['message' => 'Mail sent to '.config('mail.reply_to.address')], 200);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
|
Log::error('Mail sent error using '.config('mail.reply_to.address') .': '. $e->getMessage());
|
||||||
|
Log::debug($e);
|
||||||
return response()->json(['message' => $e->getMessage()], 500);
|
return response()->json(['message' => $e->getMessage()], 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -315,4 +318,4 @@ class SettingsController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ class SuppliersController extends Controller
|
|||||||
public function destroy($id) : JsonResponse
|
public function destroy($id) : JsonResponse
|
||||||
{
|
{
|
||||||
$this->authorize('delete', Supplier::class);
|
$this->authorize('delete', Supplier::class);
|
||||||
$supplier = Supplier::with('asset_maintenances', 'assets', 'licenses')->withCount('asset_maintenances as asset_maintenances_count', 'assets as assets_count', 'licenses as licenses_count')->findOrFail($id);
|
$supplier = Supplier::with('maintenances', 'assets', 'licenses')->withCount('maintenances as maintenances_count', 'assets as assets_count', 'licenses as licenses_count')->findOrFail($id);
|
||||||
$this->authorize('delete', $supplier);
|
$this->authorize('delete', $supplier);
|
||||||
|
|
||||||
|
|
||||||
@@ -202,8 +202,8 @@ class SuppliersController extends Controller
|
|||||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/suppliers/message.delete.assoc_assets', ['asset_count' => (int) $supplier->assets_count])));
|
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/suppliers/message.delete.assoc_assets', ['asset_count' => (int) $supplier->assets_count])));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($supplier->asset_maintenances_count > 0) {
|
if ($supplier->maintenances_count > 0) {
|
||||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/suppliers/message.delete.assoc_maintenances', ['asset_maintenances_count' => $supplier->asset_maintenances_count])));
|
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/suppliers/message.delete.assoc_maintenances', ['maintenances_count' => $supplier->maintenances_count])));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($supplier->licenses_count > 0) {
|
if ($supplier->licenses_count > 0) {
|
||||||
|
|||||||
@@ -7,18 +7,9 @@ use App\Helpers\StorageHelper;
|
|||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\UploadFileRequest;
|
use App\Http\Requests\UploadFileRequest;
|
||||||
use App\Http\Transformers\UploadedFilesTransformer;
|
use App\Http\Transformers\UploadedFilesTransformer;
|
||||||
use App\Models\Accessory;
|
|
||||||
use App\Models\Actionlog;
|
use App\Models\Actionlog;
|
||||||
use App\Models\Asset;
|
|
||||||
use App\Models\AssetModel;
|
|
||||||
use App\Models\Component;
|
|
||||||
use App\Models\Consumable;
|
|
||||||
use App\Models\License;
|
|
||||||
use App\Models\Location;
|
|
||||||
use App\Models\User;
|
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||||
@@ -28,42 +19,6 @@ class UploadedFilesController extends Controller
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
static $map_object_type = [
|
|
||||||
'accessories' => Accessory::class,
|
|
||||||
'assets' => Asset::class,
|
|
||||||
'components' => Component::class,
|
|
||||||
'consumables' => Consumable::class,
|
|
||||||
'licenses' => License::class,
|
|
||||||
'locations' => Location::class,
|
|
||||||
'models' => AssetModel::class,
|
|
||||||
'users' => User::class,
|
|
||||||
];
|
|
||||||
|
|
||||||
static $map_storage_path = [
|
|
||||||
'accessories' => 'private_uploads/accessories/',
|
|
||||||
'assets' => 'private_uploads/assets/',
|
|
||||||
'components' => 'private_uploads/components/',
|
|
||||||
'consumables' => 'private_uploads/consumables/',
|
|
||||||
'licenses' => 'private_uploads/licenses/',
|
|
||||||
'locations' => 'private_uploads/locations/',
|
|
||||||
'models' => 'private_uploads/assetmodels/',
|
|
||||||
'users' => 'private_uploads/users/',
|
|
||||||
];
|
|
||||||
|
|
||||||
static $map_file_prefix= [
|
|
||||||
'accessories' => 'accessory',
|
|
||||||
'assets' => 'asset',
|
|
||||||
'components' => 'component',
|
|
||||||
'consumables' => 'consumable',
|
|
||||||
'licenses' => 'license',
|
|
||||||
'locations' => 'location',
|
|
||||||
'models' => 'model',
|
|
||||||
'users' => 'user',
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List files for an object
|
* List files for an object
|
||||||
*
|
*
|
||||||
@@ -90,19 +45,27 @@ class UploadedFilesController extends Controller
|
|||||||
'id',
|
'id',
|
||||||
'filename',
|
'filename',
|
||||||
'action_type',
|
'action_type',
|
||||||
|
'action_date',
|
||||||
'note',
|
'note',
|
||||||
'created_at',
|
'created_at',
|
||||||
];
|
];
|
||||||
|
|
||||||
$uploads = $object->uploads();
|
|
||||||
$offset = ($request->input('offset') > $object->count()) ? $object->count() : abs($request->input('offset'));
|
$uploads = Actionlog::select('action_logs.*')
|
||||||
|
->whereNotNull('filename')
|
||||||
|
->where('item_type', self::$map_object_type[$object_type])
|
||||||
|
->where('item_id', $object->id)
|
||||||
|
->where('action_type', '=', 'uploaded')
|
||||||
|
->with('adminuser');
|
||||||
|
|
||||||
|
$offset = ($request->input('offset') > $uploads->count()) ? $uploads->count() : abs($request->input('offset'));
|
||||||
$limit = app('api_limit_value');
|
$limit = app('api_limit_value');
|
||||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||||
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'action_logs.created_at';
|
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';
|
||||||
|
|
||||||
// Text search on action_logs fields
|
// Text search on action_logs fields
|
||||||
// We could use the normal Actionlogs text scope, but it's a very heavy query since it's searcghing across all relations
|
// We could use the normal Actionlogs text scope, but it's a very heavy query since it's searching across all relations
|
||||||
// And we generally won't need that here
|
// and we generally won't need that here
|
||||||
if ($request->filled('search')) {
|
if ($request->filled('search')) {
|
||||||
|
|
||||||
$uploads->where(
|
$uploads->where(
|
||||||
@@ -113,8 +76,10 @@ class UploadedFilesController extends Controller
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$total = $uploads->count();
|
||||||
$uploads = $uploads->skip($offset)->take($limit)->orderBy($sort, $order)->get();
|
$uploads = $uploads->skip($offset)->take($limit)->orderBy($sort, $order)->get();
|
||||||
return (new UploadedFilesTransformer())->transformFiles($uploads, $uploads->count());
|
|
||||||
|
return (new UploadedFilesTransformer())->transformFiles($uploads, $total);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,9 +20,11 @@ use App\Models\Consumable;
|
|||||||
use App\Models\License;
|
use App\Models\License;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Notifications\CurrentInventory;
|
use App\Notifications\CurrentInventory;
|
||||||
|
use Illuminate\Support\Facades\Artisan;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Gate;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
@@ -68,6 +70,7 @@ class UsersController extends Controller
|
|||||||
'users.notes',
|
'users.notes',
|
||||||
'users.permissions',
|
'users.permissions',
|
||||||
'users.phone',
|
'users.phone',
|
||||||
|
'users.mobile',
|
||||||
'users.state',
|
'users.state',
|
||||||
'users.two_factor_enrolled',
|
'users.two_factor_enrolled',
|
||||||
'users.two_factor_optin',
|
'users.two_factor_optin',
|
||||||
@@ -81,7 +84,12 @@ class UsersController extends Controller
|
|||||||
'users.autoassign_licenses',
|
'users.autoassign_licenses',
|
||||||
'users.website',
|
'users.website',
|
||||||
|
|
||||||
])->with('manager', 'groups', 'userloc', 'company', 'department', 'assets', 'licenses', 'accessories', 'consumables', 'createdBy', 'managesUsers', 'managedLocations', 'eulas')
|
])->with('manager')
|
||||||
|
->with('groups')
|
||||||
|
->with('userloc')
|
||||||
|
->with('company')
|
||||||
|
->with('department')
|
||||||
|
->with('createdBy')
|
||||||
->withCount([
|
->withCount([
|
||||||
'assets as assets_count' => function(Builder $query) {
|
'assets as assets_count' => function(Builder $query) {
|
||||||
$query->withoutTrashed();
|
$query->withoutTrashed();
|
||||||
@@ -102,10 +110,26 @@ class UsersController extends Controller
|
|||||||
$users = $users->where('users.activated', '=', $request->input('activated'));
|
$users = $users->where('users.activated', '=', $request->input('activated'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($request->input('admins') == 'true') {
|
||||||
|
$users = $users->OnlyAdminsAndSuperAdmins();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->input('superadmins') == 'true') {
|
||||||
|
$users = $users->OnlySuperAdmins();
|
||||||
|
}
|
||||||
|
|
||||||
if ($request->filled('company_id')) {
|
if ($request->filled('company_id')) {
|
||||||
$users = $users->where('users.company_id', '=', $request->input('company_id'));
|
$users = $users->where('users.company_id', '=', $request->input('company_id'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($request->filled('phone')) {
|
||||||
|
$users = $users->where('users.phone', '=', $request->input('phone'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->filled('mobile')) {
|
||||||
|
$users = $users->where('users.mobile', '=', $request->input('mobile'));
|
||||||
|
}
|
||||||
|
|
||||||
if ($request->filled('location_id')) {
|
if ($request->filled('location_id')) {
|
||||||
$users = $users->where('users.location_id', '=', $request->input('location_id'));
|
$users = $users->where('users.location_id', '=', $request->input('location_id'));
|
||||||
}
|
}
|
||||||
@@ -278,6 +302,7 @@ class UsersController extends Controller
|
|||||||
'manages_users_count',
|
'manages_users_count',
|
||||||
'manages_locations_count',
|
'manages_locations_count',
|
||||||
'phone',
|
'phone',
|
||||||
|
'mobile',
|
||||||
'address',
|
'address',
|
||||||
'city',
|
'city',
|
||||||
'state',
|
'state',
|
||||||
@@ -475,8 +500,25 @@ class UsersController extends Controller
|
|||||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'You cannot be your own manager'));
|
return response()->json(Helper::formatStandardApiResponse('error', null, 'You cannot be your own manager'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($request->filled('password')) {
|
// check for permissions related fields and pull them out if the current user cannot edit them
|
||||||
$user->password = bcrypt($request->input('password'));
|
if (auth()->user()->can('canEditAuthFields', $user) && auth()->user()->can('editableOnDemo')) {
|
||||||
|
|
||||||
|
if ($request->filled('password')) {
|
||||||
|
$user->password = bcrypt($request->input('password'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->filled('username')) {
|
||||||
|
$user->username = $request->input('username');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->filled('email')) {
|
||||||
|
$user->email = $request->input('email');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->filled('activated')) {
|
||||||
|
$user->activated = $request->input('activated');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to use has() instead of filled()
|
// We need to use has() instead of filled()
|
||||||
@@ -791,4 +833,37 @@ class UsersController extends Controller
|
|||||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.user_not_found')), 200);
|
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.user_not_found')), 200);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the LDAP sync command to import users from LDAP via API.
|
||||||
|
*
|
||||||
|
* @author A. Gianotto <snipe@snipe.net>
|
||||||
|
* @since 8.2.2
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function syncLdapUsers(Request $request)
|
||||||
|
{
|
||||||
|
$this->authorize('update', User::class);
|
||||||
|
// Call Artisan LDAP import command.
|
||||||
|
|
||||||
|
Artisan::call('snipeit:ldap-sync', ['--location_id' => $request->input('location_id'), '--json_summary' => true]);
|
||||||
|
|
||||||
|
// Collect and parse JSON summary.
|
||||||
|
$ldap_results_json = Artisan::output();
|
||||||
|
$ldap_results = json_decode($ldap_results_json, true);
|
||||||
|
|
||||||
|
if (!$ldap_results) {
|
||||||
|
return response()->json(Helper::formatStandardApiResponse('error', null,trans('general.no_results')), 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Direct user to appropriate status page.
|
||||||
|
if ($ldap_results['error']) {
|
||||||
|
return response()->json(Helper::formatStandardApiResponse('error', null, $ldap_results['error_message']), 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json(Helper::formatStandardApiResponse('success', null, $ldap_results['summary']), 200);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,20 @@ class AssetModelsController extends Controller
|
|||||||
$model->fieldset_id = $request->input('fieldset_id');
|
$model->fieldset_id = $request->input('fieldset_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
$model = $request->handleImages($model);
|
if ($request->has('use_cloned_image')) {
|
||||||
|
$cloned_model_img = AssetModel::select('image')->find($request->input('clone_image_from_id'));
|
||||||
|
if ($cloned_model_img) {
|
||||||
|
$new_image_name = 'clone-'.date('U').'-'.$cloned_model_img->image;
|
||||||
|
$new_image = 'models/'.$new_image_name;
|
||||||
|
Storage::disk('public')->copy('models/'.$cloned_model_img->image, $new_image);
|
||||||
|
$model->image = $new_image_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$model = $request->handleImages($model);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ($model->save()) {
|
if ($model->save()) {
|
||||||
if ($this->shouldAddDefaultValues($request->input())) {
|
if ($this->shouldAddDefaultValues($request->input())) {
|
||||||
@@ -271,7 +284,7 @@ class AssetModelsController extends Controller
|
|||||||
->with('depreciation_list', Helper::depreciationList())
|
->with('depreciation_list', Helper::depreciationList())
|
||||||
->with('item', $model)
|
->with('item', $model)
|
||||||
->with('model_id', $model->id)
|
->with('model_id', $model->id)
|
||||||
->with('clone_model', $cloned_model);
|
->with('cloned_model', $cloned_model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,115 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
use App\Helpers\StorageHelper;
|
|
||||||
use App\Http\Requests\UploadFileRequest;
|
|
||||||
use App\Models\Actionlog;
|
|
||||||
use App\Models\AssetModel;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Illuminate\Http\Response;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
use \Symfony\Component\HttpFoundation\StreamedResponse;
|
|
||||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
|
||||||
|
|
||||||
class AssetModelsFilesController extends Controller
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Upload a file to the server.
|
|
||||||
*
|
|
||||||
* @param UploadFileRequest $request
|
|
||||||
* @param int $modelId
|
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
|
||||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
|
||||||
*@since [v1.0]
|
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
*/
|
|
||||||
public function store(UploadFileRequest $request, $modelId = null) : RedirectResponse
|
|
||||||
{
|
|
||||||
if (! $model = AssetModel::find($modelId)) {
|
|
||||||
return redirect()->route('models.index')->with('error', trans('admin/hardware/message.does_not_exist'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->authorize('update', $model);
|
|
||||||
|
|
||||||
if ($request->hasFile('file')) {
|
|
||||||
if (! Storage::exists('private_uploads/assetmodels')) {
|
|
||||||
Storage::makeDirectory('private_uploads/assetmodels', 775);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($request->file('file') as $file) {
|
|
||||||
|
|
||||||
$file_name = $request->handleFile('private_uploads/assetmodels/','model-'.$model->id,$file);
|
|
||||||
|
|
||||||
$model->logUpload($file_name, $request->get('notes'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->back()->withFragment('files')->with('success', trans('general.file_upload_success'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->back()->withFragment('files')->with('error', trans('admin/hardware/message.upload.nofiles'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check for permissions and display the file.
|
|
||||||
*
|
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @param int $modelId
|
|
||||||
* @param int $fileId
|
|
||||||
* @since [v1.0]
|
|
||||||
*/
|
|
||||||
public function show(AssetModel $model, $fileId = null) : StreamedResponse | Response | RedirectResponse | BinaryFileResponse
|
|
||||||
{
|
|
||||||
|
|
||||||
$this->authorize('view', $model);
|
|
||||||
|
|
||||||
if (! $log = Actionlog::find($fileId)) {
|
|
||||||
return response('No matching record for that model/file', 500)
|
|
||||||
->header('Content-Type', 'text/plain');
|
|
||||||
}
|
|
||||||
|
|
||||||
$file = 'private_uploads/assetmodels/'.$log->filename;
|
|
||||||
|
|
||||||
if (! Storage::exists($file)) {
|
|
||||||
return response('File '.$file.' not found on server', 404)
|
|
||||||
->header('Content-Type', 'text/plain');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request('inline') == 'true') {
|
|
||||||
|
|
||||||
$headers = [
|
|
||||||
'Content-Disposition' => 'inline',
|
|
||||||
];
|
|
||||||
|
|
||||||
return Storage::download($file, $log->filename, $headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
return StorageHelper::downloader($file);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete the associated file
|
|
||||||
*
|
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @param int $modelId
|
|
||||||
* @param int $fileId
|
|
||||||
* @since [v1.0]
|
|
||||||
*/
|
|
||||||
public function destroy(AssetModel $model, $fileId = null) : RedirectResponse
|
|
||||||
{
|
|
||||||
$rel_path = 'private_uploads/assetmodels';
|
|
||||||
$this->authorize('update', $model);
|
|
||||||
$log = Actionlog::find($fileId);
|
|
||||||
if ($log) {
|
|
||||||
if (Storage::exists($rel_path.'/'.$log->filename)) {
|
|
||||||
Storage::delete($rel_path.'/'.$log->filename);
|
|
||||||
}
|
|
||||||
$log->delete();
|
|
||||||
|
|
||||||
return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success'));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Assets;
|
|
||||||
|
|
||||||
use App\Helpers\StorageHelper;
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\UploadFileRequest;
|
|
||||||
use App\Models\Actionlog;
|
|
||||||
use App\Models\Asset;
|
|
||||||
use \Illuminate\Http\Response;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
use \Illuminate\Contracts\View\View;
|
|
||||||
use \Illuminate\Http\RedirectResponse;
|
|
||||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
|
||||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
|
||||||
|
|
||||||
class AssetFilesController extends Controller
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Upload a file to the server.
|
|
||||||
*
|
|
||||||
* @param UploadFileRequest $request
|
|
||||||
* @param int $assetId
|
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
|
||||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
|
||||||
*@since [v1.0]
|
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
*/
|
|
||||||
public function store(UploadFileRequest $request, Asset $asset) : RedirectResponse
|
|
||||||
{
|
|
||||||
|
|
||||||
$this->authorize('update', $asset);
|
|
||||||
|
|
||||||
if ($request->hasFile('file')) {
|
|
||||||
if (! Storage::exists('private_uploads/assets')) {
|
|
||||||
Storage::makeDirectory('private_uploads/assets', 775);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($request->file('file') as $file) {
|
|
||||||
$file_name = $request->handleFile('private_uploads/assets/','hardware-'.$asset->id, $file);
|
|
||||||
|
|
||||||
$asset->logUpload($file_name, $request->get('notes'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.upload.success'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->back()->with('error', trans('admin/hardware/message.upload.nofiles'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check for permissions and display the file.
|
|
||||||
*
|
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @param int $assetId
|
|
||||||
* @param int $fileId
|
|
||||||
* @since [v1.0]
|
|
||||||
*/
|
|
||||||
public function show(Asset $asset, $fileId = null) : View | RedirectResponse | Response | StreamedResponse | BinaryFileResponse
|
|
||||||
{
|
|
||||||
|
|
||||||
$this->authorize('view', $asset);
|
|
||||||
|
|
||||||
if ($log = Actionlog::whereNotNull('filename')->where('item_id', $asset->id)->find($fileId)) {
|
|
||||||
$file = 'private_uploads/assets/'.$log->filename;
|
|
||||||
|
|
||||||
if ($log->action_type == 'audit') {
|
|
||||||
$file = 'private_uploads/audits/'.$log->filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
return StorageHelper::showOrDownloadFile($file, $log->filename);
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return redirect()->route('hardware.show', $asset)->with('error', trans('general.file_not_found'));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->route('hardware.show', $asset)->with('error', trans('general.log_record_not_found'));
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete the associated file
|
|
||||||
*
|
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @param int $assetId
|
|
||||||
* @param int $fileId
|
|
||||||
* @since [v1.0]
|
|
||||||
*/
|
|
||||||
public function destroy(Asset $asset, $fileId = null) : RedirectResponse
|
|
||||||
{
|
|
||||||
$this->authorize('update', $asset);
|
|
||||||
$rel_path = 'private_uploads/assets';
|
|
||||||
|
|
||||||
if ($log = Actionlog::find($fileId)) {
|
|
||||||
if (Storage::exists($rel_path.'/'.$log->filename)) {
|
|
||||||
Storage::delete($rel_path.'/'.$log->filename);
|
|
||||||
}
|
|
||||||
$log->delete();
|
|
||||||
return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->route('hardware.show', $asset)->with('error', trans('general.log_record_not_found'));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -157,8 +157,16 @@ class AssetsController extends Controller
|
|||||||
$asset->location_id = $request->input('rtd_location_id', null);
|
$asset->location_id = $request->input('rtd_location_id', null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the image (if one was chosen.)
|
if ($request->has('use_cloned_image')) {
|
||||||
if ($request->has('image')) {
|
$cloned_model_img = Asset::select('image')->find($request->input('clone_image_from_id'));
|
||||||
|
if ($cloned_model_img) {
|
||||||
|
$new_image_name = 'clone-'.date('U').'-'.$cloned_model_img->image;
|
||||||
|
$new_image = 'assets/'.$new_image_name;
|
||||||
|
Storage::disk('public')->copy('assets/'.$cloned_model_img->image, $new_image);
|
||||||
|
$asset->image = $new_image_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
$asset = $request->handleImages($asset);
|
$asset = $request->handleImages($asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,8 +234,15 @@ class AssetsController extends Controller
|
|||||||
$failures[] = join(",", $asset->getErrors()->all());
|
$failures[] = join(",", $asset->getErrors()->all());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if($request->get('redirect_option') === 'back'){
|
||||||
|
session()->put(['redirect_option' => 'index']);
|
||||||
|
} else {
|
||||||
|
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||||
|
}
|
||||||
|
|
||||||
|
session()->put(['checkout_to_type' => $request->get('checkout_to_type'),
|
||||||
|
'other_redirect' => 'model' ]);
|
||||||
|
|
||||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]);
|
|
||||||
|
|
||||||
|
|
||||||
if ($successes) {
|
if ($successes) {
|
||||||
@@ -409,6 +424,9 @@ class AssetsController extends Controller
|
|||||||
$model = AssetModel::find($request->get('model_id'));
|
$model = AssetModel::find($request->get('model_id'));
|
||||||
if (($model) && ($model->fieldset)) {
|
if (($model) && ($model->fieldset)) {
|
||||||
foreach ($model->fieldset->fields as $field) {
|
foreach ($model->fieldset->fields as $field) {
|
||||||
|
if ($field->element == 'checkbox' && !$request->has($field->db_column)) {
|
||||||
|
$asset->{$field->db_column} = null;
|
||||||
|
}
|
||||||
if ($request->has($field->db_column)) {
|
if ($request->has($field->db_column)) {
|
||||||
if ($field->field_encrypted == '1') {
|
if ($field->field_encrypted == '1') {
|
||||||
if (Gate::allows('assets.view.encrypted_custom_fields')) {
|
if (Gate::allows('assets.view.encrypted_custom_fields')) {
|
||||||
@@ -641,8 +659,9 @@ class AssetsController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function getClone(Asset $asset)
|
public function getClone(Asset $asset)
|
||||||
{
|
{
|
||||||
$this->authorize('create', $asset);
|
$this->authorize('create', Asset::class);
|
||||||
$cloned = clone $asset;
|
$cloned = clone $asset;
|
||||||
|
$cloned_model = $asset;
|
||||||
$cloned->id = null;
|
$cloned->id = null;
|
||||||
$cloned->asset_tag = '';
|
$cloned->asset_tag = '';
|
||||||
$cloned->serial = '';
|
$cloned->serial = '';
|
||||||
@@ -652,6 +671,7 @@ class AssetsController extends Controller
|
|||||||
return view('hardware/edit')
|
return view('hardware/edit')
|
||||||
->with('statuslabel_list', Helper::statusLabelList())
|
->with('statuslabel_list', Helper::statusLabelList())
|
||||||
->with('statuslabel_types', Helper::statusTypeList())
|
->with('statuslabel_types', Helper::statusTypeList())
|
||||||
|
->with('cloned_model', $cloned_model)
|
||||||
->with('item', $cloned);
|
->with('item', $cloned);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -161,6 +161,7 @@ class BulkAssetsController extends Controller
|
|||||||
|
|
||||||
$models = $assets->unique('model_id');
|
$models = $assets->unique('model_id');
|
||||||
$modelNames = [];
|
$modelNames = [];
|
||||||
|
|
||||||
foreach($models as $model) {
|
foreach($models as $model) {
|
||||||
$modelNames[] = $model->model->name;
|
$modelNames[] = $model->model->name;
|
||||||
}
|
}
|
||||||
@@ -196,7 +197,6 @@ class BulkAssetsController extends Controller
|
|||||||
|
|
||||||
case 'edit':
|
case 'edit':
|
||||||
$this->authorize('update', Asset::class);
|
$this->authorize('update', Asset::class);
|
||||||
|
|
||||||
return view('hardware/bulk')
|
return view('hardware/bulk')
|
||||||
->with('assets', $asset_ids)
|
->with('assets', $asset_ids)
|
||||||
->with('statuslabel_list', Helper::statusLabelList())
|
->with('statuslabel_list', Helper::statusLabelList())
|
||||||
@@ -224,11 +224,8 @@ class BulkAssetsController extends Controller
|
|||||||
$error_array = array();
|
$error_array = array();
|
||||||
|
|
||||||
// Get the back url from the session and then destroy the session
|
// Get the back url from the session and then destroy the session
|
||||||
$bulk_back_url = route('hardware.index');
|
|
||||||
|
|
||||||
if ($request->session()->has('bulk_back_url')) {
|
$bulk_back_url = $request->session()->pull('bulk_back_url', url()->previous());
|
||||||
$bulk_back_url = $request->session()->pull('bulk_back_url');
|
|
||||||
}
|
|
||||||
|
|
||||||
$custom_field_columns = CustomField::all()->pluck('db_column')->toArray();
|
$custom_field_columns = CustomField::all()->pluck('db_column')->toArray();
|
||||||
|
|
||||||
@@ -543,7 +540,13 @@ class BulkAssetsController extends Controller
|
|||||||
} // end asset foreach
|
} // end asset foreach
|
||||||
|
|
||||||
if ($has_errors > 0) {
|
if ($has_errors > 0) {
|
||||||
return redirect($bulk_back_url)->with('bulk_asset_errors', $error_array);
|
session()->put('bulkedit_ids', $request->input('ids'));
|
||||||
|
session()->put('bulk_asset_errors',$error_array);
|
||||||
|
|
||||||
|
return redirect()
|
||||||
|
->route('hardware.index')
|
||||||
|
->with('bulk_asset_errors', $error_array)
|
||||||
|
->withInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect($bulk_back_url)->with('success', trans('admin/hardware/message.update.success'));
|
return redirect($bulk_back_url)->with('success', trans('admin/hardware/message.update.success'));
|
||||||
@@ -735,4 +738,33 @@ class BulkAssetsController extends Controller
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function bulkEditForm(): View|RedirectResponse
|
||||||
|
{
|
||||||
|
$this->authorize('update', Asset::class);
|
||||||
|
|
||||||
|
$asset_ids = session()->pull('bulkedit_ids', []);
|
||||||
|
|
||||||
|
if (empty($asset_ids)) {
|
||||||
|
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.update.no_assets_selected'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$assets = Asset::with('model')->withTrashed()->whereIn('id', $asset_ids)->get();
|
||||||
|
|
||||||
|
if ($assets->isEmpty()) {
|
||||||
|
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.update.assets_do_not_exist_or_are_invalid'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$models = $assets->unique('model_id');
|
||||||
|
$modelNames = [];
|
||||||
|
foreach ($models as $model) {
|
||||||
|
$modelNames[] = $model->model->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return view('hardware/bulk')
|
||||||
|
->with('assets', $asset_ids)
|
||||||
|
->with('statuslabel_list', Helper::statusLabelList())
|
||||||
|
->with('models', $models->pluck(['model']))
|
||||||
|
->with('modelNames', $modelNames);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,7 +88,12 @@ class ComponentsController extends Controller
|
|||||||
|
|
||||||
$component = $request->handleImages($component);
|
$component = $request->handleImages($component);
|
||||||
|
|
||||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
if($request->get('redirect_option') === 'back'){
|
||||||
|
session()->put(['redirect_option' => 'index']);
|
||||||
|
} else {
|
||||||
|
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($component->save()) {
|
if ($component->save()) {
|
||||||
return Helper::getRedirectOption($request, $component->id, 'Components')
|
return Helper::getRedirectOption($request, $component->id, 'Components')
|
||||||
|
|||||||
@@ -1,138 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Components;
|
|
||||||
|
|
||||||
use App\Helpers\StorageHelper;
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\UploadFileRequest;
|
|
||||||
use App\Models\Actionlog;
|
|
||||||
use App\Models\Component;
|
|
||||||
use Illuminate\Support\Facades\Response;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
|
|
||||||
class ComponentsFilesController extends Controller
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Validates and stores files associated with a component.
|
|
||||||
*
|
|
||||||
* @param UploadFileRequest $request
|
|
||||||
* @param int $componentId
|
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
|
||||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
|
||||||
*@author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @since [v1.0]
|
|
||||||
* @todo Switch to using the AssetFileRequest form request validator.
|
|
||||||
*/
|
|
||||||
public function store(UploadFileRequest $request, $componentId = null)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (config('app.lock_passwords')) {
|
|
||||||
return redirect()->route('components.show', ['component'=>$componentId])->with('error', trans('general.feature_disabled'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$component = Component::find($componentId);
|
|
||||||
|
|
||||||
if (isset($component->id)) {
|
|
||||||
$this->authorize('update', $component);
|
|
||||||
|
|
||||||
if ($request->hasFile('file')) {
|
|
||||||
if (! Storage::exists('private_uploads/components')) {
|
|
||||||
Storage::makeDirectory('private_uploads/components', 775);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($request->file('file') as $file) {
|
|
||||||
$file_name = $request->handleFile('private_uploads/components/','component-'.$component->id, $file);
|
|
||||||
|
|
||||||
//Log the upload to the log
|
|
||||||
$component->logUpload($file_name, e($request->input('notes')));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return redirect()->route('components.show', $component->id)->withFragment('files')->with('success', trans('general.file_upload_success'));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->route('components.show', $component->id)->with('error', trans('general.no_files_uploaded'));
|
|
||||||
}
|
|
||||||
// Prepare the error message
|
|
||||||
return redirect()->route('components.index')
|
|
||||||
->with('error', trans('general.file_does_not_exist'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes the selected component file.
|
|
||||||
*
|
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @since [v1.0]
|
|
||||||
* @param int $componentId
|
|
||||||
* @param int $fileId
|
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
|
||||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
|
||||||
*/
|
|
||||||
public function destroy($componentId = null, $fileId = null)
|
|
||||||
{
|
|
||||||
$component = Component::find($componentId);
|
|
||||||
|
|
||||||
// the asset is valid
|
|
||||||
if (isset($component->id)) {
|
|
||||||
$this->authorize('update', $component);
|
|
||||||
$log = Actionlog::find($fileId);
|
|
||||||
|
|
||||||
// Remove the file if one exists
|
|
||||||
if (Storage::exists('components/'.$log->filename)) {
|
|
||||||
try {
|
|
||||||
Storage::delete('components/'.$log->filename);
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
Log::debug($e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$log->delete();
|
|
||||||
|
|
||||||
return redirect()->back()->withFragment('files')
|
|
||||||
->with('success', trans('admin/hardware/message.deletefile.success'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Redirect to the licence management page
|
|
||||||
return redirect()->route('components.index')->with('error', trans('general.file_does_not_exist'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows the selected file to be viewed.
|
|
||||||
*
|
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @since [v1.4]
|
|
||||||
* @param int $componentId
|
|
||||||
* @param int $fileId
|
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
|
||||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
|
||||||
*/
|
|
||||||
public function show($componentId = null, $fileId = null)
|
|
||||||
{
|
|
||||||
Log::debug('Private filesystem is: '.config('filesystems.default'));
|
|
||||||
|
|
||||||
|
|
||||||
// the component is valid
|
|
||||||
if ($component = Component::find($componentId)) {
|
|
||||||
$this->authorize('view', $component);
|
|
||||||
$this->authorize('components.files', $component);
|
|
||||||
|
|
||||||
if ($log = Actionlog::whereNotNull('filename')->where('item_id', $component->id)->find($fileId)) {
|
|
||||||
|
|
||||||
$file = 'private_uploads/components/'.$log->filename;
|
|
||||||
|
|
||||||
try {
|
|
||||||
return StorageHelper::showOrDownloadFile($file, $log->filename);
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return redirect()->route('components.show', ['component' => $component])->with('error', trans('general.file_not_found'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return redirect()->route('components.show', ['component' => $component])->with('error', trans('general.log_record_not_found'));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->route('components.index')->with('error', trans('general.file_does_not_exist', ['id' => $fileId]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,7 @@ use App\Http\Controllers\Controller;
|
|||||||
use App\Http\Requests\ImageUploadRequest;
|
use App\Http\Requests\ImageUploadRequest;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use App\Models\Consumable;
|
use App\Models\Consumable;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use \Illuminate\Contracts\View\View;
|
use \Illuminate\Contracts\View\View;
|
||||||
@@ -81,13 +81,29 @@ class ConsumablesController extends Controller
|
|||||||
$consumable->purchase_date = $request->input('purchase_date');
|
$consumable->purchase_date = $request->input('purchase_date');
|
||||||
$consumable->purchase_cost = $request->input('purchase_cost');
|
$consumable->purchase_cost = $request->input('purchase_cost');
|
||||||
$consumable->qty = $request->input('qty');
|
$consumable->qty = $request->input('qty');
|
||||||
$consumable->created_by = auth()->id();
|
$consumable->created_by = auth()->id();
|
||||||
$consumable->notes = $request->input('notes');
|
$consumable->notes = $request->input('notes');
|
||||||
|
|
||||||
|
|
||||||
$consumable = $request->handleImages($consumable);
|
if ($request->has('use_cloned_image')) {
|
||||||
|
$cloned_model_img = Consumable::select('image')->find($request->input('clone_image_from_id'));
|
||||||
|
if ($cloned_model_img) {
|
||||||
|
$new_image_name = 'clone-'.date('U').'-'.$cloned_model_img->image;
|
||||||
|
$new_image = 'consumables/'.$new_image_name;
|
||||||
|
Storage::disk('public')->copy('consumables/'.$cloned_model_img->image, $new_image);
|
||||||
|
$consumable->image = $new_image_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$consumable = $request->handleImages($consumable);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($request->get('redirect_option') === 'back'){
|
||||||
|
session()->put(['redirect_option' => 'index']);
|
||||||
|
} else {
|
||||||
|
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||||
|
}
|
||||||
|
|
||||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
|
||||||
|
|
||||||
if ($consumable->save()) {
|
if ($consumable->save()) {
|
||||||
return Helper::getRedirectOption($request, $consumable->id, 'Consumables')
|
return Helper::getRedirectOption($request, $consumable->id, 'Consumables')
|
||||||
@@ -213,9 +229,10 @@ class ConsumablesController extends Controller
|
|||||||
$consumable_to_close = $consumable;
|
$consumable_to_close = $consumable;
|
||||||
$consumable = clone $consumable_to_close;
|
$consumable = clone $consumable_to_close;
|
||||||
$consumable->id = null;
|
$consumable->id = null;
|
||||||
$consumable->image = null;
|
|
||||||
$consumable->created_by = null;
|
$consumable->created_by = null;
|
||||||
|
|
||||||
return view('consumables/edit')->with('item', $consumable);
|
return view('consumables/edit')
|
||||||
|
->with('cloned_model', $consumable_to_close)
|
||||||
|
->with('item', $consumable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,134 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Consumables;
|
|
||||||
|
|
||||||
use App\Helpers\StorageHelper;
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\UploadFileRequest;
|
|
||||||
use App\Models\Actionlog;
|
|
||||||
use App\Models\Consumable;
|
|
||||||
use Illuminate\Support\Facades\Response;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
use Symfony\Consumable\HttpFoundation\JsonResponse;
|
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
class ConsumablesFilesController extends Controller
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Validates and stores files associated with a consumable.
|
|
||||||
*
|
|
||||||
* @param UploadFileRequest $request
|
|
||||||
* @param int $consumableId
|
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
|
||||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
|
||||||
*@author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @since [v1.0]
|
|
||||||
* @todo Switch to using the AssetFileRequest form request validator.
|
|
||||||
*/
|
|
||||||
public function store(UploadFileRequest $request, $consumableId = null)
|
|
||||||
{
|
|
||||||
if (config('app.lock_passwords')) {
|
|
||||||
return redirect()->route('consumables.show', ['consumable'=>$consumableId])->with('error', trans('general.feature_disabled'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$consumable = Consumable::find($consumableId);
|
|
||||||
|
|
||||||
if (isset($consumable->id)) {
|
|
||||||
$this->authorize('update', $consumable);
|
|
||||||
|
|
||||||
if ($request->hasFile('file')) {
|
|
||||||
if (! Storage::exists('private_uploads/consumables')) {
|
|
||||||
Storage::makeDirectory('private_uploads/consumables', 775);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($request->file('file') as $file) {
|
|
||||||
$file_name = $request->handleFile('private_uploads/consumables/','consumable-'.$consumable->id, $file);
|
|
||||||
|
|
||||||
//Log the upload to the log
|
|
||||||
$consumable->logUpload($file_name, e($request->input('notes')));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return redirect()->route('consumables.show', $consumable->id)->withFragment('files')->with('success', trans('general.file_upload_success'));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->route('consumables.show', $consumable->id)->with('error', trans('general.no_files_uploaded'));
|
|
||||||
}
|
|
||||||
// Prepare the error message
|
|
||||||
return redirect()->route('consumables.index')
|
|
||||||
->with('error', trans('general.file_does_not_exist'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes the selected consumable file.
|
|
||||||
*
|
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @since [v1.0]
|
|
||||||
* @param int $consumableId
|
|
||||||
* @param int $fileId
|
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
|
||||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
|
||||||
*/
|
|
||||||
public function destroy($consumableId = null, $fileId = null)
|
|
||||||
{
|
|
||||||
$consumable = Consumable::find($consumableId);
|
|
||||||
|
|
||||||
// the asset is valid
|
|
||||||
if (isset($consumable->id)) {
|
|
||||||
$this->authorize('update', $consumable);
|
|
||||||
$log = Actionlog::find($fileId);
|
|
||||||
|
|
||||||
// Remove the file if one exists
|
|
||||||
if (Storage::exists('consumables/'.$log->filename)) {
|
|
||||||
try {
|
|
||||||
Storage::delete('consumables/'.$log->filename);
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
Log::debug($e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$log->delete();
|
|
||||||
|
|
||||||
return redirect()->back()->withFragment('files')
|
|
||||||
->with('success', trans('admin/hardware/message.deletefile.success'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Redirect to the licence management page
|
|
||||||
return redirect()->route('consumables.index')->with('error', trans('general.file_does_not_exist'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows the selected file to be viewed.
|
|
||||||
*
|
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @since [v1.4]
|
|
||||||
* @param int $consumableId
|
|
||||||
* @param int $fileId
|
|
||||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
|
||||||
*/
|
|
||||||
public function show($consumableId = null, $fileId = null)
|
|
||||||
{
|
|
||||||
$consumable = Consumable::find($consumableId);
|
|
||||||
|
|
||||||
// the consumable is valid
|
|
||||||
if (isset($consumable->id)) {
|
|
||||||
$this->authorize('view', $consumable);
|
|
||||||
$this->authorize('consumables.files', $consumable);
|
|
||||||
|
|
||||||
if ($log = Actionlog::whereNotNull('filename')->where('item_id', $consumable->id)->find($fileId)) {
|
|
||||||
$file = 'private_uploads/consumables/'.$log->filename;
|
|
||||||
|
|
||||||
try {
|
|
||||||
return StorageHelper::showOrDownloadFile($file, $log->filename);
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return redirect()->route('consumables.show', ['consumable' => $consumable])->with('error', trans('general.file_not_found'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// The log record doesn't exist somehow
|
|
||||||
return redirect()->route('consumables.show', ['consumable' => $consumable])->with('error', trans('general.log_record_not_found'));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->route('consumables.index')->with('error', trans('general.file_does_not_exist', ['id' => $fileId]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -22,6 +22,15 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\Accessory;
|
||||||
|
use App\Models\Asset;
|
||||||
|
use App\Models\AssetModel;
|
||||||
|
use App\Models\Component;
|
||||||
|
use App\Models\Consumable;
|
||||||
|
use App\Models\License;
|
||||||
|
use App\Models\Location;
|
||||||
|
use App\Models\Maintenance;
|
||||||
|
use App\Models\User;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||||
@@ -32,6 +41,45 @@ abstract class Controller extends BaseController
|
|||||||
{
|
{
|
||||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||||
|
|
||||||
|
static $map_object_type = [
|
||||||
|
'accessories' => Accessory::class,
|
||||||
|
'maintenances' => Maintenance::class,
|
||||||
|
'assets' => Asset::class,
|
||||||
|
'components' => Component::class,
|
||||||
|
'consumables' => Consumable::class,
|
||||||
|
'hardware' => Asset::class,
|
||||||
|
'licenses' => License::class,
|
||||||
|
'locations' => Location::class,
|
||||||
|
'models' => AssetModel::class,
|
||||||
|
'users' => User::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
static $map_storage_path = [
|
||||||
|
'accessories' => 'private_uploads/accessories/',
|
||||||
|
'maintenances' => 'private_uploads/maintenances/',
|
||||||
|
'assets' => 'private_uploads/assets/',
|
||||||
|
'components' => 'private_uploads/components/',
|
||||||
|
'consumables' => 'private_uploads/consumables/',
|
||||||
|
'hardware' => 'private_uploads/assets/',
|
||||||
|
'licenses' => 'private_uploads/licenses/',
|
||||||
|
'locations' => 'private_uploads/locations/',
|
||||||
|
'models' => 'private_uploads/models/',
|
||||||
|
'users' => 'private_uploads/users/',
|
||||||
|
];
|
||||||
|
|
||||||
|
static $map_file_prefix= [
|
||||||
|
'accessories' => 'accessory',
|
||||||
|
'maintenances' => 'maintenance',
|
||||||
|
'assets' => 'asset',
|
||||||
|
'components' => 'component',
|
||||||
|
'consumables' => 'consumable',
|
||||||
|
'hardware' => 'asset',
|
||||||
|
'licenses' => 'license',
|
||||||
|
'locations' => 'location',
|
||||||
|
'models' => 'model',
|
||||||
|
'users' => 'user',
|
||||||
|
];
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
view()->share('signedIn', Auth::check());
|
view()->share('signedIn', Auth::check());
|
||||||
|
|||||||
@@ -144,10 +144,9 @@ class CustomFieldsController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function deleteFieldFromFieldset($field_id, $fieldset_id) : RedirectResponse
|
public function deleteFieldFromFieldset($field_id, $fieldset_id) : RedirectResponse
|
||||||
{
|
{
|
||||||
|
$this->authorize('update', CustomField::class);
|
||||||
$field = CustomField::find($field_id);
|
$field = CustomField::find($field_id);
|
||||||
|
|
||||||
$this->authorize('update', $field);
|
|
||||||
|
|
||||||
// Check that the field exists - this is mostly related to the demo, where we
|
// Check that the field exists - this is mostly related to the demo, where we
|
||||||
// rewrite the data every x minutes, so it's possible someone might be disassociating
|
// rewrite the data every x minutes, so it's possible someone might be disassociating
|
||||||
// a field from a fieldset just as we're wiping the database
|
// a field from a fieldset just as we're wiping the database
|
||||||
@@ -157,11 +156,12 @@ class CustomFieldsController extends Controller
|
|||||||
return redirect()->route('fieldsets.show', ['fieldset' => $fieldset_id])
|
return redirect()->route('fieldsets.show', ['fieldset' => $fieldset_id])
|
||||||
->with('success', trans('admin/custom_fields/message.field.delete.success'));
|
->with('success', trans('admin/custom_fields/message.field.delete.success'));
|
||||||
} else {
|
} else {
|
||||||
return redirect()->back()->withErrors(['message' => "Field is in use and cannot be deleted."]);
|
return redirect()->back()->with('error', trans('admin/custom_fields/message.field.delete.error'))
|
||||||
|
->withInput();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()->back()->withErrors(['message' => "Error deleting field from fieldset"]);
|
return redirect()->back()->with('error', trans('admin/custom_fields/message.field.delete.error'));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -172,20 +172,16 @@ class CustomFieldsController extends Controller
|
|||||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||||
* @since [v1.8]
|
* @since [v1.8]
|
||||||
*/
|
*/
|
||||||
public function destroy($field_id) : RedirectResponse
|
public function destroy(CustomField $field) : RedirectResponse
|
||||||
{
|
{
|
||||||
if ($field = CustomField::find($field_id)) {
|
$this->authorize('delete', CustomField::class);
|
||||||
$this->authorize('delete', $field);
|
|
||||||
|
|
||||||
if (($field->fieldset) && ($field->fieldset->count() > 0)) {
|
if (($field->fieldset) && ($field->fieldset->count() > 0)) {
|
||||||
return redirect()->back()->withErrors(['message' => 'Field is in-use']);
|
return redirect()->back()->with('error', trans('admin/custom_fields/message.field.delete.in_use'));
|
||||||
}
|
|
||||||
$field->delete();
|
|
||||||
return redirect()->route("fields.index")
|
|
||||||
->with("success", trans('admin/custom_fields/message.field.delete.success'));
|
|
||||||
}
|
}
|
||||||
|
$field->delete();
|
||||||
return redirect()->back()->withErrors(['message' => 'Field does not exist']);
|
return redirect()->route("fields.index")
|
||||||
|
->with("success", trans('admin/custom_fields/message.field.delete.success'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -198,7 +194,7 @@ class CustomFieldsController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function edit(Request $request, CustomField $field) : View | RedirectResponse
|
public function edit(Request $request, CustomField $field) : View | RedirectResponse
|
||||||
{
|
{
|
||||||
$this->authorize('update', $field);
|
$this->authorize('update', CustomField::class);
|
||||||
$fieldsets = CustomFieldset::get();
|
$fieldsets = CustomFieldset::get();
|
||||||
$customFormat = '';
|
$customFormat = '';
|
||||||
if ((stripos($field->format, 'regex') === 0) && ($field->format !== CustomField::PREDEFINED_FORMATS['MAC'])) {
|
if ((stripos($field->format, 'regex') === 0) && ($field->format !== CustomField::PREDEFINED_FORMATS['MAC'])) {
|
||||||
@@ -228,7 +224,7 @@ class CustomFieldsController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function update(CustomFieldRequest $request, CustomField $field) : RedirectResponse
|
public function update(CustomFieldRequest $request, CustomField $field) : RedirectResponse
|
||||||
{
|
{
|
||||||
$this->authorize('update', $field);
|
$this->authorize('update', CustomField::class);
|
||||||
$show_in_email = $request->get("show_in_email", 0);
|
$show_in_email = $request->get("show_in_email", 0);
|
||||||
$display_in_user_view = $request->get("display_in_user_view", 0);
|
$display_in_user_view = $request->get("display_in_user_view", 0);
|
||||||
|
|
||||||
@@ -265,7 +261,6 @@ class CustomFieldsController extends Controller
|
|||||||
|
|
||||||
if ($field->save()) {
|
if ($field->save()) {
|
||||||
|
|
||||||
|
|
||||||
// Sync fields with fieldsets
|
// Sync fields with fieldsets
|
||||||
$fieldset_array = $request->input('associate_fieldsets');
|
$fieldset_array = $request->input('associate_fieldsets');
|
||||||
if ($request->has('associate_fieldsets') && (is_array($fieldset_array))) {
|
if ($request->has('associate_fieldsets') && (is_array($fieldset_array))) {
|
||||||
|
|||||||
@@ -87,7 +87,9 @@ class LicenseCheckinController extends Controller
|
|||||||
|
|
||||||
if($licenseSeat->assigned_to != null){
|
if($licenseSeat->assigned_to != null){
|
||||||
$return_to = User::withTrashed()->find($licenseSeat->assigned_to);
|
$return_to = User::withTrashed()->find($licenseSeat->assigned_to);
|
||||||
session()->put('checkedInFrom', $return_to->id);
|
if ($return_to) {
|
||||||
|
session()->put('checkedInFrom', $return_to->id);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$return_to = Asset::find($licenseSeat->asset_id);
|
$return_to = Asset::find($licenseSeat->asset_id);
|
||||||
}
|
}
|
||||||
@@ -98,7 +100,9 @@ class LicenseCheckinController extends Controller
|
|||||||
$licenseSeat->notes = $request->input('notes');
|
$licenseSeat->notes = $request->input('notes');
|
||||||
|
|
||||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||||
|
if ($request->get('redirect_option') === 'target'){
|
||||||
|
session()->put(['checkout_to_type' => 'user']);
|
||||||
|
}
|
||||||
|
|
||||||
// Was the asset updated?
|
// Was the asset updated?
|
||||||
if ($licenseSeat->save()) {
|
if ($licenseSeat->save()) {
|
||||||
|
|||||||
@@ -1,132 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Licenses;
|
|
||||||
|
|
||||||
use App\Helpers\StorageHelper;
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\UploadFileRequest;
|
|
||||||
use App\Models\Actionlog;
|
|
||||||
use App\Models\License;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
|
|
||||||
class LicenseFilesController extends Controller
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Validates and stores files associated with a license.
|
|
||||||
*
|
|
||||||
* @param UploadFileRequest $request
|
|
||||||
* @param int $licenseId
|
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
|
||||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @since [v1.0]
|
|
||||||
* @todo Switch to using the AssetFileRequest form request validator.
|
|
||||||
*/
|
|
||||||
public function store(UploadFileRequest $request, $licenseId = null)
|
|
||||||
{
|
|
||||||
$license = License::find($licenseId);
|
|
||||||
|
|
||||||
if (isset($license->id)) {
|
|
||||||
$this->authorize('update', $license);
|
|
||||||
|
|
||||||
if ($request->hasFile('file')) {
|
|
||||||
if (! Storage::exists('private_uploads/licenses')) {
|
|
||||||
Storage::makeDirectory('private_uploads/licenses', 775);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($request->file('file') as $file) {
|
|
||||||
$file_name = $request->handleFile('private_uploads/licenses/','license-'.$license->id, $file);
|
|
||||||
|
|
||||||
//Log the upload to the log
|
|
||||||
$license->logUpload($file_name, e($request->input('notes')));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return redirect()->route('licenses.show', $license->id)->with('success', trans('admin/licenses/message.upload.success'));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->route('licenses.show', $license->id)->with('error', trans('admin/licenses/message.upload.nofiles'));
|
|
||||||
}
|
|
||||||
// Prepare the error message
|
|
||||||
return redirect()->route('licenses.index')
|
|
||||||
->with('error', trans('admin/licenses/message.does_not_exist'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes the selected license file.
|
|
||||||
*
|
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @since [v1.0]
|
|
||||||
* @param int $licenseId
|
|
||||||
* @param int $fileId
|
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
|
||||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
|
||||||
*/
|
|
||||||
public function destroy($licenseId = null, $fileId = null)
|
|
||||||
{
|
|
||||||
if ($license = License::find($licenseId)) {
|
|
||||||
|
|
||||||
$this->authorize('update', $license);
|
|
||||||
|
|
||||||
if ($log = Actionlog::find($fileId)) {
|
|
||||||
|
|
||||||
// Remove the file if one exists
|
|
||||||
if (Storage::exists('licenses/'.$log->filename)) {
|
|
||||||
try {
|
|
||||||
Storage::delete('licenses/'.$log->filename);
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
Log::debug($e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$log->delete();
|
|
||||||
|
|
||||||
return redirect()->back()
|
|
||||||
->with('success', trans('admin/hardware/message.deletefile.success'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->route('licenses.index')->with('error', trans('general.log_does_not_exist'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.does_not_exist'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows the selected file to be viewed.
|
|
||||||
*
|
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @since [v1.4]
|
|
||||||
* @param int $licenseId
|
|
||||||
* @param int $fileId
|
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
|
||||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
|
||||||
*/
|
|
||||||
public function show($licenseId = null, $fileId = null, $download = true)
|
|
||||||
{
|
|
||||||
$license = License::find($licenseId);
|
|
||||||
|
|
||||||
// the license is valid
|
|
||||||
if (isset($license->id)) {
|
|
||||||
$this->authorize('view', $license);
|
|
||||||
$this->authorize('licenses.files', $license);
|
|
||||||
|
|
||||||
if ($log = Actionlog::whereNotNull('filename')->where('item_id', $license->id)->find($fileId)) {
|
|
||||||
$file = 'private_uploads/licenses/'.$log->filename;
|
|
||||||
|
|
||||||
try {
|
|
||||||
return StorageHelper::showOrDownloadFile($file, $log->filename);
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return redirect()->route('licenses.show', ['licenses' => $license])->with('error', trans('general.file_not_found'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The log record doesn't exist somehow
|
|
||||||
return redirect()->route('licenses.show', ['licenses' => $license])->with('error', trans('general.log_record_not_found'));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.does_not_exist', ['id' => $fileId]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -102,7 +102,11 @@ class LicensesController extends Controller
|
|||||||
$license->created_by = auth()->id();
|
$license->created_by = auth()->id();
|
||||||
$license->min_amt = $request->input('min_amt');
|
$license->min_amt = $request->input('min_amt');
|
||||||
|
|
||||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
if($request->get('redirect_option') === 'back'){
|
||||||
|
session()->put(['redirect_option' => 'index']);
|
||||||
|
} else {
|
||||||
|
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||||
|
}
|
||||||
|
|
||||||
if ($license->save()) {
|
if ($license->save()) {
|
||||||
return Helper::getRedirectOption($request, $license->id, 'Licenses')
|
return Helper::getRedirectOption($request, $license->id, 'Licenses')
|
||||||
@@ -304,13 +308,16 @@ class LicensesController extends Controller
|
|||||||
$response = new StreamedResponse(function () {
|
$response = new StreamedResponse(function () {
|
||||||
// Open output stream
|
// Open output stream
|
||||||
$handle = fopen('php://output', 'w');
|
$handle = fopen('php://output', 'w');
|
||||||
$licenses= License::with('company',
|
$licenses = License::with('company',
|
||||||
'manufacturer',
|
'manufacturer',
|
||||||
'category',
|
'category',
|
||||||
'supplier',
|
'supplier',
|
||||||
'adminuser',
|
'adminuser',
|
||||||
'assignedusers')
|
'assignedusers');
|
||||||
->orderBy('created_at', 'DESC');
|
if (request()->filled('category_id')) {
|
||||||
|
$licenses = $licenses->where('category_id', request()->input('category_id'));
|
||||||
|
}
|
||||||
|
$licenses = $licenses->orderBy('created_at', 'DESC');
|
||||||
Company::scopeCompanyables($licenses)
|
Company::scopeCompanyables($licenses)
|
||||||
->chunk(500, function ($licenses) use ($handle) {
|
->chunk(500, function ($licenses) use ($handle) {
|
||||||
$headers = [
|
$headers = [
|
||||||
|
|||||||
@@ -96,7 +96,18 @@ class LocationsController extends Controller
|
|||||||
$location->company_id = $request->input('company_id');
|
$location->company_id = $request->input('company_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
$location = $request->handleImages($location);
|
if ($request->has('use_cloned_image')) {
|
||||||
|
$cloned_model_img = Location::select('image')->find($request->input('clone_image_from_id'));
|
||||||
|
if ($cloned_model_img) {
|
||||||
|
$new_image_name = 'clone-'.date('U').'-'.$cloned_model_img->image;
|
||||||
|
$new_image = 'locations/'.$new_image_name;
|
||||||
|
Storage::disk('public')->copy('locations/'.$cloned_model_img->image, $new_image);
|
||||||
|
$location->image = $new_image_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$location = $request->handleImages($location);
|
||||||
|
}
|
||||||
|
|
||||||
if ($location->save()) {
|
if ($location->save()) {
|
||||||
return redirect()->route('locations.index')->with('success', trans('admin/locations/message.create.success'));
|
return redirect()->route('locations.index')->with('success', trans('admin/locations/message.create.success'));
|
||||||
@@ -275,9 +286,9 @@ class LocationsController extends Controller
|
|||||||
|
|
||||||
// unset these values
|
// unset these values
|
||||||
$location->id = null;
|
$location->id = null;
|
||||||
$location->image = null;
|
|
||||||
|
|
||||||
return view('locations/edit')
|
return view('locations/edit')
|
||||||
|
->with('cloned_model', $location_to_clone)
|
||||||
->with('item', $location);
|
->with('item', $location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,111 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
use App\Helpers\StorageHelper;
|
|
||||||
use App\Http\Requests\UploadFileRequest;
|
|
||||||
use App\Models\Actionlog;
|
|
||||||
use App\Models\Location;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Illuminate\Http\Response;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
use \Symfony\Component\HttpFoundation\StreamedResponse;
|
|
||||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
|
||||||
|
|
||||||
class LocationsFilesController extends Controller
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Upload a file to the server.
|
|
||||||
*
|
|
||||||
* @param UploadFileRequest $request
|
|
||||||
* @param int $modelId
|
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
|
||||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
|
||||||
*@since [v1.0]
|
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
*/
|
|
||||||
public function store(UploadFileRequest $request, Location $location) : RedirectResponse
|
|
||||||
{
|
|
||||||
$this->authorize('update', $location);
|
|
||||||
|
|
||||||
if ($request->hasFile('file')) {
|
|
||||||
|
|
||||||
if (! Storage::exists('private_uploads/locations')) {
|
|
||||||
Storage::makeDirectory('private_uploads/locations', 775);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($request->file('file') as $file) {
|
|
||||||
$file_name = $request->handleFile('private_uploads/locations/','location-'.$location->id, $file);
|
|
||||||
$location->logUpload($file_name, $request->get('notes'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->back()->withFragment('files')->with('success', trans('general.file_upload_success'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->back()->withFragment('files')->with('error', trans('admin/hardware/message.upload.nofiles'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check for permissions and display the file.
|
|
||||||
*
|
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @param int $modelId
|
|
||||||
* @param int $fileId
|
|
||||||
* @since [v1.0]
|
|
||||||
*/
|
|
||||||
public function show(Location $location, $fileId = null) : StreamedResponse | Response | RedirectResponse | BinaryFileResponse
|
|
||||||
{
|
|
||||||
|
|
||||||
$this->authorize('view', $location);
|
|
||||||
|
|
||||||
if (! $log = Actionlog::find($fileId)) {
|
|
||||||
return redirect()->back()->withFragment('files')->with('error', 'No matching file record');
|
|
||||||
}
|
|
||||||
|
|
||||||
$file = 'private_uploads/locations/'.$log->filename;
|
|
||||||
|
|
||||||
if (! Storage::exists($file)) {
|
|
||||||
return redirect()->back()->withFragment('files')->with('error', 'No matching file on server');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request('inline') == 'true') {
|
|
||||||
|
|
||||||
$headers = [
|
|
||||||
'Content-Disposition' => 'inline',
|
|
||||||
];
|
|
||||||
|
|
||||||
return Storage::download($file, $log->filename, $headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
return StorageHelper::downloader($file);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete the associated file
|
|
||||||
*
|
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @param int $modelId
|
|
||||||
* @param int $fileId
|
|
||||||
* @since [v1.0]
|
|
||||||
*/
|
|
||||||
public function destroy(Location $location, $fileId = null) : RedirectResponse
|
|
||||||
{
|
|
||||||
$rel_path = 'private_uploads/locations';
|
|
||||||
$this->authorize('update', $location);
|
|
||||||
$log = Actionlog::find($fileId);
|
|
||||||
|
|
||||||
if ($log) {
|
|
||||||
|
|
||||||
// This should be moved to purge
|
|
||||||
// if (Storage::exists($rel_path.'/'.$log->filename)) {
|
|
||||||
// Storage::delete($rel_path.'/'.$log->filename);
|
|
||||||
// }
|
|
||||||
$log->delete();
|
|
||||||
|
|
||||||
return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success'));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Requests\ImageUploadRequest;
|
||||||
use App\Models\Asset;
|
use App\Models\Asset;
|
||||||
use App\Models\AssetMaintenance;
|
use App\Models\Maintenance;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
@@ -17,29 +18,23 @@ use \Illuminate\Http\RedirectResponse;
|
|||||||
*
|
*
|
||||||
* @version v2.0
|
* @version v2.0
|
||||||
*/
|
*/
|
||||||
class AssetMaintenancesController extends Controller
|
class MaintenancesController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a view that invokes the ajax tables which actually contains
|
* Returns a view that invokes the ajax tables which actually contains
|
||||||
* the content for the asset maintenances listing, which is generated in getDatatable.
|
* the content for the asset maintenances listing.
|
||||||
*
|
|
||||||
* @todo This should be replaced with middleware and/or policies
|
|
||||||
* @see AssetMaintenancesController::getDatatable() method that generates the JSON response
|
|
||||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
|
||||||
* @version v1.0
|
|
||||||
* @since [v1.8]
|
|
||||||
*/
|
*/
|
||||||
public function index() : View
|
public function index() : View
|
||||||
{
|
{
|
||||||
$this->authorize('view', Asset::class);
|
$this->authorize('view', Asset::class);
|
||||||
return view('asset_maintenances/index');
|
return view('maintenances.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a form view to create a new asset maintenance.
|
* Returns a form view to create a new asset maintenance.
|
||||||
*
|
*
|
||||||
* @see AssetMaintenancesController::postCreate() method that stores the data
|
* @see MaintenancesController::postCreate() method that stores the data
|
||||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||||
* @version v1.0
|
* @version v1.0
|
||||||
* @since [v1.8]
|
* @since [v1.8]
|
||||||
@@ -55,21 +50,21 @@ class AssetMaintenancesController extends Controller
|
|||||||
$asset->asset_id = $asset->id;
|
$asset->asset_id = $asset->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return view('asset_maintenances/edit')
|
return view('maintenances/edit')
|
||||||
->with('assetMaintenanceType', AssetMaintenance::getImprovementOptions())
|
->with('maintenanceType', Maintenance::getImprovementOptions())
|
||||||
->with('asset', $asset)
|
->with('asset', $asset)
|
||||||
->with('item', new AssetMaintenance);
|
->with('item', new Maintenance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates and stores the new asset maintenance
|
* Validates and stores the new asset maintenance
|
||||||
*
|
*
|
||||||
* @see AssetMaintenancesController::getCreate() method for the form
|
* @see MaintenancesController::getCreate() method for the form
|
||||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||||
* @version v1.0
|
* @version v1.0
|
||||||
* @since [v1.8]
|
* @since [v1.8]
|
||||||
*/
|
*/
|
||||||
public function store(Request $request) : RedirectResponse
|
public function store(ImageUploadRequest $request) : RedirectResponse
|
||||||
{
|
{
|
||||||
$this->authorize('update', Asset::class);
|
$this->authorize('update', Asset::class);
|
||||||
|
|
||||||
@@ -78,72 +73,73 @@ class AssetMaintenancesController extends Controller
|
|||||||
// Loop through the selected assets
|
// Loop through the selected assets
|
||||||
foreach ($assets as $asset) {
|
foreach ($assets as $asset) {
|
||||||
|
|
||||||
$assetMaintenance = new AssetMaintenance();
|
$maintenance = new Maintenance();
|
||||||
$assetMaintenance->supplier_id = $request->input('supplier_id');
|
$maintenance->supplier_id = $request->input('supplier_id');
|
||||||
$assetMaintenance->is_warranty = $request->input('is_warranty');
|
$maintenance->is_warranty = $request->input('is_warranty');
|
||||||
$assetMaintenance->cost = $request->input('cost');
|
$maintenance->cost = $request->input('cost');
|
||||||
$assetMaintenance->notes = $request->input('notes');
|
$maintenance->notes = $request->input('notes');
|
||||||
|
|
||||||
// Save the asset maintenance data
|
// Save the asset maintenance data
|
||||||
$assetMaintenance->asset_id = $asset->id;
|
$maintenance->asset_id = $asset->id;
|
||||||
$assetMaintenance->asset_maintenance_type = $request->input('asset_maintenance_type');
|
$maintenance->asset_maintenance_type = $request->input('asset_maintenance_type');
|
||||||
$assetMaintenance->title = $request->input('title');
|
$maintenance->name = $request->input('name');
|
||||||
$assetMaintenance->start_date = $request->input('start_date');
|
$maintenance->start_date = $request->input('start_date');
|
||||||
$assetMaintenance->completion_date = $request->input('completion_date');
|
$maintenance->completion_date = $request->input('completion_date');
|
||||||
$assetMaintenance->created_by = auth()->id();
|
$maintenance->created_by = auth()->id();
|
||||||
|
|
||||||
if (($assetMaintenance->completion_date !== null)
|
if (($maintenance->completion_date !== null)
|
||||||
&& ($assetMaintenance->start_date !== '')
|
&& ($maintenance->start_date !== '')
|
||||||
&& ($assetMaintenance->start_date !== '0000-00-00')
|
&& ($maintenance->start_date !== '0000-00-00')
|
||||||
) {
|
) {
|
||||||
$startDate = Carbon::parse($assetMaintenance->start_date);
|
$startDate = Carbon::parse($maintenance->start_date);
|
||||||
$completionDate = Carbon::parse($assetMaintenance->completion_date);
|
$completionDate = Carbon::parse($maintenance->completion_date);
|
||||||
$assetMaintenance->asset_maintenance_time = (int) $completionDate->diffInDays($startDate, true);
|
$maintenance->asset_maintenance_time = (int) $completionDate->diffInDays($startDate, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$maintenance = $request->handleImages($maintenance);
|
||||||
|
|
||||||
// Was the asset maintenance created?
|
// Was the asset maintenance created?
|
||||||
if (!$assetMaintenance->save()) {
|
if (!$maintenance->save()) {
|
||||||
return redirect()->back()->withInput()->withErrors($assetMaintenance->getErrors());
|
return redirect()->back()->withInput()->withErrors($maintenance->getErrors());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()->route('maintenances.index')
|
return redirect()->route('maintenances.index')
|
||||||
->with('success', trans('admin/asset_maintenances/message.create.success'));
|
->with('success', trans('admin/maintenances/message.create.success'));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a form view to edit a selected asset maintenance.
|
* Returns a form view to edit a selected asset maintenance.
|
||||||
*
|
*
|
||||||
* @see AssetMaintenancesController::postEdit() method that stores the data
|
* @see MaintenancesController::postEdit() method that stores the data
|
||||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||||
* @version v1.0
|
* @version v1.0
|
||||||
* @since [v1.8]
|
* @since [v1.8]
|
||||||
*/
|
*/
|
||||||
public function edit(AssetMaintenance $maintenance) : View | RedirectResponse
|
public function edit(Maintenance $maintenance) : View | RedirectResponse
|
||||||
{
|
{
|
||||||
$this->authorize('update', Asset::class);
|
$this->authorize('update', Asset::class);
|
||||||
$this->authorize('update', $maintenance->asset);
|
$this->authorize('update', $maintenance->asset);
|
||||||
|
|
||||||
return view('asset_maintenances/edit')
|
return view('maintenances/edit')
|
||||||
->with('selected_assets', $maintenance->asset->pluck('id')->toArray())
|
->with('selected_assets', $maintenance->asset->pluck('id')->toArray())
|
||||||
->with('asset_ids', request()->input('asset_ids', []))
|
->with('asset_ids', request()->input('asset_ids', []))
|
||||||
->with('assetMaintenanceType', AssetMaintenance::getImprovementOptions())
|
->with('maintenanceType', Maintenance::getImprovementOptions())
|
||||||
->with('item', $maintenance);
|
->with('item', $maintenance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates and stores an update to an asset maintenance
|
* Validates and stores an update to an asset maintenance
|
||||||
*
|
*
|
||||||
* @see AssetMaintenancesController::postEdit() method that stores the data
|
* @see MaintenancesController::postEdit() method that stores the data
|
||||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @param int $assetMaintenanceId
|
* @param int $maintenanceId
|
||||||
* @version v1.0
|
* @version v1.0
|
||||||
* @since [v1.8]
|
* @since [v1.8]
|
||||||
*/
|
*/
|
||||||
public function update(Request $request, AssetMaintenance $maintenance) : View | RedirectResponse
|
public function update(ImageUploadRequest $request, Maintenance $maintenance) : View | RedirectResponse
|
||||||
{
|
{
|
||||||
$this->authorize('update', Asset::class);
|
$this->authorize('update', Asset::class);
|
||||||
$this->authorize('update', $maintenance->asset);
|
$this->authorize('update', $maintenance->asset);
|
||||||
@@ -153,7 +149,7 @@ class AssetMaintenancesController extends Controller
|
|||||||
$maintenance->cost = $request->input('cost');
|
$maintenance->cost = $request->input('cost');
|
||||||
$maintenance->notes = $request->input('notes');
|
$maintenance->notes = $request->input('notes');
|
||||||
$maintenance->asset_maintenance_type = $request->input('asset_maintenance_type');
|
$maintenance->asset_maintenance_type = $request->input('asset_maintenance_type');
|
||||||
$maintenance->title = $request->input('title');
|
$maintenance->name = $request->input('name');
|
||||||
$maintenance->start_date = $request->input('start_date');
|
$maintenance->start_date = $request->input('start_date');
|
||||||
$maintenance->completion_date = $request->input('completion_date');
|
$maintenance->completion_date = $request->input('completion_date');
|
||||||
|
|
||||||
@@ -176,10 +172,11 @@ class AssetMaintenancesController extends Controller
|
|||||||
$completionDate = Carbon::parse($maintenance->completion_date);
|
$completionDate = Carbon::parse($maintenance->completion_date);
|
||||||
$maintenance->asset_maintenance_time = (int) $completionDate->diffInDays($startDate, true);
|
$maintenance->asset_maintenance_time = (int) $completionDate->diffInDays($startDate, true);
|
||||||
}
|
}
|
||||||
|
$maintenance = $request->handleImages($maintenance);
|
||||||
|
|
||||||
if ($maintenance->save()) {
|
if ($maintenance->save()) {
|
||||||
return redirect()->route('maintenances.index')
|
return redirect()->route('maintenances.index')
|
||||||
->with('success', trans('admin/asset_maintenances/message.edit.success'));
|
->with('success', trans('admin/maintenances/message.edit.success'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()->back()->withInput()->withErrors($maintenance->getErrors());
|
return redirect()->back()->withInput()->withErrors($maintenance->getErrors());
|
||||||
@@ -189,11 +186,11 @@ class AssetMaintenancesController extends Controller
|
|||||||
* Delete an asset maintenance
|
* Delete an asset maintenance
|
||||||
*
|
*
|
||||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||||
* @param int $assetMaintenanceId
|
* @param int $maintenanceId
|
||||||
* @version v1.0
|
* @version v1.0
|
||||||
* @since [v1.8]
|
* @since [v1.8]
|
||||||
*/
|
*/
|
||||||
public function destroy(AssetMaintenance $maintenance) : RedirectResponse
|
public function destroy(Maintenance $maintenance) : RedirectResponse
|
||||||
{
|
{
|
||||||
$this->authorize('update', Asset::class);
|
$this->authorize('update', Asset::class);
|
||||||
$this->authorize('update', $maintenance->asset);
|
$this->authorize('update', $maintenance->asset);
|
||||||
@@ -201,19 +198,19 @@ class AssetMaintenancesController extends Controller
|
|||||||
$maintenance->delete();
|
$maintenance->delete();
|
||||||
// Redirect to the asset_maintenance management page
|
// Redirect to the asset_maintenance management page
|
||||||
return redirect()->route('maintenances.index')
|
return redirect()->route('maintenances.index')
|
||||||
->with('success', trans('admin/asset_maintenances/message.delete.success'));
|
->with('success', trans('admin/maintenances/message.delete.success'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* View an asset maintenance
|
* View an asset maintenance
|
||||||
*
|
*
|
||||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||||
* @param int $assetMaintenanceId
|
* @param int $maintenanceId
|
||||||
* @version v1.0
|
* @version v1.0
|
||||||
* @since [v1.8]
|
* @since [v1.8]
|
||||||
*/
|
*/
|
||||||
public function show(AssetMaintenance $maintenance) : View | RedirectResponse
|
public function show(Maintenance $maintenance) : View | RedirectResponse
|
||||||
{
|
{
|
||||||
return view('asset_maintenances/view')->with('assetMaintenance', $maintenance);
|
return view('maintenances.view')->with('maintenance', $maintenance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,7 @@ class ManufacturersController extends Controller
|
|||||||
$manufacturers_count = Manufacturer::withTrashed()->count();
|
$manufacturers_count = Manufacturer::withTrashed()->count();
|
||||||
|
|
||||||
if ($manufacturers_count == 0) {
|
if ($manufacturers_count == 0) {
|
||||||
Artisan::call('db:seed', ['--class' => 'ManufacturerSeeder']);
|
Artisan::call('db:seed', ['--class' => 'Database\\Seeders\\ManufacturerSeeder', '--force' => true]);
|
||||||
return redirect()->route('manufacturers.index')->with('success', trans('general.seeding.manufacturers.success'));
|
return redirect()->route('manufacturers.index')->with('success', trans('general.seeding.manufacturers.success'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use App\Models\Actionlog;
|
|||||||
use App\Models\Asset;
|
use App\Models\Asset;
|
||||||
use App\Models\AssetModel;
|
use App\Models\AssetModel;
|
||||||
use App\Models\Category;
|
use App\Models\Category;
|
||||||
use App\Models\AssetMaintenance;
|
use App\Models\Maintenance;
|
||||||
use App\Models\CheckoutAcceptance;
|
use App\Models\CheckoutAcceptance;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use App\Models\CustomField;
|
use App\Models\CustomField;
|
||||||
@@ -17,13 +17,11 @@ use App\Models\Depreciation;
|
|||||||
use App\Models\License;
|
use App\Models\License;
|
||||||
use App\Models\ReportTemplate;
|
use App\Models\ReportTemplate;
|
||||||
use App\Models\Setting;
|
use App\Models\Setting;
|
||||||
use App\Notifications\CheckoutAssetNotification;
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Illuminate\Support\Facades\Mail;
|
use Illuminate\Support\Facades\Mail;
|
||||||
use Illuminate\Support\Facades\Notification;
|
|
||||||
use \Illuminate\Contracts\View\View;
|
use \Illuminate\Contracts\View\View;
|
||||||
use League\Csv\Reader;
|
use League\Csv\Reader;
|
||||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||||
@@ -1038,11 +1036,11 @@ class ReportsController extends Controller
|
|||||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||||
* @version v1.0
|
* @version v1.0
|
||||||
*/
|
*/
|
||||||
public function getAssetMaintenancesReport() : View
|
public function getMaintenancesReport() : View
|
||||||
{
|
{
|
||||||
$this->authorize('reports.view');
|
$this->authorize('reports.view');
|
||||||
|
|
||||||
return view('reports.asset_maintenances');
|
return view('reports.maintenances');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1051,11 +1049,11 @@ class ReportsController extends Controller
|
|||||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||||
* @version v1.0
|
* @version v1.0
|
||||||
*/
|
*/
|
||||||
public function exportAssetMaintenancesReport() : Response
|
public function exportMaintenancesReport() : Response
|
||||||
{
|
{
|
||||||
$this->authorize('reports.view');
|
$this->authorize('reports.view');
|
||||||
// Grab all the improvements
|
// Grab all the improvements
|
||||||
$assetMaintenances = AssetMaintenance::with('asset', 'supplier')
|
$Maintenances = Maintenance::with('asset', 'supplier')
|
||||||
->orderBy('created_at', 'DESC')
|
->orderBy('created_at', 'DESC')
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
@@ -1063,36 +1061,36 @@ class ReportsController extends Controller
|
|||||||
|
|
||||||
$header = [
|
$header = [
|
||||||
trans('admin/hardware/table.asset_tag'),
|
trans('admin/hardware/table.asset_tag'),
|
||||||
trans('admin/asset_maintenances/table.asset_name'),
|
trans('admin/maintenances/table.asset_name'),
|
||||||
trans('general.supplier'),
|
trans('general.supplier'),
|
||||||
trans('admin/asset_maintenances/form.asset_maintenance_type'),
|
trans('admin/maintenances/form.asset_maintenance_type'),
|
||||||
trans('admin/asset_maintenances/form.title'),
|
trans('admin/maintenances/form.title'),
|
||||||
trans('admin/asset_maintenances/form.start_date'),
|
trans('admin/maintenances/form.start_date'),
|
||||||
trans('admin/asset_maintenances/form.completion_date'),
|
trans('admin/maintenances/form.completion_date'),
|
||||||
trans('admin/asset_maintenances/form.asset_maintenance_time'),
|
trans('admin/maintenances/form.asset_maintenance_time'),
|
||||||
trans('admin/asset_maintenances/form.cost'),
|
trans('admin/maintenances/form.cost'),
|
||||||
];
|
];
|
||||||
|
|
||||||
$header = array_map('trim', $header);
|
$header = array_map('trim', $header);
|
||||||
$rows[] = implode(',', $header);
|
$rows[] = implode(',', $header);
|
||||||
|
|
||||||
foreach ($assetMaintenances as $assetMaintenance) {
|
foreach ($Maintenances as $maintenance) {
|
||||||
$row = [];
|
$row = [];
|
||||||
$row[] = str_replace(',', '', e($assetMaintenance->asset->asset_tag));
|
$row[] = str_replace(',', '', e($maintenance->asset->asset_tag));
|
||||||
$row[] = str_replace(',', '', e($assetMaintenance->asset->name));
|
$row[] = str_replace(',', '', e($maintenance->asset->name));
|
||||||
$row[] = str_replace(',', '', e($assetMaintenance->supplier->name));
|
$row[] = str_replace(',', '', e($maintenance->supplier->name));
|
||||||
$row[] = e($assetMaintenance->improvement_type);
|
$row[] = e($maintenance->improvement_type);
|
||||||
$row[] = e($assetMaintenance->title);
|
$row[] = e($maintenance->name);
|
||||||
$row[] = e($assetMaintenance->start_date);
|
$row[] = e($maintenance->start_date);
|
||||||
$row[] = e($assetMaintenance->completion_date);
|
$row[] = e($maintenance->completion_date);
|
||||||
if (is_null($assetMaintenance->asset_maintenance_time)) {
|
if (is_null($maintenance->asset_maintenance_time)) {
|
||||||
$improvementTime = (int) Carbon::now()
|
$improvementTime = (int) Carbon::now()
|
||||||
->diffInDays(Carbon::parse($assetMaintenance->start_date), true);
|
->diffInDays(Carbon::parse($maintenance->start_date), true);
|
||||||
} else {
|
} else {
|
||||||
$improvementTime = (int) $assetMaintenance->asset_maintenance_time;
|
$improvementTime = (int) $maintenance->asset_maintenance_time;
|
||||||
}
|
}
|
||||||
$row[] = $improvementTime;
|
$row[] = $improvementTime;
|
||||||
$row[] = trans('general.currency') . Helper::formatCurrencyOutput($assetMaintenance->cost);
|
$row[] = trans('general.currency') . Helper::formatCurrencyOutput($maintenance->cost);
|
||||||
$rows[] = implode(',', $row);
|
$rows[] = implode(',', $row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1084,6 +1084,7 @@ class SettingsController extends Controller
|
|||||||
|
|
||||||
if (! config('app.lock_passwords')) {
|
if (! config('app.lock_passwords')) {
|
||||||
if (Storage::exists($path.'/'.$filename)) {
|
if (Storage::exists($path.'/'.$filename)) {
|
||||||
|
Log::warning('User '.auth()->user()->username.' is attempting to download backup file: '.$filename);
|
||||||
return StorageHelper::downloader($path.'/'.$filename);
|
return StorageHelper::downloader($path.'/'.$filename);
|
||||||
} else {
|
} else {
|
||||||
// Redirect to the backup page
|
// Redirect to the backup page
|
||||||
@@ -1111,6 +1112,7 @@ class SettingsController extends Controller
|
|||||||
if (Storage::exists($path . '/' . $filename)) {
|
if (Storage::exists($path . '/' . $filename)) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
Log::warning('User '.auth()->user()->username.' is attempting to delete backup file: '.$filename);
|
||||||
Storage::delete($path . '/' . $filename);
|
Storage::delete($path . '/' . $filename);
|
||||||
return redirect()->route('settings.backups.index')->with('success', trans('admin/settings/message.backup.file_deleted'));
|
return redirect()->route('settings.backups.index')->with('success', trans('admin/settings/message.backup.file_deleted'));
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
@@ -1190,7 +1192,7 @@ class SettingsController extends Controller
|
|||||||
'--force' => true,
|
'--force' => true,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Log::debug('Attempting to restore from: '. storage_path($path).'/'.$filename);
|
Log::warning('User '.auth()->user()->username.' is attempting to restore from: '. storage_path($path).'/'.$filename);
|
||||||
|
|
||||||
$restore_params = [
|
$restore_params = [
|
||||||
'--force' => true,
|
'--force' => true,
|
||||||
@@ -1339,9 +1341,11 @@ class SettingsController extends Controller
|
|||||||
'name' => config('mail.from.name'),
|
'name' => config('mail.from.name'),
|
||||||
'email' => config('mail.from.address'),
|
'email' => config('mail.from.address'),
|
||||||
])->notify(new MailTest());
|
])->notify(new MailTest());
|
||||||
|
Log::debug('Attempting to send mail to '.config('mail.from.address'));
|
||||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('mail_sent.mail_sent')));
|
return response()->json(Helper::formatStandardApiResponse('success', null, trans('mail_sent.mail_sent')));
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
|
Log::error('Mail sent from '.config('mail.from.address') .' with errors '. $e->getMessage());
|
||||||
|
Log::debug($e);
|
||||||
return response()->json(Helper::formatStandardApiResponse('success', null, $e->getMessage()));
|
return response()->json(Helper::formatStandardApiResponse('success', null, $e->getMessage()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ namespace App\Http\Controllers;
|
|||||||
|
|
||||||
use App\Http\Requests\ImageUploadRequest;
|
use App\Http\Requests\ImageUploadRequest;
|
||||||
use App\Models\Supplier;
|
use App\Models\Supplier;
|
||||||
use Illuminate\Support\Facades\Auth;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use \Illuminate\Contracts\View\View;
|
use \Illuminate\Contracts\View\View;
|
||||||
|
|
||||||
@@ -122,7 +121,7 @@ class SuppliersController extends Controller
|
|||||||
public function destroy($supplierId) : RedirectResponse
|
public function destroy($supplierId) : RedirectResponse
|
||||||
{
|
{
|
||||||
$this->authorize('delete', Supplier::class);
|
$this->authorize('delete', Supplier::class);
|
||||||
if (is_null($supplier = Supplier::with('asset_maintenances', 'assets', 'licenses')->withCount('asset_maintenances as asset_maintenances_count', 'assets as assets_count', 'licenses as licenses_count')->find($supplierId))) {
|
if (is_null($supplier = Supplier::with('maintenances', 'assets', 'licenses')->withCount('maintenances as maintenances_count', 'assets as assets_count', 'licenses as licenses_count')->find($supplierId))) {
|
||||||
return redirect()->route('suppliers.index')->with('error', trans('admin/suppliers/message.not_found'));
|
return redirect()->route('suppliers.index')->with('error', trans('admin/suppliers/message.not_found'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,8 +129,8 @@ class SuppliersController extends Controller
|
|||||||
return redirect()->route('suppliers.index')->with('error', trans('admin/suppliers/message.delete.assoc_assets', ['asset_count' => (int) $supplier->assets_count]));
|
return redirect()->route('suppliers.index')->with('error', trans('admin/suppliers/message.delete.assoc_assets', ['asset_count' => (int) $supplier->assets_count]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($supplier->asset_maintenances_count > 0) {
|
if ($supplier->maintenances_count > 0) {
|
||||||
return redirect()->route('suppliers.index')->with('error', trans('admin/suppliers/message.delete.assoc_maintenances', ['asset_maintenances_count' => $supplier->asset_maintenances_count]));
|
return redirect()->route('suppliers.index')->with('error', trans('admin/suppliers/message.delete.assoc_maintenances', ['maintenances_count' => $supplier->maintenances_count]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($supplier->licenses_count > 0) {
|
if ($supplier->licenses_count > 0) {
|
||||||
|
|||||||
162
app/Http/Controllers/UploadedFilesController.php
Normal file
162
app/Http/Controllers/UploadedFilesController.php
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Helpers\StorageHelper;
|
||||||
|
use App\Http\Requests\UploadFileRequest;
|
||||||
|
use App\Models\Actionlog;
|
||||||
|
use Illuminate\Http\RedirectResponse;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||||
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This controller provide the health route for
|
||||||
|
* the Snipe-IT Asset Management application.
|
||||||
|
*
|
||||||
|
* @version v1.0
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
|
||||||
|
*/
|
||||||
|
class UploadedFilesController extends Controller
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accepts a POST to upload a file to the server.
|
||||||
|
*
|
||||||
|
* @param \App\Http\Requests\UploadFileRequest $request
|
||||||
|
* @param string $object_type the type of object to upload the file to
|
||||||
|
* @param int $id the ID of the object to store so we can check permisisons
|
||||||
|
* @since [v8.2.2]
|
||||||
|
* @author [A. Gianotto <snipe@snipe.net>]
|
||||||
|
*/
|
||||||
|
public function store(UploadFileRequest $request, $object_type, $id) : RedirectResponse
|
||||||
|
{
|
||||||
|
|
||||||
|
// Check the permissions to make sure the user can view the object
|
||||||
|
$object = self::$map_object_type[$object_type]::find($id);
|
||||||
|
$this->authorize('update', $object);
|
||||||
|
|
||||||
|
if (!$object) {
|
||||||
|
return redirect()->back()->withFragment('files')->with('error',trans('general.file_upload_status.invalid_object'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the file storage directory doesn't exist, create it
|
||||||
|
if (! Storage::exists(self::$map_storage_path[$object_type])) {
|
||||||
|
Storage::makeDirectory(self::$map_storage_path[$object_type], 775);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ($request->hasFile('file')) {
|
||||||
|
// Loop over the attached files and add them to the object
|
||||||
|
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'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$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();
|
||||||
|
|
||||||
|
return redirect()->back()->withFragment('files')->with('success', trans_choice('general.file_upload_status.upload.success', count($files)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// No files were submitted
|
||||||
|
return redirect()->back()->withFragment('files')->with('error', trans('general.file_upload_status.nofiles'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for permissions and display the file.
|
||||||
|
* This isn't currently used, but is here for future use.
|
||||||
|
*
|
||||||
|
* @param \App\Http\Requests\UploadFileRequest $request
|
||||||
|
* @param string $object_type the type of object to upload the file to
|
||||||
|
* @param int $id the ID of the object to delete from so we can check permisisons
|
||||||
|
* @param $file_id the ID of the file to show from the action_logs table
|
||||||
|
* @since [v8.2.2]
|
||||||
|
* @author [A. Gianotto <snipe@snipe.net>]
|
||||||
|
*/
|
||||||
|
public function show($object_type, $id, $file_id) : RedirectResponse | StreamedResponse | Storage | StorageHelper | BinaryFileResponse
|
||||||
|
{
|
||||||
|
// Check the permissions to make sure the user can view the object
|
||||||
|
$object = self::$map_object_type[$object_type]::find($id);
|
||||||
|
$this->authorize('view', $object);
|
||||||
|
|
||||||
|
if (!$object) {
|
||||||
|
return redirect()->back()->withFragment('files')->with('error',trans('general.file_upload_status.invalid_object'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Check that the file being requested exists for the object
|
||||||
|
if (! $log = Actionlog::whereNotNull('filename')->where('item_type', self::$map_object_type[$object_type])->where('item_id', $object->id)->find($file_id))
|
||||||
|
{
|
||||||
|
return redirect()->back()->withFragment('files')->with('error', trans('general.file_upload_status.invalid_id'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (! Storage::exists(self::$map_storage_path[$object_type].'/'.$log->filename))
|
||||||
|
{
|
||||||
|
return redirect()->back()->withFragment('files')->with('error', trans('general.file_upload_status.file_not_found'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request('inline') == 'true') {
|
||||||
|
$headers = [
|
||||||
|
'Content-Disposition' => 'inline',
|
||||||
|
];
|
||||||
|
return Storage::download(self::$map_storage_path[$object_type].'/'.$log->filename, $log->filename, $headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
return StorageHelper::downloader(self::$map_storage_path[$object_type].'/'.$log->filename);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete the associated file
|
||||||
|
*
|
||||||
|
* @param \App\Http\Requests\UploadFileRequest $request
|
||||||
|
* @param string $object_type the type of object to upload the file to
|
||||||
|
* @param int $id the ID of the object to delete from so we can check permisisons
|
||||||
|
* @param $file_id the ID of the file to delete from the action_logs table
|
||||||
|
* @since [v8.2.2]
|
||||||
|
* @author [A. Gianotto <snipe@snipe.net>]
|
||||||
|
*/
|
||||||
|
public function destroy($object_type, $id, $file_id) : RedirectResponse
|
||||||
|
{
|
||||||
|
|
||||||
|
// Check the permissions to make sure the user can view the object
|
||||||
|
$object = self::$map_object_type[$object_type]::find($id);
|
||||||
|
$this->authorize('update', self::$map_object_type[$object_type]);
|
||||||
|
|
||||||
|
if (!$object) {
|
||||||
|
return redirect()->back()->withFragment('files')->with('error',trans('general.file_upload_status.invalid_object'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Check for the file
|
||||||
|
$log = Actionlog::find($file_id)->where('item_type', self::$map_object_type[$object_type])
|
||||||
|
->where('item_id', $object->id)->first();
|
||||||
|
|
||||||
|
if ($log) {
|
||||||
|
// Check the file actually exists, and delete it
|
||||||
|
if (Storage::exists(self::$map_storage_path[$object_type].'/'.$log->filename)) {
|
||||||
|
Storage::delete(self::$map_storage_path[$object_type].'/'.$log->filename);
|
||||||
|
}
|
||||||
|
// Delete the record of the file
|
||||||
|
if ($log->delete()) {
|
||||||
|
return redirect()->back()->withFragment('files')->with('success', trans_choice('general.file_upload_status.delete.success', 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// The file doesn't seem to really exist, so report an error
|
||||||
|
return redirect()->back()->withFragment('files')->with('success', trans_choice('general.file_upload_status.delete.error', 1));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Users;
|
|
||||||
|
|
||||||
use App\Helpers\StorageHelper;
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\UploadFileRequest;
|
|
||||||
use App\Models\Actionlog;
|
|
||||||
use App\Models\User;
|
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
|
|
||||||
class UserFilesController extends Controller
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Return JSON response with a list of user details for the getIndex() view.
|
|
||||||
*
|
|
||||||
* @param UploadFileRequest $request
|
|
||||||
* @param int $userId
|
|
||||||
* @return string JSON
|
|
||||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
|
||||||
*@author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @since [v1.6]
|
|
||||||
*/
|
|
||||||
public function store(UploadFileRequest $request, User $user)
|
|
||||||
{
|
|
||||||
$this->authorize('update', $user);
|
|
||||||
$files = $request->file('file');
|
|
||||||
|
|
||||||
if (is_null($files)) {
|
|
||||||
return redirect()->back()->with('error', trans('admin/users/message.upload.nofiles'));
|
|
||||||
}
|
|
||||||
foreach ($files as $file) {
|
|
||||||
$file_name = $request->handleFile('private_uploads/users/', 'user-'.$user->id, $file);
|
|
||||||
|
|
||||||
//Log the uploaded file to the log
|
|
||||||
$logAction = new Actionlog();
|
|
||||||
$logAction->item_id = $user->id;
|
|
||||||
$logAction->item_type = User::class;
|
|
||||||
$logAction->created_by = auth()->id();
|
|
||||||
$logAction->note = $request->input('notes');
|
|
||||||
$logAction->target_id = null;
|
|
||||||
$logAction->created_at = date("Y-m-d H:i:s");
|
|
||||||
$logAction->filename = $file_name;
|
|
||||||
$logAction->action_type = 'uploaded';
|
|
||||||
|
|
||||||
if (! $logAction->save()) {
|
|
||||||
return JsonResponse::create(['error' => 'Failed validation: '.print_r($logAction->getErrors(), true)], 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->back()->withFragment('files')->with('success', trans('admin/users/message.upload.success'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete file
|
|
||||||
*
|
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @since [v1.6]
|
|
||||||
* @param int $userId
|
|
||||||
* @param int $fileId
|
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
|
||||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
|
||||||
*/
|
|
||||||
public function destroy($userId = null, $fileId = null)
|
|
||||||
{
|
|
||||||
if ($user = User::find($userId)) {
|
|
||||||
|
|
||||||
$this->authorize('delete', $user);
|
|
||||||
$rel_path = 'private_uploads/users';
|
|
||||||
|
|
||||||
|
|
||||||
if ($log = Actionlog::find($fileId)) {
|
|
||||||
$filename = $log->filename;
|
|
||||||
$log->delete();
|
|
||||||
|
|
||||||
if (Storage::exists($rel_path.'/'.$filename)) {
|
|
||||||
Storage::delete($rel_path.'/'.$filename);
|
|
||||||
return redirect()->back()->withFragment('files')->with('success', trans('admin/users/message.deletefile.success'));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// The log record doesn't exist somehow
|
|
||||||
return redirect()->back()->with('success', trans('admin/users/message.deletefile.success'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->route('users.index')->with('error', trans('admin/users/message.user_not_found', ['id' => $userId]));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display/download the uploaded file
|
|
||||||
*
|
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @since [v1.6]
|
|
||||||
* @param int $userId
|
|
||||||
* @param int $fileId
|
|
||||||
* @return mixed
|
|
||||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
|
||||||
*/
|
|
||||||
public function show(User $user, $fileId = null)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
if (empty($fileId)) {
|
|
||||||
return redirect()->route('users.show')->with('error', 'Invalid file request');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->authorize('view', $user);
|
|
||||||
|
|
||||||
if ($log = Actionlog::whereNotNull('filename')->where('item_id', $user->id)->find($fileId)) {
|
|
||||||
$file = 'private_uploads/users/'.$log->filename;
|
|
||||||
|
|
||||||
try {
|
|
||||||
return StorageHelper::showOrDownloadFile($file, $log->filename);
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return redirect()->route('users.show', ['user' => $user])->with('error', trans('general.file_not_found'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The log record doesn't exist somehow
|
|
||||||
return redirect()->route('users.show', ['user' => $user])->with('error', trans('general.log_record_not_found'));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -13,15 +13,8 @@ use App\Models\Company;
|
|||||||
use App\Models\Group;
|
use App\Models\Group;
|
||||||
use App\Models\Setting;
|
use App\Models\Setting;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Notifications\WelcomeNotification;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
|
||||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use Illuminate\Support\Facades\Password;
|
use Illuminate\Support\Facades\Password;
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
use Redirect;
|
|
||||||
use Str;
|
|
||||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||||
use App\Notifications\CurrentInventory;
|
use App\Notifications\CurrentInventory;
|
||||||
|
|
||||||
@@ -105,6 +98,7 @@ class UsersController extends Controller
|
|||||||
$user->activated = $request->input('activated', 0);
|
$user->activated = $request->input('activated', 0);
|
||||||
$user->jobtitle = $request->input('jobtitle');
|
$user->jobtitle = $request->input('jobtitle');
|
||||||
$user->phone = $request->input('phone');
|
$user->phone = $request->input('phone');
|
||||||
|
$user->mobile = $request->input('mobile');
|
||||||
$user->location_id = $request->input('location_id', null);
|
$user->location_id = $request->input('location_id', null);
|
||||||
$user->department_id = $request->input('department_id', null);
|
$user->department_id = $request->input('department_id', null);
|
||||||
$user->company_id = Company::getIdForUser($request->input('company_id', null));
|
$user->company_id = Company::getIdForUser($request->input('company_id', null));
|
||||||
@@ -130,10 +124,15 @@ class UsersController extends Controller
|
|||||||
}
|
}
|
||||||
$user->permissions = json_encode($permissions_array);
|
$user->permissions = json_encode($permissions_array);
|
||||||
|
|
||||||
// we have to invoke the
|
// we have to invoke the form request here to handle image uploads
|
||||||
app(ImageUploadRequest::class)->handleImages($user, 600, 'avatar', 'avatars', 'avatar');
|
app(ImageUploadRequest::class)->handleImages($user, 600, 'avatar', 'avatars', 'avatar');
|
||||||
|
|
||||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
if($request->get('redirect_option') === 'back'){
|
||||||
|
session()->put(['redirect_option' => 'index']);
|
||||||
|
} else {
|
||||||
|
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($user->save()) {
|
if ($user->save()) {
|
||||||
if ($request->filled('groups')) {
|
if ($request->filled('groups')) {
|
||||||
@@ -142,18 +141,6 @@ class UsersController extends Controller
|
|||||||
$user->groups()->sync([]);
|
$user->groups()->sync([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($request->input('email_user') == 1) && ($request->filled('email'))) {
|
|
||||||
// Send the credentials through email
|
|
||||||
$data = [];
|
|
||||||
$data['email'] = e($request->input('email'));
|
|
||||||
$data['username'] = e($request->input('username'));
|
|
||||||
$data['first_name'] = e($request->input('first_name'));
|
|
||||||
$data['last_name'] = e($request->input('last_name'));
|
|
||||||
$data['password'] = e($request->input('password'));
|
|
||||||
|
|
||||||
$user->notify(new WelcomeNotification($data));
|
|
||||||
}
|
|
||||||
|
|
||||||
return Helper::getRedirectOption($request, $user->id, 'Users')
|
return Helper::getRedirectOption($request, $user->id, 'Users')
|
||||||
->with('success', trans('admin/users/message.success.create'));
|
->with('success', trans('admin/users/message.success.create'));
|
||||||
}
|
}
|
||||||
@@ -248,22 +235,17 @@ class UsersController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only save groups if the user is a superuser
|
|
||||||
if (auth()->user()->isSuperUser()) {
|
|
||||||
$user->groups()->sync($request->input('groups'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the user fields
|
// Update the user fields
|
||||||
$user->username = trim($request->input('username'));
|
|
||||||
$user->email = trim($request->input('email'));
|
|
||||||
$user->first_name = $request->input('first_name');
|
$user->first_name = $request->input('first_name');
|
||||||
$user->last_name = $request->input('last_name');
|
$user->last_name = $request->input('last_name');
|
||||||
$user->two_factor_optin = $request->input('two_factor_optin') ?: 0;
|
$user->two_factor_optin = $request->input('two_factor_optin') ?: 0;
|
||||||
$user->locale = $request->input('locale');
|
$user->locale = $request->input('locale');
|
||||||
$user->employee_num = $request->input('employee_num');
|
$user->employee_num = $request->input('employee_num');
|
||||||
$user->activated = $request->input('activated', 0);
|
|
||||||
$user->jobtitle = $request->input('jobtitle', null);
|
$user->jobtitle = $request->input('jobtitle', null);
|
||||||
$user->phone = $request->input('phone');
|
$user->phone = $request->input('phone');
|
||||||
|
$user->mobile = $request->input('mobile');
|
||||||
$user->location_id = $request->input('location_id', null);
|
$user->location_id = $request->input('location_id', null);
|
||||||
$user->company_id = Company::getIdForUser($request->input('company_id', null));
|
$user->company_id = Company::getIdForUser($request->input('company_id', null));
|
||||||
$user->manager_id = $request->input('manager_id', null);
|
$user->manager_id = $request->input('manager_id', null);
|
||||||
@@ -273,8 +255,6 @@ class UsersController extends Controller
|
|||||||
$user->city = $request->input('city', null);
|
$user->city = $request->input('city', null);
|
||||||
$user->state = $request->input('state', null);
|
$user->state = $request->input('state', null);
|
||||||
$user->country = $request->input('country', null);
|
$user->country = $request->input('country', null);
|
||||||
// if a user is editing themselves we should always keep activated true
|
|
||||||
$user->activated = $request->input('activated', $request->user()->is($user) ? 1 : 0);
|
|
||||||
$user->zip = $request->input('zip', null);
|
$user->zip = $request->input('zip', null);
|
||||||
$user->remote = $request->input('remote', 0);
|
$user->remote = $request->input('remote', 0);
|
||||||
$user->vip = $request->input('vip', 0);
|
$user->vip = $request->input('vip', 0);
|
||||||
@@ -283,30 +263,49 @@ class UsersController extends Controller
|
|||||||
$user->end_date = $request->input('end_date', null);
|
$user->end_date = $request->input('end_date', null);
|
||||||
$user->autoassign_licenses = $request->input('autoassign_licenses', 0);
|
$user->autoassign_licenses = $request->input('autoassign_licenses', 0);
|
||||||
|
|
||||||
|
// Set this here so that we can overwrite it later if the user is an admin or superadmin
|
||||||
|
$user->activated = $request->input('activated', auth()->user()->is($user) ? 1 : $user->activated);
|
||||||
|
|
||||||
|
|
||||||
// Update the location of any assets checked out to this user
|
// Update the location of any assets checked out to this user
|
||||||
Asset::where('assigned_type', User::class)
|
Asset::where('assigned_type', User::class)
|
||||||
->where('assigned_to', $user->id)
|
->where('assigned_to', $user->id)
|
||||||
->update(['location_id' => $request->input('location_id', null)]);
|
->update(['location_id' => $request->input('location_id', null)]);
|
||||||
|
|
||||||
// Do we want to update the user password?
|
// check for permissions related fields and only set them if the user has permission to edit them
|
||||||
if ($request->filled('password')) {
|
if (auth()->user()->can('canEditAuthFields', $user) && auth()->user()->can('editableOnDemo')) {
|
||||||
$user->password = bcrypt($request->input('password'));
|
|
||||||
|
$user->username = trim($request->input('username'));
|
||||||
|
$user->email = trim($request->input('email'));
|
||||||
|
$user->activated = $request->input('activated', $request->user()->is($user) ? 1 : 0);
|
||||||
|
|
||||||
|
// Do we want to update the user password?
|
||||||
|
if ($request->filled('password')) {
|
||||||
|
$user->password = bcrypt($request->input('password'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$permissions_array = $request->input('permission');
|
||||||
|
|
||||||
|
// Strip out the superuser permission if the user isn't a superadmin
|
||||||
|
if (! auth()->user()->isSuperUser()) {
|
||||||
|
unset($permissions_array['superuser']);
|
||||||
|
$permissions_array['superuser'] = $orig_superuser;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user->permissions = json_encode($permissions_array);
|
||||||
|
|
||||||
|
// Only save groups if the user is a superuser
|
||||||
|
if (auth()->user()->isSuperUser()) {
|
||||||
|
$user->groups()->sync($request->input('groups'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Update the location of any assets checked out to this user
|
// Update the location of any assets checked out to this user
|
||||||
Asset::where('assigned_type', User::class)
|
Asset::where('assigned_type', User::class)
|
||||||
->where('assigned_to', $user->id)
|
->where('assigned_to', $user->id)
|
||||||
->update(['location_id' => $user->location_id]);
|
->update(['location_id' => $user->location_id]);
|
||||||
|
|
||||||
$permissions_array = $request->input('permission');
|
|
||||||
|
|
||||||
// Strip out the superuser permission if the user isn't a superadmin
|
|
||||||
if (! auth()->user()->isSuperUser()) {
|
|
||||||
unset($permissions_array['superuser']);
|
|
||||||
$permissions_array['superuser'] = $orig_superuser;
|
|
||||||
}
|
|
||||||
|
|
||||||
$user->permissions = json_encode($permissions_array);
|
|
||||||
|
|
||||||
// Handle uploaded avatar
|
// Handle uploaded avatar
|
||||||
app(ImageUploadRequest::class)->handleImages($user, 600, 'avatar', 'avatars', 'avatar');
|
app(ImageUploadRequest::class)->handleImages($user, 600, 'avatar', 'avatars', 'avatar');
|
||||||
@@ -440,7 +439,7 @@ class UsersController extends Controller
|
|||||||
app('request')->request->set('permissions', $permissions);
|
app('request')->request->set('permissions', $permissions);
|
||||||
|
|
||||||
|
|
||||||
$user_to_clone = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed()->find($user->id);
|
$user_to_clone = User::with('userloc')->withTrashed()->find($user->id);
|
||||||
// Make sure they can view this particular user
|
// Make sure they can view this particular user
|
||||||
$this->authorize('view', $user_to_clone);
|
$this->authorize('view', $user_to_clone);
|
||||||
|
|
||||||
@@ -455,6 +454,8 @@ class UsersController extends Controller
|
|||||||
$user->last_name = '';
|
$user->last_name = '';
|
||||||
$user->email = substr($user->email, ($pos = strpos($user->email, '@')) !== false ? $pos : 0);
|
$user->email = substr($user->email, ($pos = strpos($user->email, '@')) !== false ? $pos : 0);
|
||||||
$user->id = null;
|
$user->id = null;
|
||||||
|
$user->username = null;
|
||||||
|
$user->avatar = null;
|
||||||
|
|
||||||
// Get this user's groups
|
// Get this user's groups
|
||||||
$userGroups = $user_to_clone->groups()->pluck('name', 'id');
|
$userGroups = $user_to_clone->groups()->pluck('name', 'id');
|
||||||
@@ -470,7 +471,7 @@ class UsersController extends Controller
|
|||||||
->with('user', $user)
|
->with('user', $user)
|
||||||
->with('groups', Group::pluck('name', 'id'))
|
->with('groups', Group::pluck('name', 'id'))
|
||||||
->with('userGroups', $userGroups)
|
->with('userGroups', $userGroups)
|
||||||
->with('clone_user', $user_to_clone)
|
->with('cloned_model', $user_to_clone)
|
||||||
->with('item', $user);
|
->with('item', $user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -512,6 +513,8 @@ class UsersController extends Controller
|
|||||||
trans('admin/companies/table.title'),
|
trans('admin/companies/table.title'),
|
||||||
trans('admin/users/table.title'),
|
trans('admin/users/table.title'),
|
||||||
trans('general.employee_number'),
|
trans('general.employee_number'),
|
||||||
|
trans('admin/users/table.first_name'),
|
||||||
|
trans('admin/users/table.last_name'),
|
||||||
trans('admin/users/table.name'),
|
trans('admin/users/table.name'),
|
||||||
trans('admin/users/table.username'),
|
trans('admin/users/table.username'),
|
||||||
trans('admin/users/table.email'),
|
trans('admin/users/table.email'),
|
||||||
@@ -557,6 +560,8 @@ class UsersController extends Controller
|
|||||||
($user->company) ? $user->company->name : '',
|
($user->company) ? $user->company->name : '',
|
||||||
$user->jobtitle,
|
$user->jobtitle,
|
||||||
$user->employee_num,
|
$user->employee_num,
|
||||||
|
$user->first_name,
|
||||||
|
$user->last_name,
|
||||||
$user->present()->fullName(),
|
$user->present()->fullName(),
|
||||||
$user->username,
|
$user->username,
|
||||||
$user->email,
|
$user->email,
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ class SecurityHeaders
|
|||||||
$response = $next($request);
|
$response = $next($request);
|
||||||
|
|
||||||
$response->headers->set('X-Content-Type-Options', 'nosniff');
|
$response->headers->set('X-Content-Type-Options', 'nosniff');
|
||||||
$response->headers->set('X-XSS-Protection', '1; mode=block');
|
|
||||||
|
|
||||||
// Ugh. Feature-Policy is dumb and clumsy and mostly irrelevant for Snipe-IT,
|
// Ugh. Feature-Policy is dumb and clumsy and mostly irrelevant for Snipe-IT,
|
||||||
// since we don't provide any way to IFRAME anything in in the first place.
|
// since we don't provide any way to IFRAME anything in in the first place.
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use Illuminate\Support\Facades\Storage;
|
|||||||
use Intervention\Image\Exception\NotReadableException;
|
use Intervention\Image\Exception\NotReadableException;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class ImageUploadRequest extends Request
|
class ImageUploadRequest extends Request
|
||||||
{
|
{
|
||||||
@@ -70,19 +71,25 @@ class ImageUploadRequest extends Request
|
|||||||
public function handleImages($item, $w = 600, $form_fieldname = 'image', $path = null, $db_fieldname = 'image')
|
public function handleImages($item, $w = 600, $form_fieldname = 'image', $path = null, $db_fieldname = 'image')
|
||||||
{
|
{
|
||||||
|
|
||||||
$type = strtolower(class_basename(get_class($item)));
|
$type = class_basename(get_class($item));
|
||||||
|
|
||||||
if (is_null($path)) {
|
if (is_null($path)) {
|
||||||
|
|
||||||
$path = str_plural($type);
|
$path = strtolower(str_plural($type));
|
||||||
|
|
||||||
if ($type == 'assetmodel') {
|
if ($type == 'AssetModel') {
|
||||||
$path = 'models';
|
$path = 'models';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($type == 'user') {
|
if ($type == 'user') {
|
||||||
$path = 'avatars';
|
$path = 'avatars';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!Storage::disk('public')->exists($path)) {
|
||||||
|
Storage::disk('public')->makeDirectory($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->offsetGet($form_fieldname) instanceof UploadedFile) {
|
if ($this->offsetGet($form_fieldname) instanceof UploadedFile) {
|
||||||
@@ -93,10 +100,9 @@ class ImageUploadRequest extends Request
|
|||||||
|
|
||||||
if (isset($image)) {
|
if (isset($image)) {
|
||||||
|
|
||||||
if (!config('app.lock_passwords')) {
|
|
||||||
|
|
||||||
$ext = $image->guessExtension();
|
$ext = $image->guessExtension();
|
||||||
$file_name = $type.'-'.$form_fieldname.'-'.$item->id.'-'.str_random(10).'.'.$ext;
|
$file_name = $type.'-'.$form_fieldname.($item->id ?? '-'.$item->id).'-'.str_random(10).'.'.$ext;
|
||||||
|
|
||||||
if (($image->getMimeType() == 'image/vnd.microsoft.icon') || ($image->getMimeType() == 'image/x-icon') || ($image->getMimeType() == 'image/avif') || ($image->getMimeType() == 'image/webp')) {
|
if (($image->getMimeType() == 'image/vnd.microsoft.icon') || ($image->getMimeType() == 'image/x-icon') || ($image->getMimeType() == 'image/avif') || ($image->getMimeType() == 'image/webp')) {
|
||||||
// If the file is an icon, webp or avif, we need to just move it since gd doesn't support resizing
|
// If the file is an icon, webp or avif, we need to just move it since gd doesn't support resizing
|
||||||
@@ -138,7 +144,7 @@ class ImageUploadRequest extends Request
|
|||||||
// Remove Current image if exists
|
// Remove Current image if exists
|
||||||
$item = $this->deleteExistingImage($item, $path, $db_fieldname);
|
$item = $this->deleteExistingImage($item, $path, $db_fieldname);
|
||||||
$item->{$db_fieldname} = $file_name;
|
$item->{$db_fieldname} = $file_name;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// If the user isn't uploading anything new but wants to delete their old image, do so
|
// If the user isn't uploading anything new but wants to delete their old image, do so
|
||||||
|
|||||||
@@ -80,9 +80,20 @@ class UploadFileRequest extends Request
|
|||||||
{
|
{
|
||||||
$attributes = [];
|
$attributes = [];
|
||||||
|
|
||||||
if ($this->file) {
|
if (($this->file) && (is_array($this->file))) {
|
||||||
|
|
||||||
for ($i = 0; $i < count($this->file); $i++) {
|
for ($i = 0; $i < count($this->file); $i++) {
|
||||||
$attributes['file.'.$i] = $this->file[$i]->getClientOriginalName();
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
if ($this->file[$i]) {
|
||||||
|
$attributes['file.'.$i] = $this->file[$i]->getClientOriginalName();
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$attributes['file.'.$i] = 'Invalid file';
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
namespace App\Http\Transformers;
|
namespace App\Http\Transformers;
|
||||||
|
|
||||||
use App\Helpers\Helper;
|
use App\Helpers\Helper;
|
||||||
|
use App\Helpers\StorageHelper;
|
||||||
use App\Models\Actionlog;
|
use App\Models\Actionlog;
|
||||||
use App\Models\Asset;
|
use App\Models\Asset;
|
||||||
use App\Models\CustomField;
|
use App\Models\CustomField;
|
||||||
@@ -16,6 +17,7 @@ use Illuminate\Contracts\Encryption\DecryptException;
|
|||||||
use Illuminate\Support\Facades\Crypt;
|
use Illuminate\Support\Facades\Crypt;
|
||||||
use Illuminate\Support\Facades\Gate;
|
use Illuminate\Support\Facades\Gate;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
class ActionlogsTransformer
|
class ActionlogsTransformer
|
||||||
{
|
{
|
||||||
@@ -133,24 +135,6 @@ class ActionlogsTransformer
|
|||||||
$clean_meta= $this->changedInfo($clean_meta);
|
$clean_meta= $this->changedInfo($clean_meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
$file_url = '';
|
|
||||||
if($actionlog->filename!='') {
|
|
||||||
if ($actionlog->action_type == 'accepted') {
|
|
||||||
$file_url = route('log.storedeula.download', ['filename' => $actionlog->filename]);
|
|
||||||
} else {
|
|
||||||
if ($actionlog->item) {
|
|
||||||
if ($actionlog->itemType() == 'asset') {
|
|
||||||
$file_url = route('show/assetfile', ['asset' => $actionlog->item->id, 'fileId' => $actionlog->id]);
|
|
||||||
} elseif ($actionlog->itemType() == 'accessory') {
|
|
||||||
$file_url = route('show.accessoryfile', ['accessoryId' => $actionlog->item->id, 'fileId' => $actionlog->id]);
|
|
||||||
} elseif ($actionlog->itemType() == 'license') {
|
|
||||||
$file_url = route('show.licensefile', ['licenseId' => $actionlog->item->id, 'fileId' => $actionlog->id]);
|
|
||||||
} elseif ($actionlog->itemType() == 'user') {
|
|
||||||
$file_url = route('show/userfile', ['user' => $actionlog->item->id, 'fileId' => $actionlog->id]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$array = [
|
$array = [
|
||||||
'id' => (int) $actionlog->id,
|
'id' => (int) $actionlog->id,
|
||||||
@@ -158,8 +142,10 @@ class ActionlogsTransformer
|
|||||||
'file' => ($actionlog->filename!='')
|
'file' => ($actionlog->filename!='')
|
||||||
?
|
?
|
||||||
[
|
[
|
||||||
'url' => $file_url,
|
'url' => $actionlog->uploads_file_url(),
|
||||||
'filename' => $actionlog->filename,
|
'filename' => $actionlog->filename,
|
||||||
|
'inlineable' => StorageHelper::allowSafeInline($actionlog->uploads_file_url()),
|
||||||
|
'exists_on_disk' => Storage::exists($actionlog->uploads_file_path()) ? true : false,
|
||||||
] : null,
|
] : null,
|
||||||
|
|
||||||
'item' => ($actionlog->item) ? [
|
'item' => ($actionlog->item) ? [
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ class AssetsTransformer
|
|||||||
'qr' => ($setting->qr_code=='1') ? config('app.url').'/uploads/barcodes/qr-'.str_slug($asset->asset_tag).'-'.str_slug($asset->id).'.png' : null,
|
'qr' => ($setting->qr_code=='1') ? config('app.url').'/uploads/barcodes/qr-'.str_slug($asset->asset_tag).'-'.str_slug($asset->id).'.png' : null,
|
||||||
'alt_barcode' => ($setting->alt_barcode_enabled=='1') ? config('app.url').'/uploads/barcodes/'.str_slug($setting->alt_barcode).'-'.str_slug($asset->asset_tag).'.png' : null,
|
'alt_barcode' => ($setting->alt_barcode_enabled=='1') ? config('app.url').'/uploads/barcodes/'.str_slug($setting->alt_barcode).'-'.str_slug($asset->asset_tag).'.png' : null,
|
||||||
'assigned_to' => $this->transformAssignedTo($asset),
|
'assigned_to' => $this->transformAssignedTo($asset),
|
||||||
'jobtitle' => $asset->assigned ? e($asset->assigned->jobtitle) : null,
|
|
||||||
'warranty_months' => ($asset->warranty_months > 0) ? e($asset->warranty_months.' '.trans('admin/hardware/form.months')) : null,
|
'warranty_months' => ($asset->warranty_months > 0) ? e($asset->warranty_months.' '.trans('admin/hardware/form.months')) : null,
|
||||||
'warranty_expires' => ($asset->warranty_months > 0) ? Helper::getFormattedDateObject($asset->warranty_expires, 'date') : null,
|
'warranty_expires' => ($asset->warranty_months > 0) ? Helper::getFormattedDateObject($asset->warranty_expires, 'date') : null,
|
||||||
'created_by' => ($asset->adminuser) ? [
|
'created_by' => ($asset->adminuser) ? [
|
||||||
@@ -204,6 +203,7 @@ class AssetsTransformer
|
|||||||
'last_name'=> ($asset->assigned->last_name) ? e($asset->assigned->last_name) : null,
|
'last_name'=> ($asset->assigned->last_name) ? e($asset->assigned->last_name) : null,
|
||||||
'email'=> ($asset->assigned->email) ? e($asset->assigned->email) : null,
|
'email'=> ($asset->assigned->email) ? e($asset->assigned->email) : null,
|
||||||
'employee_number' => ($asset->assigned->employee_num) ? e($asset->assigned->employee_num) : null,
|
'employee_number' => ($asset->assigned->employee_num) ? e($asset->assigned->employee_num) : null,
|
||||||
|
'jobtitle' => $asset->assigned->jobtitle ? e($asset->assigned->jobtitle) : null,
|
||||||
'type' => 'user',
|
'type' => 'user',
|
||||||
] : null;
|
] : null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class ConsumablesTransformer
|
|||||||
$array = [
|
$array = [
|
||||||
'id' => (int) $consumable->id,
|
'id' => (int) $consumable->id,
|
||||||
'name' => e($consumable->name),
|
'name' => e($consumable->name),
|
||||||
'image' => ($consumable->image) ? Storage::disk('public')->url('consumables/'.e($consumable->image)) : null,
|
'image' => ($consumable->getImageUrl()) ? ($consumable->getImageUrl()) : null,
|
||||||
'category' => ($consumable->category) ? ['id' => $consumable->category->id, 'name' => e($consumable->category->name)] : null,
|
'category' => ($consumable->category) ? ['id' => $consumable->category->id, 'name' => e($consumable->category->name)] : null,
|
||||||
'company' => ($consumable->company) ? ['id' => (int) $consumable->company->id, 'name' => e($consumable->company->name)] : null,
|
'company' => ($consumable->company) ? ['id' => (int) $consumable->company->id, 'name' => e($consumable->company->name)] : null,
|
||||||
'item_no' => e($consumable->item_no),
|
'item_no' => e($consumable->item_no),
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class LicensesTransformer
|
|||||||
'checkin' => Gate::allows('checkin', License::class),
|
'checkin' => Gate::allows('checkin', License::class),
|
||||||
'clone' => Gate::allows('create', License::class),
|
'clone' => Gate::allows('create', License::class),
|
||||||
'update' => Gate::allows('update', License::class),
|
'update' => Gate::allows('update', License::class),
|
||||||
'delete' => (Gate::allows('delete', License::class) && ($license->free_seats_count > 0)) ? true : false,
|
'delete' => (Gate::allows('delete', License::class) && ($license->free_seats_count == $license->seats)) ? true : false,
|
||||||
];
|
];
|
||||||
|
|
||||||
$array += $permissions_array;
|
$array += $permissions_array;
|
||||||
|
|||||||
@@ -4,23 +4,24 @@ namespace App\Http\Transformers;
|
|||||||
|
|
||||||
use App\Helpers\Helper;
|
use App\Helpers\Helper;
|
||||||
use App\Models\Asset;
|
use App\Models\Asset;
|
||||||
use App\Models\AssetMaintenance;
|
use App\Models\Maintenance;
|
||||||
use Illuminate\Support\Facades\Gate;
|
use Illuminate\Support\Facades\Gate;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
class AssetMaintenancesTransformer
|
class MaintenancesTransformer
|
||||||
{
|
{
|
||||||
public function transformAssetMaintenances(Collection $assetmaintenances, $total)
|
public function transformMaintenances(Collection $maintenances, $total)
|
||||||
{
|
{
|
||||||
$array = [];
|
$array = [];
|
||||||
foreach ($assetmaintenances as $assetmaintenance) {
|
foreach ($maintenances as $assetmaintenance) {
|
||||||
$array[] = self::transformAssetMaintenance($assetmaintenance);
|
$array[] = self::transformMaintenance($assetmaintenance);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function transformAssetMaintenance(AssetMaintenance $assetmaintenance)
|
public function transformMaintenance(Maintenance $assetmaintenance)
|
||||||
{
|
{
|
||||||
$array = [
|
$array = [
|
||||||
'id' => (int) $assetmaintenance->id,
|
'id' => (int) $assetmaintenance->id,
|
||||||
@@ -33,6 +34,7 @@ class AssetMaintenancesTransformer
|
|||||||
'created_at' => Helper::getFormattedDateObject($assetmaintenance->asset->created_at, 'datetime'),
|
'created_at' => Helper::getFormattedDateObject($assetmaintenance->asset->created_at, 'datetime'),
|
||||||
'updated_at' => Helper::getFormattedDateObject($assetmaintenance->asset->updated_at, 'datetime'),
|
'updated_at' => Helper::getFormattedDateObject($assetmaintenance->asset->updated_at, 'datetime'),
|
||||||
] : null,
|
] : null,
|
||||||
|
'image' => ($assetmaintenance->image != '') ? Storage::disk('public')->url('maintenances/'.e($assetmaintenance->image)) : null,
|
||||||
'model' => (($assetmaintenance->asset) && ($assetmaintenance->asset->model)) ? [
|
'model' => (($assetmaintenance->asset) && ($assetmaintenance->asset->model)) ? [
|
||||||
'id' => (int) $assetmaintenance->asset->model->id,
|
'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).' '.e($assetmaintenance->asset->model->model_number) : null,
|
||||||
@@ -48,7 +50,8 @@ class AssetMaintenancesTransformer
|
|||||||
'name'=> ($assetmaintenance->asset->company->name) ? e($assetmaintenance->asset->company->name) : null,
|
'name'=> ($assetmaintenance->asset->company->name) ? e($assetmaintenance->asset->company->name) : null,
|
||||||
|
|
||||||
] : null,
|
] : null,
|
||||||
'title' => ($assetmaintenance->title) ? e($assetmaintenance->title) : null,
|
'name' => ($assetmaintenance->name) ? e($assetmaintenance->name) : null,
|
||||||
|
'title' => ($assetmaintenance->name) ? e($assetmaintenance->name) : null, // legacy to not change the shape of the API
|
||||||
'location' => (($assetmaintenance->asset) && ($assetmaintenance->asset->location)) ? [
|
'location' => (($assetmaintenance->asset) && ($assetmaintenance->asset->location)) ? [
|
||||||
'id' => (int) $assetmaintenance->asset->location->id,
|
'id' => (int) $assetmaintenance->asset->location->id,
|
||||||
'name'=> e($assetmaintenance->asset->location->name),
|
'name'=> e($assetmaintenance->asset->location->name),
|
||||||
@@ -32,10 +32,11 @@ class UploadedFilesTransformer
|
|||||||
'name' => e($file->filename),
|
'name' => e($file->filename),
|
||||||
'item' => ($file->item_type) ? [
|
'item' => ($file->item_type) ? [
|
||||||
'id' => (int) $file->item_id,
|
'id' => (int) $file->item_id,
|
||||||
'type' => strtolower(class_basename($file->item_type)),
|
'type' => str_plural(strtolower(class_basename($file->item_type))),
|
||||||
] : null,
|
] : null,
|
||||||
'filename' => e($file->filename),
|
'filename' => e($file->filename),
|
||||||
'filetype' => StorageHelper::getFiletype($file->uploads_file_path()),
|
'filetype' => StorageHelper::getFiletype($file->uploads_file_path()),
|
||||||
|
'mediatype' => StorageHelper::getMediaType($file->uploads_file_path()),
|
||||||
'url' => $file->uploads_file_url(),
|
'url' => $file->uploads_file_url(),
|
||||||
'note' => ($file->note) ? e($file->note) : null,
|
'note' => ($file->note) ? e($file->note) : null,
|
||||||
'created_by' => ($file->adminuser) ? [
|
'created_by' => ($file->adminuser) ? [
|
||||||
@@ -44,7 +45,7 @@ class UploadedFilesTransformer
|
|||||||
] : null,
|
] : null,
|
||||||
'created_at' => Helper::getFormattedDateObject($file->created_at, 'datetime'),
|
'created_at' => Helper::getFormattedDateObject($file->created_at, 'datetime'),
|
||||||
'deleted_at' => Helper::getFormattedDateObject($file->deleted_at, 'datetime'),
|
'deleted_at' => Helper::getFormattedDateObject($file->deleted_at, 'datetime'),
|
||||||
'inline' => StorageHelper::allowSafeInline($file->uploads_file_path()),
|
'inlineable' => StorageHelper::allowSafeInline($file->uploads_file_path()),
|
||||||
'exists_on_disk' => (Storage::exists($file->uploads_file_path()) ? true : false),
|
'exists_on_disk' => (Storage::exists($file->uploads_file_path()) ? true : false),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,12 @@ class UsersTransformer
|
|||||||
public function transformUser(User $user)
|
public function transformUser(User $user)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
$role = '';
|
||||||
|
if ($user->isSuperUser()) {
|
||||||
|
$role = 'superadmin';
|
||||||
|
} elseif ($user->isAdmin()) {
|
||||||
|
$role = 'admin';
|
||||||
|
}
|
||||||
$array = [
|
$array = [
|
||||||
'id' => (int) $user->id,
|
'id' => (int) $user->id,
|
||||||
'avatar' => e($user->present()->gravatar) ?? null,
|
'avatar' => e($user->present()->gravatar) ?? null,
|
||||||
@@ -39,6 +45,7 @@ class UsersTransformer
|
|||||||
'jobtitle' => ($user->jobtitle) ? e($user->jobtitle) : null,
|
'jobtitle' => ($user->jobtitle) ? e($user->jobtitle) : null,
|
||||||
'vip' => ($user->vip == '1') ? true : false,
|
'vip' => ($user->vip == '1') ? true : false,
|
||||||
'phone' => ($user->phone) ? e($user->phone) : null,
|
'phone' => ($user->phone) ? e($user->phone) : null,
|
||||||
|
'mobile' => ($user->mobile) ? e($user->mobile) : null,
|
||||||
'website' => ($user->website) ? e($user->website) : null,
|
'website' => ($user->website) ? e($user->website) : null,
|
||||||
'address' => ($user->address) ? e($user->address) : null,
|
'address' => ($user->address) ? e($user->address) : null,
|
||||||
'city' => ($user->city) ? e($user->city) : null,
|
'city' => ($user->city) ? e($user->city) : null,
|
||||||
@@ -59,6 +66,7 @@ class UsersTransformer
|
|||||||
'name'=> e($user->userloc->name),
|
'name'=> e($user->userloc->name),
|
||||||
] : null,
|
] : null,
|
||||||
'notes'=> Helper::parseEscapedMarkedownInline($user->notes),
|
'notes'=> Helper::parseEscapedMarkedownInline($user->notes),
|
||||||
|
'role' => $role,
|
||||||
'permissions' => $user->decodePermissions(),
|
'permissions' => $user->decodePermissions(),
|
||||||
'activated' => ($user->activated == '1') ? true : false,
|
'activated' => ($user->activated == '1') ? true : false,
|
||||||
'autoassign_licenses' => ($user->autoassign_licenses == '1') ? true : false,
|
'autoassign_licenses' => ($user->autoassign_licenses == '1') ? true : false,
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ abstract class Importer
|
|||||||
} else {
|
} else {
|
||||||
$this->csv = Reader::createFromString($file);
|
$this->csv = Reader::createFromString($file);
|
||||||
}
|
}
|
||||||
$this->tempPassword = substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, 40);
|
$this->tempPassword = '*** NO PASSWORD - IMPORTED VIA CSV ***';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cached Values for import lookups
|
// Cached Values for import lookups
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ use App\Models\Department;
|
|||||||
use App\Models\Setting;
|
use App\Models\Setting;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Notifications\WelcomeNotification;
|
use App\Notifications\WelcomeNotification;
|
||||||
|
use Illuminate\Support\Facades\Gate;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Facades\Password;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is ONLY used for the User Import. When we are importing users
|
* This is ONLY used for the User Import. When we are importing users
|
||||||
@@ -50,6 +52,7 @@ class UserImporter extends ItemImporter
|
|||||||
$this->item['email'] = trim($this->findCsvMatch($row, 'email'));
|
$this->item['email'] = trim($this->findCsvMatch($row, 'email'));
|
||||||
$this->item['gravatar'] = trim($this->findCsvMatch($row, 'gravatar'));
|
$this->item['gravatar'] = trim($this->findCsvMatch($row, 'gravatar'));
|
||||||
$this->item['phone'] = trim($this->findCsvMatch($row, 'phone_number'));
|
$this->item['phone'] = trim($this->findCsvMatch($row, 'phone_number'));
|
||||||
|
$this->item['mobile'] = trim($this->findCsvMatch($row, 'mobile_number'));
|
||||||
$this->item['website'] = trim($this->findCsvMatch($row, 'website'));
|
$this->item['website'] = trim($this->findCsvMatch($row, 'website'));
|
||||||
$this->item['jobtitle'] = trim($this->findCsvMatch($row, 'jobtitle'));
|
$this->item['jobtitle'] = trim($this->findCsvMatch($row, 'jobtitle'));
|
||||||
$this->item['address'] = trim($this->findCsvMatch($row, 'address'));
|
$this->item['address'] = trim($this->findCsvMatch($row, 'address'));
|
||||||
@@ -80,6 +83,7 @@ class UserImporter extends ItemImporter
|
|||||||
$this->item['username'] = $user_formatted_array['username'];
|
$this->item['username'] = $user_formatted_array['username'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Check if a numeric ID was passed. If it does, use that above all else.
|
// Check if a numeric ID was passed. If it does, use that above all else.
|
||||||
if ((array_key_exists('id', $this->item) && ($this->item['id'] != "") && (is_numeric($this->item['id'])))) {
|
if ((array_key_exists('id', $this->item) && ($this->item['id'] != "") && (is_numeric($this->item['id'])))) {
|
||||||
$user = User::find($this->item['id']);
|
$user = User::find($this->item['id']);
|
||||||
@@ -89,12 +93,25 @@ class UserImporter extends ItemImporter
|
|||||||
|
|
||||||
if ($user) {
|
if ($user) {
|
||||||
|
|
||||||
|
// If the user does not want to update existing values, only add new ones, bail out
|
||||||
if (! $this->updating) {
|
if (! $this->updating) {
|
||||||
Log::debug('A matching User '.$this->item['name'].' already exists. ');
|
Log::debug('A matching User '.$this->item['name'].' already exists. ');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->log('Updating User');
|
$this->log('Updating User');
|
||||||
|
|
||||||
|
// Todo - check that this works
|
||||||
|
if (!Gate::allows('canEditAuthFields', $user)) {
|
||||||
|
unset($user->username);
|
||||||
|
unset($user->email);
|
||||||
|
unset($user->password);
|
||||||
|
unset($user->activated);
|
||||||
|
}
|
||||||
|
|
||||||
$user->update($this->sanitizeItemForUpdating($user));
|
$user->update($this->sanitizeItemForUpdating($user));
|
||||||
|
|
||||||
|
// Why do we have to do this twice? Update should
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
||||||
// Update the location of any assets checked out to this user
|
// Update the location of any assets checked out to this user
|
||||||
@@ -110,28 +127,32 @@ class UserImporter extends ItemImporter
|
|||||||
|
|
||||||
// This needs to be applied after the update logic, otherwise we'll overwrite user passwords
|
// This needs to be applied after the update logic, otherwise we'll overwrite user passwords
|
||||||
// Issue #5408
|
// Issue #5408
|
||||||
$this->item['password'] = bcrypt($this->tempPassword);
|
$this->item['password'] = $this->tempPassword;
|
||||||
|
|
||||||
$this->log('No matching user, creating one');
|
$this->log('No matching user, creating one');
|
||||||
$user = new User();
|
$user = new User();
|
||||||
$user->created_by = auth()->id();
|
$user->created_by = auth()->id();
|
||||||
|
|
||||||
$user->fill($this->sanitizeItemForStoring($user));
|
$user->fill($this->sanitizeItemForStoring($user));
|
||||||
|
|
||||||
|
// TODO - check for gate here I guess
|
||||||
|
|
||||||
|
|
||||||
if ($user->save()) {
|
if ($user->save()) {
|
||||||
$this->log('User '.$this->item['name'].' was created');
|
$this->log('User '.$this->item['name'].' was created');
|
||||||
|
|
||||||
if (($user->email) && ($user->activated == '1')) {
|
if (($user->email) && ($user->activated == '1')) {
|
||||||
$data = [
|
|
||||||
'email' => $user->email,
|
|
||||||
'username' => $user->username,
|
|
||||||
'first_name' => $user->first_name,
|
|
||||||
'last_name' => $user->last_name,
|
|
||||||
'password' => $this->tempPassword,
|
|
||||||
];
|
|
||||||
|
|
||||||
if ($this->send_welcome) {
|
if ($this->send_welcome) {
|
||||||
$user->notify(new WelcomeNotification($data));
|
|
||||||
|
try {
|
||||||
|
$user->notify(new WelcomeNotification($user));
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::warning('Could not send welcome notification for user: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
$user = null;
|
$user = null;
|
||||||
$this->item = null;
|
$this->item = null;
|
||||||
@@ -140,9 +161,9 @@ class UserImporter extends ItemImporter
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->logError($user, 'User');
|
$this->logError($user, 'User');
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch an existing department, or create new if it doesn't exist
|
* Fetch an existing department, or create new if it doesn't exist
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -4,10 +4,12 @@ namespace App\Listeners;
|
|||||||
|
|
||||||
use App\Events\CheckoutableCheckedOut;
|
use App\Events\CheckoutableCheckedOut;
|
||||||
use App\Mail\CheckinAccessoryMail;
|
use App\Mail\CheckinAccessoryMail;
|
||||||
|
use App\Mail\CheckinComponentMail;
|
||||||
use App\Mail\CheckinLicenseMail;
|
use App\Mail\CheckinLicenseMail;
|
||||||
use App\Mail\CheckoutAccessoryMail;
|
use App\Mail\CheckoutAccessoryMail;
|
||||||
use App\Mail\CheckoutAssetMail;
|
use App\Mail\CheckoutAssetMail;
|
||||||
use App\Mail\CheckinAssetMail;
|
use App\Mail\CheckinAssetMail;
|
||||||
|
use App\Mail\CheckoutComponentMail;
|
||||||
use App\Mail\CheckoutConsumableMail;
|
use App\Mail\CheckoutConsumableMail;
|
||||||
use App\Mail\CheckoutLicenseMail;
|
use App\Mail\CheckoutLicenseMail;
|
||||||
use App\Models\Accessory;
|
use App\Models\Accessory;
|
||||||
@@ -22,9 +24,11 @@ use App\Models\Setting;
|
|||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Notifications\CheckinAccessoryNotification;
|
use App\Notifications\CheckinAccessoryNotification;
|
||||||
use App\Notifications\CheckinAssetNotification;
|
use App\Notifications\CheckinAssetNotification;
|
||||||
|
use App\Notifications\CheckinComponentNotification;
|
||||||
use App\Notifications\CheckinLicenseSeatNotification;
|
use App\Notifications\CheckinLicenseSeatNotification;
|
||||||
use App\Notifications\CheckoutAccessoryNotification;
|
use App\Notifications\CheckoutAccessoryNotification;
|
||||||
use App\Notifications\CheckoutAssetNotification;
|
use App\Notifications\CheckoutAssetNotification;
|
||||||
|
use App\Notifications\CheckoutComponentNotification;
|
||||||
use App\Notifications\CheckoutConsumableNotification;
|
use App\Notifications\CheckoutConsumableNotification;
|
||||||
use App\Notifications\CheckoutLicenseSeatNotification;
|
use App\Notifications\CheckoutLicenseSeatNotification;
|
||||||
use GuzzleHttp\Exception\ClientException;
|
use GuzzleHttp\Exception\ClientException;
|
||||||
@@ -39,7 +43,7 @@ use Osama\LaravelTeamsNotification\TeamsNotification;
|
|||||||
class CheckoutableListener
|
class CheckoutableListener
|
||||||
{
|
{
|
||||||
private array $skipNotificationsFor = [
|
private array $skipNotificationsFor = [
|
||||||
Component::class,
|
// Component::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -145,7 +149,6 @@ class CheckoutableListener
|
|||||||
$shouldSendEmailToUser = $this->checkoutableCategoryShouldSendEmail($event->checkoutable);
|
$shouldSendEmailToUser = $this->checkoutableCategoryShouldSendEmail($event->checkoutable);
|
||||||
$shouldSendEmailToAlertAddress = $this->shouldSendEmailToAlertAddress();
|
$shouldSendEmailToAlertAddress = $this->shouldSendEmailToAlertAddress();
|
||||||
$shouldSendWebhookNotification = $this->shouldSendWebhookNotification();
|
$shouldSendWebhookNotification = $this->shouldSendWebhookNotification();
|
||||||
|
|
||||||
if (!$shouldSendEmailToUser && !$shouldSendEmailToAlertAddress && !$shouldSendWebhookNotification) {
|
if (!$shouldSendEmailToUser && !$shouldSendEmailToAlertAddress && !$shouldSendWebhookNotification) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -269,6 +272,9 @@ class CheckoutableListener
|
|||||||
case LicenseSeat::class:
|
case LicenseSeat::class:
|
||||||
$notificationClass = CheckinLicenseSeatNotification::class;
|
$notificationClass = CheckinLicenseSeatNotification::class;
|
||||||
break;
|
break;
|
||||||
|
case Component::class:
|
||||||
|
$notificationClass = CheckinComponentNotification::class;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::debug('Notification class: '.$notificationClass);
|
Log::debug('Notification class: '.$notificationClass);
|
||||||
@@ -299,6 +305,9 @@ class CheckoutableListener
|
|||||||
case LicenseSeat::class:
|
case LicenseSeat::class:
|
||||||
$notificationClass = CheckoutLicenseSeatNotification::class;
|
$notificationClass = CheckoutLicenseSeatNotification::class;
|
||||||
break;
|
break;
|
||||||
|
case Component::class:
|
||||||
|
$notificationClass = CheckoutComponentNotification::class;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -310,6 +319,7 @@ class CheckoutableListener
|
|||||||
Asset::class => CheckoutAssetMail::class,
|
Asset::class => CheckoutAssetMail::class,
|
||||||
LicenseSeat::class => CheckoutLicenseMail::class,
|
LicenseSeat::class => CheckoutLicenseMail::class,
|
||||||
Consumable::class => CheckoutConsumableMail::class,
|
Consumable::class => CheckoutConsumableMail::class,
|
||||||
|
Component::class => CheckoutComponentMail::class,
|
||||||
];
|
];
|
||||||
$mailable= $lookup[get_class($event->checkoutable)];
|
$mailable= $lookup[get_class($event->checkoutable)];
|
||||||
|
|
||||||
@@ -322,8 +332,8 @@ class CheckoutableListener
|
|||||||
Accessory::class => CheckinAccessoryMail::class,
|
Accessory::class => CheckinAccessoryMail::class,
|
||||||
Asset::class => CheckinAssetMail::class,
|
Asset::class => CheckinAssetMail::class,
|
||||||
LicenseSeat::class => CheckinLicenseMail::class,
|
LicenseSeat::class => CheckinLicenseMail::class,
|
||||||
|
Component::class => CheckinComponentMail::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
$mailable= $lookup[get_class($event->checkoutable)];
|
$mailable= $lookup[get_class($event->checkoutable)];
|
||||||
|
|
||||||
return new $mailable($event->checkoutable, $event->checkedOutTo, $event->checkedInBy, $event->note);
|
return new $mailable($event->checkoutable, $event->checkedOutTo, $event->checkedInBy, $event->note);
|
||||||
@@ -469,7 +479,8 @@ class CheckoutableListener
|
|||||||
return match (true) {
|
return match (true) {
|
||||||
$checkoutable instanceof Asset => $checkoutable->model->category,
|
$checkoutable instanceof Asset => $checkoutable->model->category,
|
||||||
$checkoutable instanceof Accessory,
|
$checkoutable instanceof Accessory,
|
||||||
$checkoutable instanceof Consumable => $checkoutable->category,
|
$checkoutable instanceof Consumable,
|
||||||
|
$checkoutable instanceof Component => $checkoutable->category,
|
||||||
$checkoutable instanceof LicenseSeat => $checkoutable->license->category,
|
$checkoutable instanceof LicenseSeat => $checkoutable->license->category,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -334,6 +334,7 @@ class Importer extends Component
|
|||||||
'manager_username' => trans('general.importer.manager_username'),
|
'manager_username' => trans('general.importer.manager_username'),
|
||||||
'notes' => trans('general.notes'),
|
'notes' => trans('general.notes'),
|
||||||
'phone_number' => trans('admin/users/table.phone'),
|
'phone_number' => trans('admin/users/table.phone'),
|
||||||
|
'mobile_number' => trans('admin/users/table.mobile'),
|
||||||
'remote' => trans('admin/users/general.remote'),
|
'remote' => trans('admin/users/general.remote'),
|
||||||
'start_date' => trans('general.start_date'),
|
'start_date' => trans('general.start_date'),
|
||||||
'state' => trans('general.state'),
|
'state' => trans('general.state'),
|
||||||
@@ -510,6 +511,13 @@ class Importer extends Component
|
|||||||
'telephone',
|
'telephone',
|
||||||
'tel.',
|
'tel.',
|
||||||
],
|
],
|
||||||
|
'mobile_number' =>
|
||||||
|
[
|
||||||
|
'mobile',
|
||||||
|
'mobile number',
|
||||||
|
'cell',
|
||||||
|
'cellphone',
|
||||||
|
],
|
||||||
|
|
||||||
'serial' =>
|
'serial' =>
|
||||||
[
|
[
|
||||||
|
|||||||
71
app/Mail/CheckinComponentMail.php
Normal file
71
app/Mail/CheckinComponentMail.php
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Mail;
|
||||||
|
|
||||||
|
use App\Models\Accessory;
|
||||||
|
use App\Models\Component;
|
||||||
|
use App\Models\Setting;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Mail\Mailable;
|
||||||
|
use Illuminate\Mail\Mailables\Address;
|
||||||
|
use Illuminate\Mail\Mailables\Content;
|
||||||
|
use Illuminate\Mail\Mailables\Envelope;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
class CheckinComponentMail extends Mailable
|
||||||
|
{
|
||||||
|
use Queueable, SerializesModels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new message instance.
|
||||||
|
*/
|
||||||
|
public function __construct(Component $component, $checkedOutTo, User $checkedInby, $note)
|
||||||
|
{
|
||||||
|
$this->item = $component;
|
||||||
|
$this->target = $checkedOutTo;
|
||||||
|
$this->admin = $checkedInby;
|
||||||
|
$this->note = $note;
|
||||||
|
$this->settings = Setting::getSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the message envelope.
|
||||||
|
*/
|
||||||
|
public function envelope(): Envelope
|
||||||
|
{
|
||||||
|
$from = new Address(config('mail.from.address'), config('mail.from.name'));
|
||||||
|
|
||||||
|
return new Envelope(
|
||||||
|
from: $from,
|
||||||
|
subject: trans('mail.Confirm_component_checkin'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the message content definition.
|
||||||
|
*/
|
||||||
|
public function content(): Content
|
||||||
|
{
|
||||||
|
return new Content(
|
||||||
|
markdown: 'mail.markdown.checkin-component',
|
||||||
|
with: [
|
||||||
|
'item' => $this->item,
|
||||||
|
'admin' => $this->admin,
|
||||||
|
'note' => $this->note,
|
||||||
|
'target' => $this->target,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the attachments for the message.
|
||||||
|
*
|
||||||
|
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
|
||||||
|
*/
|
||||||
|
public function attachments(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,6 @@ use Illuminate\Mail\Mailables\Address;
|
|||||||
use Illuminate\Mail\Mailables\Attachment;
|
use Illuminate\Mail\Mailables\Attachment;
|
||||||
use Illuminate\Mail\Mailables\Content;
|
use Illuminate\Mail\Mailables\Content;
|
||||||
use Illuminate\Mail\Mailables\Envelope;
|
use Illuminate\Mail\Mailables\Envelope;
|
||||||
use Illuminate\Notifications\Messages\MailMessage;
|
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
class CheckoutAssetMail extends Mailable
|
class CheckoutAssetMail extends Mailable
|
||||||
@@ -24,16 +23,25 @@ class CheckoutAssetMail extends Mailable
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new message instance.
|
* Create a new message instance.
|
||||||
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function __construct(Asset $asset, $checkedOutTo, User $checkedOutBy, $acceptance, $note, bool $firstTimeSending = true)
|
public function __construct(Asset $asset, $checkedOutTo, User $checkedOutBy, $acceptance, $note, bool $firstTimeSending = true)
|
||||||
{
|
{
|
||||||
$this->item = $asset;
|
$this->item = $asset;
|
||||||
$this->admin = $checkedOutBy;
|
$this->admin = $checkedOutBy;
|
||||||
$this->note = $note;
|
$this->note = $note;
|
||||||
$this->target = $checkedOutTo;
|
|
||||||
$this->acceptance = $acceptance;
|
$this->acceptance = $acceptance;
|
||||||
|
|
||||||
$this->settings = Setting::getSettings();
|
$this->settings = Setting::getSettings();
|
||||||
|
$this->target = $checkedOutTo;
|
||||||
|
|
||||||
|
// Location is a target option, but there are no emails currently associated with locations.
|
||||||
|
if($this->target instanceof User){
|
||||||
|
$this->target = $this->target->present()?->fullName();
|
||||||
|
}
|
||||||
|
else if($this->target instanceof Asset){
|
||||||
|
$this->target = $this->target->assignedto?->present()?->fullName();
|
||||||
|
}
|
||||||
|
|
||||||
$this->last_checkout = '';
|
$this->last_checkout = '';
|
||||||
$this->expected_checkin = '';
|
$this->expected_checkin = '';
|
||||||
@@ -91,7 +99,7 @@ class CheckoutAssetMail extends Mailable
|
|||||||
'admin' => $this->admin,
|
'admin' => $this->admin,
|
||||||
'status' => $this->item->assetstatus?->name,
|
'status' => $this->item->assetstatus?->name,
|
||||||
'note' => $this->note,
|
'note' => $this->note,
|
||||||
'target' => $this->target,
|
'target' => $this->target->name ?? $this->admin->present()->fullName(),
|
||||||
'fields' => $fields,
|
'fields' => $fields,
|
||||||
'eula' => $eula,
|
'eula' => $eula,
|
||||||
'req_accept' => $req_accept,
|
'req_accept' => $req_accept,
|
||||||
@@ -116,7 +124,7 @@ class CheckoutAssetMail extends Mailable
|
|||||||
private function getSubject(): string
|
private function getSubject(): string
|
||||||
{
|
{
|
||||||
if ($this->firstTimeSending) {
|
if ($this->firstTimeSending) {
|
||||||
return trans('mail.Asset_Checkout_Notification');
|
return trans('mail.Asset_Checkout_Notification').' - '.$this->item->asset_tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
return trans('mail.unaccepted_asset_reminder');
|
return trans('mail.unaccepted_asset_reminder');
|
||||||
|
|||||||
82
app/Mail/CheckoutComponentMail.php
Normal file
82
app/Mail/CheckoutComponentMail.php
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Mail;
|
||||||
|
|
||||||
|
use App\Models\Component;
|
||||||
|
use App\Models\Setting;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Mail\Mailable;
|
||||||
|
use Illuminate\Mail\Mailables\Address;
|
||||||
|
use Illuminate\Mail\Mailables\Content;
|
||||||
|
use Illuminate\Mail\Mailables\Envelope;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
class CheckoutComponentMail extends Mailable
|
||||||
|
{
|
||||||
|
use Queueable, SerializesModels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new message instance.
|
||||||
|
*/
|
||||||
|
public function __construct(Component $component, $checkedOutTo, User $checkedOutBy, $acceptance, $note)
|
||||||
|
{
|
||||||
|
$this->item = $component;
|
||||||
|
$this->admin = $checkedOutBy;
|
||||||
|
$this->note = $note;
|
||||||
|
$this->target = $checkedOutTo;
|
||||||
|
$this->acceptance = $acceptance;
|
||||||
|
$this->qty = $component->assets->first()?->pivot?->assigned_qty;
|
||||||
|
|
||||||
|
$this->settings = Setting::getSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the message envelope.
|
||||||
|
*/
|
||||||
|
public function envelope(): Envelope
|
||||||
|
{
|
||||||
|
$from = new Address(config('mail.from.address'), config('mail.from.name'));
|
||||||
|
|
||||||
|
return new Envelope(
|
||||||
|
from: $from,
|
||||||
|
subject: trans('mail.Confirm_component_delivery'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the message content definition.
|
||||||
|
*/
|
||||||
|
public function content(): Content
|
||||||
|
{
|
||||||
|
|
||||||
|
$eula = $this->item->getEula();
|
||||||
|
$req_accept = $this->item->requireAcceptance();
|
||||||
|
|
||||||
|
$accept_url = is_null($this->acceptance) ? null : route('account.accept.item', $this->acceptance);
|
||||||
|
|
||||||
|
return new Content(
|
||||||
|
markdown: 'mail.markdown.checkout-component',
|
||||||
|
with: [
|
||||||
|
'item' => $this->item,
|
||||||
|
'admin' => $this->admin,
|
||||||
|
'note' => $this->note,
|
||||||
|
'target' => $this->target,
|
||||||
|
'eula' => $eula,
|
||||||
|
'req_accept' => $req_accept,
|
||||||
|
'accept_url' => $accept_url,
|
||||||
|
'qty' => $this->qty,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the attachments for the message.
|
||||||
|
*
|
||||||
|
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
|
||||||
|
*/
|
||||||
|
public function attachments(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Mail;
|
namespace App\Mail;
|
||||||
|
|
||||||
|
use App\Models\Asset;
|
||||||
use App\Models\LicenseSeat;
|
use App\Models\LicenseSeat;
|
||||||
use App\Models\Setting;
|
use App\Models\Setting;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
@@ -25,9 +26,16 @@ class CheckoutLicenseMail extends Mailable
|
|||||||
$this->item = $licenseSeat;
|
$this->item = $licenseSeat;
|
||||||
$this->admin = $checkedOutBy;
|
$this->admin = $checkedOutBy;
|
||||||
$this->note = $note;
|
$this->note = $note;
|
||||||
$this->target = $checkedOutTo;
|
|
||||||
$this->acceptance = $acceptance;
|
$this->acceptance = $acceptance;
|
||||||
$this->settings = Setting::getSettings();
|
$this->settings = Setting::getSettings();
|
||||||
|
$this->target = $checkedOutTo;
|
||||||
|
|
||||||
|
if($this->target instanceof User){
|
||||||
|
$this->target = $this->target->present()?->fullName();
|
||||||
|
}
|
||||||
|
elseif($this->target instanceof Asset){
|
||||||
|
$this->target = $this->target->assignedto?->present()?->fullName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use Watson\Validating\ValidatingTrait;
|
|||||||
/**
|
/**
|
||||||
* Model for Accessories.
|
* Model for Accessories.
|
||||||
*
|
*
|
||||||
* @version v1.0
|
* @version v1.0
|
||||||
*/
|
*/
|
||||||
class Accessory extends SnipeModel
|
class Accessory extends SnipeModel
|
||||||
{
|
{
|
||||||
@@ -56,8 +56,8 @@ class Accessory extends SnipeModel
|
|||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accessory validation rules
|
* Accessory validation rules
|
||||||
*/
|
*/
|
||||||
public $rules = [
|
public $rules = [
|
||||||
'name' => 'required|min:3|max:255',
|
'name' => 'required|min:3|max:255',
|
||||||
'qty' => 'required|integer|min:1',
|
'qty' => 'required|integer|min:1',
|
||||||
@@ -71,12 +71,12 @@ class Accessory extends SnipeModel
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the model should inject it's identifier to the unique
|
* Whether the model should inject it's identifier to the unique
|
||||||
* validation rules before attempting validation. If this property
|
* validation rules before attempting validation. If this property
|
||||||
* is not set in the model it will default to true.
|
* is not set in the model it will default to true.
|
||||||
*
|
*
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
protected $injectUniqueIdentifier = true;
|
protected $injectUniqueIdentifier = true;
|
||||||
use ValidatingTrait;
|
use ValidatingTrait;
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ class Accessory extends SnipeModel
|
|||||||
* Establishes the accessory -> supplier relationship
|
* Establishes the accessory -> supplier relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function supplier()
|
public function supplier()
|
||||||
@@ -121,7 +121,7 @@ class Accessory extends SnipeModel
|
|||||||
* Sets the requestable attribute on the accessory
|
* Sets the requestable attribute on the accessory
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v4.0]
|
* @since [v4.0]
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setRequestableAttribute($value)
|
public function setRequestableAttribute($value)
|
||||||
@@ -136,7 +136,7 @@ class Accessory extends SnipeModel
|
|||||||
* Establishes the accessory -> company relationship
|
* Establishes the accessory -> company relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function company()
|
public function company()
|
||||||
@@ -148,7 +148,7 @@ class Accessory extends SnipeModel
|
|||||||
* Establishes the accessory -> location relationship
|
* Establishes the accessory -> location relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function location()
|
public function location()
|
||||||
@@ -160,7 +160,7 @@ class Accessory extends SnipeModel
|
|||||||
* Establishes the accessory -> category relationship
|
* Establishes the accessory -> category relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function category()
|
public function category()
|
||||||
@@ -172,7 +172,7 @@ class Accessory extends SnipeModel
|
|||||||
* Returns the action logs associated with the accessory
|
* Returns the action logs associated with the accessory
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function assetlog()
|
public function assetlog()
|
||||||
@@ -201,8 +201,8 @@ class Accessory extends SnipeModel
|
|||||||
*
|
*
|
||||||
* It's super-mega-assy, but it's the best I could do for now.
|
* It's super-mega-assy, but it's the best I could do for now.
|
||||||
*
|
*
|
||||||
* @author A. Gianotto <snipe@snipe.net>
|
* @author A. Gianotto <snipe@snipe.net>
|
||||||
* @since v5.0.0
|
* @since v5.0.0
|
||||||
*
|
*
|
||||||
* @see \App\Http\Controllers\Api\AccessoriesController\checkedout()
|
* @see \App\Http\Controllers\Api\AccessoriesController\checkedout()
|
||||||
*/
|
*/
|
||||||
@@ -219,7 +219,7 @@ class Accessory extends SnipeModel
|
|||||||
* presenter or service provider
|
* presenter or service provider
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getImageUrl()
|
public function getImageUrl()
|
||||||
@@ -235,7 +235,7 @@ class Accessory extends SnipeModel
|
|||||||
* Establishes the accessory -> users relationship
|
* Establishes the accessory -> users relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function checkouts()
|
public function checkouts()
|
||||||
@@ -248,7 +248,7 @@ class Accessory extends SnipeModel
|
|||||||
* Establishes the accessory -> admin user relationship
|
* Establishes the accessory -> admin user relationship
|
||||||
*
|
*
|
||||||
* @author A. Gianotto <snipe@snipe.net>
|
* @author A. Gianotto <snipe@snipe.net>
|
||||||
* @since [v7.0.13]
|
* @since [v7.0.13]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function adminuser()
|
public function adminuser()
|
||||||
@@ -260,7 +260,7 @@ class Accessory extends SnipeModel
|
|||||||
* Checks whether or not the accessory has users
|
* Checks whether or not the accessory has users
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function hasUsers()
|
public function hasUsers()
|
||||||
@@ -274,7 +274,7 @@ class Accessory extends SnipeModel
|
|||||||
* Establishes the accessory -> manufacturer relationship
|
* Establishes the accessory -> manufacturer relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function manufacturer()
|
public function manufacturer()
|
||||||
@@ -287,7 +287,7 @@ class Accessory extends SnipeModel
|
|||||||
* accessory based on the category it belongs to.
|
* accessory based on the category it belongs to.
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function checkin_email()
|
public function checkin_email()
|
||||||
@@ -300,7 +300,7 @@ class Accessory extends SnipeModel
|
|||||||
* accept it via email.
|
* accept it via email.
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function requireAcceptance()
|
public function requireAcceptance()
|
||||||
@@ -313,7 +313,7 @@ class Accessory extends SnipeModel
|
|||||||
* checks for a settings level EULA
|
* checks for a settings level EULA
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getEula()
|
public function getEula()
|
||||||
@@ -333,7 +333,7 @@ class Accessory extends SnipeModel
|
|||||||
* Check how many items within an accessory are checked out
|
* Check how many items within an accessory are checked out
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v5.0]
|
* @since [v5.0]
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function numCheckedOut()
|
public function numCheckedOut()
|
||||||
@@ -350,7 +350,7 @@ class Accessory extends SnipeModel
|
|||||||
* bad things happen.
|
* bad things happen.
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function numRemaining()
|
public function numRemaining()
|
||||||
@@ -365,8 +365,8 @@ class Accessory extends SnipeModel
|
|||||||
/**
|
/**
|
||||||
* Run after the checkout acceptance was declined by the user
|
* Run after the checkout acceptance was declined by the user
|
||||||
*
|
*
|
||||||
* @param User $acceptedBy
|
* @param User $acceptedBy
|
||||||
* @param string $signature
|
* @param string $signature
|
||||||
*/
|
*/
|
||||||
public function declinedCheckout(User $declinedBy, $signature)
|
public function declinedCheckout(User $declinedBy, $signature)
|
||||||
{
|
{
|
||||||
@@ -392,8 +392,8 @@ class Accessory extends SnipeModel
|
|||||||
* This simply checks that there is a value for quantity, and if there isn't, set it to 0.
|
* This simply checks that there is a value for quantity, and if there isn't, set it to 0.
|
||||||
*
|
*
|
||||||
* @author A. Gianotto <snipe@snipe.net>
|
* @author A. Gianotto <snipe@snipe.net>
|
||||||
* @since v6.3.4
|
* @since v6.3.4
|
||||||
* @param $value
|
* @param $value
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setQtyAttribute($value)
|
public function setQtyAttribute($value)
|
||||||
@@ -410,7 +410,6 @@ class Accessory extends SnipeModel
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Query builder scope to order on created_by name
|
* Query builder scope to order on created_by name
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public function scopeOrderByCreatedByName($query, $order)
|
public function scopeOrderByCreatedByName($query, $order)
|
||||||
{
|
{
|
||||||
@@ -418,68 +417,68 @@ class Accessory extends SnipeModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query builder scope to order on company
|
* Query builder scope to order on company
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @param text $order Order
|
* @param text $order Order
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
public function scopeOrderCompany($query, $order)
|
public function scopeOrderCompany($query, $order)
|
||||||
{
|
{
|
||||||
return $query->leftJoin('companies', 'accessories.company_id', '=', 'companies.id')
|
return $query->leftJoin('companies', 'accessories.company_id', '=', 'companies.id')
|
||||||
->orderBy('companies.name', $order);
|
->orderBy('companies.name', $order);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query builder scope to order on category
|
* Query builder scope to order on category
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @param text $order Order
|
* @param text $order Order
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
public function scopeOrderCategory($query, $order)
|
public function scopeOrderCategory($query, $order)
|
||||||
{
|
{
|
||||||
return $query->leftJoin('categories', 'accessories.category_id', '=', 'categories.id')
|
return $query->leftJoin('categories', 'accessories.category_id', '=', 'categories.id')
|
||||||
->orderBy('categories.name', $order);
|
->orderBy('categories.name', $order);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query builder scope to order on location
|
* Query builder scope to order on location
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @param text $order Order
|
* @param text $order Order
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
public function scopeOrderLocation($query, $order)
|
public function scopeOrderLocation($query, $order)
|
||||||
{
|
{
|
||||||
return $query->leftJoin('locations', 'accessories.location_id', '=', 'locations.id')
|
return $query->leftJoin('locations', 'accessories.location_id', '=', 'locations.id')
|
||||||
->orderBy('locations.name', $order);
|
->orderBy('locations.name', $order);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query builder scope to order on manufacturer
|
* Query builder scope to order on manufacturer
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @param text $order Order
|
* @param text $order Order
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
public function scopeOrderManufacturer($query, $order)
|
public function scopeOrderManufacturer($query, $order)
|
||||||
{
|
{
|
||||||
return $query->leftJoin('manufacturers', 'accessories.manufacturer_id', '=', 'manufacturers.id')->orderBy('manufacturers.name', $order);
|
return $query->leftJoin('manufacturers', 'accessories.manufacturer_id', '=', 'manufacturers.id')->orderBy('manufacturers.name', $order);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query builder scope to order on supplier
|
* Query builder scope to order on supplier
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @param text $order Order
|
* @param text $order Order
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
public function scopeOrderSupplier($query, $order)
|
public function scopeOrderSupplier($query, $order)
|
||||||
{
|
{
|
||||||
return $query->leftJoin('suppliers', 'accessories.supplier_id', '=', 'suppliers.id')->orderBy('suppliers.name', $order);
|
return $query->leftJoin('suppliers', 'accessories.supplier_id', '=', 'suppliers.id')->orderBy('suppliers.name', $order);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use Watson\Validating\ValidatingTrait;
|
|||||||
/**
|
/**
|
||||||
* Model for Accessories.
|
* Model for Accessories.
|
||||||
*
|
*
|
||||||
* @version v1.0
|
* @version v1.0
|
||||||
*/
|
*/
|
||||||
class AccessoryCheckout extends Model
|
class AccessoryCheckout extends Model
|
||||||
{
|
{
|
||||||
@@ -36,7 +36,7 @@ class AccessoryCheckout extends Model
|
|||||||
* Establishes the accessory checkout -> accessory relationship
|
* Establishes the accessory checkout -> accessory relationship
|
||||||
*
|
*
|
||||||
* @author [A. Kroeger]
|
* @author [A. Kroeger]
|
||||||
* @since [v7.0.9]
|
* @since [v7.0.9]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function accessory()
|
public function accessory()
|
||||||
@@ -52,7 +52,7 @@ class AccessoryCheckout extends Model
|
|||||||
* Establishes the accessory checkout -> user relationship
|
* Establishes the accessory checkout -> user relationship
|
||||||
*
|
*
|
||||||
* @author [A. Kroeger]
|
* @author [A. Kroeger]
|
||||||
* @since [v7.0.9]
|
* @since [v7.0.9]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function adminuser()
|
public function adminuser()
|
||||||
@@ -64,7 +64,7 @@ class AccessoryCheckout extends Model
|
|||||||
* Get the target this asset is checked out to
|
* Get the target this asset is checked out to
|
||||||
*
|
*
|
||||||
* @author [A. Kroeger]
|
* @author [A. Kroeger]
|
||||||
* @since [v7.0]
|
* @since [v7.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function assignedTo()
|
public function assignedTo()
|
||||||
@@ -76,7 +76,7 @@ class AccessoryCheckout extends Model
|
|||||||
* Gets the lowercased name of the type of target the asset is assigned to
|
* Gets the lowercased name of the type of target the asset is assigned to
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v4.0]
|
* @since [v4.0]
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function assignedType()
|
public function assignedType()
|
||||||
@@ -91,7 +91,7 @@ class AccessoryCheckout extends Model
|
|||||||
* this method is an easy way of seeing if we are checked out to a user.
|
* this method is an easy way of seeing if we are checked out to a user.
|
||||||
*
|
*
|
||||||
* @author [A. Kroeger]
|
* @author [A. Kroeger]
|
||||||
* @since [v7.0]
|
* @since [v7.0]
|
||||||
*/
|
*/
|
||||||
public function checkedOutToUser(): bool
|
public function checkedOutToUser(): bool
|
||||||
{
|
{
|
||||||
@@ -127,50 +127,64 @@ class AccessoryCheckout extends Model
|
|||||||
* Run additional, advanced searches.
|
* Run additional, advanced searches.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||||
* @param array $terms The search terms
|
* @param array $terms The search terms
|
||||||
* @return \Illuminate\Database\Eloquent\Builder
|
* @return \Illuminate\Database\Eloquent\Builder
|
||||||
*/
|
*/
|
||||||
public function advancedTextSearch(Builder $query, array $terms)
|
public function advancedTextSearch(Builder $query, array $terms)
|
||||||
{
|
{
|
||||||
|
|
||||||
$userQuery = User::where(function ($query) use ($terms) {
|
$userQuery = User::where(
|
||||||
foreach ($terms as $term) {
|
function ($query) use ($terms) {
|
||||||
$search_str = '%' . $term . '%';
|
foreach ($terms as $term) {
|
||||||
$query->where('first_name', 'like', $search_str)
|
$search_str = '%' . $term . '%';
|
||||||
->orWhere('last_name', 'like', $search_str)
|
$query->where('first_name', 'like', $search_str)
|
||||||
->orWhere('note', 'like', $search_str);
|
->orWhere('last_name', 'like', $search_str)
|
||||||
|
->orWhere('note', 'like', $search_str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})->select('id');
|
)->select('id');
|
||||||
|
|
||||||
$locationQuery = Location::where(function ($query) use ($terms) {
|
$locationQuery = Location::where(
|
||||||
foreach ($terms as $term) {
|
function ($query) use ($terms) {
|
||||||
$search_str = '%' . $term . '%';
|
foreach ($terms as $term) {
|
||||||
$query->where('name', 'like', $search_str);
|
$search_str = '%' . $term . '%';
|
||||||
|
$query->where('name', 'like', $search_str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})->select('id');
|
)->select('id');
|
||||||
|
|
||||||
$assetQuery = Asset::where(function ($query) use ($terms) {
|
$assetQuery = Asset::where(
|
||||||
foreach ($terms as $term) {
|
function ($query) use ($terms) {
|
||||||
$search_str = '%' . $term . '%';
|
foreach ($terms as $term) {
|
||||||
$query->where('name', 'like', $search_str);
|
$search_str = '%' . $term . '%';
|
||||||
|
$query->where('name', 'like', $search_str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})->select('id');
|
)->select('id');
|
||||||
|
|
||||||
$query->where(function ($query) use ($userQuery) {
|
$query->where(
|
||||||
$query->where('assigned_type', User::class)
|
function ($query) use ($userQuery) {
|
||||||
->whereIn('assigned_to', $userQuery);
|
$query->where('assigned_type', User::class)
|
||||||
})->orWhere(function($query) use ($locationQuery) {
|
->whereIn('assigned_to', $userQuery);
|
||||||
$query->where('assigned_type', Location::class)
|
|
||||||
->whereIn('assigned_to', $locationQuery);
|
|
||||||
})->orWhere(function($query) use ($assetQuery) {
|
|
||||||
$query->where('assigned_type', Asset::class)
|
|
||||||
->whereIn('assigned_to', $assetQuery);
|
|
||||||
})->orWhere(function($query) use ($terms) {
|
|
||||||
foreach ($terms as $term) {
|
|
||||||
$search_str = '%' . $term . '%';
|
|
||||||
$query->where('note', 'like', $search_str);
|
|
||||||
}
|
}
|
||||||
});
|
)->orWhere(
|
||||||
|
function ($query) use ($locationQuery) {
|
||||||
|
$query->where('assigned_type', Location::class)
|
||||||
|
->whereIn('assigned_to', $locationQuery);
|
||||||
|
}
|
||||||
|
)->orWhere(
|
||||||
|
function ($query) use ($assetQuery) {
|
||||||
|
$query->where('assigned_type', Asset::class)
|
||||||
|
->whereIn('assigned_to', $assetQuery);
|
||||||
|
}
|
||||||
|
)->orWhere(
|
||||||
|
function ($query) use ($terms) {
|
||||||
|
foreach ($terms as $term) {
|
||||||
|
$search_str = '%' . $term . '%';
|
||||||
|
$query->where('note', 'like', $search_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,13 @@ use App\Presenters\Presentable;
|
|||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Model for the Actionlog (the table that keeps a historical log of
|
* Model for the Actionlog (the table that keeps a historical log of
|
||||||
* checkouts, checkins, and updates).
|
* checkouts, checkins, and updates).
|
||||||
*
|
*
|
||||||
* @version v1.0
|
* @version v1.0
|
||||||
*/
|
*/
|
||||||
class Actionlog extends SnipeModel
|
class Actionlog extends SnipeModel
|
||||||
{
|
{
|
||||||
@@ -74,6 +75,8 @@ class Actionlog extends SnipeModel
|
|||||||
'assets' => ['asset_tag','name', 'serial', 'order_number', 'notes', 'purchase_date'],
|
'assets' => ['asset_tag','name', 'serial', 'order_number', 'notes', 'purchase_date'],
|
||||||
'assets.model' => ['name', 'model_number', 'eol', 'notes'],
|
'assets.model' => ['name', 'model_number', 'eol', 'notes'],
|
||||||
'assets.model.category' => ['name', 'notes'],
|
'assets.model.category' => ['name', 'notes'],
|
||||||
|
'assets.location' => ['name'],
|
||||||
|
'assets.defaultLoc' => ['name'],
|
||||||
'assets.model.manufacturer' => ['name', 'notes'],
|
'assets.model.manufacturer' => ['name', 'notes'],
|
||||||
'licenses' => ['name', 'serial', 'notes', 'order_number', 'license_email', 'license_name', 'purchase_order', 'purchase_date'],
|
'licenses' => ['name', 'serial', 'notes', 'order_number', 'license_email', 'license_name', 'purchase_order', 'purchase_date'],
|
||||||
'licenses.category' => ['name', 'notes'],
|
'licenses.category' => ['name', 'notes'],
|
||||||
@@ -96,29 +99,31 @@ class Actionlog extends SnipeModel
|
|||||||
* Override from Builder to automatically add the company
|
* Override from Builder to automatically add the company
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public static function boot()
|
public static function boot()
|
||||||
{
|
{
|
||||||
parent::boot();
|
parent::boot();
|
||||||
static::creating(function (self $actionlog) {
|
static::creating(
|
||||||
// If the admin is a superadmin, let's see if the target instead has a company.
|
function (self $actionlog) {
|
||||||
if (auth()->user() && auth()->user()->isSuperUser()) {
|
// If the admin is a superadmin, let's see if the target instead has a company.
|
||||||
if ($actionlog->target) {
|
if (auth()->user() && auth()->user()->isSuperUser()) {
|
||||||
$actionlog->company_id = $actionlog->target->company_id;
|
if ($actionlog->target) {
|
||||||
} elseif ($actionlog->item) {
|
$actionlog->company_id = $actionlog->target->company_id;
|
||||||
$actionlog->company_id = $actionlog->item->company_id;
|
} elseif ($actionlog->item) {
|
||||||
|
$actionlog->company_id = $actionlog->item->company_id;
|
||||||
|
}
|
||||||
|
} elseif (auth()->user() && auth()->user()->company) {
|
||||||
|
$actionlog->company_id = auth()->user()->company_id;
|
||||||
}
|
}
|
||||||
} elseif (auth()->user() && auth()->user()->company) {
|
|
||||||
$actionlog->company_id = auth()->user()->company_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($actionlog->action_date == '') {
|
if ($actionlog->action_date == '') {
|
||||||
$actionlog->action_date = Carbon::now();
|
$actionlog->action_date = Carbon::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -126,7 +131,7 @@ class Actionlog extends SnipeModel
|
|||||||
* Establishes the actionlog -> item relationship
|
* Establishes the actionlog -> item relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function item()
|
public function item()
|
||||||
@@ -138,7 +143,7 @@ class Actionlog extends SnipeModel
|
|||||||
* Establishes the actionlog -> company relationship
|
* Establishes the actionlog -> company relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function company()
|
public function company()
|
||||||
@@ -151,7 +156,7 @@ class Actionlog extends SnipeModel
|
|||||||
* Establishes the actionlog -> asset relationship
|
* Establishes the actionlog -> asset relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function assets()
|
public function assets()
|
||||||
@@ -163,7 +168,7 @@ class Actionlog extends SnipeModel
|
|||||||
* Establishes the actionlog -> license relationship
|
* Establishes the actionlog -> license relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function licenses()
|
public function licenses()
|
||||||
@@ -175,7 +180,7 @@ class Actionlog extends SnipeModel
|
|||||||
* Establishes the actionlog -> consumable relationship
|
* Establishes the actionlog -> consumable relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function consumables()
|
public function consumables()
|
||||||
@@ -187,7 +192,7 @@ class Actionlog extends SnipeModel
|
|||||||
* Establishes the actionlog -> consumable relationship
|
* Establishes the actionlog -> consumable relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function accessories()
|
public function accessories()
|
||||||
@@ -199,7 +204,7 @@ class Actionlog extends SnipeModel
|
|||||||
* Establishes the actionlog -> components relationship
|
* Establishes the actionlog -> components relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function components()
|
public function components()
|
||||||
@@ -211,7 +216,7 @@ class Actionlog extends SnipeModel
|
|||||||
* Establishes the actionlog -> item type relationship
|
* Establishes the actionlog -> item type relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function itemType()
|
public function itemType()
|
||||||
@@ -227,7 +232,7 @@ class Actionlog extends SnipeModel
|
|||||||
* Establishes the actionlog -> target type relationship
|
* Establishes the actionlog -> target type relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function targetType()
|
public function targetType()
|
||||||
@@ -244,7 +249,7 @@ class Actionlog extends SnipeModel
|
|||||||
* Establishes the actionlog -> uploads relationship
|
* Establishes the actionlog -> uploads relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function uploads()
|
public function uploads()
|
||||||
@@ -258,7 +263,7 @@ class Actionlog extends SnipeModel
|
|||||||
* Establishes the actionlog -> userlog relationship
|
* Establishes the actionlog -> userlog relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function userlog()
|
public function userlog()
|
||||||
@@ -270,7 +275,7 @@ class Actionlog extends SnipeModel
|
|||||||
* Establishes the actionlog -> admin user relationship
|
* Establishes the actionlog -> admin user relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function adminuser()
|
public function adminuser()
|
||||||
@@ -283,7 +288,7 @@ class Actionlog extends SnipeModel
|
|||||||
* Establishes the actionlog -> user relationship
|
* Establishes the actionlog -> user relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function user()
|
public function user()
|
||||||
@@ -296,7 +301,7 @@ class Actionlog extends SnipeModel
|
|||||||
* Establishes the actionlog -> target relationship
|
* Establishes the actionlog -> target relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function target()
|
public function target()
|
||||||
@@ -308,7 +313,7 @@ class Actionlog extends SnipeModel
|
|||||||
* Establishes the actionlog -> location relationship
|
* Establishes the actionlog -> location relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function location()
|
public function location()
|
||||||
@@ -321,7 +326,7 @@ class Actionlog extends SnipeModel
|
|||||||
* Check if the file exists, and if it does, force a download
|
* Check if the file exists, and if it does, force a download
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return string | false
|
* @return string | false
|
||||||
*/
|
*/
|
||||||
public function get_src($type = 'assets', $fieldname = 'filename')
|
public function get_src($type = 'assets', $fieldname = 'filename')
|
||||||
@@ -339,7 +344,7 @@ class Actionlog extends SnipeModel
|
|||||||
* Saves the log record with the action type
|
* Saves the log record with the action type
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function logaction($actiontype)
|
public function logaction($actiontype)
|
||||||
@@ -360,7 +365,7 @@ class Actionlog extends SnipeModel
|
|||||||
* Calculate the number of days until the next audit
|
* Calculate the number of days until the next audit
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v4.0]
|
* @since [v4.0]
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function daysUntilNextAudit($monthInterval = 12, $asset = null)
|
public function daysUntilNextAudit($monthInterval = 12, $asset = null)
|
||||||
@@ -389,7 +394,7 @@ class Actionlog extends SnipeModel
|
|||||||
* Calculate the date of the next audit
|
* Calculate the date of the next audit
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v4.0]
|
* @since [v4.0]
|
||||||
* @return \Datetime
|
* @return \Datetime
|
||||||
*/
|
*/
|
||||||
public function calcNextAuditDate($monthInterval = 12, $asset = null)
|
public function calcNextAuditDate($monthInterval = 12, $asset = null)
|
||||||
@@ -406,8 +411,8 @@ class Actionlog extends SnipeModel
|
|||||||
/**
|
/**
|
||||||
* Gets action logs in chronological order, excluding uploads
|
* Gets action logs in chronological order, excluding uploads
|
||||||
*
|
*
|
||||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||||
* @since v1.0
|
* @since v1.0
|
||||||
* @return \Illuminate\Database\Eloquent\Collection
|
* @return \Illuminate\Database\Eloquent\Collection
|
||||||
*/
|
*/
|
||||||
public function getListingOfActionLogsChronologicalOrder()
|
public function getListingOfActionLogsChronologicalOrder()
|
||||||
@@ -423,7 +428,7 @@ class Actionlog extends SnipeModel
|
|||||||
* Determines what the type of request is so we can log it to the action_log
|
* Determines what the type of request is so we can log it to the action_log
|
||||||
*
|
*
|
||||||
* @author A. Gianotto <snipe@snipe.net>
|
* @author A. Gianotto <snipe@snipe.net>
|
||||||
* @since v6.3.0
|
* @since v6.3.0
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function determineActionSource(): string
|
public function determineActionSource(): string
|
||||||
@@ -435,7 +440,8 @@ class Actionlog extends SnipeModel
|
|||||||
|
|
||||||
// This is an API call
|
// This is an API call
|
||||||
if (((request()->header('content-type') && (request()->header('accept'))=='application/json'))
|
if (((request()->header('content-type') && (request()->header('accept'))=='application/json'))
|
||||||
&& (starts_with(request()->header('authorization'), 'Bearer '))) {
|
&& (starts_with(request()->header('authorization'), 'Bearer '))
|
||||||
|
) {
|
||||||
return 'api';
|
return 'api';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,59 +458,58 @@ class Actionlog extends SnipeModel
|
|||||||
public function uploads_file_url()
|
public function uploads_file_url()
|
||||||
{
|
{
|
||||||
|
|
||||||
switch ($this->item_type) {
|
|
||||||
case Accessory::class:
|
|
||||||
return route('show.accessoryfile', [$this->item_id, $this->id]);
|
if (($this->action_type == 'accepted') || ($this->action_type == 'declined')) {
|
||||||
case Asset::class:
|
return route('log.storedeula.download', ['filename' => $this->filename]);
|
||||||
return route('show/assetfile', [$this->item_id, $this->id]);
|
|
||||||
case AssetModel::class:
|
|
||||||
return route('show/modelfile', [$this->item_id, $this->id]);
|
|
||||||
case Consumable::class:
|
|
||||||
return route('show/locationsfile', [$this->item_id, $this->id]);
|
|
||||||
case Component::class:
|
|
||||||
return route('show.componentfile', [$this->item_id, $this->id]);
|
|
||||||
case License::class:
|
|
||||||
return route('show.licensefile', [$this->item_id, $this->id]);
|
|
||||||
case Location::class:
|
|
||||||
return route('show/locationsfile', [$this->item_id, $this->id]);
|
|
||||||
case User::class:
|
|
||||||
return route('show/userfile', [$this->item_id, $this->id]);
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$object = Str::snake(str_plural(str_replace("App\Models\\", '', $this->item_type)));
|
||||||
|
|
||||||
|
if ($object == 'asset_models') {
|
||||||
|
$object = 'models';
|
||||||
|
}
|
||||||
|
|
||||||
|
return route('ui.files.show', [
|
||||||
|
'object_type' => $object,
|
||||||
|
'id' => $this->item_id,
|
||||||
|
'file_id' => $this->id,
|
||||||
|
]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function uploads_file_path()
|
public function uploads_file_path()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (($this->action_type == 'accepted') || ($this->action_type == 'declined')) {
|
||||||
|
return 'private_uploads/eula-pdfs/'.$this->filename;
|
||||||
|
}
|
||||||
|
|
||||||
switch ($this->item_type) {
|
switch ($this->item_type) {
|
||||||
case Accessory::class:
|
case Accessory::class:
|
||||||
return 'private_uploads/accessories/'.$this->filename;
|
return 'private_uploads/accessories/'.$this->filename;
|
||||||
case Asset::class:
|
case Asset::class:
|
||||||
return 'private_uploads/assets/'.$this->filename;
|
return 'private_uploads/assets/'.$this->filename;
|
||||||
case AssetModel::class:
|
case AssetModel::class:
|
||||||
return 'private_uploads/assetmodels/'.$this->filename;
|
return 'private_uploads/models/'.$this->filename;
|
||||||
case Consumable::class:
|
case Consumable::class:
|
||||||
return 'private_uploads/consumables/'.$this->filename;
|
return 'private_uploads/consumables/'.$this->filename;
|
||||||
case Component::class:
|
case Component::class:
|
||||||
return 'private_uploads/components/'.$this->filename;
|
return 'private_uploads/components/'.$this->filename;
|
||||||
case License::class:
|
case License::class:
|
||||||
return 'private_uploads/licenses/'.$this->filename;
|
return 'private_uploads/licenses/'.$this->filename;
|
||||||
case Location::class:
|
case Location::class:
|
||||||
return 'private_uploads/locations/'.$this->filename;
|
return 'private_uploads/locations/'.$this->filename;
|
||||||
case User::class:
|
case Maintenance::class:
|
||||||
return 'private_uploads/users/'.$this->filename;
|
return 'private_uploads/maintenances/'.$this->filename;
|
||||||
default:
|
case User::class:
|
||||||
return null;
|
return 'private_uploads/users/'.$this->filename;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Manually sets $this->source for determineActionSource()
|
// Manually sets $this->source for determineActionSource()
|
||||||
public function setActionSource($source = null): void
|
public function setActionSource($source = null): void
|
||||||
{
|
{
|
||||||
|
|||||||
1247
app/Models/Asset.php
1247
app/Models/Asset.php
File diff suppressed because it is too large
Load Diff
@@ -17,7 +17,7 @@ use App\Http\Traits\TwoColumnUniqueUndeletedTrait;
|
|||||||
* Model for Asset Models. Asset Models contain higher level
|
* Model for Asset Models. Asset Models contain higher level
|
||||||
* attributes that are common among the same type of asset.
|
* attributes that are common among the same type of asset.
|
||||||
*
|
*
|
||||||
* @version v1.0
|
* @version v1.0
|
||||||
*/
|
*/
|
||||||
class AssetModel extends SnipeModel
|
class AssetModel extends SnipeModel
|
||||||
{
|
{
|
||||||
@@ -98,14 +98,22 @@ class AssetModel extends SnipeModel
|
|||||||
'manufacturer' => ['name'],
|
'manufacturer' => ['name'],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
protected static function booted(): void
|
||||||
|
{
|
||||||
|
static::forceDeleted(function (AssetModel $assetModel) {
|
||||||
|
$assetModel->requests()->forceDelete();
|
||||||
|
});
|
||||||
|
|
||||||
|
static::softDeleted(function (AssetModel $assetModel) {
|
||||||
|
$assetModel->requests()->delete();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Establishes the model -> assets relationship
|
* Establishes the model -> assets relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v1.0]
|
* @since [v1.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function assets()
|
public function assets()
|
||||||
@@ -117,7 +125,7 @@ class AssetModel extends SnipeModel
|
|||||||
* Establishes the model -> category relationship
|
* Establishes the model -> category relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v1.0]
|
* @since [v1.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function category()
|
public function category()
|
||||||
@@ -129,7 +137,7 @@ class AssetModel extends SnipeModel
|
|||||||
* Establishes the model -> depreciation relationship
|
* Establishes the model -> depreciation relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v1.0]
|
* @since [v1.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function depreciation()
|
public function depreciation()
|
||||||
@@ -141,7 +149,7 @@ class AssetModel extends SnipeModel
|
|||||||
* Establishes the model -> manufacturer relationship
|
* Establishes the model -> manufacturer relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v1.0]
|
* @since [v1.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function manufacturer()
|
public function manufacturer()
|
||||||
@@ -153,7 +161,7 @@ class AssetModel extends SnipeModel
|
|||||||
* Establishes the model -> fieldset relationship
|
* Establishes the model -> fieldset relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v2.0]
|
* @since [v2.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function fieldset()
|
public function fieldset()
|
||||||
@@ -163,14 +171,14 @@ class AssetModel extends SnipeModel
|
|||||||
|
|
||||||
public function customFields()
|
public function customFields()
|
||||||
{
|
{
|
||||||
return $this->fieldset()->first()->fields();
|
return $this->fieldset()->first()->fields();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Establishes the model -> custom field default values relationship
|
* Establishes the model -> custom field default values relationship
|
||||||
*
|
*
|
||||||
* @author hannah tinkler
|
* @author hannah tinkler
|
||||||
* @since [v4.3]
|
* @since [v4.3]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function defaultValues()
|
public function defaultValues()
|
||||||
@@ -184,7 +192,7 @@ class AssetModel extends SnipeModel
|
|||||||
* @todo this should probably be moved
|
* @todo this should probably be moved
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v2.0]
|
* @since [v2.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function getImageUrl()
|
public function getImageUrl()
|
||||||
@@ -201,7 +209,7 @@ class AssetModel extends SnipeModel
|
|||||||
* Checks if the model is deletable
|
* Checks if the model is deletable
|
||||||
*
|
*
|
||||||
* @author A. Gianotto <snipe@snipe.net>
|
* @author A. Gianotto <snipe@snipe.net>
|
||||||
* @since [v6.3.4]
|
* @since [v6.3.4]
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isDeletable()
|
public function isDeletable()
|
||||||
@@ -216,7 +224,7 @@ class AssetModel extends SnipeModel
|
|||||||
* Get user who created the item
|
* Get user who created the item
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v1.0]
|
* @since [v1.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function adminuser()
|
public function adminuser()
|
||||||
@@ -235,10 +243,10 @@ class AssetModel extends SnipeModel
|
|||||||
* scopeInCategory
|
* scopeInCategory
|
||||||
* Get all models that are in the array of category ids
|
* Get all models that are in the array of category ids
|
||||||
*
|
*
|
||||||
* @param $query
|
* @param $query
|
||||||
* @param array $categoryIdListing
|
* @param array $categoryIdListing
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||||
* @version v1.0
|
* @version v1.0
|
||||||
*/
|
*/
|
||||||
@@ -251,9 +259,9 @@ class AssetModel extends SnipeModel
|
|||||||
* scopeRequestable
|
* scopeRequestable
|
||||||
* Get all models that are requestable by a user.
|
* Get all models that are requestable by a user.
|
||||||
*
|
*
|
||||||
* @param $query
|
* @param $query
|
||||||
*
|
*
|
||||||
* @return $query
|
* @return $query
|
||||||
* @author Daniel Meltzer <dmeltzer.devel@gmail.com>
|
* @author Daniel Meltzer <dmeltzer.devel@gmail.com>
|
||||||
* @version v3.5
|
* @version v3.5
|
||||||
*/
|
*/
|
||||||
@@ -265,8 +273,8 @@ class AssetModel extends SnipeModel
|
|||||||
/**
|
/**
|
||||||
* Query builder scope to search on text, including catgeory and manufacturer name
|
* Query builder scope to search on text, including catgeory and manufacturer name
|
||||||
*
|
*
|
||||||
* @param Illuminate\Database\Query\Builder $query Query builder instance
|
* @param Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @param text $search Search term
|
* @param text $search Search term
|
||||||
*
|
*
|
||||||
* @return Illuminate\Database\Query\Builder Modified query builder
|
* @return Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
@@ -274,23 +282,31 @@ class AssetModel extends SnipeModel
|
|||||||
{
|
{
|
||||||
return $query->where('models.name', 'LIKE', "%$search%")
|
return $query->where('models.name', 'LIKE', "%$search%")
|
||||||
->orWhere('model_number', 'LIKE', "%$search%")
|
->orWhere('model_number', 'LIKE', "%$search%")
|
||||||
->orWhere(function ($query) use ($search) {
|
->orWhere(
|
||||||
$query->whereHas('category', function ($query) use ($search) {
|
function ($query) use ($search) {
|
||||||
$query->where('categories.name', 'LIKE', '%'.$search.'%');
|
$query->whereHas(
|
||||||
});
|
'category', function ($query) use ($search) {
|
||||||
})
|
$query->where('categories.name', 'LIKE', '%'.$search.'%');
|
||||||
->orWhere(function ($query) use ($search) {
|
}
|
||||||
$query->whereHas('manufacturer', function ($query) use ($search) {
|
);
|
||||||
$query->where('manufacturers.name', 'LIKE', '%'.$search.'%');
|
}
|
||||||
});
|
)
|
||||||
});
|
->orWhere(
|
||||||
|
function ($query) use ($search) {
|
||||||
|
$query->whereHas(
|
||||||
|
'manufacturer', function ($query) use ($search) {
|
||||||
|
$query->where('manufacturers.name', 'LIKE', '%'.$search.'%');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query builder scope to order on manufacturer
|
* Query builder scope to order on manufacturer
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @param text $order Order
|
* @param text $order Order
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
@@ -302,8 +318,8 @@ class AssetModel extends SnipeModel
|
|||||||
/**
|
/**
|
||||||
* Query builder scope to order on category name
|
* Query builder scope to order on category name
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @param text $order Order
|
* @param text $order Order
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
@@ -319,7 +335,6 @@ class AssetModel extends SnipeModel
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Query builder scope to order on created_by name
|
* Query builder scope to order on created_by name
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public function scopeOrderByCreatedByName($query, $order)
|
public function scopeOrderByCreatedByName($query, $order)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use Illuminate\Support\Str;
|
|||||||
* to require acceptance from the user, whether or not to
|
* to require acceptance from the user, whether or not to
|
||||||
* send a EULA to the user, etc.
|
* send a EULA to the user, etc.
|
||||||
*
|
*
|
||||||
* @version v1.0
|
* @version v1.0
|
||||||
*/
|
*/
|
||||||
class Category extends SnipeModel
|
class Category extends SnipeModel
|
||||||
{
|
{
|
||||||
@@ -96,7 +96,7 @@ class Category extends SnipeModel
|
|||||||
* Checks if category can be deleted
|
* Checks if category can be deleted
|
||||||
*
|
*
|
||||||
* @author [Dan Meltzer] [<dmeltzer.devel@gmail.com>]
|
* @author [Dan Meltzer] [<dmeltzer.devel@gmail.com>]
|
||||||
* @since [v5.0]
|
* @since [v5.0]
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isDeletable()
|
public function isDeletable()
|
||||||
@@ -119,7 +119,7 @@ class Category extends SnipeModel
|
|||||||
* Establishes the category -> accessories relationship
|
* Establishes the category -> accessories relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v2.0]
|
* @since [v2.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function accessories()
|
public function accessories()
|
||||||
@@ -131,7 +131,7 @@ class Category extends SnipeModel
|
|||||||
* Establishes the category -> licenses relationship
|
* Establishes the category -> licenses relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v4.3]
|
* @since [v4.3]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function licenses()
|
public function licenses()
|
||||||
@@ -143,7 +143,7 @@ class Category extends SnipeModel
|
|||||||
* Establishes the category -> consumables relationship
|
* Establishes the category -> consumables relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function consumables()
|
public function consumables()
|
||||||
@@ -155,7 +155,7 @@ class Category extends SnipeModel
|
|||||||
* Establishes the category -> consumables relationship
|
* Establishes the category -> consumables relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function components()
|
public function components()
|
||||||
@@ -170,7 +170,7 @@ class Category extends SnipeModel
|
|||||||
* It should only be used in a single category context.
|
* It should only be used in a single category context.
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v2.0]
|
* @since [v2.0]
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function itemCount()
|
public function itemCount()
|
||||||
@@ -181,18 +181,18 @@ class Category extends SnipeModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch ($this->category_type) {
|
switch ($this->category_type) {
|
||||||
case 'asset':
|
case 'asset':
|
||||||
return $this->assets->count();
|
return $this->assets->count();
|
||||||
case 'accessory':
|
case 'accessory':
|
||||||
return $this->accessories->count();
|
return $this->accessories->count();
|
||||||
case 'component':
|
case 'component':
|
||||||
return $this->components->count();
|
return $this->components->count();
|
||||||
case 'consumable':
|
case 'consumable':
|
||||||
return $this->consumables->count();
|
return $this->consumables->count();
|
||||||
case 'license':
|
case 'license':
|
||||||
return $this->licenses->count();
|
return $this->licenses->count();
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -201,7 +201,7 @@ class Category extends SnipeModel
|
|||||||
* Establishes the category -> assets relationship
|
* Establishes the category -> assets relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v2.0]
|
* @since [v2.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function assets()
|
public function assets()
|
||||||
@@ -218,8 +218,8 @@ class Category extends SnipeModel
|
|||||||
* by their category.
|
* by their category.
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v6.1.0]
|
* @since [v6.1.0]
|
||||||
* @see \App\Models\Asset::scopeAssetsForShow()
|
* @see \App\Models\Asset::scopeAssetsForShow()
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function showableAssets()
|
public function showableAssets()
|
||||||
@@ -231,7 +231,7 @@ class Category extends SnipeModel
|
|||||||
* Establishes the category -> models relationship
|
* Establishes the category -> models relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v2.0]
|
* @since [v2.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function models()
|
public function models()
|
||||||
@@ -249,7 +249,7 @@ class Category extends SnipeModel
|
|||||||
* checks for a settings level EULA
|
* checks for a settings level EULA
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v2.0]
|
* @since [v2.0]
|
||||||
* @return string | null
|
* @return string | null
|
||||||
*/
|
*/
|
||||||
public function getEula()
|
public function getEula()
|
||||||
@@ -276,7 +276,7 @@ class Category extends SnipeModel
|
|||||||
*
|
*
|
||||||
* This will also correctly parse a 1/0 if "true"/"false" is passed.
|
* This will also correctly parse a 1/0 if "true"/"false" is passed.
|
||||||
*
|
*
|
||||||
* @param $value
|
* @param $value
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setCheckinEmailAttribute($value)
|
public function setCheckinEmailAttribute($value)
|
||||||
@@ -293,9 +293,9 @@ class Category extends SnipeModel
|
|||||||
/**
|
/**
|
||||||
* Query builder scope for whether or not the category requires acceptance
|
* Query builder scope for whether or not the category requires acceptance
|
||||||
*
|
*
|
||||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
public function scopeRequiresAcceptance($query)
|
public function scopeRequiresAcceptance($query)
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ class CheckoutAcceptance extends Model
|
|||||||
/**
|
/**
|
||||||
* Was the checkoutable checked out to this user?
|
* Was the checkoutable checked out to this user?
|
||||||
*
|
*
|
||||||
* @param User $user
|
* @param User $user
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isCheckedOutTo(User $user)
|
public function isCheckedOutTo(User $user)
|
||||||
@@ -79,7 +79,7 @@ class CheckoutAcceptance extends Model
|
|||||||
* Do not add stuff here that doesn't have a corresponding column in the
|
* Do not add stuff here that doesn't have a corresponding column in the
|
||||||
* checkout_acceptances table or you'll get an error.
|
* checkout_acceptances table or you'll get an error.
|
||||||
*
|
*
|
||||||
* @param string $signature_filename
|
* @param string $signature_filename
|
||||||
*/
|
*/
|
||||||
public function accept($signature_filename, $eula = null, $filename = null, $note = null)
|
public function accept($signature_filename, $eula = null, $filename = null, $note = null)
|
||||||
{
|
{
|
||||||
@@ -99,7 +99,7 @@ class CheckoutAcceptance extends Model
|
|||||||
/**
|
/**
|
||||||
* Decline the checkout acceptance
|
* Decline the checkout acceptance
|
||||||
*
|
*
|
||||||
* @param string $signature_filename
|
* @param string $signature_filename
|
||||||
*/
|
*/
|
||||||
public function decline($signature_filename, $note = null)
|
public function decline($signature_filename, $note = null)
|
||||||
{
|
{
|
||||||
@@ -116,8 +116,9 @@ class CheckoutAcceptance extends Model
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter checkout acceptences by the user
|
* Filter checkout acceptences by the user
|
||||||
|
*
|
||||||
* @param Illuminate\Database\Eloquent\Builder $query
|
* @param Illuminate\Database\Eloquent\Builder $query
|
||||||
* @param User $user
|
* @param User $user
|
||||||
* @return \Illuminate\Database\Eloquent\Builder
|
* @return \Illuminate\Database\Eloquent\Builder
|
||||||
*/
|
*/
|
||||||
public function scopeForUser(Builder $query, User $user)
|
public function scopeForUser(Builder $query, User $user)
|
||||||
@@ -127,6 +128,7 @@ class CheckoutAcceptance extends Model
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter to only get pending acceptances
|
* Filter to only get pending acceptances
|
||||||
|
*
|
||||||
* @param Illuminate\Database\Eloquent\Builder $query
|
* @param Illuminate\Database\Eloquent\Builder $query
|
||||||
* @return \Illuminate\Database\Eloquent\Builder
|
* @return \Illuminate\Database\Eloquent\Builder
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -2,11 +2,13 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class CheckoutRequest extends Model
|
class CheckoutRequest extends Model
|
||||||
{
|
{
|
||||||
|
use HasFactory;
|
||||||
use SoftDeletes;
|
use SoftDeletes;
|
||||||
protected $fillable = ['user_id'];
|
protected $fillable = ['user_id'];
|
||||||
protected $table = 'checkout_requests';
|
protected $table = 'checkout_requests';
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use Illuminate\Support\Facades\Schema;
|
|||||||
/**
|
/**
|
||||||
* Model for Companies.
|
* Model for Companies.
|
||||||
*
|
*
|
||||||
* @version v1.8
|
* @version v1.8
|
||||||
*/
|
*/
|
||||||
final class Company extends SnipeModel
|
final class Company extends SnipeModel
|
||||||
{
|
{
|
||||||
@@ -28,19 +28,19 @@ final class Company extends SnipeModel
|
|||||||
'name' => 'required|min:1|max:255|unique:companies,name',
|
'name' => 'required|min:1|max:255|unique:companies,name',
|
||||||
'fax' => 'min:7|max:35|nullable',
|
'fax' => 'min:7|max:35|nullable',
|
||||||
'phone' => 'min:7|max:35|nullable',
|
'phone' => 'min:7|max:35|nullable',
|
||||||
'email' => 'email|max:150|nullable',
|
'email' => 'email|max:150|nullable',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $presenter = \App\Presenters\CompanyPresenter::class;
|
protected $presenter = \App\Presenters\CompanyPresenter::class;
|
||||||
use Presentable;
|
use Presentable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the model should inject it's identifier to the unique
|
* Whether the model should inject it's identifier to the unique
|
||||||
* validation rules before attempting validation. If this property
|
* validation rules before attempting validation. If this property
|
||||||
* is not set in the model it will default to true.
|
* is not set in the model it will default to true.
|
||||||
*
|
*
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
protected $injectUniqueIdentifier = true;
|
protected $injectUniqueIdentifier = true;
|
||||||
use ValidatingTrait;
|
use ValidatingTrait;
|
||||||
use Searchable;
|
use Searchable;
|
||||||
@@ -102,7 +102,7 @@ final class Company extends SnipeModel
|
|||||||
* account the full multiple company support setting
|
* account the full multiple company support setting
|
||||||
* and if the current user is a super user.
|
* and if the current user is a super user.
|
||||||
*
|
*
|
||||||
* @param $unescaped_input
|
* @param $unescaped_input
|
||||||
* @return int|mixed|string|null
|
* @return int|mixed|string|null
|
||||||
*/
|
*/
|
||||||
public static function getIdForCurrentUser($unescaped_input)
|
public static function getIdForCurrentUser($unescaped_input)
|
||||||
@@ -129,7 +129,7 @@ final class Company extends SnipeModel
|
|||||||
* Check to see if the current user should have access to the model.
|
* Check to see if the current user should have access to the model.
|
||||||
* I hate this method and I think it should be refactored.
|
* I hate this method and I think it should be refactored.
|
||||||
*
|
*
|
||||||
* @param $companyable
|
* @param $companyable
|
||||||
* @return bool|void
|
* @return bool|void
|
||||||
*/
|
*/
|
||||||
public static function isCurrentUserHasAccess($companyable)
|
public static function isCurrentUserHasAccess($companyable)
|
||||||
@@ -192,7 +192,7 @@ final class Company extends SnipeModel
|
|||||||
* Checks if company can be deleted
|
* Checks if company can be deleted
|
||||||
*
|
*
|
||||||
* @author [Dan Meltzer] [<dmeltzer.devel@gmail.com>]
|
* @author [Dan Meltzer] [<dmeltzer.devel@gmail.com>]
|
||||||
* @since [v5.0]
|
* @since [v5.0]
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isDeletable()
|
public function isDeletable()
|
||||||
@@ -209,7 +209,7 @@ final class Company extends SnipeModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $unescaped_input
|
* @param $unescaped_input
|
||||||
* @return int|mixed|string|null
|
* @return int|mixed|string|null
|
||||||
*/
|
*/
|
||||||
public static function getIdForUser($unescaped_input)
|
public static function getIdForUser($unescaped_input)
|
||||||
@@ -265,9 +265,9 @@ final class Company extends SnipeModel
|
|||||||
* @todo - refactor that trait to handle the user's model as well.
|
* @todo - refactor that trait to handle the user's model as well.
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] <snipe@snipe.net>
|
* @author [A. Gianotto] <snipe@snipe.net>
|
||||||
* @param $query
|
* @param $query
|
||||||
* @param $column
|
* @param $column
|
||||||
* @param $table_name
|
* @param $table_name
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function scopeCompanyables($query, $column = 'company_id', $table_name = null)
|
public static function scopeCompanyables($query, $column = 'company_id', $table_name = null)
|
||||||
@@ -327,8 +327,8 @@ final class Company extends SnipeModel
|
|||||||
* This gets invoked by CompanyableChildScope, but I'm not sure what it does.
|
* This gets invoked by CompanyableChildScope, but I'm not sure what it does.
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] <snipe@snipe.net>
|
* @author [A. Gianotto] <snipe@snipe.net>
|
||||||
* @param array $companyable_names
|
* @param array $companyable_names
|
||||||
* @param $query
|
* @param $query
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function scopeCompanyableChildren(array $companyable_names, $query)
|
public static function scopeCompanyableChildren(array $companyable_names, $query)
|
||||||
@@ -343,13 +343,15 @@ final class Company extends SnipeModel
|
|||||||
static::scopeCompanyablesDirectly($q);
|
static::scopeCompanyablesDirectly($q);
|
||||||
};
|
};
|
||||||
|
|
||||||
$q = $query->where(function ($q) use ($companyable_names, $f) {
|
$q = $query->where(
|
||||||
$q2 = $q->whereHas($companyable_names[0], $f);
|
function ($q) use ($companyable_names, $f) {
|
||||||
|
$q2 = $q->whereHas($companyable_names[0], $f);
|
||||||
|
|
||||||
for ($i = 1; $i < count($companyable_names); $i++) {
|
for ($i = 1; $i < count($companyable_names); $i++) {
|
||||||
$q2 = $q2->orWhereHas($companyable_names[$i], $f);
|
$q2 = $q2->orWhereHas($companyable_names[$i], $f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
|
|
||||||
return $q;
|
return $q;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,15 +9,15 @@ use Illuminate\Database\Eloquent\Scope;
|
|||||||
/**
|
/**
|
||||||
* Handle query scoping for full company support.
|
* Handle query scoping for full company support.
|
||||||
*
|
*
|
||||||
* @todo Move this to a more Laravel 5.2 esque way
|
* @todo Move this to a more Laravel 5.2 esque way
|
||||||
* @version v1.0
|
* @version v1.0
|
||||||
*/
|
*/
|
||||||
final class CompanyableChildScope implements Scope
|
final class CompanyableChildScope implements Scope
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Apply the scope to a given Eloquent query builder.
|
* Apply the scope to a given Eloquent query builder.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Eloquent\Builder $builder
|
* @param \Illuminate\Database\Eloquent\Builder $builder
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function apply(Builder $builder, Model $model)
|
public function apply(Builder $builder, Model $model)
|
||||||
@@ -31,7 +31,7 @@ final class CompanyableChildScope implements Scope
|
|||||||
* @todo IMPLEMENT
|
* @todo IMPLEMENT
|
||||||
* Remove the scope from the given Eloquent query builder.
|
* Remove the scope from the given Eloquent query builder.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Eloquent\Builder $builder
|
* @param \Illuminate\Database\Eloquent\Builder $builder
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function remove(Builder $builder)
|
public function remove(Builder $builder)
|
||||||
|
|||||||
@@ -9,15 +9,15 @@ use Illuminate\Database\Eloquent\Scope;
|
|||||||
/**
|
/**
|
||||||
* Handle query scoping for full company support.
|
* Handle query scoping for full company support.
|
||||||
*
|
*
|
||||||
* @todo Move this to a more Laravel 5.2 esque way
|
* @todo Move this to a more Laravel 5.2 esque way
|
||||||
* @version v1.0
|
* @version v1.0
|
||||||
*/
|
*/
|
||||||
final class CompanyableScope implements Scope
|
final class CompanyableScope implements Scope
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Apply the scope to a given Eloquent query builder.
|
* Apply the scope to a given Eloquent query builder.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Eloquent\Builder $builder
|
* @param \Illuminate\Database\Eloquent\Builder $builder
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function apply(Builder $builder, Model $model)
|
public function apply(Builder $builder, Model $model)
|
||||||
@@ -29,7 +29,7 @@ final class CompanyableScope implements Scope
|
|||||||
* @todo IMPLEMENT
|
* @todo IMPLEMENT
|
||||||
* Remove the scope from the given Eloquent query builder.
|
* Remove the scope from the given Eloquent query builder.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Eloquent\Builder $builder
|
* @param \Illuminate\Database\Eloquent\Builder $builder
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function remove(Builder $builder)
|
public function remove(Builder $builder)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ trait CompanyableTrait
|
|||||||
* This trait is used to scope models to the current company. To use this scope on companyable models,
|
* This trait is used to scope models to the current company. To use this scope on companyable models,
|
||||||
* we use the "use Companyable;" statement at the top of the mode.
|
* we use the "use Companyable;" statement at the top of the mode.
|
||||||
*
|
*
|
||||||
* @see \App\Models\Company\Company::scopeCompanyables()
|
* @see \App\Models\Company\Company::scopeCompanyables()
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function bootCompanyableTrait()
|
public static function bootCompanyableTrait()
|
||||||
|
|||||||
@@ -2,18 +2,20 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Helpers\Helper;
|
||||||
use App\Models\Traits\HasUploads;
|
use App\Models\Traits\HasUploads;
|
||||||
use App\Models\Traits\Searchable;
|
use App\Models\Traits\Searchable;
|
||||||
use App\Presenters\Presentable;
|
use App\Presenters\Presentable;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Illuminate\Support\Facades\Gate;
|
use Illuminate\Support\Facades\Gate;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Watson\Validating\ValidatingTrait;
|
use Watson\Validating\ValidatingTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Model for Components.
|
* Model for Components.
|
||||||
*
|
*
|
||||||
* @version v1.0
|
* @version v1.0
|
||||||
*/
|
*/
|
||||||
class Component extends SnipeModel
|
class Component extends SnipeModel
|
||||||
{
|
{
|
||||||
@@ -121,7 +123,7 @@ class Component extends SnipeModel
|
|||||||
* Establishes the component -> location relationship
|
* Establishes the component -> location relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function location()
|
public function location()
|
||||||
@@ -133,7 +135,7 @@ class Component extends SnipeModel
|
|||||||
* Establishes the component -> assets relationship
|
* Establishes the component -> assets relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function assets()
|
public function assets()
|
||||||
@@ -147,7 +149,7 @@ class Component extends SnipeModel
|
|||||||
* @todo this is probably not needed - refactor
|
* @todo this is probably not needed - refactor
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function adminuser()
|
public function adminuser()
|
||||||
@@ -159,7 +161,7 @@ class Component extends SnipeModel
|
|||||||
* Establishes the component -> company relationship
|
* Establishes the component -> company relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function company()
|
public function company()
|
||||||
@@ -171,7 +173,7 @@ class Component extends SnipeModel
|
|||||||
* Establishes the component -> category relationship
|
* Establishes the component -> category relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function category()
|
public function category()
|
||||||
@@ -183,7 +185,7 @@ class Component extends SnipeModel
|
|||||||
* Establishes the item -> supplier relationship
|
* Establishes the item -> supplier relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v6.1.1]
|
* @since [v6.1.1]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function supplier()
|
public function supplier()
|
||||||
@@ -196,19 +198,49 @@ class Component extends SnipeModel
|
|||||||
* Establishes the item -> manufacturer relationship
|
* Establishes the item -> manufacturer relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function manufacturer()
|
public function manufacturer()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(\App\Models\Manufacturer::class, 'manufacturer_id');
|
return $this->belongsTo(\App\Models\Manufacturer::class, 'manufacturer_id');
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Determine whether this asset requires acceptance by the assigned user
|
||||||
|
*
|
||||||
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
|
* @since [v4.0]
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function requireAcceptance()
|
||||||
|
{
|
||||||
|
return $this->category->require_acceptance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for a category-specific EULA, and if that doesn't exist,
|
||||||
|
* checks for a settings level EULA
|
||||||
|
*
|
||||||
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
|
* @since [v4.0]
|
||||||
|
* @return string | false
|
||||||
|
*/
|
||||||
|
public function getEula()
|
||||||
|
{
|
||||||
|
if ($this->category->eula_text) {
|
||||||
|
return Helper::parseEscapedMarkedown($this->category->eula_text);
|
||||||
|
} elseif ((Setting::getSettings()->default_eula_text) && ($this->category->use_default_eula == '1')) {
|
||||||
|
return Helper::parseEscapedMarkedown(Setting::getSettings()->default_eula_text);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Establishes the component -> action logs relationship
|
* Establishes the component -> action logs relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function assetlog()
|
public function assetlog()
|
||||||
@@ -220,7 +252,7 @@ class Component extends SnipeModel
|
|||||||
* Check how many items within a component are checked out
|
* Check how many items within a component are checked out
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v5.0]
|
* @since [v5.0]
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function numCheckedOut()
|
public function numCheckedOut()
|
||||||
@@ -239,20 +271,34 @@ class Component extends SnipeModel
|
|||||||
*
|
*
|
||||||
* This allows us to get the assets with assigned components without the company restriction
|
* This allows us to get the assets with assigned components without the company restriction
|
||||||
*/
|
*/
|
||||||
public function uncontrainedAssets() {
|
public function uncontrainedAssets()
|
||||||
|
{
|
||||||
|
|
||||||
return $this->belongsToMany(\App\Models\Asset::class, 'components_assets')
|
return $this->belongsToMany(\App\Models\Asset::class, 'components_assets')
|
||||||
->withPivot('id', 'assigned_qty', 'created_at', 'created_by', 'note')
|
->withPivot('id', 'assigned_qty', 'created_at', 'created_by', 'note')
|
||||||
->withoutGlobalScope(new CompanyableScope);
|
->withoutGlobalScope(new CompanyableScope);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether to send a checkin/checkout email based on
|
||||||
|
* asset model category
|
||||||
|
*
|
||||||
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
|
* @since [v4.0]
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function checkin_email()
|
||||||
|
{
|
||||||
|
return $this->category?->checkin_email;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check how many items within a component are remaining
|
* Check how many items within a component are remaining
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function numRemaining()
|
public function numRemaining()
|
||||||
@@ -275,8 +321,8 @@ class Component extends SnipeModel
|
|||||||
* This simply checks that there is a value for quantity, and if there isn't, set it to 0.
|
* This simply checks that there is a value for quantity, and if there isn't, set it to 0.
|
||||||
*
|
*
|
||||||
* @author A. Gianotto <snipe@snipe.net>
|
* @author A. Gianotto <snipe@snipe.net>
|
||||||
* @since v6.3.4
|
* @since v6.3.4
|
||||||
* @param $value
|
* @param $value
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setQtyAttribute($value)
|
public function setQtyAttribute($value)
|
||||||
@@ -294,8 +340,8 @@ class Component extends SnipeModel
|
|||||||
/**
|
/**
|
||||||
* Query builder scope to order on company
|
* Query builder scope to order on company
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @param string $order Order
|
* @param string $order Order
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
@@ -307,8 +353,8 @@ class Component extends SnipeModel
|
|||||||
/**
|
/**
|
||||||
* Query builder scope to order on company
|
* Query builder scope to order on company
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @param string $order Order
|
* @param string $order Order
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
@@ -320,8 +366,8 @@ class Component extends SnipeModel
|
|||||||
/**
|
/**
|
||||||
* Query builder scope to order on company
|
* Query builder scope to order on company
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @param string $order Order
|
* @param string $order Order
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
@@ -333,8 +379,8 @@ class Component extends SnipeModel
|
|||||||
/**
|
/**
|
||||||
* Query builder scope to order on supplier
|
* Query builder scope to order on supplier
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @param text $order Order
|
* @param text $order Order
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
@@ -346,8 +392,8 @@ class Component extends SnipeModel
|
|||||||
/**
|
/**
|
||||||
* Query builder scope to order on manufacturer
|
* Query builder scope to order on manufacturer
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @param text $order Order
|
* @param text $order Order
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ class Consumable extends SnipeModel
|
|||||||
* @todo Update this comment once it's been implemented
|
* @todo Update this comment once it's been implemented
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function setRequestableAttribute($value)
|
public function setRequestableAttribute($value)
|
||||||
@@ -140,7 +140,7 @@ class Consumable extends SnipeModel
|
|||||||
* Establishes the consumable -> admin user relationship
|
* Establishes the consumable -> admin user relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function adminuser()
|
public function adminuser()
|
||||||
@@ -152,7 +152,7 @@ class Consumable extends SnipeModel
|
|||||||
* Establishes the component -> assignments relationship
|
* Establishes the component -> assignments relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function consumableAssignments()
|
public function consumableAssignments()
|
||||||
@@ -164,7 +164,7 @@ class Consumable extends SnipeModel
|
|||||||
* Establishes the component -> company relationship
|
* Establishes the component -> company relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function company()
|
public function company()
|
||||||
@@ -176,7 +176,7 @@ class Consumable extends SnipeModel
|
|||||||
* Establishes the component -> manufacturer relationship
|
* Establishes the component -> manufacturer relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function manufacturer()
|
public function manufacturer()
|
||||||
@@ -188,7 +188,7 @@ class Consumable extends SnipeModel
|
|||||||
* Establishes the component -> location relationship
|
* Establishes the component -> location relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function location()
|
public function location()
|
||||||
@@ -200,7 +200,7 @@ class Consumable extends SnipeModel
|
|||||||
* Establishes the component -> category relationship
|
* Establishes the component -> category relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function category()
|
public function category()
|
||||||
@@ -213,7 +213,7 @@ class Consumable extends SnipeModel
|
|||||||
* Establishes the component -> action logs relationship
|
* Establishes the component -> action logs relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function assetlog()
|
public function assetlog()
|
||||||
@@ -225,23 +225,28 @@ class Consumable extends SnipeModel
|
|||||||
* Gets the full image url for the consumable
|
* Gets the full image url for the consumable
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return string | false
|
* @return string | false
|
||||||
*/
|
*/
|
||||||
public function getImageUrl()
|
public function getImageUrl()
|
||||||
{
|
{
|
||||||
|
// If there is a consumable image, use that
|
||||||
if ($this->image) {
|
if ($this->image) {
|
||||||
return Storage::disk('public')->url(app('consumables_upload_path').$this->image);
|
return Storage::disk('public')->url(app('consumables_upload_path').$this->image);
|
||||||
}
|
|
||||||
return false;
|
|
||||||
|
|
||||||
|
// Otherwise check for a category image
|
||||||
|
} elseif (($this->category) && ($this->category->image)) {
|
||||||
|
return Storage::disk('public')->url(app('categories_upload_path').e($this->category->image));
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Establishes the component -> users relationship
|
* Establishes the component -> users relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
*/
|
*/
|
||||||
public function users() : Relation
|
public function users() : Relation
|
||||||
{
|
{
|
||||||
@@ -252,7 +257,7 @@ class Consumable extends SnipeModel
|
|||||||
* Establishes the item -> supplier relationship
|
* Establishes the item -> supplier relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v6.1.1]
|
* @since [v6.1.1]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function supplier()
|
public function supplier()
|
||||||
@@ -266,7 +271,7 @@ class Consumable extends SnipeModel
|
|||||||
* asset model category
|
* asset model category
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v4.0]
|
* @since [v4.0]
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function checkin_email()
|
public function checkin_email()
|
||||||
@@ -278,7 +283,7 @@ class Consumable extends SnipeModel
|
|||||||
* Determine whether this asset requires acceptance by the assigned user
|
* Determine whether this asset requires acceptance by the assigned user
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v4.0]
|
* @since [v4.0]
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function requireAcceptance()
|
public function requireAcceptance()
|
||||||
@@ -291,7 +296,7 @@ class Consumable extends SnipeModel
|
|||||||
* checks for a settings level EULA
|
* checks for a settings level EULA
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v4.0]
|
* @since [v4.0]
|
||||||
* @return string | false
|
* @return string | false
|
||||||
*/
|
*/
|
||||||
public function getEula()
|
public function getEula()
|
||||||
@@ -309,7 +314,7 @@ class Consumable extends SnipeModel
|
|||||||
* Check how many items within a consumable are checked out
|
* Check how many items within a consumable are checked out
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v5.0]
|
* @since [v5.0]
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function numCheckedOut()
|
public function numCheckedOut()
|
||||||
@@ -321,7 +326,7 @@ class Consumable extends SnipeModel
|
|||||||
* Checks the number of available consumables
|
* Checks the number of available consumables
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v4.0]
|
* @since [v4.0]
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function numRemaining()
|
public function numRemaining()
|
||||||
@@ -347,8 +352,8 @@ class Consumable extends SnipeModel
|
|||||||
* This simply checks that there is a value for quantity, and if there isn't, set it to 0.
|
* This simply checks that there is a value for quantity, and if there isn't, set it to 0.
|
||||||
*
|
*
|
||||||
* @author A. Gianotto <snipe@snipe.net>
|
* @author A. Gianotto <snipe@snipe.net>
|
||||||
* @since v6.3.4
|
* @since v6.3.4
|
||||||
* @param $value
|
* @param $value
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setQtyAttribute($value)
|
public function setQtyAttribute($value)
|
||||||
@@ -365,8 +370,8 @@ class Consumable extends SnipeModel
|
|||||||
/**
|
/**
|
||||||
* Query builder scope to order on company
|
* Query builder scope to order on company
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @param string $order Order
|
* @param string $order Order
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
@@ -378,8 +383,8 @@ class Consumable extends SnipeModel
|
|||||||
/**
|
/**
|
||||||
* Query builder scope to order on location
|
* Query builder scope to order on location
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @param text $order Order
|
* @param text $order Order
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
@@ -391,8 +396,8 @@ class Consumable extends SnipeModel
|
|||||||
/**
|
/**
|
||||||
* Query builder scope to order on manufacturer
|
* Query builder scope to order on manufacturer
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @param string $order Order
|
* @param string $order Order
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
@@ -404,8 +409,8 @@ class Consumable extends SnipeModel
|
|||||||
/**
|
/**
|
||||||
* Query builder scope to order on company
|
* Query builder scope to order on company
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @param string $order Order
|
* @param string $order Order
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
@@ -417,8 +422,8 @@ class Consumable extends SnipeModel
|
|||||||
/**
|
/**
|
||||||
* Query builder scope to order on remaining
|
* Query builder scope to order on remaining
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @param string $order Order
|
* @param string $order Order
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
@@ -431,8 +436,8 @@ class Consumable extends SnipeModel
|
|||||||
/**
|
/**
|
||||||
* Query builder scope to order on supplier
|
* Query builder scope to order on supplier
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @param text $order Order
|
* @param text $order Order
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class CustomField extends Model
|
|||||||
UniqueUndeletedTrait;
|
UniqueUndeletedTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
*
|
||||||
* Custom field predfined formats
|
* Custom field predfined formats
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
@@ -92,7 +93,7 @@ class CustomField extends Model
|
|||||||
* table instead of the assets table.
|
* table instead of the assets table.
|
||||||
*
|
*
|
||||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
*/
|
*/
|
||||||
public static $table_name = 'assets';
|
public static $table_name = 'assets';
|
||||||
|
|
||||||
@@ -103,7 +104,7 @@ class CustomField extends Model
|
|||||||
* do with previously existing values. - @snipe
|
* do with previously existing values. - @snipe
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.4]
|
* @since [v3.4]
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function name_to_db_name($name)
|
public static function name_to_db_name($name)
|
||||||
@@ -120,66 +121,78 @@ class CustomField extends Model
|
|||||||
* to do it in the controllers.
|
* to do it in the controllers.
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.4]
|
* @since [v3.4]
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function boot()
|
public static function boot()
|
||||||
{
|
{
|
||||||
parent::boot();
|
parent::boot();
|
||||||
self::created(function ($custom_field) {
|
self::created(
|
||||||
|
function ($custom_field) {
|
||||||
|
|
||||||
// Column already exists on the assets table - nothing to do here.
|
// Column already exists on the assets table - nothing to do here.
|
||||||
// This *shouldn't* happen in the wild.
|
// This *shouldn't* happen in the wild.
|
||||||
if (Schema::hasColumn(self::$table_name, $custom_field->db_column)) {
|
if (Schema::hasColumn(self::$table_name, $custom_field->db_column)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the column name in the assets table
|
||||||
|
Schema::table(
|
||||||
|
self::$table_name, function ($table) use ($custom_field) {
|
||||||
|
$table->text($custom_field->convertUnicodeDbSlug())->nullable();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Update the db_column property in the custom fields table
|
||||||
|
$custom_field->db_column = $custom_field->convertUnicodeDbSlug();
|
||||||
|
$custom_field->save();
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// Update the column name in the assets table
|
self::updating(
|
||||||
Schema::table(self::$table_name, function ($table) use ($custom_field) {
|
function ($custom_field) {
|
||||||
$table->text($custom_field->convertUnicodeDbSlug())->nullable();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update the db_column property in the custom fields table
|
// Column already exists on the assets table - nothing to do here.
|
||||||
$custom_field->db_column = $custom_field->convertUnicodeDbSlug();
|
if ($custom_field->isDirty('name')) {
|
||||||
$custom_field->save();
|
if (Schema::hasColumn(self::$table_name, $custom_field->convertUnicodeDbSlug())) {
|
||||||
});
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
self::updating(function ($custom_field) {
|
// Rename the field if the name has changed
|
||||||
|
Schema::table(
|
||||||
|
self::$table_name, function ($table) use ($custom_field) {
|
||||||
|
$table->renameColumn($custom_field->convertUnicodeDbSlug($custom_field->getOriginal('name')), $custom_field->convertUnicodeDbSlug());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Save the updated column name to the custom fields table
|
||||||
|
$custom_field->db_column = $custom_field->convertUnicodeDbSlug();
|
||||||
|
$custom_field->save();
|
||||||
|
|
||||||
// Column already exists on the assets table - nothing to do here.
|
|
||||||
if ($custom_field->isDirty('name')) {
|
|
||||||
if (Schema::hasColumn(self::$table_name, $custom_field->convertUnicodeDbSlug())) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rename the field if the name has changed
|
|
||||||
Schema::table(self::$table_name, function ($table) use ($custom_field) {
|
|
||||||
$table->renameColumn($custom_field->convertUnicodeDbSlug($custom_field->getOriginal('name')), $custom_field->convertUnicodeDbSlug());
|
|
||||||
});
|
|
||||||
|
|
||||||
// Save the updated column name to the custom fields table
|
|
||||||
$custom_field->db_column = $custom_field->convertUnicodeDbSlug();
|
|
||||||
$custom_field->save();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
);
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Drop the assets column if we've deleted it from custom fields
|
// Drop the assets column if we've deleted it from custom fields
|
||||||
self::deleting(function ($custom_field) {
|
self::deleting(
|
||||||
return Schema::table(self::$table_name, function ($table) use ($custom_field) {
|
function ($custom_field) {
|
||||||
$table->dropColumn($custom_field->db_column);
|
return Schema::table(
|
||||||
});
|
self::$table_name, function ($table) use ($custom_field) {
|
||||||
});
|
$table->dropColumn($custom_field->db_column);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Establishes the customfield -> fieldset relationship
|
* Establishes the customfield -> fieldset relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function fieldset()
|
public function fieldset()
|
||||||
@@ -214,26 +227,26 @@ class CustomField extends Model
|
|||||||
public function displayFieldInCurrentForm($form_type = null)
|
public function displayFieldInCurrentForm($form_type = null)
|
||||||
{
|
{
|
||||||
switch ($form_type) {
|
switch ($form_type) {
|
||||||
case 'audit':
|
case 'audit':
|
||||||
return $this->displayFieldInAuditForm();
|
return $this->displayFieldInAuditForm();
|
||||||
case 'checkin':
|
case 'checkin':
|
||||||
return $this->displayFieldInCheckinForm();
|
return $this->displayFieldInCheckinForm();
|
||||||
case 'checkout':
|
case 'checkout':
|
||||||
return $this->displayFieldInCheckoutForm();
|
return $this->displayFieldInCheckoutForm();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function assetModels()
|
public function assetModels()
|
||||||
{
|
{
|
||||||
return $this->fieldset()->with('models')->get()->pluck('models')->flatten()->unique('id');
|
return $this->fieldset()->with('models')->get()->pluck('models')->flatten()->unique('id');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Establishes the customfield -> admin user relationship
|
* Establishes the customfield -> admin user relationship
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function user()
|
public function user()
|
||||||
@@ -245,7 +258,7 @@ class CustomField extends Model
|
|||||||
* Establishes the customfield -> default values relationship
|
* Establishes the customfield -> default values relationship
|
||||||
*
|
*
|
||||||
* @author Hannah Tinkler
|
* @author Hannah Tinkler
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function defaultValues()
|
public function defaultValues()
|
||||||
@@ -262,19 +275,23 @@ class CustomField extends Model
|
|||||||
*/
|
*/
|
||||||
public function defaultValue($modelId)
|
public function defaultValue($modelId)
|
||||||
{
|
{
|
||||||
return $this->defaultValues->filter(function ($item) use ($modelId) {
|
return $this->defaultValues->filter(
|
||||||
return $item->pivot->asset_model_id == $modelId;
|
function ($item) use ($modelId) {
|
||||||
})->map(function ($item) {
|
return $item->pivot->asset_model_id == $modelId;
|
||||||
return $item->pivot->default_value;
|
}
|
||||||
})->first();
|
)->map(
|
||||||
|
function ($item) {
|
||||||
|
return $item->pivot->default_value;
|
||||||
|
}
|
||||||
|
)->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the format of the attribute
|
* Checks the format of the attribute
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @param $value string
|
* @param $value string
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function check_format($value)
|
public function check_format($value)
|
||||||
@@ -286,7 +303,7 @@ class CustomField extends Model
|
|||||||
* Gets the DB column name.
|
* Gets the DB column name.
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function db_column_name()
|
public function db_column_name()
|
||||||
@@ -302,7 +319,7 @@ class CustomField extends Model
|
|||||||
* user-friendly text in the dropdowns, and in the custom fields display.
|
* user-friendly text in the dropdowns, and in the custom fields display.
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.4]
|
* @since [v3.4]
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getFormatAttribute($value)
|
public function getFormatAttribute($value)
|
||||||
@@ -320,7 +337,7 @@ class CustomField extends Model
|
|||||||
* Format a value string as an array for select boxes and checkboxes.
|
* Format a value string as an array for select boxes and checkboxes.
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.4]
|
* @since [v3.4]
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function setFormatAttribute($value)
|
public function setFormatAttribute($value)
|
||||||
@@ -336,7 +353,7 @@ class CustomField extends Model
|
|||||||
* Format a value string as an array for select boxes and checkboxes.
|
* Format a value string as an array for select boxes and checkboxes.
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.4]
|
* @since [v3.4]
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function formatFieldValuesAsArray()
|
public function formatFieldValuesAsArray()
|
||||||
@@ -366,7 +383,7 @@ class CustomField extends Model
|
|||||||
* Check whether the field is encrypted
|
* Check whether the field is encrypted
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.4]
|
* @since [v3.4]
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isFieldDecryptable($string)
|
public function isFieldDecryptable($string)
|
||||||
@@ -383,7 +400,7 @@ class CustomField extends Model
|
|||||||
* won't break the database.
|
* won't break the database.
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.4]
|
* @since [v3.4]
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function convertUnicodeDbSlug($original = null)
|
public function convertUnicodeDbSlug($original = null)
|
||||||
@@ -392,7 +409,7 @@ class CustomField extends Model
|
|||||||
$id = $this->id ? $this->id : 'xx';
|
$id = $this->id ? $this->id : 'xx';
|
||||||
|
|
||||||
if (! function_exists('transliterator_transliterate')) {
|
if (! function_exists('transliterator_transliterate')) {
|
||||||
$long_slug = '_snipeit_'.str_slug(mb_convert_encoding(trim($name),"UTF-8"), '_');
|
$long_slug = '_snipeit_'.str_slug(mb_convert_encoding(trim($name), "UTF-8"), '_');
|
||||||
} else {
|
} else {
|
||||||
$long_slug = '_snipeit_'.Utf8Slugger::slugify($name, '_');
|
$long_slug = '_snipeit_'.Utf8Slugger::slugify($name, '_');
|
||||||
}
|
}
|
||||||
@@ -402,9 +419,10 @@ class CustomField extends Model
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get validation rules for custom fields to use with Validator
|
* Get validation rules for custom fields to use with Validator
|
||||||
|
*
|
||||||
* @author [V. Cordes] [<volker@fdatek.de>]
|
* @author [V. Cordes] [<volker@fdatek.de>]
|
||||||
* @param int $id
|
* @param int $id
|
||||||
* @since [v4.1.10]
|
* @since [v4.1.10]
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function validationRules($regex_format = null)
|
public function validationRules($regex_format = null)
|
||||||
@@ -418,6 +436,7 @@ class CustomField extends Model
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Check to see if there is a custom regex format type
|
* Check to see if there is a custom regex format type
|
||||||
|
*
|
||||||
* @see https://github.com/grokability/snipe-it/issues/5896
|
* @see https://github.com/grokability/snipe-it/issues/5896
|
||||||
*
|
*
|
||||||
* @author Wes Hulette <jwhulette@gmail.com>
|
* @author Wes Hulette <jwhulette@gmail.com>
|
||||||
|
|||||||
@@ -3,12 +3,19 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Rules\AlphaEncrypted;
|
use App\Rules\AlphaEncrypted;
|
||||||
|
use App\Rules\BooleanEncrypted;
|
||||||
|
use App\Rules\DateEncrypted;
|
||||||
|
use App\Rules\EmailEncrypted;
|
||||||
|
use App\Rules\IPEncrypted;
|
||||||
|
use App\Rules\IPv4Encrypted;
|
||||||
|
use App\Rules\IPv6Encrypted;
|
||||||
|
use App\Rules\MacEncrypted;
|
||||||
use App\Rules\NumericEncrypted;
|
use App\Rules\NumericEncrypted;
|
||||||
|
use App\Rules\RegexEncrypted;
|
||||||
|
use App\Rules\UrlEncrypted;
|
||||||
use Gate;
|
use Gate;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
use Watson\Validating\ValidatingTrait;
|
use Watson\Validating\ValidatingTrait;
|
||||||
|
|
||||||
class CustomFieldset extends Model
|
class CustomFieldset extends Model
|
||||||
@@ -20,6 +27,7 @@ class CustomFieldset extends Model
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Validation rules
|
* Validation rules
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
public $rules = [
|
public $rules = [
|
||||||
@@ -39,7 +47,7 @@ class CustomFieldset extends Model
|
|||||||
* Establishes the fieldset -> field relationship
|
* Establishes the fieldset -> field relationship
|
||||||
*
|
*
|
||||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function fields()
|
public function fields()
|
||||||
@@ -51,7 +59,7 @@ class CustomFieldset extends Model
|
|||||||
* Establishes the fieldset -> models relationship
|
* Establishes the fieldset -> models relationship
|
||||||
*
|
*
|
||||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function models()
|
public function models()
|
||||||
@@ -63,7 +71,7 @@ class CustomFieldset extends Model
|
|||||||
* Establishes the fieldset -> admin user relationship
|
* Establishes the fieldset -> admin user relationship
|
||||||
*
|
*
|
||||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function user()
|
public function user()
|
||||||
@@ -76,14 +84,14 @@ class CustomFieldset extends Model
|
|||||||
if ($this->fields) {
|
if ($this->fields) {
|
||||||
|
|
||||||
switch ($form_type) {
|
switch ($form_type) {
|
||||||
case 'audit':
|
case 'audit':
|
||||||
return $this->fields->where('display_audit', '1')->count() > 0;
|
return $this->fields->where('display_audit', '1')->count() > 0;
|
||||||
case 'checkin':
|
case 'checkin':
|
||||||
return $this->fields->where('display_checkin', '1')->count() > 0;
|
return $this->fields->where('display_checkin', '1')->count() > 0;
|
||||||
case 'checkout':
|
case 'checkout':
|
||||||
return $this->fields->where('display_checkout', '1')->count() > 0;
|
return $this->fields->where('display_checkout', '1')->count() > 0;
|
||||||
default:
|
default:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,17 +103,18 @@ class CustomFieldset extends Model
|
|||||||
* custom field format
|
* custom field format
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v3.0]
|
* @since [v3.0]
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function validation_rules()
|
public function validation_rules(): array
|
||||||
{
|
{
|
||||||
$rules = [];
|
$rules = [];
|
||||||
foreach ($this->fields as $field) {
|
foreach ($this->fields as $field) {
|
||||||
$rule = [];
|
$rule = [];
|
||||||
|
|
||||||
if (($field->field_encrypted != '1') ||
|
if (($field->field_encrypted != '1')
|
||||||
(($field->field_encrypted == '1') && (Gate::allows('admin')))) {
|
|| (($field->field_encrypted == '1') && (Gate::allows('admin')))
|
||||||
|
) {
|
||||||
$rule[] = ($field->pivot->required == '1') ? 'required' : 'nullable';
|
$rule[] = ($field->pivot->required == '1') ? 'required' : 'nullable';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,18 +128,65 @@ class CustomFieldset extends Model
|
|||||||
|
|
||||||
$rules[$field->db_column_name()] = $rule;
|
$rules[$field->db_column_name()] = $rule;
|
||||||
|
|
||||||
|
// this is to switch the rules to rules specially made for encrypted custom fields that decrypt the value before validating
|
||||||
// these are to replace the standard 'numeric' and 'alpha' rules if the custom field is also encrypted.
|
if ($field->field_encrypted) {
|
||||||
// the values need to be decrypted first, because encrypted strings are alphanumeric
|
|
||||||
if ($field->format === 'NUMERIC' && $field->field_encrypted) {
|
|
||||||
$numericKey = array_search('numeric', $rules[$field->db_column_name()]);
|
$numericKey = array_search('numeric', $rules[$field->db_column_name()]);
|
||||||
$rules[$field->db_column_name()][$numericKey] = new NumericEncrypted;
|
$alphaKey = array_search('alpha', $rules[$field->db_column_name()]);
|
||||||
|
$emailKey = array_search('email', $rules[$field->db_column_name()]);
|
||||||
|
$dateKey = array_search('date', $rules[$field->db_column_name()]);
|
||||||
|
$urlKey = array_search('url', $rules[$field->db_column_name()]);
|
||||||
|
$ipKey = array_search('ip', $rules[$field->db_column_name()]);
|
||||||
|
$ipv4Key = array_search('ipv4', $rules[$field->db_column_name()]);
|
||||||
|
$ipv6Key = array_search('ipv6', $rules[$field->db_column_name()]);
|
||||||
|
$macKey = array_search('regex:/^[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}$/', $rules[$field->db_column_name()]);
|
||||||
|
$booleanKey = array_search('boolean', $rules[$field->db_column_name()]);
|
||||||
|
// find objects in array that start with "regex:"
|
||||||
|
// collect because i couldn't figure how to do this
|
||||||
|
// with array filter and get keys out of it
|
||||||
|
$regexCollect = collect($rules[$field->db_column_name()]);
|
||||||
|
$regexKeys = $regexCollect->filter(function ($value, $key) {
|
||||||
|
return starts_with($value, 'regex:');
|
||||||
|
})->keys()->values()->toArray();
|
||||||
|
|
||||||
|
switch ($field->format) {
|
||||||
|
case 'NUMERIC':
|
||||||
|
$rules[$field->db_column_name()][$numericKey] = new NumericEncrypted;
|
||||||
|
break;
|
||||||
|
case 'ALPHA':
|
||||||
|
$rules[$field->db_column_name()][$alphaKey] = new AlphaEncrypted;
|
||||||
|
break;
|
||||||
|
case 'EMAIL':
|
||||||
|
$rules[$field->db_column_name()][$emailKey] = new EmailEncrypted;
|
||||||
|
break;
|
||||||
|
case 'DATE':
|
||||||
|
$rules[$field->db_column_name()][$dateKey] = new DateEncrypted;
|
||||||
|
break;
|
||||||
|
case 'URL':
|
||||||
|
$rules[$field->db_column_name()][$urlKey] = new UrlEncrypted;
|
||||||
|
break;
|
||||||
|
case 'IP':
|
||||||
|
$rules[$field->db_column_name()][$ipKey] = new IPEncrypted;
|
||||||
|
break;
|
||||||
|
case 'IPV4':
|
||||||
|
$rules[$field->db_column_name()][$ipv4Key] = new IPv4Encrypted;
|
||||||
|
break;
|
||||||
|
case 'IPV6':
|
||||||
|
$rules[$field->db_column_name()][$ipv6Key] = new IPv6Encrypted;
|
||||||
|
break;
|
||||||
|
case 'MAC':
|
||||||
|
$rules[$field->db_column_name()][$macKey] = new MacEncrypted;
|
||||||
|
break;
|
||||||
|
case 'BOOLEAN':
|
||||||
|
$rules[$field->db_column_name()][$booleanKey] = new BooleanEncrypted;
|
||||||
|
break;
|
||||||
|
case starts_with($field->format, 'regex'):
|
||||||
|
foreach ($regexKeys as $regexKey) {
|
||||||
|
$rules[$field->db_column_name()][$regexKey] = new RegexEncrypted;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($field->format === 'ALPHA' && $field->field_encrypted) {
|
|
||||||
$alphaKey = array_search('alpha', $rules[$field->db_column_name()]);
|
|
||||||
$rules[$field->db_column_name()][$alphaKey] = new AlphaEncrypted;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add not_array to rules for all fields but checkboxes
|
// add not_array to rules for all fields but checkboxes
|
||||||
if ($field->element != 'checkbox') {
|
if ($field->element != 'checkbox') {
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ class Department extends SnipeModel
|
|||||||
* Establishes the department -> company relationship
|
* Establishes the department -> company relationship
|
||||||
*
|
*
|
||||||
* @author A. Gianotto <snipe@snipe.net>
|
* @author A. Gianotto <snipe@snipe.net>
|
||||||
* @since [v4.0]
|
* @since [v4.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function company()
|
public function company()
|
||||||
@@ -84,7 +84,7 @@ class Department extends SnipeModel
|
|||||||
* Establishes the department -> users relationship
|
* Establishes the department -> users relationship
|
||||||
*
|
*
|
||||||
* @author A. Gianotto <snipe@snipe.net>
|
* @author A. Gianotto <snipe@snipe.net>
|
||||||
* @since [v4.0]
|
* @since [v4.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function users()
|
public function users()
|
||||||
@@ -96,7 +96,7 @@ class Department extends SnipeModel
|
|||||||
* Establishes the department -> manager relationship
|
* Establishes the department -> manager relationship
|
||||||
*
|
*
|
||||||
* @author A. Gianotto <snipe@snipe.net>
|
* @author A. Gianotto <snipe@snipe.net>
|
||||||
* @since [v4.0]
|
* @since [v4.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function manager()
|
public function manager()
|
||||||
@@ -108,7 +108,7 @@ class Department extends SnipeModel
|
|||||||
* Establishes the department -> location relationship
|
* Establishes the department -> location relationship
|
||||||
*
|
*
|
||||||
* @author A. Gianotto <snipe@snipe.net>
|
* @author A. Gianotto <snipe@snipe.net>
|
||||||
* @since [v4.0]
|
* @since [v4.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function location()
|
public function location()
|
||||||
@@ -119,8 +119,8 @@ class Department extends SnipeModel
|
|||||||
/**
|
/**
|
||||||
* Query builder scope to order on location name
|
* Query builder scope to order on location name
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @param text $order Order
|
* @param text $order Order
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
@@ -132,8 +132,8 @@ class Department extends SnipeModel
|
|||||||
/**
|
/**
|
||||||
* Query builder scope to order on manager name
|
* Query builder scope to order on manager name
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @param text $order Order
|
* @param text $order Order
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
@@ -145,8 +145,8 @@ class Department extends SnipeModel
|
|||||||
/**
|
/**
|
||||||
* Query builder scope to order on company
|
* Query builder scope to order on company
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||||
* @param text $order Order
|
* @param text $order Order
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -48,15 +48,15 @@ class Depreciable extends SnipeModel
|
|||||||
$depreciation = 0;
|
$depreciation = 0;
|
||||||
$setting = Setting::getSettings();
|
$setting = Setting::getSettings();
|
||||||
switch ($setting->depreciation_method) {
|
switch ($setting->depreciation_method) {
|
||||||
case 'half_1':
|
case 'half_1':
|
||||||
$depreciation = $this->getHalfYearDepreciatedValue(true);
|
$depreciation = $this->getHalfYearDepreciatedValue(true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'half_2':
|
case 'half_2':
|
||||||
$depreciation = $this->getHalfYearDepreciatedValue(false);
|
$depreciation = $this->getHalfYearDepreciatedValue(false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$depreciation = $this->getLinearDepreciatedValue();
|
$depreciation = $this->getLinearDepreciatedValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ class Depreciable extends SnipeModel
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($months_passed >= $this->get_depreciation()->months){
|
if ($months_passed >= $this->get_depreciation()->months) {
|
||||||
//if there is a floor use it
|
//if there is a floor use it
|
||||||
if($this->get_depreciation()->depreciation_min) {
|
if($this->get_depreciation()->depreciation_min) {
|
||||||
|
|
||||||
@@ -93,14 +93,15 @@ class Depreciable extends SnipeModel
|
|||||||
return $current_value;
|
return $current_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getMonthlyDepreciation(){
|
public function getMonthlyDepreciation()
|
||||||
|
{
|
||||||
|
|
||||||
return ($this->purchase_cost-$this->calculateDepreciation())/$this->get_depreciation()->months;
|
return ($this->purchase_cost-$this->calculateDepreciation())/$this->get_depreciation()->months;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param onlyHalfFirstYear Boolean always applied only second half of the first year
|
* @param onlyHalfFirstYear Boolean always applied only second half of the first year
|
||||||
* @return float|int
|
* @return float|int
|
||||||
*/
|
*/
|
||||||
public function getHalfYearDepreciatedValue($onlyHalfFirstYear = false)
|
public function getHalfYearDepreciatedValue($onlyHalfFirstYear = false)
|
||||||
@@ -131,7 +132,7 @@ class Depreciable extends SnipeModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \DateTime $date
|
* @param \DateTime $date
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
protected function get_fiscal_year($date)
|
protected function get_fiscal_year($date)
|
||||||
@@ -146,7 +147,7 @@ class Depreciable extends SnipeModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \DateTime $date
|
* @param \DateTime $date
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
protected function is_first_half_of_year($date)
|
protected function is_first_half_of_year($date)
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class Depreciation extends SnipeModel
|
|||||||
* Establishes the depreciation -> models relationship
|
* Establishes the depreciation -> models relationship
|
||||||
*
|
*
|
||||||
* @author A. Gianotto <snipe@snipe.net>
|
* @author A. Gianotto <snipe@snipe.net>
|
||||||
* @since [v5.0]
|
* @since [v5.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function models()
|
public function models()
|
||||||
@@ -68,7 +68,7 @@ class Depreciation extends SnipeModel
|
|||||||
* Establishes the depreciation -> licenses relationship
|
* Establishes the depreciation -> licenses relationship
|
||||||
*
|
*
|
||||||
* @author A. Gianotto <snipe@snipe.net>
|
* @author A. Gianotto <snipe@snipe.net>
|
||||||
* @since [v5.0]
|
* @since [v5.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function licenses()
|
public function licenses()
|
||||||
@@ -80,7 +80,7 @@ class Depreciation extends SnipeModel
|
|||||||
* Establishes the depreciation -> assets relationship
|
* Establishes the depreciation -> assets relationship
|
||||||
*
|
*
|
||||||
* @author A. Gianotto <snipe@snipe.net>
|
* @author A. Gianotto <snipe@snipe.net>
|
||||||
* @since [v5.0]
|
* @since [v5.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function assets()
|
public function assets()
|
||||||
@@ -92,7 +92,7 @@ class Depreciation extends SnipeModel
|
|||||||
* Get the user that created the depreciation
|
* Get the user that created the depreciation
|
||||||
*
|
*
|
||||||
* @author A. Gianotto <snipe@snipe.net>
|
* @author A. Gianotto <snipe@snipe.net>
|
||||||
* @since [v7.0.13]
|
* @since [v7.0.13]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function adminuser()
|
public function adminuser()
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class Group extends SnipeModel
|
|||||||
* Establishes the groups -> users relationship
|
* Establishes the groups -> users relationship
|
||||||
*
|
*
|
||||||
* @author A. Gianotto <snipe@snipe.net>
|
* @author A. Gianotto <snipe@snipe.net>
|
||||||
* @since [v1.0]
|
* @since [v1.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function users()
|
public function users()
|
||||||
@@ -63,7 +63,7 @@ class Group extends SnipeModel
|
|||||||
* Get the user that created the group
|
* Get the user that created the group
|
||||||
*
|
*
|
||||||
* @author A. Gianotto <snipe@snipe.net>
|
* @author A. Gianotto <snipe@snipe.net>
|
||||||
* @since [v6.3.0]
|
* @since [v6.3.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function adminuser()
|
public function adminuser()
|
||||||
@@ -75,7 +75,7 @@ class Group extends SnipeModel
|
|||||||
* Decode JSON permissions into array
|
* Decode JSON permissions into array
|
||||||
*
|
*
|
||||||
* @author A. Gianotto <snipe@snipe.net>
|
* @author A. Gianotto <snipe@snipe.net>
|
||||||
* @since [v1.0]
|
* @since [v1.0]
|
||||||
* @return array | \stdClass
|
* @return array | \stdClass
|
||||||
*/
|
*/
|
||||||
public function decodePermissions()
|
public function decodePermissions()
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class Import extends Model
|
|||||||
* Establishes the license -> admin user relationship
|
* Establishes the license -> admin user relationship
|
||||||
*
|
*
|
||||||
* @author A. Gianotto <snipe@snipe.net>
|
* @author A. Gianotto <snipe@snipe.net>
|
||||||
* @since [v2.0]
|
* @since [v2.0]
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||||
*/
|
*/
|
||||||
public function adminuser()
|
public function adminuser()
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ class DefaultLabel extends RectangleSheet
|
|||||||
private int $rows;
|
private int $rows;
|
||||||
|
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct()
|
||||||
|
{
|
||||||
$settings = Setting::getSettings();
|
$settings = Setting::getSettings();
|
||||||
|
|
||||||
$this->textSize = Helper::convertUnit($settings->labels_fontsize, 'pt', 'in');
|
$this->textSize = Helper::convertUnit($settings->labels_fontsize, 'pt', 'in');
|
||||||
@@ -74,41 +75,116 @@ class DefaultLabel extends RectangleSheet
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUnit() { return 'in'; }
|
public function getUnit()
|
||||||
|
{
|
||||||
|
return 'in';
|
||||||
|
}
|
||||||
|
|
||||||
public function getPageWidth() { return $this->pageWidth; }
|
public function getPageWidth()
|
||||||
public function getPageHeight() { return $this->pageHeight; }
|
{
|
||||||
|
return $this->pageWidth;
|
||||||
|
}
|
||||||
|
public function getPageHeight()
|
||||||
|
{
|
||||||
|
return $this->pageHeight;
|
||||||
|
}
|
||||||
|
|
||||||
public function getPageMarginTop() { return $this->pageMarginTop; }
|
public function getPageMarginTop()
|
||||||
public function getPageMarginBottom() { return $this->pageMarginBottom; }
|
{
|
||||||
public function getPageMarginLeft() { return $this->pageMarginLeft; }
|
return $this->pageMarginTop;
|
||||||
public function getPageMarginRight() { return $this->pageMarginRight; }
|
}
|
||||||
|
public function getPageMarginBottom()
|
||||||
|
{
|
||||||
|
return $this->pageMarginBottom;
|
||||||
|
}
|
||||||
|
public function getPageMarginLeft()
|
||||||
|
{
|
||||||
|
return $this->pageMarginLeft;
|
||||||
|
}
|
||||||
|
public function getPageMarginRight()
|
||||||
|
{
|
||||||
|
return $this->pageMarginRight;
|
||||||
|
}
|
||||||
|
|
||||||
public function getColumns() { return $this->columns; }
|
public function getColumns()
|
||||||
public function getRows() { return $this->rows; }
|
{
|
||||||
public function getLabelBorder() { return 0; }
|
return $this->columns;
|
||||||
|
}
|
||||||
|
public function getRows()
|
||||||
|
{
|
||||||
|
return $this->rows;
|
||||||
|
}
|
||||||
|
public function getLabelBorder()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
public function getLabelWidth() { return $this->labelWidth; }
|
public function getLabelWidth()
|
||||||
public function getLabelHeight() { return $this->labelHeight; }
|
{
|
||||||
|
return $this->labelWidth;
|
||||||
|
}
|
||||||
|
public function getLabelHeight()
|
||||||
|
{
|
||||||
|
return $this->labelHeight;
|
||||||
|
}
|
||||||
|
|
||||||
public function getLabelMarginTop() { return 0; }
|
public function getLabelMarginTop()
|
||||||
public function getLabelMarginBottom() { return 0; }
|
{
|
||||||
public function getLabelMarginLeft() { return 0; }
|
return 0;
|
||||||
public function getLabelMarginRight() { return 0; }
|
}
|
||||||
|
public function getLabelMarginBottom()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
public function getLabelMarginLeft()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
public function getLabelMarginRight()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
public function getLabelColumnSpacing() { return $this->labelSpacingH; }
|
public function getLabelColumnSpacing()
|
||||||
public function getLabelRowSpacing() { return $this->labelSpacingV; }
|
{
|
||||||
|
return $this->labelSpacingH;
|
||||||
|
}
|
||||||
|
public function getLabelRowSpacing()
|
||||||
|
{
|
||||||
|
return $this->labelSpacingV;
|
||||||
|
}
|
||||||
|
|
||||||
public function getSupportAssetTag() { return false; }
|
public function getSupportAssetTag()
|
||||||
public function getSupport1DBarcode() { return true; }
|
{
|
||||||
public function getSupport2DBarcode() { return true; }
|
return false;
|
||||||
public function getSupportFields() { return 4; }
|
}
|
||||||
public function getSupportTitle() { return true; }
|
public function getSupport1DBarcode()
|
||||||
public function getSupportLogo() { return true; }
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public function getSupport2DBarcode()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public function getSupportFields()
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
public function getSupportTitle()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public function getSupportLogo()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public function preparePDF($pdf) {}
|
public function preparePDF($pdf)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public function write($pdf, $record) {
|
public function write($pdf, $record)
|
||||||
|
{
|
||||||
|
|
||||||
$asset = $record->get('asset');
|
$asset = $record->get('asset');
|
||||||
$settings = Setting::getSettings();
|
$settings = Setting::getSettings();
|
||||||
|
|||||||
@@ -5,21 +5,30 @@ namespace App\Models\Labels;
|
|||||||
use App\Models\Asset;
|
use App\Models\Asset;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
class Field {
|
class Field
|
||||||
|
{
|
||||||
protected Collection $options;
|
protected Collection $options;
|
||||||
public function getOptions() { return $this->options; }
|
public function getOptions()
|
||||||
public function setOptions($options) {
|
{
|
||||||
|
return $this->options;
|
||||||
|
}
|
||||||
|
public function setOptions($options)
|
||||||
|
{
|
||||||
$tempCollect = collect($options);
|
$tempCollect = collect($options);
|
||||||
if (!$tempCollect->contains(fn($o) => !is_subclass_of($o, FieldOption::class))) {
|
if (!$tempCollect->contains(fn($o) => !is_subclass_of($o, FieldOption::class))) {
|
||||||
$this->options = $options;
|
$this->options = $options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toArray(Asset $asset) { return Field::makeArray($this, $asset); }
|
public function toArray(Asset $asset)
|
||||||
|
{
|
||||||
|
return Field::makeArray($this, $asset);
|
||||||
|
}
|
||||||
|
|
||||||
/* Statics */
|
/* Statics */
|
||||||
|
|
||||||
public static function makeArray(Field $field, Asset $asset) {
|
public static function makeArray(Field $field, Asset $asset)
|
||||||
|
{
|
||||||
return $field->getOptions()
|
return $field->getOptions()
|
||||||
// filter out any FieldOptions that are accidentally null
|
// filter out any FieldOptions that are accidentally null
|
||||||
->filter()
|
->filter()
|
||||||
@@ -27,11 +36,13 @@ class Field {
|
|||||||
->filter(fn($result) => $result['value'] != null);
|
->filter(fn($result) => $result['value'] != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function makeString(Field $option) {
|
public static function makeString(Field $option)
|
||||||
|
{
|
||||||
return implode('|', $option->getOptions());
|
return implode('|', $option->getOptions());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function fromString(string $theString) {
|
public static function fromString(string $theString)
|
||||||
|
{
|
||||||
$field = new Field();
|
$field = new Field();
|
||||||
$field->options = collect(explode('|', $theString))
|
$field->options = collect(explode('|', $theString))
|
||||||
->filter(fn($optionString) => !empty($optionString))
|
->filter(fn($optionString) => !empty($optionString))
|
||||||
|
|||||||
@@ -5,14 +5,22 @@ namespace App\Models\Labels;
|
|||||||
use App\Models\Asset;
|
use App\Models\Asset;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
class FieldOption {
|
class FieldOption
|
||||||
|
{
|
||||||
protected string $label;
|
protected string $label;
|
||||||
public function getLabel() { return $this->label; }
|
public function getLabel()
|
||||||
|
{
|
||||||
|
return $this->label;
|
||||||
|
}
|
||||||
|
|
||||||
protected string $dataSource;
|
protected string $dataSource;
|
||||||
public function getDataSource() { return $this->dataSource; }
|
public function getDataSource()
|
||||||
|
{
|
||||||
|
return $this->dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
public function getValue(Asset $asset) {
|
public function getValue(Asset $asset)
|
||||||
|
{
|
||||||
$dataPath = collect(explode('.', $this->dataSource));
|
$dataPath = collect(explode('.', $this->dataSource));
|
||||||
|
|
||||||
// assignedTo directly on the asset is a special case where
|
// assignedTo directly on the asset is a special case where
|
||||||
@@ -33,18 +41,29 @@ class FieldOption {
|
|||||||
return $asset->purchase_date ? $asset->purchase_date->format('Y-m-d') : null;
|
return $asset->purchase_date ? $asset->purchase_date->format('Y-m-d') : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $dataPath->reduce(function ($myValue, $path) {
|
return $dataPath->reduce(
|
||||||
try { return $myValue ? $myValue->{$path} : ${$myValue}; }
|
function ($myValue, $path) {
|
||||||
catch (\Exception $e) { return $myValue; }
|
try { return $myValue ? $myValue->{$path} : ${$myValue};
|
||||||
}, $asset);
|
}
|
||||||
|
catch (\Exception $e) { return $myValue;
|
||||||
|
}
|
||||||
|
}, $asset
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toArray(Asset $asset=null) { return FieldOption::makeArray($this, $asset); }
|
public function toArray(Asset $asset=null)
|
||||||
public function toString() { return FieldOption::makeString($this); }
|
{
|
||||||
|
return FieldOption::makeArray($this, $asset);
|
||||||
|
}
|
||||||
|
public function toString()
|
||||||
|
{
|
||||||
|
return FieldOption::makeString($this);
|
||||||
|
}
|
||||||
|
|
||||||
/* Statics */
|
/* Statics */
|
||||||
|
|
||||||
public static function makeArray(FieldOption $option, Asset $asset=null) {
|
public static function makeArray(FieldOption $option, Asset $asset=null)
|
||||||
|
{
|
||||||
return [
|
return [
|
||||||
'label' => $option->getLabel(),
|
'label' => $option->getLabel(),
|
||||||
'dataSource' => $option->getDataSource(),
|
'dataSource' => $option->getDataSource(),
|
||||||
@@ -52,11 +71,13 @@ class FieldOption {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function makeString(FieldOption $option) {
|
public static function makeString(FieldOption $option)
|
||||||
|
{
|
||||||
return $option->getLabel() . '=' . $option->getDataSource();
|
return $option->getLabel() . '=' . $option->getDataSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function fromString(string $theString) {
|
public static function fromString(string $theString)
|
||||||
|
{
|
||||||
$parts = explode('=', $theString);
|
$parts = explode('=', $theString);
|
||||||
if (count($parts) == 2) {
|
if (count($parts) == 2) {
|
||||||
$option = new FieldOption();
|
$option = new FieldOption();
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use Illuminate\Support\Facades\Log;
|
|||||||
/**
|
/**
|
||||||
* Model for Labels.
|
* Model for Labels.
|
||||||
*
|
*
|
||||||
* @version v1.0
|
* @version v1.0
|
||||||
*/
|
*/
|
||||||
abstract class Label
|
abstract class Label
|
||||||
{
|
{
|
||||||
@@ -32,7 +32,8 @@ abstract class Label
|
|||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function getRotation() {
|
public function getRotation()
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,29 +124,32 @@ abstract class Label
|
|||||||
/**
|
/**
|
||||||
* Make changes to the PDF properties here. OPTIONAL.
|
* Make changes to the PDF properties here. OPTIONAL.
|
||||||
*
|
*
|
||||||
* @param TCPDF $pdf The TCPDF instance
|
* @param TCPDF $pdf The TCPDF instance
|
||||||
*/
|
*/
|
||||||
public abstract function preparePDF(TCPDF $pdf);
|
public abstract function preparePDF(TCPDF $pdf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write single data record as content here.
|
* Write single data record as content here.
|
||||||
*
|
*
|
||||||
* @param TCPDF $pdf The TCPDF instance
|
* @param TCPDF $pdf The TCPDF instance
|
||||||
* @param Collection $record A data record
|
* @param Collection $record A data record
|
||||||
*/
|
*/
|
||||||
public abstract function write(TCPDF $pdf, Collection $record);
|
public abstract function write(TCPDF $pdf, Collection $record);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the data here. Override for multiple-per-page handling
|
* Handle the data here. Override for multiple-per-page handling
|
||||||
*
|
*
|
||||||
* @param TCPDF $pdf The TCPDF instance
|
* @param TCPDF $pdf The TCPDF instance
|
||||||
* @param Collection $data The data
|
* @param Collection $data The data
|
||||||
*/
|
*/
|
||||||
public function writeAll(TCPDF $pdf, Collection $data) {
|
public function writeAll(TCPDF $pdf, Collection $data)
|
||||||
$data->each(function ($record, $index) use ($pdf) {
|
{
|
||||||
$pdf->AddPage();
|
$data->each(
|
||||||
$this->write($pdf, $record);
|
function ($record, $index) use ($pdf) {
|
||||||
});
|
$pdf->AddPage();
|
||||||
|
$this->write($pdf, $record);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -153,7 +157,8 @@ abstract class Label
|
|||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public final function getName() {
|
public final function getName()
|
||||||
|
{
|
||||||
$refClass = new \ReflectionClass(Label::class);
|
$refClass = new \ReflectionClass(Label::class);
|
||||||
return str_replace($refClass->getNamespaceName() . '\\', '', get_class($this));
|
return str_replace($refClass->getNamespaceName() . '\\', '', get_class($this));
|
||||||
}
|
}
|
||||||
@@ -165,7 +170,8 @@ abstract class Label
|
|||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public final function getOrientation() {
|
public final function getOrientation()
|
||||||
|
{
|
||||||
return ($this->getWidth() >= $this->getHeight()) ? 'L' : 'P';
|
return ($this->getWidth() >= $this->getHeight()) ? 'L' : 'P';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +180,8 @@ abstract class Label
|
|||||||
*
|
*
|
||||||
* @return object [ 'x1'=>0.00, 'y1'=>0.00, 'x2'=>0.00, 'y2'=>0.00, 'w'=>0.00, 'h'=>0.00 ]
|
* @return object [ 'x1'=>0.00, 'y1'=>0.00, 'x2'=>0.00, 'y2'=>0.00, 'w'=>0.00, 'h'=>0.00 ]
|
||||||
*/
|
*/
|
||||||
public final function getPrintableArea() {
|
public final function getPrintableArea()
|
||||||
|
{
|
||||||
return (object)[
|
return (object)[
|
||||||
'x1' => $this->getMarginLeft(),
|
'x1' => $this->getMarginLeft(),
|
||||||
'y1' => $this->getMarginTop(),
|
'y1' => $this->getMarginTop(),
|
||||||
@@ -188,21 +195,22 @@ abstract class Label
|
|||||||
/**
|
/**
|
||||||
* Write a text cell.
|
* Write a text cell.
|
||||||
*
|
*
|
||||||
* @param TCPDF $pdf The TCPDF instance
|
* @param TCPDF $pdf The TCPDF instance
|
||||||
* @param string $text The text to write. Supports 'some **bold** text'.
|
* @param string $text The text to write. Supports 'some **bold** text'.
|
||||||
* @param float $x X position of top-left
|
* @param float $x X position of top-left
|
||||||
* @param float $y Y position of top-left
|
* @param float $y Y position of top-left
|
||||||
* @param string $font The font family
|
* @param string $font The font family
|
||||||
* @param string $style The font style
|
* @param string $style The font style
|
||||||
* @param int $size The font size in getUnit() units
|
* @param int $size The font size in getUnit() units
|
||||||
* @param string $align Align text in the box. 'L' left, 'R' right, 'C' center.
|
* @param string $align Align text in the box. 'L' left, 'R' right, 'C' center.
|
||||||
* @param float $width Force text box width. NULL to auto-fit.
|
* @param float $width Force text box width. NULL to auto-fit.
|
||||||
* @param float $height Force text box height. NULL to auto-fit.
|
* @param float $height Force text box height. NULL to auto-fit.
|
||||||
* @param bool $squash Squash text if it's too big
|
* @param bool $squash Squash text if it's too big
|
||||||
* @param int $border Thickness of border. Default = 0.
|
* @param int $border Thickness of border. Default = 0.
|
||||||
* @param int $spacing Letter spacing. Default = 0.
|
* @param int $spacing Letter spacing. Default = 0.
|
||||||
*/
|
*/
|
||||||
public final function writeText(TCPDF $pdf, $text, $x, $y, $font=null, $style=null, $size=null, $align='L', $width=null, $height=null, $squash=false, $border=0, $spacing=0) {
|
public final function writeText(TCPDF $pdf, $text, $x, $y, $font=null, $style=null, $size=null, $align='L', $width=null, $height=null, $squash=false, $border=0, $spacing=0)
|
||||||
|
{
|
||||||
$prevFamily = $pdf->getFontFamily();
|
$prevFamily = $pdf->getFontFamily();
|
||||||
$prevStyle = $pdf->getFontStyle();
|
$prevStyle = $pdf->getFontStyle();
|
||||||
$prevSizePt = $pdf->getFontSizePt();
|
$prevSizePt = $pdf->getFontSizePt();
|
||||||
@@ -211,33 +219,42 @@ abstract class Label
|
|||||||
|
|
||||||
$fontFamily = !empty($font) ? $font : $prevFamily;
|
$fontFamily = !empty($font) ? $font : $prevFamily;
|
||||||
$fontStyle = !empty($style) ? $style : $prevStyle;
|
$fontStyle = !empty($style) ? $style : $prevStyle;
|
||||||
if ($size) $fontSizePt = Helper::convertUnit($size, $this->getUnit(), 'pt', true);
|
if ($size) { $fontSizePt = Helper::convertUnit($size, $this->getUnit(), 'pt', true);
|
||||||
else $fontSizePt = $prevSizePt;
|
} else { $fontSizePt = $prevSizePt;
|
||||||
|
}
|
||||||
|
|
||||||
$pdf->SetFontSpacing($spacing);
|
$pdf->SetFontSpacing($spacing);
|
||||||
|
|
||||||
$parts = collect(explode('**', $text))
|
$parts = collect(explode('**', $text))
|
||||||
->map(function ($part, $index) use ($pdf, $fontFamily, $fontStyle, $fontSizePt) {
|
->map(
|
||||||
$modStyle = ($index % 2 == 1) ? 'B' : $fontStyle;
|
function ($part, $index) use ($pdf, $fontFamily, $fontStyle, $fontSizePt) {
|
||||||
$pdf->setFont($fontFamily, $modStyle, $fontSizePt);
|
$modStyle = ($index % 2 == 1) ? 'B' : $fontStyle;
|
||||||
return [
|
$pdf->setFont($fontFamily, $modStyle, $fontSizePt);
|
||||||
|
return [
|
||||||
'text' => $part,
|
'text' => $part,
|
||||||
'text_width' => $pdf->GetStringWidth($part),
|
'text_width' => $pdf->GetStringWidth($part),
|
||||||
'font_family' => $fontFamily,
|
'font_family' => $fontFamily,
|
||||||
'font_style' => $modStyle,
|
'font_style' => $modStyle,
|
||||||
'font_size' => $fontSizePt,
|
'font_size' => $fontSizePt,
|
||||||
];
|
];
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
$textWidth = $parts->reduce(function ($carry, $part) { return $carry += $part['text_width']; });
|
$textWidth = $parts->reduce(
|
||||||
|
function ($carry, $part) {
|
||||||
|
return $carry += $part['text_width'];
|
||||||
|
}
|
||||||
|
);
|
||||||
$cellWidth = !empty($width) ? $width : $textWidth;
|
$cellWidth = !empty($width) ? $width : $textWidth;
|
||||||
|
|
||||||
if ($squash && ($textWidth > 0)) {
|
if ($squash && ($textWidth > 0)) {
|
||||||
$scaleFactor = min(1.0, $cellWidth / $textWidth);
|
$scaleFactor = min(1.0, $cellWidth / $textWidth);
|
||||||
$parts = $parts->map(function ($part, $index) use ($scaleFactor) {
|
$parts = $parts->map(
|
||||||
$part['text_width'] = $part['text_width'] * $scaleFactor;
|
function ($part, $index) use ($scaleFactor) {
|
||||||
return $part;
|
$part['text_width'] = $part['text_width'] * $scaleFactor;
|
||||||
});
|
return $part;
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
$cellHeight = !empty($height) ? $height : Helper::convertUnit($fontSizePt, 'pt', $this->getUnit());
|
$cellHeight = !empty($height) ? $height : Helper::convertUnit($fontSizePt, 'pt', $this->getUnit());
|
||||||
|
|
||||||
@@ -249,18 +266,23 @@ abstract class Label
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch($align) {
|
switch($align) {
|
||||||
case 'R': $startX = ($x + $cellWidth) - min($cellWidth, $textWidth); break;
|
case 'R': $startX = ($x + $cellWidth) - min($cellWidth, $textWidth);
|
||||||
case 'C': $startX = ($x + ($cellWidth / 2)) - (min($cellWidth, $textWidth) / 2); break;
|
break;
|
||||||
case 'L':
|
case 'C': $startX = ($x + ($cellWidth / 2)) - (min($cellWidth, $textWidth) / 2);
|
||||||
default: $startX = $x; break;
|
break;
|
||||||
|
case 'L':
|
||||||
|
default: $startX = $x;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$parts->reduce(function ($currentX, $part) use ($pdf, $y, $cellHeight) {
|
$parts->reduce(
|
||||||
$pdf->SetXY($currentX, $y);
|
function ($currentX, $part) use ($pdf, $y, $cellHeight) {
|
||||||
$pdf->setFont($part['font_family'], $part['font_style'], $part['font_size']);
|
$pdf->SetXY($currentX, $y);
|
||||||
$pdf->Cell($part['text_width'], $cellHeight, $part['text'], 0, 0, '', false, '', 1, true);
|
$pdf->setFont($part['font_family'], $part['font_style'], $part['font_size']);
|
||||||
return $currentX += $part['text_width'];
|
$pdf->Cell($part['text_width'], $cellHeight, $part['text'], 0, 0, '', false, '', 1, true);
|
||||||
}, $startX);
|
return $currentX += $part['text_width'];
|
||||||
|
}, $startX
|
||||||
|
);
|
||||||
|
|
||||||
$pdf->SetFont($prevFamily, $prevStyle, $prevSizePt);
|
$pdf->SetFont($prevFamily, $prevStyle, $prevSizePt);
|
||||||
$pdf->SetFontSpacing(0);
|
$pdf->SetFontSpacing(0);
|
||||||
@@ -269,27 +291,30 @@ abstract class Label
|
|||||||
/**
|
/**
|
||||||
* Write an image.
|
* Write an image.
|
||||||
*
|
*
|
||||||
* @param TCPDF $pdf The TCPDF instance
|
* @param TCPDF $pdf The TCPDF instance
|
||||||
* @param string $image The image to write
|
* @param string $image The image to write
|
||||||
* @param float $x X position of top-left
|
* @param float $x X position of top-left
|
||||||
* @param float $y Y position of top-left
|
* @param float $y Y position of top-left
|
||||||
* @param float $width The container width
|
* @param float $width The container width
|
||||||
* @param float $height The container height
|
* @param float $height The container height
|
||||||
* @param string $halign Align text in the box. 'L' left, 'R' right, 'C' center. Default 'L'.
|
* @param string $halign Align text in the box. 'L' left, 'R' right, 'C' center. Default 'L'.
|
||||||
* @param string $valign Align text in the box. 'T' top, 'B' bottom, 'C' center. Default 'T'.
|
* @param string $valign Align text in the box. 'T' top, 'B' bottom, 'C' center. Default 'T'.
|
||||||
* @param int $dpi Pixels per inch
|
* @param int $dpi Pixels per inch
|
||||||
* @param bool $resize Resize to fit container
|
* @param bool $resize Resize to fit container
|
||||||
* @param bool $stretch Stretch (vs Scale) to fit container
|
* @param bool $stretch Stretch (vs Scale) to fit container
|
||||||
* @param int $border Thickness of border. Default = 0.
|
* @param int $border Thickness of border. Default = 0.
|
||||||
*
|
*
|
||||||
* @return array Returns the final calculated size [w,h]
|
* @return array Returns the final calculated size [w,h]
|
||||||
*/
|
*/
|
||||||
public final function writeImage(TCPDF $pdf, $image, $x, $y, $width=null, $height=null, $halign='L', $valign='L', $dpi=300, $resize=false, $stretch=false, $border=0) {
|
public final function writeImage(TCPDF $pdf, $image, $x, $y, $width=null, $height=null, $halign='L', $valign='L', $dpi=300, $resize=false, $stretch=false, $border=0)
|
||||||
|
{
|
||||||
|
|
||||||
if (empty($image)) return [0,0];
|
if (empty($image)) { return [0,0];
|
||||||
|
}
|
||||||
|
|
||||||
$imageInfo = getimagesize($image);
|
$imageInfo = getimagesize($image);
|
||||||
if (!$imageInfo) return [0,0]; // TODO: SVG or other
|
if (!$imageInfo) { return [0,0]; // TODO: SVG or other
|
||||||
|
}
|
||||||
|
|
||||||
$imageWidthPx = $imageInfo[0];
|
$imageWidthPx = $imageInfo[0];
|
||||||
$imageHeightPx = $imageInfo[1];
|
$imageHeightPx = $imageInfo[1];
|
||||||
@@ -342,18 +367,24 @@ abstract class Label
|
|||||||
|
|
||||||
// Horizontal Position
|
// Horizontal Position
|
||||||
switch ($halign) {
|
switch ($halign) {
|
||||||
case 'R': $originX = ($x + $containerWidth) - $outputWidth; break;
|
case 'R': $originX = ($x + $containerWidth) - $outputWidth;
|
||||||
case 'C': $originX = ($x + ($containerWidth / 2)) - ($outputWidth / 2); break;
|
break;
|
||||||
case 'L':
|
case 'C': $originX = ($x + ($containerWidth / 2)) - ($outputWidth / 2);
|
||||||
default: $originX = $x; break;
|
break;
|
||||||
|
case 'L':
|
||||||
|
default: $originX = $x;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vertical Position
|
// Vertical Position
|
||||||
switch ($valign) {
|
switch ($valign) {
|
||||||
case 'B': $originY = ($y + $containerHeight) - $outputHeight; break;
|
case 'B': $originY = ($y + $containerHeight) - $outputHeight;
|
||||||
case 'C': $originY = ($y + ($containerHeight / 2)) - ($outputHeight / 2); break;
|
break;
|
||||||
case 'T':
|
case 'C': $originY = ($y + ($containerHeight / 2)) - ($outputHeight / 2);
|
||||||
default: $originY = $y; break;
|
break;
|
||||||
|
case 'T':
|
||||||
|
default: $originY = $y;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actual Image
|
// Actual Image
|
||||||
@@ -373,16 +404,18 @@ abstract class Label
|
|||||||
/**
|
/**
|
||||||
* Write a 1D barcode.
|
* Write a 1D barcode.
|
||||||
*
|
*
|
||||||
* @param TCPDF $pdf The TCPDF instance
|
* @param TCPDF $pdf The TCPDF instance
|
||||||
* @param string $value The barcode content
|
* @param string $value The barcode content
|
||||||
* @param string $type The barcode type
|
* @param string $type The barcode type
|
||||||
* @param float $x X position of top-left
|
* @param float $x X position of top-left
|
||||||
* @param float $y Y position of top-left
|
* @param float $y Y position of top-left
|
||||||
* @param float $width The container width
|
* @param float $width The container width
|
||||||
* @param float $height The container height
|
* @param float $height The container height
|
||||||
*/
|
*/
|
||||||
public final function write1DBarcode(TCPDF $pdf, $value, $type, $x, $y, $width, $height) {
|
public final function write1DBarcode(TCPDF $pdf, $value, $type, $x, $y, $width, $height)
|
||||||
if (empty($value)) return;
|
{
|
||||||
|
if (empty($value)) { return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
$pdf->write1DBarcode($value, $type, $x, $y, $width, $height, null, ['stretch'=>true]);
|
$pdf->write1DBarcode($value, $type, $x, $y, $width, $height, null, ['stretch'=>true]);
|
||||||
} catch (\Exception|TypeError $e) {
|
} catch (\Exception|TypeError $e) {
|
||||||
@@ -393,16 +426,18 @@ abstract class Label
|
|||||||
/**
|
/**
|
||||||
* Write a 2D barcode.
|
* Write a 2D barcode.
|
||||||
*
|
*
|
||||||
* @param TCPDF $pdf The TCPDF instance
|
* @param TCPDF $pdf The TCPDF instance
|
||||||
* @param string $value The barcode content
|
* @param string $value The barcode content
|
||||||
* @param string $type The barcode type
|
* @param string $type The barcode type
|
||||||
* @param float $x X position of top-left
|
* @param float $x X position of top-left
|
||||||
* @param float $y Y position of top-left
|
* @param float $y Y position of top-left
|
||||||
* @param float $width The container width
|
* @param float $width The container width
|
||||||
* @param float $height The container height
|
* @param float $height The container height
|
||||||
*/
|
*/
|
||||||
public final function write2DBarcode(TCPDF $pdf, $value, $type, $x, $y, $width, $height) {
|
public final function write2DBarcode(TCPDF $pdf, $value, $type, $x, $y, $width, $height)
|
||||||
if (empty($value)) return;
|
{
|
||||||
|
if (empty($value)) { return;
|
||||||
|
}
|
||||||
$pdf->write2DBarcode($value, $type, $x, $y, $width, $height, null, ['stretch'=>true]);
|
$pdf->write2DBarcode($value, $type, $x, $y, $width, $height, null, ['stretch'=>true]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,127 +446,180 @@ abstract class Label
|
|||||||
/**
|
/**
|
||||||
* Checks the template is internally valid
|
* Checks the template is internally valid
|
||||||
*/
|
*/
|
||||||
public final function validate() : void {
|
public final function validate() : void
|
||||||
|
{
|
||||||
$this->validateUnits();
|
$this->validateUnits();
|
||||||
$this->validateSize();
|
$this->validateSize();
|
||||||
$this->validateMargins();
|
$this->validateMargins();
|
||||||
$this->validateSupport();
|
$this->validateSupport();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function validateUnits() : void {
|
private function validateUnits() : void
|
||||||
|
{
|
||||||
$validUnits = [ 'pt', 'mm', 'cm', 'in' ];
|
$validUnits = [ 'pt', 'mm', 'cm', 'in' ];
|
||||||
$unit = $this->getUnit();
|
$unit = $this->getUnit();
|
||||||
if (!in_array(strtolower($unit), $validUnits)) {
|
if (!in_array(strtolower($unit), $validUnits)) {
|
||||||
throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_value', [
|
throw new \UnexpectedValueException(
|
||||||
'name' => 'getUnit()',
|
trans(
|
||||||
'expected' => '[ \''.implode('\', \'', $validUnits).'\' ]',
|
'admin/labels/message.invalid_return_value', [
|
||||||
'actual' => '\''.$unit.'\''
|
'name' => 'getUnit()',
|
||||||
]));
|
'expected' => '[ \''.implode('\', \'', $validUnits).'\' ]',
|
||||||
|
'actual' => '\''.$unit.'\''
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function validateSize() : void {
|
private function validateSize() : void
|
||||||
|
{
|
||||||
$width = $this->getWidth();
|
$width = $this->getWidth();
|
||||||
if (!is_numeric($width) || is_string($width)) {
|
if (!is_numeric($width) || is_string($width)) {
|
||||||
throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_type', [
|
throw new \UnexpectedValueException(
|
||||||
'name' => 'getWidth()',
|
trans(
|
||||||
'expected' => 'float',
|
'admin/labels/message.invalid_return_type', [
|
||||||
'actual' => gettype($width)
|
'name' => 'getWidth()',
|
||||||
]));
|
'expected' => 'float',
|
||||||
|
'actual' => gettype($width)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$height = $this->getHeight();
|
$height = $this->getHeight();
|
||||||
if (!is_numeric($height) || is_string($height)) {
|
if (!is_numeric($height) || is_string($height)) {
|
||||||
throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_type', [
|
throw new \UnexpectedValueException(
|
||||||
'name' => 'getHeight()',
|
trans(
|
||||||
'expected' => 'float',
|
'admin/labels/message.invalid_return_type', [
|
||||||
'actual' => gettype($height)
|
'name' => 'getHeight()',
|
||||||
]));
|
'expected' => 'float',
|
||||||
|
'actual' => gettype($height)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function validateMargins() : void {
|
private function validateMargins() : void
|
||||||
|
{
|
||||||
$marginTop = $this->getMarginTop();
|
$marginTop = $this->getMarginTop();
|
||||||
if (!is_numeric($marginTop) || is_string($marginTop)) {
|
if (!is_numeric($marginTop) || is_string($marginTop)) {
|
||||||
throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_type', [
|
throw new \UnexpectedValueException(
|
||||||
'name' => 'getMarginTop()',
|
trans(
|
||||||
'expected' => 'float',
|
'admin/labels/message.invalid_return_type', [
|
||||||
'actual' => gettype($marginTop)
|
'name' => 'getMarginTop()',
|
||||||
]));
|
'expected' => 'float',
|
||||||
|
'actual' => gettype($marginTop)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$marginBottom = $this->getMarginBottom();
|
$marginBottom = $this->getMarginBottom();
|
||||||
if (!is_numeric($marginBottom) || is_string($marginBottom)) {
|
if (!is_numeric($marginBottom) || is_string($marginBottom)) {
|
||||||
throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_type', [
|
throw new \UnexpectedValueException(
|
||||||
'name' => 'getMarginBottom()',
|
trans(
|
||||||
'expected' => 'float',
|
'admin/labels/message.invalid_return_type', [
|
||||||
'actual' => gettype($marginBottom)
|
'name' => 'getMarginBottom()',
|
||||||
]));
|
'expected' => 'float',
|
||||||
|
'actual' => gettype($marginBottom)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$marginLeft = $this->getMarginLeft();
|
$marginLeft = $this->getMarginLeft();
|
||||||
if (!is_numeric($marginLeft) || is_string($marginLeft)) {
|
if (!is_numeric($marginLeft) || is_string($marginLeft)) {
|
||||||
throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_type', [
|
throw new \UnexpectedValueException(
|
||||||
'name' => 'getMarginLeft()',
|
trans(
|
||||||
'expected' => 'float',
|
'admin/labels/message.invalid_return_type', [
|
||||||
'actual' => gettype($marginLeft)
|
'name' => 'getMarginLeft()',
|
||||||
]));
|
'expected' => 'float',
|
||||||
|
'actual' => gettype($marginLeft)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$marginRight = $this->getMarginRight();
|
$marginRight = $this->getMarginRight();
|
||||||
if (!is_numeric($marginRight) || is_string($marginRight)) {
|
if (!is_numeric($marginRight) || is_string($marginRight)) {
|
||||||
throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_type', [
|
throw new \UnexpectedValueException(
|
||||||
'name' => 'getMarginRight()',
|
trans(
|
||||||
'expected' => 'float',
|
'admin/labels/message.invalid_return_type', [
|
||||||
'actual' => gettype($marginRight)
|
'name' => 'getMarginRight()',
|
||||||
]));
|
'expected' => 'float',
|
||||||
|
'actual' => gettype($marginRight)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function validateSupport() : void {
|
private function validateSupport() : void
|
||||||
|
{
|
||||||
$support1D = $this->getSupport1DBarcode();
|
$support1D = $this->getSupport1DBarcode();
|
||||||
if (!is_bool($support1D)) {
|
if (!is_bool($support1D)) {
|
||||||
throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_type', [
|
throw new \UnexpectedValueException(
|
||||||
'name' => 'getSupport1DBarcode()',
|
trans(
|
||||||
'expected' => 'boolean',
|
'admin/labels/message.invalid_return_type', [
|
||||||
'actual' => gettype($support1D)
|
'name' => 'getSupport1DBarcode()',
|
||||||
]));
|
'expected' => 'boolean',
|
||||||
|
'actual' => gettype($support1D)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$support2D = $this->getSupport2DBarcode();
|
$support2D = $this->getSupport2DBarcode();
|
||||||
if (!is_bool($support2D)) {
|
if (!is_bool($support2D)) {
|
||||||
throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_type', [
|
throw new \UnexpectedValueException(
|
||||||
'name' => 'getSupport2DBarcode()',
|
trans(
|
||||||
'expected' => 'boolean',
|
'admin/labels/message.invalid_return_type', [
|
||||||
'actual' => gettype($support2D)
|
'name' => 'getSupport2DBarcode()',
|
||||||
]));
|
'expected' => 'boolean',
|
||||||
|
'actual' => gettype($support2D)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$supportFields = $this->getSupportFields();
|
$supportFields = $this->getSupportFields();
|
||||||
if (!is_int($supportFields)) {
|
if (!is_int($supportFields)) {
|
||||||
throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_type', [
|
throw new \UnexpectedValueException(
|
||||||
'name' => 'getSupportFields()',
|
trans(
|
||||||
'expected' => 'integer',
|
'admin/labels/message.invalid_return_type', [
|
||||||
'actual' => gettype($supportFields)
|
'name' => 'getSupportFields()',
|
||||||
]));
|
'expected' => 'integer',
|
||||||
|
'actual' => gettype($supportFields)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$supportLogo = $this->getSupportLogo();
|
$supportLogo = $this->getSupportLogo();
|
||||||
if (!is_bool($supportLogo)) {
|
if (!is_bool($supportLogo)) {
|
||||||
throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_type', [
|
throw new \UnexpectedValueException(
|
||||||
'name' => 'getSupportLogo()',
|
trans(
|
||||||
'expected' => 'boolean',
|
'admin/labels/message.invalid_return_type', [
|
||||||
'actual' => gettype($supportLogo)
|
'name' => 'getSupportLogo()',
|
||||||
]));
|
'expected' => 'boolean',
|
||||||
|
'actual' => gettype($supportLogo)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$supportTitle = $this->getSupportTitle();
|
$supportTitle = $this->getSupportTitle();
|
||||||
if (!is_bool($supportTitle)) {
|
if (!is_bool($supportTitle)) {
|
||||||
throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_type', [
|
throw new \UnexpectedValueException(
|
||||||
'name' => 'getSupportTitle()',
|
trans(
|
||||||
'expected' => 'boolean',
|
'admin/labels/message.invalid_return_type', [
|
||||||
'actual' => gettype($supportTitle)
|
'name' => 'getSupportTitle()',
|
||||||
]));
|
'expected' => 'boolean',
|
||||||
|
'actual' => gettype($supportTitle)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -539,23 +627,26 @@ abstract class Label
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Public Static Functions
|
* Public Static Functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find size of a page by its format.
|
* Find size of a page by its format.
|
||||||
*
|
*
|
||||||
* @param string $format Format name (eg: 'A4', 'LETTER', etc.)
|
* @param string $format Format name (eg: 'A4', 'LETTER', etc.)
|
||||||
* @param string $orientation 'L' for Landscape, 'P' for Portrait ('L' default)
|
* @param string $orientation 'L' for Landscape, 'P' for Portrait ('L' default)
|
||||||
* @param string $unit Unit of measure to return in ('mm' default)
|
* @param string $unit Unit of measure to return in ('mm' default)
|
||||||
*
|
*
|
||||||
* @return object (object)[ 'width' => (float)123.4, 'height' => (float)123.4 ]
|
* @return object (object)[ 'width' => (float)123.4, 'height' => (float)123.4 ]
|
||||||
*/
|
*/
|
||||||
public static function fromFormat($format, $orientation='L', $unit='mm', $round=false) {
|
public static function fromFormat($format, $orientation='L', $unit='mm', $round=false)
|
||||||
|
{
|
||||||
$size = collect(TCPDF_STATIC::getPageSizeFromFormat(strtoupper($format)))
|
$size = collect(TCPDF_STATIC::getPageSizeFromFormat(strtoupper($format)))
|
||||||
->sort()
|
->sort()
|
||||||
->map(function ($value) use ($unit) {
|
->map(
|
||||||
return Helper::convertUnit($value, 'pt', $unit);
|
function ($value) use ($unit) {
|
||||||
})
|
return Helper::convertUnit($value, 'pt', $unit);
|
||||||
|
}
|
||||||
|
)
|
||||||
->toArray();
|
->toArray();
|
||||||
$width = ($orientation == 'L') ? $size[1] : $size[0];
|
$width = ($orientation == 'L') ? $size[1] : $size[0];
|
||||||
$height = ($orientation == 'L') ? $size[0] : $size[1];
|
$height = ($orientation == 'L') ? $size[0] : $size[1];
|
||||||
@@ -571,16 +662,19 @@ abstract class Label
|
|||||||
* Unlike most Models, these are defined by their existence as non-
|
* Unlike most Models, these are defined by their existence as non-
|
||||||
* abstract classes stored in Models\Labels.
|
* abstract classes stored in Models\Labels.
|
||||||
*
|
*
|
||||||
* @param string|Arrayable|array|null $path Label path[s]
|
* @param string|Arrayable|array|null $path Label path[s]
|
||||||
* @return Collection|Label|null
|
* @return Collection|Label|null
|
||||||
*/
|
*/
|
||||||
public static function find($name=null) {
|
public static function find($name=null)
|
||||||
|
{
|
||||||
// Find many
|
// Find many
|
||||||
if (is_array($name) || $name instanceof Arrayable) {
|
if (is_array($name) || $name instanceof Arrayable) {
|
||||||
$labels = collect($name)
|
$labels = collect($name)
|
||||||
->map(function ($thisname) {
|
->map(
|
||||||
return static::find($thisname);
|
function ($thisname) {
|
||||||
})
|
return static::find($thisname);
|
||||||
|
}
|
||||||
|
)
|
||||||
->whereNotNull();
|
->whereNotNull();
|
||||||
return ($labels->count() > 0) ? $labels : null;
|
return ($labels->count() > 0) ? $labels : null;
|
||||||
}
|
}
|
||||||
@@ -588,26 +682,36 @@ abstract class Label
|
|||||||
// Find one
|
// Find one
|
||||||
if ($name !== null) {
|
if ($name !== null) {
|
||||||
return static::find()
|
return static::find()
|
||||||
->sole(function ($label) use ($name) {
|
->sole(
|
||||||
return $label->getName() == $name;
|
function ($label) use ($name) {
|
||||||
});
|
return $label->getName() == $name;
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find all
|
// Find all
|
||||||
return collect(File::allFiles(__DIR__))
|
return collect(File::allFiles(__DIR__))
|
||||||
->map(function ($file) {
|
->map(
|
||||||
preg_match_all('/\/*(.+?)(?:\/|\.)/', $file->getRelativePathName(), $matches);
|
function ($file) {
|
||||||
return __NAMESPACE__ . '\\' . implode('\\', $matches[1]);
|
preg_match_all('/\/*(.+?)(?:\/|\.)/', $file->getRelativePathName(), $matches);
|
||||||
})
|
return __NAMESPACE__ . '\\' . implode('\\', $matches[1]);
|
||||||
->filter(function ($name) {
|
}
|
||||||
if (!class_exists($name)) return false;
|
)
|
||||||
$refClass = new \ReflectionClass($name);
|
->filter(
|
||||||
if ($refClass->isAbstract()) return false;
|
function ($name) {
|
||||||
return $refClass->isSubclassOf(Label::class);
|
if (!class_exists($name)) { return false;
|
||||||
})
|
}
|
||||||
->map(function ($name) {
|
$refClass = new \ReflectionClass($name);
|
||||||
return new $name();
|
if ($refClass->isAbstract()) { return false;
|
||||||
});
|
}
|
||||||
|
return $refClass->isSubclassOf(Label::class);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
->map(
|
||||||
|
function ($name) {
|
||||||
|
return new $name();
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -33,9 +33,13 @@ abstract class RectangleSheet extends Sheet
|
|||||||
public abstract function getLabelRowSpacing();
|
public abstract function getLabelRowSpacing();
|
||||||
|
|
||||||
|
|
||||||
public function getLabelsPerPage() { return $this->getColumns() * $this->getRows(); }
|
public function getLabelsPerPage()
|
||||||
|
{
|
||||||
|
return $this->getColumns() * $this->getRows();
|
||||||
|
}
|
||||||
|
|
||||||
public function getLabelPosition($index) {
|
public function getLabelPosition($index)
|
||||||
|
{
|
||||||
$printIndex = $index + $this->getLabelIndexOffset();
|
$printIndex = $index + $this->getLabelIndexOffset();
|
||||||
$row = (int)($printIndex / $this->getColumns());
|
$row = (int)($printIndex / $this->getColumns());
|
||||||
$col = $printIndex - ($row * $this->getColumns());
|
$col = $printIndex - ($row * $this->getColumns());
|
||||||
|
|||||||
@@ -6,12 +6,30 @@ abstract class Sheet extends Label
|
|||||||
{
|
{
|
||||||
protected int $indexOffset = 0;
|
protected int $indexOffset = 0;
|
||||||
|
|
||||||
public function getWidth() { return $this->getPageWidth(); }
|
public function getWidth()
|
||||||
public function getHeight() { return $this->getPageHeight(); }
|
{
|
||||||
public function getMarginTop() { return $this->getPageMarginTop(); }
|
return $this->getPageWidth();
|
||||||
public function getMarginBottom() { return $this->getPageMarginBottom(); }
|
}
|
||||||
public function getMarginLeft() { return $this->getPageMarginLeft(); }
|
public function getHeight()
|
||||||
public function getMarginRight() { return $this->getPageMarginRight(); }
|
{
|
||||||
|
return $this->getPageHeight();
|
||||||
|
}
|
||||||
|
public function getMarginTop()
|
||||||
|
{
|
||||||
|
return $this->getPageMarginTop();
|
||||||
|
}
|
||||||
|
public function getMarginBottom()
|
||||||
|
{
|
||||||
|
return $this->getPageMarginBottom();
|
||||||
|
}
|
||||||
|
public function getMarginLeft()
|
||||||
|
{
|
||||||
|
return $this->getPageMarginLeft();
|
||||||
|
}
|
||||||
|
public function getMarginRight()
|
||||||
|
{
|
||||||
|
return $this->getPageMarginRight();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the page width in getUnit() units
|
* Returns the page width in getUnit() units
|
||||||
@@ -107,7 +125,7 @@ abstract class Sheet extends Label
|
|||||||
/**
|
/**
|
||||||
* Returns label position based on its index
|
* Returns label position based on its index
|
||||||
*
|
*
|
||||||
* @param int $index
|
* @param int $index
|
||||||
*
|
*
|
||||||
* @return array [x,y]
|
* @return array [x,y]
|
||||||
*/
|
*/
|
||||||
@@ -123,10 +141,11 @@ abstract class Sheet extends Label
|
|||||||
/**
|
/**
|
||||||
* Handle the data here. Override for multiple-per-page handling
|
* Handle the data here. Override for multiple-per-page handling
|
||||||
*
|
*
|
||||||
* @param TCPDF $pdf The TCPDF instance
|
* @param TCPDF $pdf The TCPDF instance
|
||||||
* @param Collection $data The data
|
* @param Collection $data The data
|
||||||
*/
|
*/
|
||||||
public function writeAll($pdf, $data) {
|
public function writeAll($pdf, $data)
|
||||||
|
{
|
||||||
$prevPageNumber = -1;
|
$prevPageNumber = -1;
|
||||||
|
|
||||||
foreach ($data->toArray() as $recordIndex => $record) {
|
foreach ($data->toArray() as $recordIndex => $record) {
|
||||||
@@ -170,7 +189,8 @@ abstract class Sheet extends Label
|
|||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public final function getLabelOrientation() {
|
public final function getLabelOrientation()
|
||||||
|
{
|
||||||
return ($this->getLabelWidth() >= $this->getLabelHeight()) ? 'L' : 'P';
|
return ($this->getLabelWidth() >= $this->getLabelHeight()) ? 'L' : 'P';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +199,8 @@ abstract class Sheet extends Label
|
|||||||
*
|
*
|
||||||
* @return object [ 'x1'=>0.00, 'y1'=>0.00, 'x2'=>0.00, 'y2'=>0.00, 'w'=>0.00, 'h'=>0.00 ]
|
* @return object [ 'x1'=>0.00, 'y1'=>0.00, 'x2'=>0.00, 'y2'=>0.00, 'w'=>0.00, 'h'=>0.00 ]
|
||||||
*/
|
*/
|
||||||
public final function getLabelPrintableArea() {
|
public final function getLabelPrintableArea()
|
||||||
|
{
|
||||||
return (object)[
|
return (object)[
|
||||||
'x1' => $this->getLabelMarginLeft(),
|
'x1' => $this->getLabelMarginLeft(),
|
||||||
'y1' => $this->getLabelMarginTop(),
|
'y1' => $this->getLabelMarginTop(),
|
||||||
@@ -195,15 +216,20 @@ abstract class Sheet extends Label
|
|||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function getLabelIndexOffset() { return $this->indexOffset; }
|
public function getLabelIndexOffset()
|
||||||
|
{
|
||||||
|
return $this->indexOffset;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets label index offset (skip positions)
|
* Sets label index offset (skip positions)
|
||||||
*
|
*
|
||||||
* @param int $offset
|
* @param int $offset
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public function setLabelIndexOffset(int $offset) { $this->indexOffset = $offset; }
|
public function setLabelIndexOffset(int $offset)
|
||||||
|
{
|
||||||
|
$this->indexOffset = $offset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
@@ -31,7 +31,8 @@ abstract class L7162 extends RectangleSheet
|
|||||||
private float $labelWidth;
|
private float $labelWidth;
|
||||||
private float $labelHeight;
|
private float $labelHeight;
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct()
|
||||||
|
{
|
||||||
$paperSize = static::fromFormat(self::PAPER_FORMAT, self::PAPER_ORIENTATION, $this->getUnit(), 0);
|
$paperSize = static::fromFormat(self::PAPER_FORMAT, self::PAPER_ORIENTATION, $this->getUnit(), 0);
|
||||||
$this->pageWidth = $paperSize->width;
|
$this->pageWidth = $paperSize->width;
|
||||||
$this->pageHeight = $paperSize->height;
|
$this->pageHeight = $paperSize->height;
|
||||||
@@ -48,24 +49,63 @@ abstract class L7162 extends RectangleSheet
|
|||||||
$this->labelHeight = Helper::convertUnit(self::LABEL_H, 'pt', $this->getUnit());
|
$this->labelHeight = Helper::convertUnit(self::LABEL_H, 'pt', $this->getUnit());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPageWidth() { return $this->pageWidth; }
|
public function getPageWidth()
|
||||||
public function getPageHeight() { return $this->pageHeight; }
|
{
|
||||||
|
return $this->pageWidth;
|
||||||
|
}
|
||||||
|
public function getPageHeight()
|
||||||
|
{
|
||||||
|
return $this->pageHeight;
|
||||||
|
}
|
||||||
|
|
||||||
public function getPageMarginTop() { return $this->pageMarginTop; }
|
public function getPageMarginTop()
|
||||||
public function getPageMarginBottom() { return $this->pageMarginTop; }
|
{
|
||||||
public function getPageMarginLeft() { return $this->pageMarginLeft; }
|
return $this->pageMarginTop;
|
||||||
public function getPageMarginRight() { return $this->pageMarginLeft; }
|
}
|
||||||
|
public function getPageMarginBottom()
|
||||||
|
{
|
||||||
|
return $this->pageMarginTop;
|
||||||
|
}
|
||||||
|
public function getPageMarginLeft()
|
||||||
|
{
|
||||||
|
return $this->pageMarginLeft;
|
||||||
|
}
|
||||||
|
public function getPageMarginRight()
|
||||||
|
{
|
||||||
|
return $this->pageMarginLeft;
|
||||||
|
}
|
||||||
|
|
||||||
public function getColumns() { return 2; }
|
public function getColumns()
|
||||||
public function getRows() { return 8; }
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
public function getRows()
|
||||||
|
{
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
public function getLabelColumnSpacing() { return $this->columnSpacing; }
|
public function getLabelColumnSpacing()
|
||||||
public function getLabelRowSpacing() { return $this->rowSpacing; }
|
{
|
||||||
|
return $this->columnSpacing;
|
||||||
|
}
|
||||||
|
public function getLabelRowSpacing()
|
||||||
|
{
|
||||||
|
return $this->rowSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
public function getLabelWidth() { return $this->labelWidth; }
|
public function getLabelWidth()
|
||||||
public function getLabelHeight() { return $this->labelHeight; }
|
{
|
||||||
|
return $this->labelWidth;
|
||||||
|
}
|
||||||
|
public function getLabelHeight()
|
||||||
|
{
|
||||||
|
return $this->labelHeight;
|
||||||
|
}
|
||||||
|
|
||||||
public function getLabelBorder() { return 0; }
|
public function getLabelBorder()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
@@ -14,23 +14,59 @@ class L7162_A extends L7162
|
|||||||
private const FIELD_SIZE = 4.60;
|
private const FIELD_SIZE = 4.60;
|
||||||
private const FIELD_MARGIN = 0.30;
|
private const FIELD_MARGIN = 0.30;
|
||||||
|
|
||||||
public function getUnit() { return 'mm'; }
|
public function getUnit()
|
||||||
|
{
|
||||||
|
return 'mm';
|
||||||
|
}
|
||||||
|
|
||||||
public function getLabelMarginTop() { return 1.0; }
|
public function getLabelMarginTop()
|
||||||
public function getLabelMarginBottom() { return 1.0; }
|
{
|
||||||
public function getLabelMarginLeft() { return 1.0; }
|
return 1.0;
|
||||||
public function getLabelMarginRight() { return 1.0; }
|
}
|
||||||
|
public function getLabelMarginBottom()
|
||||||
|
{
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
public function getLabelMarginLeft()
|
||||||
|
{
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
public function getLabelMarginRight()
|
||||||
|
{
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
public function getSupportAssetTag() { return true; }
|
public function getSupportAssetTag()
|
||||||
public function getSupport1DBarcode() { return false; }
|
{
|
||||||
public function getSupport2DBarcode() { return true; }
|
return true;
|
||||||
public function getSupportFields() { return 4; }
|
}
|
||||||
public function getSupportLogo() { return false; }
|
public function getSupport1DBarcode()
|
||||||
public function getSupportTitle() { return true; }
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public function getSupport2DBarcode()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public function getSupportFields()
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
public function getSupportLogo()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public function getSupportTitle()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public function preparePDF($pdf) {}
|
public function preparePDF($pdf)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public function write($pdf, $record) {
|
public function write($pdf, $record)
|
||||||
|
{
|
||||||
$pa = $this->getLabelPrintableArea();
|
$pa = $this->getLabelPrintableArea();
|
||||||
|
|
||||||
$usableWidth = $pa->w;
|
$usableWidth = $pa->w;
|
||||||
|
|||||||
@@ -17,23 +17,59 @@ class L7162_B extends L7162
|
|||||||
private const FIELD_SIZE = 4.20;
|
private const FIELD_SIZE = 4.20;
|
||||||
private const FIELD_MARGIN = 0.30;
|
private const FIELD_MARGIN = 0.30;
|
||||||
|
|
||||||
public function getUnit() { return 'mm'; }
|
public function getUnit()
|
||||||
|
{
|
||||||
|
return 'mm';
|
||||||
|
}
|
||||||
|
|
||||||
public function getLabelMarginTop() { return 1.0; }
|
public function getLabelMarginTop()
|
||||||
public function getLabelMarginBottom() { return 0; }
|
{
|
||||||
public function getLabelMarginLeft() { return 1.0; }
|
return 1.0;
|
||||||
public function getLabelMarginRight() { return 1.0; }
|
}
|
||||||
|
public function getLabelMarginBottom()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
public function getLabelMarginLeft()
|
||||||
|
{
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
public function getLabelMarginRight()
|
||||||
|
{
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
public function getSupportAssetTag() { return true; }
|
public function getSupportAssetTag()
|
||||||
public function getSupport1DBarcode() { return true; }
|
{
|
||||||
public function getSupport2DBarcode() { return false; }
|
return true;
|
||||||
public function getSupportFields() { return 3; }
|
}
|
||||||
public function getSupportLogo() { return true; }
|
public function getSupport1DBarcode()
|
||||||
public function getSupportTitle() { return true; }
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public function getSupport2DBarcode()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public function getSupportFields()
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
public function getSupportLogo()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public function getSupportTitle()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public function preparePDF($pdf) {}
|
public function preparePDF($pdf)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public function write($pdf, $record) {
|
public function write($pdf, $record)
|
||||||
|
{
|
||||||
$pa = $this->getLabelPrintableArea();
|
$pa = $this->getLabelPrintableArea();
|
||||||
|
|
||||||
$usableWidth = $pa->w;
|
$usableWidth = $pa->w;
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ abstract class L7163 extends RectangleSheet
|
|||||||
private float $labelWidth;
|
private float $labelWidth;
|
||||||
private float $labelHeight;
|
private float $labelHeight;
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct()
|
||||||
|
{
|
||||||
$paperSize = static::fromFormat(self::PAPER_FORMAT, self::PAPER_ORIENTATION, $this->getUnit(), 0);
|
$paperSize = static::fromFormat(self::PAPER_FORMAT, self::PAPER_ORIENTATION, $this->getUnit(), 0);
|
||||||
$this->pageWidth = $paperSize->width;
|
$this->pageWidth = $paperSize->width;
|
||||||
$this->pageHeight = $paperSize->height;
|
$this->pageHeight = $paperSize->height;
|
||||||
@@ -48,24 +49,63 @@ abstract class L7163 extends RectangleSheet
|
|||||||
$this->labelHeight = Helper::convertUnit(self::LABEL_H, 'pt', $this->getUnit());
|
$this->labelHeight = Helper::convertUnit(self::LABEL_H, 'pt', $this->getUnit());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPageWidth() { return $this->pageWidth; }
|
public function getPageWidth()
|
||||||
public function getPageHeight() { return $this->pageHeight; }
|
{
|
||||||
|
return $this->pageWidth;
|
||||||
|
}
|
||||||
|
public function getPageHeight()
|
||||||
|
{
|
||||||
|
return $this->pageHeight;
|
||||||
|
}
|
||||||
|
|
||||||
public function getPageMarginTop() { return $this->pageMarginTop; }
|
public function getPageMarginTop()
|
||||||
public function getPageMarginBottom() { return $this->pageMarginTop; }
|
{
|
||||||
public function getPageMarginLeft() { return $this->pageMarginLeft; }
|
return $this->pageMarginTop;
|
||||||
public function getPageMarginRight() { return $this->pageMarginLeft; }
|
}
|
||||||
|
public function getPageMarginBottom()
|
||||||
|
{
|
||||||
|
return $this->pageMarginTop;
|
||||||
|
}
|
||||||
|
public function getPageMarginLeft()
|
||||||
|
{
|
||||||
|
return $this->pageMarginLeft;
|
||||||
|
}
|
||||||
|
public function getPageMarginRight()
|
||||||
|
{
|
||||||
|
return $this->pageMarginLeft;
|
||||||
|
}
|
||||||
|
|
||||||
public function getColumns() { return 2; }
|
public function getColumns()
|
||||||
public function getRows() { return 7; }
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
public function getRows()
|
||||||
|
{
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
|
||||||
public function getLabelColumnSpacing() { return $this->columnSpacing; }
|
public function getLabelColumnSpacing()
|
||||||
public function getLabelRowSpacing() { return $this->rowSpacing; }
|
{
|
||||||
|
return $this->columnSpacing;
|
||||||
|
}
|
||||||
|
public function getLabelRowSpacing()
|
||||||
|
{
|
||||||
|
return $this->rowSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
public function getLabelWidth() { return $this->labelWidth; }
|
public function getLabelWidth()
|
||||||
public function getLabelHeight() { return $this->labelHeight; }
|
{
|
||||||
|
return $this->labelWidth;
|
||||||
|
}
|
||||||
|
public function getLabelHeight()
|
||||||
|
{
|
||||||
|
return $this->labelHeight;
|
||||||
|
}
|
||||||
|
|
||||||
public function getLabelBorder() { return 0; }
|
public function getLabelBorder()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
@@ -14,23 +14,59 @@ class L7163_A extends L7163
|
|||||||
private const FIELD_SIZE = 4.80;
|
private const FIELD_SIZE = 4.80;
|
||||||
private const FIELD_MARGIN = 0.30;
|
private const FIELD_MARGIN = 0.30;
|
||||||
|
|
||||||
public function getUnit() { return 'mm'; }
|
public function getUnit()
|
||||||
|
{
|
||||||
|
return 'mm';
|
||||||
|
}
|
||||||
|
|
||||||
public function getLabelMarginTop() { return 1.0; }
|
public function getLabelMarginTop()
|
||||||
public function getLabelMarginBottom() { return 1.0; }
|
{
|
||||||
public function getLabelMarginLeft() { return 1.0; }
|
return 1.0;
|
||||||
public function getLabelMarginRight() { return 1.0; }
|
}
|
||||||
|
public function getLabelMarginBottom()
|
||||||
|
{
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
public function getLabelMarginLeft()
|
||||||
|
{
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
public function getLabelMarginRight()
|
||||||
|
{
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
public function getSupportAssetTag() { return true; }
|
public function getSupportAssetTag()
|
||||||
public function getSupport1DBarcode() { return false; }
|
{
|
||||||
public function getSupport2DBarcode() { return true; }
|
return true;
|
||||||
public function getSupportFields() { return 4; }
|
}
|
||||||
public function getSupportLogo() { return false; }
|
public function getSupport1DBarcode()
|
||||||
public function getSupportTitle() { return true; }
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public function getSupport2DBarcode()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public function getSupportFields()
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
public function getSupportLogo()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public function getSupportTitle()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public function preparePDF($pdf) {}
|
public function preparePDF($pdf)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public function write($pdf, $record) {
|
public function write($pdf, $record)
|
||||||
|
{
|
||||||
$pa = $this->getLabelPrintableArea();
|
$pa = $this->getLabelPrintableArea();
|
||||||
|
|
||||||
$usableWidth = $pa->w;
|
$usableWidth = $pa->w;
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ abstract class _3490 extends RectangleSheet
|
|||||||
private float $labelWidth;
|
private float $labelWidth;
|
||||||
private float $labelHeight;
|
private float $labelHeight;
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct()
|
||||||
|
{
|
||||||
$paperSize = static::fromFormat(self::PAPER_FORMAT, self::PAPER_ORIENTATION, $this->getUnit(), 2);
|
$paperSize = static::fromFormat(self::PAPER_FORMAT, self::PAPER_ORIENTATION, $this->getUnit(), 2);
|
||||||
$this->pageWidth = $paperSize->width;
|
$this->pageWidth = $paperSize->width;
|
||||||
$this->pageHeight = $paperSize->height;
|
$this->pageHeight = $paperSize->height;
|
||||||
@@ -48,24 +49,63 @@ abstract class _3490 extends RectangleSheet
|
|||||||
$this->labelHeight = Helper::convertUnit(self::LABEL_H, 'pt', $this->getUnit());
|
$this->labelHeight = Helper::convertUnit(self::LABEL_H, 'pt', $this->getUnit());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPageWidth() { return $this->pageWidth; }
|
public function getPageWidth()
|
||||||
public function getPageHeight() { return $this->pageHeight; }
|
{
|
||||||
|
return $this->pageWidth;
|
||||||
|
}
|
||||||
|
public function getPageHeight()
|
||||||
|
{
|
||||||
|
return $this->pageHeight;
|
||||||
|
}
|
||||||
|
|
||||||
public function getPageMarginTop() { return $this->pageMarginTop; }
|
public function getPageMarginTop()
|
||||||
public function getPageMarginBottom() { return $this->pageMarginTop; }
|
{
|
||||||
public function getPageMarginLeft() { return $this->pageMarginLeft; }
|
return $this->pageMarginTop;
|
||||||
public function getPageMarginRight() { return $this->pageMarginLeft; }
|
}
|
||||||
|
public function getPageMarginBottom()
|
||||||
|
{
|
||||||
|
return $this->pageMarginTop;
|
||||||
|
}
|
||||||
|
public function getPageMarginLeft()
|
||||||
|
{
|
||||||
|
return $this->pageMarginLeft;
|
||||||
|
}
|
||||||
|
public function getPageMarginRight()
|
||||||
|
{
|
||||||
|
return $this->pageMarginLeft;
|
||||||
|
}
|
||||||
|
|
||||||
public function getColumns() { return 3; }
|
public function getColumns()
|
||||||
public function getRows() { return 10; }
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
public function getRows()
|
||||||
|
{
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
|
||||||
public function getLabelColumnSpacing() { return $this->columnSpacing; }
|
public function getLabelColumnSpacing()
|
||||||
public function getLabelRowSpacing() { return $this->rowSpacing; }
|
{
|
||||||
|
return $this->columnSpacing;
|
||||||
|
}
|
||||||
|
public function getLabelRowSpacing()
|
||||||
|
{
|
||||||
|
return $this->rowSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
public function getLabelWidth() { return $this->labelWidth; }
|
public function getLabelWidth()
|
||||||
public function getLabelHeight() { return $this->labelHeight; }
|
{
|
||||||
|
return $this->labelWidth;
|
||||||
|
}
|
||||||
|
public function getLabelHeight()
|
||||||
|
{
|
||||||
|
return $this->labelHeight;
|
||||||
|
}
|
||||||
|
|
||||||
public function getLabelBorder() { return 0; }
|
public function getLabelBorder()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user