mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-08-28 17:07:21 +00:00
Compare commits
633 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
c2216843d8 | ||
|
339fb5099f | ||
|
cf56707b02 | ||
|
19f38aa6ed | ||
|
9f69e112d0 | ||
|
8eb4259be0 | ||
|
d3a1f43cbb | ||
|
18b06ff283 | ||
|
53addcf99a | ||
|
0fa4d75a47 | ||
|
2ef86c3339 | ||
|
d48c3a6d2f | ||
|
2260ede559 | ||
|
5690a44c38 | ||
|
e36a9fda1b | ||
|
10f195d334 | ||
|
54afc6ca8c | ||
|
2e67bd3b78 | ||
|
f27eb084c7 | ||
|
7629dfd54a | ||
|
f62fd18b72 | ||
|
c6b60ff6b4 | ||
|
e9655e6d86 | ||
|
3bca9b06f8 | ||
|
d97fdc3393 | ||
|
7dc72f98bf | ||
|
da00179066 | ||
|
89910031cd | ||
|
5676aeac80 | ||
|
b0b9055e2e | ||
|
c0aefed764 | ||
|
e2ec9ca5fb | ||
|
8e38f5c2c0 | ||
|
99b2858863 | ||
|
b43669e731 | ||
|
3bc9905715 | ||
|
c55aebd005 | ||
|
55c331f536 | ||
|
ce236284f4 | ||
|
c24cac68f6 | ||
|
db149ca6e1 | ||
|
0502f2a4a5 | ||
|
f13df7e605 | ||
|
36a6981329 | ||
|
7abcdea816 | ||
|
0509e54a95 | ||
|
b8893bcad7 | ||
|
c9356c1237 | ||
|
2d7b7c2f3f | ||
|
d0db1117f7 | ||
|
e287e76db5 | ||
|
8c28c4b5ac | ||
|
f048e943f8 | ||
|
12a84572e2 | ||
|
c8de1d3372 | ||
|
234e3f4ca5 | ||
|
7749fb1a0b | ||
|
f55d4e32c0 | ||
|
cfd98a33fe | ||
|
7bdf20fee5 | ||
|
e906fa3653 | ||
|
57cf7f6f0d | ||
|
d378e7e897 | ||
|
a8e666db34 | ||
|
7b46339a5d | ||
|
20aa6e429b | ||
|
7ba11a57a8 | ||
|
49de4f2200 | ||
|
5d01955133 | ||
|
7591f3fa29 | ||
|
89f8f9b45b | ||
|
59f5b38dca | ||
|
5b0e61033c | ||
|
096af00a72 | ||
|
dca2dc4600 | ||
|
96b482dac5 | ||
|
e05664f34f | ||
|
72cca5ccbf | ||
|
0b9be029ac | ||
|
91701473af | ||
|
ad6a9a7df7 | ||
|
32b6ded008 | ||
|
4f2d0a0322 | ||
|
793cfcb2c5 | ||
|
3a71bd01fb | ||
|
a1d99c1954 | ||
|
19a874b274 | ||
|
b95dd5c238 | ||
|
7c84af2370 | ||
|
db1c27d833 | ||
|
636cd84f4f | ||
|
f2d4fae813 | ||
|
986c9ab20a | ||
|
cd7e222b72 | ||
|
50b599b1a9 | ||
|
1d162edb59 | ||
|
7bdd4ddeab | ||
|
ae6e5a5599 | ||
|
1222184b68 | ||
|
18f779c6de | ||
|
138f67581c | ||
|
597d6ac513 | ||
|
3ab25c2e8c | ||
|
b11d97ba4e | ||
|
080c810131 | ||
|
56bc79d64e | ||
|
72d2c9d600 | ||
|
0374c32236 | ||
|
d73cd4b515 | ||
|
54e3e3f051 | ||
|
abf218fc21 | ||
|
dcf90b6159 | ||
|
1cf91c78f8 | ||
|
968abd26e8 | ||
|
aa05f7a2d2 | ||
|
181c23b07c | ||
|
955cde3ed9 | ||
|
477a3c7eb2 | ||
|
f4b66b980b | ||
|
281de63e0d | ||
|
c19a700662 | ||
|
fc011ba1d9 | ||
|
b941f590e0 | ||
|
8f4db78ff2 | ||
|
4b4dc2e298 | ||
|
2de19547ca | ||
|
5a058491b0 | ||
|
6743d99d9b | ||
|
35a5ec78c3 | ||
|
3440c3e77a | ||
|
dd17f06362 | ||
|
8a15cb3a34 | ||
|
4a548ac282 | ||
|
d22353b13d | ||
|
c18046c25d | ||
|
4a12d4d156 | ||
|
20044427b4 | ||
|
073dedd483 | ||
|
06c25c913c | ||
|
08d06cf465 | ||
|
1e9eb843c0 | ||
|
78a5dae2a0 | ||
|
19443a5b34 | ||
|
74acc90702 | ||
|
349f580371 | ||
|
f019d33a03 | ||
|
c7af25ac38 | ||
|
b52bd59cea | ||
|
332d32c319 | ||
|
2f824ba1a8 | ||
|
a6b09acd5e | ||
|
d4779c8c8f | ||
|
ba01c4bbe8 | ||
|
ddc1d81665 | ||
|
790aeb3c46 | ||
|
6ed5be10b1 | ||
|
a7b8470d9e | ||
|
2a05cc382f | ||
|
1e10a6ce1b | ||
|
7645ef55c2 | ||
|
6ce200b60d | ||
|
d782e28906 | ||
|
da3bd31fb8 | ||
|
aa3ed40430 | ||
|
ad7e564f14 | ||
|
f23ee2dac5 | ||
|
1962f74439 | ||
|
0064d060ea | ||
|
e47e6b1958 | ||
|
4c04415e80 | ||
|
3654e75b8c | ||
|
66fa73aea4 | ||
|
df87d03f32 | ||
|
3fbe851a0b | ||
|
d1b2e63950 | ||
|
34fd8cf751 | ||
|
f1fe90fce0 | ||
|
2ba6fa0dda | ||
|
f2928e3d7d | ||
|
895ab9c5d8 | ||
|
fb07c68132 | ||
|
68e7d45f63 | ||
|
49e302e1bc | ||
|
b33ca786ae | ||
|
dc77d8edda | ||
|
c339a183b9 | ||
|
f263795a99 | ||
|
e9e771e57b | ||
|
fbb9d7c6b4 | ||
|
10abd7b0ae | ||
|
3de36901b8 | ||
|
5b4967acb9 | ||
|
0a007b1e6e | ||
|
4ad68b7dfa | ||
|
73aef1b9a4 | ||
|
dcfea20973 | ||
|
9b6766d3b2 | ||
|
b8bc8e2c47 | ||
|
039e3aa34c | ||
|
551ff109c9 | ||
|
664451d0c6 | ||
|
4031057bc0 | ||
|
fcf9b782c1 | ||
|
d693d382b9 | ||
|
0a1b6c7793 | ||
|
5acba2bddf | ||
|
883b16fad1 | ||
|
ef48b3e751 | ||
|
3c956e7e98 | ||
|
519ea271a9 | ||
|
09d5160404 | ||
|
97dcf03334 | ||
|
896a804a72 | ||
|
656bb5043d | ||
|
e953becbae | ||
|
6c9901b919 | ||
|
ff45c94106 | ||
|
a8a3fbeef4 | ||
|
dae8092ecd | ||
|
70110208fc | ||
|
217ca98933 | ||
|
c2945c532e | ||
|
ea750576b3 | ||
|
82538ba4fc | ||
|
2b2f37a8c9 | ||
|
4db2ec60e0 | ||
|
7d88d35556 | ||
|
3c3e91ff48 | ||
|
039e8d6e17 | ||
|
50bf79ab18 | ||
|
467c6762fa | ||
|
740f4e403f | ||
|
5664d51695 | ||
|
b195a61498 | ||
|
94e6816bf6 | ||
|
ebf97f710f | ||
|
714b54ed06 | ||
|
620c5f515e | ||
|
c06fd12b07 | ||
|
2c206bba64 | ||
|
04953b5645 | ||
|
1732ce63f3 | ||
|
1e212c6da2 | ||
|
7d8fc54351 | ||
|
dd44a1e517 | ||
|
9f26757e8a | ||
|
a9c8c8384d | ||
|
a826b0e0fb | ||
|
4aaec0e379 | ||
|
69019d5215 | ||
|
96411b17e9 | ||
|
5a093b58d8 | ||
|
470b3e0973 | ||
|
dc251c216c | ||
|
ae9ef61f80 | ||
|
d9ca7b7277 | ||
|
0c99248deb | ||
|
1aae84a4d0 | ||
|
528da3f08e | ||
|
9c507f7f62 | ||
|
07da2fdda3 | ||
|
ca3366544e | ||
|
ccee7b483c | ||
|
5903133e3b | ||
|
5bf520b6ed | ||
|
a47da92d81 | ||
|
63f84ae7b1 | ||
|
4d6bc55723 | ||
|
9bb4df4cc3 | ||
|
c47a5379ae | ||
|
cde9c4a2bc | ||
|
5a560b42ef | ||
|
50874c9cf7 | ||
|
6f984aa591 | ||
|
274162afcd | ||
|
6bd23d897f | ||
|
73f29ebf69 | ||
|
cabcb9c6d0 | ||
|
116f7ed613 | ||
|
6ef0eb73d0 | ||
|
7f4feb0cfc | ||
|
626f7357bb | ||
|
690c9203c8 | ||
|
1209f3b39a | ||
|
a4524b3c2c | ||
|
a3cbdadb39 | ||
|
9e3c5fd984 | ||
|
7d80ac37a6 | ||
|
f74b9ba7ab | ||
|
3ac240dc1c | ||
|
d233b3f24f | ||
|
19fff681d2 | ||
|
bc7c3bb9b3 | ||
|
57be7f2905 | ||
|
1c0da454db | ||
|
b541f7b944 | ||
|
6e84326583 | ||
|
ca14496e4e | ||
|
480d65fc1f | ||
|
6bddb63b45 | ||
|
c5142aeba5 | ||
|
38d9f10672 | ||
|
937394af7a | ||
|
fe10955eb9 | ||
|
ccda71ff8e | ||
|
cd75224cdd | ||
|
1c2089b8a3 | ||
|
3ead4d4587 | ||
|
f2b71bc280 | ||
|
f027d71136 | ||
|
fa41d6df04 | ||
|
d2bb65bf04 | ||
|
b5be1b11d1 | ||
|
9fb049991f | ||
|
fba847dd28 | ||
|
b33883b334 | ||
|
f74a6dffca | ||
|
7390e20218 | ||
|
9646dc439e | ||
|
554c63b9c7 | ||
|
24d8640e9b | ||
|
ea151d069c | ||
|
f140d2f37a | ||
|
4e163c4bda | ||
|
ddcf8b892b | ||
|
49138eb03a | ||
|
71b63bd33b | ||
|
88348f59c2 | ||
|
7eb5643204 | ||
|
565cb6d79e | ||
|
c0d715c78a | ||
|
a3d0355ddd | ||
|
bc4e06568d | ||
|
8acb9f4056 | ||
|
9cbbd581ee | ||
|
fdc9467218 | ||
|
84ac3df580 | ||
|
7f459df9e9 | ||
|
3625f3293a | ||
|
0a2308592f | ||
|
8ef3f18da7 | ||
|
e126427809 | ||
|
7b39828980 | ||
|
d03de52735 | ||
|
cabe90b2dd | ||
|
13b78bdc20 | ||
|
6f0e1c79ac | ||
|
b66daad3d3 | ||
|
9c5523252d | ||
|
bc8bcf7a1a | ||
|
85d655d3e2 | ||
|
ac419e01d3 | ||
|
5d4467a6c0 | ||
|
81da7f3667 | ||
|
9734196eb9 | ||
|
7e0f9b9b8e | ||
|
bb25132865 | ||
|
28bcff99f6 | ||
|
246cb36836 | ||
|
9a0c0f6d21 | ||
|
a9dd8eb9e7 | ||
|
9026c9d6f1 | ||
|
d5f7430723 | ||
|
5a53249fbb | ||
|
d2848cf569 | ||
|
71f39f55f2 | ||
|
490c817fc1 | ||
|
2e1a777811 | ||
|
48357d1cc9 | ||
|
846df21764 | ||
|
f78b8f9267 | ||
|
798d9ee876 | ||
|
1eea81e9dd | ||
|
4fcdfd41fa | ||
|
36a5f17af2 | ||
|
8032684ad0 | ||
|
f7d3d4a010 | ||
|
9975e0b3f3 | ||
|
ea484a7787 | ||
|
c2e8a67330 | ||
|
8f3e4a2dee | ||
|
07768a43c8 | ||
|
01c10e320c | ||
|
f16b2257c6 | ||
|
e005fe7ce1 | ||
|
c682e69ee7 | ||
|
49421f50ac | ||
|
529dd490b7 | ||
|
36329e596e | ||
|
fb75e2ef02 | ||
|
352171e339 | ||
|
592901b143 | ||
|
769b4819b2 | ||
|
77fa2bcc39 | ||
|
1129001bc6 | ||
|
8dd765ee89 | ||
|
479648e7c1 | ||
|
45cd19d1e3 | ||
|
f8718e0b7b | ||
|
dcc45631da | ||
|
c6d3a5bedc | ||
|
7cc8539298 | ||
|
900e8202e6 | ||
|
eb6ac7d1d1 | ||
|
178f917a49 | ||
|
1a8293d9ef | ||
|
ecdc00dcb7 | ||
|
147e04ecd2 | ||
|
49e48725a5 | ||
|
b3af744041 | ||
|
58a6a95d90 | ||
|
1aa9461370 | ||
|
1f78b9d4bc | ||
|
6f974fe285 | ||
|
f4f3c8798e | ||
|
ce1614f4e7 | ||
|
91494584c2 | ||
|
a85ebb49b2 | ||
|
ae273f8320 | ||
|
ef62e31b61 | ||
|
0c2c5d5344 | ||
|
11e93eac3d | ||
|
dbe17debb4 | ||
|
6c12337317 | ||
|
b2aa73b31e | ||
|
38b1fc7aa6 | ||
|
f4afcb4d50 | ||
|
4b019fe38b | ||
|
191401f32b | ||
|
62b68c6a21 | ||
|
15a22f0bfc | ||
|
926c03986c | ||
|
d8a00f4314 | ||
|
5862b832d9 | ||
|
67fa4a0fc7 | ||
|
90cf7a3bf5 | ||
|
0847040017 | ||
|
69b577048e | ||
|
3fbd2f93c8 | ||
|
8f0e36a8e4 | ||
|
7583698ee5 | ||
|
b561e79a6c | ||
|
5850ad06b1 | ||
|
e597f04b0d | ||
|
7b715925cf | ||
|
d3701837e3 | ||
|
7af10aca9e | ||
|
b54e99642b | ||
|
b1ad0668cc | ||
|
6583d0f69b | ||
|
cee6bbf134 | ||
|
43e49bf14a | ||
|
371b58a807 | ||
|
7812a1bb51 | ||
|
538e045e4c | ||
|
91fe1493a7 | ||
|
4650a2ea52 | ||
|
7cd51a7747 | ||
|
b55545b959 | ||
|
2685256c93 | ||
|
3819de4e74 | ||
|
73fee4eb6b | ||
|
609c193b88 | ||
|
03a42976b1 | ||
|
6db0efdfbc | ||
|
ebbbe1a620 | ||
|
5d1c77cb16 | ||
|
d48fb3ba55 | ||
|
8c024a1ae9 | ||
|
a3c34e6b3c | ||
|
fa7ab45a40 | ||
|
379b104778 | ||
|
d956c795a4 | ||
|
7d02d0f762 | ||
|
f96f38b172 | ||
|
4cea5d65a6 | ||
|
40d94e7a62 | ||
|
66019fdbbf | ||
|
37b02e3d5b | ||
|
093bdd6090 | ||
|
52656b25da | ||
|
1386c9d915 | ||
|
02c9441727 | ||
|
b1e926f2cb | ||
|
df9dcb395b | ||
|
ad59dad921 | ||
|
46e75968f5 | ||
|
0df5c5121d | ||
|
16f04b45ac | ||
|
5ce35a50c2 | ||
|
7110c1178a | ||
|
220f5e2913 | ||
|
9f8c75efc6 | ||
|
8f3e84df4d | ||
|
08ff3d8ad0 | ||
|
5c4d7734ac | ||
|
15f8cd49d3 | ||
|
62b3986fcd | ||
|
55b6d711f3 | ||
|
7e51d57d21 | ||
|
170d23d768 | ||
|
40266c6821 | ||
|
0a71077513 | ||
|
be5c44af61 | ||
|
720dcb0fe5 | ||
|
c86b207b1c | ||
|
413c1bc2fe | ||
|
5ca31ea3dd | ||
|
dd5d2d1616 | ||
|
5f08790f12 | ||
|
d5ef5ee5a7 | ||
|
f641c70172 | ||
|
992657b942 | ||
|
41e468b507 | ||
|
6660306ac4 | ||
|
dd9694890a | ||
|
0b8654d865 | ||
|
f07dc7bd81 | ||
|
6a6482dc7f | ||
|
3c9b7c07af | ||
|
796ab4bf2c | ||
|
55602d632d | ||
|
310ed9f504 | ||
|
dafddfa39a | ||
|
3e22c9860e | ||
|
fb0a0c3fb5 | ||
|
3b735c7533 | ||
|
1645490f5c | ||
|
aecffe10d9 | ||
|
4e69bc0e32 | ||
|
909f72e6be | ||
|
6a1d39d5f8 | ||
|
c5d4ec17c3 | ||
|
ed33a72945 | ||
|
d8c0091680 | ||
|
6419d68626 | ||
|
e2ecaf5bcf | ||
|
31146954d1 | ||
|
601ca9ec80 | ||
|
082b5ba895 | ||
|
e06361d5d7 | ||
|
552a8e130c | ||
|
40787bc29a | ||
|
6ab03bb228 | ||
|
3fdb782321 | ||
|
c8f52a1c40 | ||
|
eb63090387 | ||
|
5bc8f31c31 | ||
|
5776de7745 | ||
|
f45d0bb317 | ||
|
93aa5b7753 | ||
|
dd6a6a565f | ||
|
aba8025645 | ||
|
b12872e5de | ||
|
5a7b1ba292 | ||
|
24715c72a2 | ||
|
ed3a4e4663 | ||
|
e97283b34b | ||
|
c2dfbcba10 | ||
|
a9870b35be | ||
|
ed5cd2b9ca | ||
|
a9356ca1e2 | ||
|
cfba11e9ca | ||
|
4304a3c916 | ||
|
9e6194bfdc | ||
|
7d6c8aa9dc | ||
|
aad0864018 | ||
|
a55d18709c | ||
|
dd2f3c861b | ||
|
da1dc67e1c | ||
|
0c2b35e542 | ||
|
85dc1263ea | ||
|
c8ecb3e0ee | ||
|
ce10036a27 | ||
|
30e49846e0 | ||
|
be97dd1c57 | ||
|
648a6dca42 | ||
|
0566d0d198 | ||
|
dfc25722c9 | ||
|
a436c55c50 | ||
|
0d58530f55 | ||
|
04b2eaf535 | ||
|
ace2ed8bd0 | ||
|
dff2d716a1 | ||
|
ad18b9b81b | ||
|
eabfe0769b | ||
|
19f7027718 | ||
|
f537945351 | ||
|
d02372ab90 | ||
|
1b020c522f | ||
|
79d0450c77 | ||
|
bc32bc8831 | ||
|
f68a307eeb | ||
|
82e7479cfe | ||
|
462fe5d89f | ||
|
b0d8ac83ae | ||
|
d8ac817c91 | ||
|
5105bc6f64 | ||
|
47c9f1e9b8 | ||
|
49d0ed0c1b | ||
|
99f5151aab | ||
|
0a056ad02d | ||
|
c76b634d0b | ||
|
a81698d50f | ||
|
bae79063e1 | ||
|
fb5323c283 | ||
|
e2d1de94b7 | ||
|
7109fd8196 | ||
|
a5fd821e0c | ||
|
6c63583e49 | ||
|
dd16e1b784 | ||
|
d52d8d7970 | ||
|
f349aa47ce | ||
|
ef4018934c | ||
|
951aa9535e | ||
|
de1fe36226 | ||
|
64fd36d437 | ||
|
6f9ecc0ffa | ||
|
a97bfc92e1 | ||
|
0d72fcdf02 | ||
|
0e84ca1df5 | ||
|
b28bdda510 | ||
|
72314e2d9f | ||
|
d22fb9f438 | ||
|
04b8552d27 | ||
|
5d6f44cd91 | ||
|
afc8ad7ff5 | ||
|
ae039bf1c7 | ||
|
8fa25e9d37 | ||
|
0daab491ec | ||
|
4f825bac1a | ||
|
39c8b79ebb | ||
|
7d66c90beb |
29
.deploy/docker/entrypoint.sh
Executable file
29
.deploy/docker/entrypoint.sh
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
|
||||
# make sure the correct directories exists (suggested by @chrif):
|
||||
mkdir -p $FIREFLY_PATH/storage/app
|
||||
mkdir -p $FIREFLY_PATH/storage/app/public
|
||||
mkdir -p $FIREFLY_PATH/storage/build
|
||||
mkdir -p $FIREFLY_PATH/storage/database
|
||||
mkdir -p $FIREFLY_PATH/storage/debugbar
|
||||
mkdir -p $FIREFLY_PATH/storage/export
|
||||
mkdir -p $FIREFLY_PATH/storage/framework/cache
|
||||
mkdir -p $FIREFLY_PATH/storage/framework/sessions
|
||||
mkdir -p $FIREFLY_PATH/storage/framework/testing
|
||||
mkdir -p $FIREFLY_PATH/storage/framework/views
|
||||
mkdir -p $FIREFLY_PATH/storage/logs
|
||||
mkdir -p $FIREFLY_PATH/storage/upload
|
||||
|
||||
|
||||
# make sure we own the volumes:
|
||||
chown -R www-data:www-data -R $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload $FIREFLY_PATH/storage/logs $FIREFLY_PATH/storage/framework/cache
|
||||
chmod -R 775 $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload $FIREFLY_PATH/storage/upload $FIREFLY_PATH/storage/logs $FIREFLY_PATH/storage/framework/cache
|
||||
|
||||
# remove any lingering files that may break upgrades:
|
||||
rm -f $FIREFLY_PATH/storage/logs/laravel.log
|
||||
|
||||
cat .env.docker | envsubst > .env && cat .env
|
||||
composer dump-autoload
|
||||
php artisan package:discover
|
||||
php artisan firefly:instructions install
|
||||
exec apache2-foreground
|
82
.deploy/kubernetes/firefly.yaml
Normal file
82
.deploy/kubernetes/firefly.yaml
Normal file
@@ -0,0 +1,82 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: mysql-pv-export-claim
|
||||
labels:
|
||||
app: firefly-local
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 20Gi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: mysql-pv-upload-claim
|
||||
labels:
|
||||
app: firefly-local
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 20Gi
|
||||
---
|
||||
apiVersion: apps/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: firefly-local
|
||||
namespace: firefly
|
||||
labels:
|
||||
app: firefly-local
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: firefly-local
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: firefly-local
|
||||
spec:
|
||||
containers:
|
||||
- image: firefly-local
|
||||
name: firefly-local
|
||||
env:
|
||||
- name: FF_APP_ENV
|
||||
value: "local"
|
||||
- name: FF_APP_KEY
|
||||
value: "S0m3R@nd0mString0f32Ch@rsEx@ct1y"
|
||||
- name: FF_DB_HOST
|
||||
value: "172.17.0.9"
|
||||
- name: FF_DB_NAME
|
||||
value: "firefly_db"
|
||||
- name: FF_DB_USER
|
||||
value: "firefly_db"
|
||||
- name: FF_DB_PASSWORD
|
||||
value: "password"
|
||||
volumeMounts:
|
||||
- mountPath: "/var/www/firefly-iii/storage/export"
|
||||
name: mysql-persistent-export
|
||||
- mountPath: "/var/www/firefly-iii/storage/upload"
|
||||
name: mysql-persistent-upload
|
||||
imagePullPolicy: IfNotPresent
|
||||
volumes:
|
||||
- name: mysql-persistent-export
|
||||
persistentVolumeClaim:
|
||||
claimName: mysql-pv-export-claim
|
||||
- name: mysql-persistent-upload
|
||||
persistentVolumeClaim:
|
||||
claimName: mysql-pv-upload-claim
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: firefly-local
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
type: NodePort
|
||||
selector:
|
||||
app: firefly-local
|
49
.deploy/kubernetes/sql.yaml
Normal file
49
.deploy/kubernetes/sql.yaml
Normal file
@@ -0,0 +1,49 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: sql-pass
|
||||
type: Opaque
|
||||
data:
|
||||
password: cGFzc3dvcmQ=
|
||||
---
|
||||
apiVersion: apps/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mysql
|
||||
namespace: firefly
|
||||
labels:
|
||||
app: mysql
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mysql
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mysql
|
||||
spec:
|
||||
containers:
|
||||
- image: mysql
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: mysql
|
||||
env:
|
||||
- name: MYSQL_ROOT_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: sql-pass
|
||||
key: password
|
||||
ports:
|
||||
- containerPort: 3306
|
||||
name: mysql
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mysql
|
||||
spec:
|
||||
ports:
|
||||
- port: 3306
|
||||
type: NodePort
|
||||
selector:
|
||||
app: mysql
|
||||
|
22
.env.docker
22
.env.docker
@@ -17,11 +17,14 @@ APP_KEY=${FF_APP_KEY}
|
||||
APP_URL=${APP_URL}
|
||||
TRUSTED_PROXIES=${TRUSTED_PROXIES}
|
||||
|
||||
# The log channel defines where your log entries go to.
|
||||
LOG_CHANNEL=${LOG_CHANNEL}
|
||||
|
||||
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
|
||||
# If you use SQLite, set connection to `sqlite` and remove the database, username and password settings.
|
||||
DB_CONNECTION=mysql
|
||||
DB_CONNECTION=${FF_DB_CONNECTION}
|
||||
DB_HOST=${FF_DB_HOST}
|
||||
DB_PORT=3306
|
||||
DB_PORT=${FF_DB_PORT}
|
||||
DB_DATABASE=${FF_DB_NAME}
|
||||
DB_USERNAME=${FF_DB_USER}
|
||||
DB_PASSWORD=${FF_DB_PASSWORD}
|
||||
@@ -47,6 +50,7 @@ COOKIE_DOMAIN=
|
||||
COOKIE_SECURE=false
|
||||
|
||||
# If you want Firefly III to mail you, update these settings
|
||||
# For instructions, see: https://firefly-iii.readthedocs.io/en/latest/installation/mail.html
|
||||
MAIL_DRIVER=${MAIL_DRIVER}
|
||||
MAIL_HOST=${MAIL_HOST}
|
||||
MAIL_PORT=${MAIL_PORT}
|
||||
@@ -55,6 +59,12 @@ MAIL_USERNAME=${MAIL_USERNAME}
|
||||
MAIL_PASSWORD=${MAIL_PASSWORD}
|
||||
MAIL_ENCRYPTION=${MAIL_ENCRYPTION}
|
||||
|
||||
# Other mail drivers:
|
||||
MAILGUN_DOMAIN=${MAILGUN_DOMAIN}
|
||||
MAILGUN_SECRET=${MAILGUN_SECRET}
|
||||
MANDRILL_SECRET=${MANDRILL_SECRET}
|
||||
SPARKPOST_SECRET=${SPARKPOST_SECRET}
|
||||
|
||||
# Firefly III can send you the following messages
|
||||
SEND_REGISTRATION_MAIL=true
|
||||
SEND_ERROR_MESSAGE=false
|
||||
@@ -62,6 +72,11 @@ SEND_ERROR_MESSAGE=false
|
||||
# Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places.
|
||||
MAPBOX_API_KEY=${MAPBOX_API_KEY}
|
||||
|
||||
# Set a Fixer IO API key here (see https://fixer.io) to enable live currency exchange rates.
|
||||
# Please note that this will only work for paid fixer.io accounts because they severly limited
|
||||
# the free API up to the point where you might as well offer nothing.
|
||||
FIXER_API_KEY=${FIXER_API_KEY}
|
||||
|
||||
# If you wish to track your own behavior over Firefly III, set a valid analytics tracker ID here.
|
||||
ANALYTICS_ID=${ANALYTICS_ID}
|
||||
|
||||
@@ -79,7 +94,6 @@ REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
CACHE_PREFIX=firefly
|
||||
SEARCH_RESULT_LIMIT=50
|
||||
EXCHANGE_RATE_SERVICE=fixerio
|
||||
PUSHER_KEY=
|
||||
PUSHER_SECRET=
|
||||
PUSHER_ID=
|
||||
@@ -88,3 +102,5 @@ DEMO_PASSWORD=
|
||||
IS_DOCKER=true
|
||||
IS_SANDSTORM=false
|
||||
IS_HEROKU=false
|
||||
BUNQ_USE_SANDBOX=false
|
||||
TZ=${TZ}
|
||||
|
27
.env.example
27
.env.example
@@ -13,12 +13,19 @@ SITE_OWNER=mail@example.com
|
||||
# Change it to a string of exactly 32 chars or use command `php artisan key:generate` to generate it
|
||||
APP_KEY=SomeRandomStringOf32CharsExactly
|
||||
|
||||
# Change this value to your preferred time zone.
|
||||
# Example: Europe/Amsterdam
|
||||
TZ=UTC
|
||||
|
||||
# APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy.
|
||||
APP_URL=http://localhost
|
||||
TRUSTED_PROXIES=
|
||||
|
||||
# The log channel defines where your log entries go to.
|
||||
LOG_CHANNEL=daily
|
||||
|
||||
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
|
||||
# If you use SQLite, set connection to `sqlite` and remove the database, username and password settings.
|
||||
# For other database types, please see the FAQ: http://firefly-iii.readthedocs.io/en/latest/support/faq.html
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
@@ -47,7 +54,8 @@ COOKIE_DOMAIN=
|
||||
COOKIE_SECURE=false
|
||||
|
||||
# If you want Firefly III to mail you, update these settings
|
||||
MAIL_DRIVER=smtp
|
||||
# For instructions, see: https://firefly-iii.readthedocs.io/en/latest/installation/mail.html
|
||||
MAIL_DRIVER=log
|
||||
MAIL_HOST=smtp.mailtrap.io
|
||||
MAIL_PORT=2525
|
||||
MAIL_FROM=changeme@example.com
|
||||
@@ -55,6 +63,12 @@ MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
|
||||
# Other mail drivers:
|
||||
MAILGUN_DOMAIN=
|
||||
MAILGUN_SECRET=
|
||||
MANDRILL_SECRET=
|
||||
SPARKPOST_SECRET=
|
||||
|
||||
# Firefly III can send you the following messages
|
||||
SEND_REGISTRATION_MAIL=true
|
||||
SEND_ERROR_MESSAGE=true
|
||||
@@ -62,6 +76,11 @@ SEND_ERROR_MESSAGE=true
|
||||
# Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places.
|
||||
MAPBOX_API_KEY=
|
||||
|
||||
# Set a Fixer IO API key here (see https://fixer.io) to enable live currency exchange rates.
|
||||
# Please note that this will only work for paid fixer.io accounts because they severly limited
|
||||
# the free API up to the point where you might as well offer nothing.
|
||||
FIXER_API_KEY=
|
||||
|
||||
# If you wish to track your own behavior over Firefly III, set a valid analytics tracker ID here.
|
||||
ANALYTICS_ID=
|
||||
|
||||
@@ -79,7 +98,6 @@ REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
CACHE_PREFIX=firefly
|
||||
SEARCH_RESULT_LIMIT=50
|
||||
EXCHANGE_RATE_SERVICE=fixerio
|
||||
PUSHER_KEY=
|
||||
PUSHER_SECRET=
|
||||
PUSHER_ID=
|
||||
@@ -87,4 +105,7 @@ DEMO_USERNAME=
|
||||
DEMO_PASSWORD=
|
||||
IS_DOCKER=false
|
||||
IS_SANDSTORM=false
|
||||
BUNQ_USE_SANDBOX=false
|
||||
IS_HEROKU=false
|
||||
MAILGUN_DOMAIN=
|
||||
MAILGUN_SECRET=
|
||||
|
25
.env.heroku
25
.env.heroku
@@ -13,10 +13,17 @@ SITE_OWNER=heroku@example.com
|
||||
# Change it to a string of exactly 32 chars or use command `php artisan key:generate` to generate it
|
||||
APP_KEY=7ahyYVPVsmxjdhsweWCauGeJfwc92NP2
|
||||
|
||||
# Change this value to your preferred time zone.
|
||||
# Example: Europe/Amsterdam
|
||||
TZ=UTC
|
||||
|
||||
# APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy.
|
||||
APP_URL=http://localhost
|
||||
TRUSTED_PROXIES=
|
||||
|
||||
# The log channel defines where your log entries go to.
|
||||
LOG_CHANNEL=syslog
|
||||
|
||||
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
|
||||
# If you use SQLite, set connection to `sqlite` and remove the database, username and password settings.
|
||||
DB_CONNECTION=pgsql
|
||||
@@ -47,7 +54,8 @@ COOKIE_DOMAIN=
|
||||
COOKIE_SECURE=false
|
||||
|
||||
# If you want Firefly III to mail you, update these settings
|
||||
MAIL_DRIVER=smtp
|
||||
# For instructions, see: https://firefly-iii.readthedocs.io/en/latest/installation/mail.html
|
||||
MAIL_DRIVER=log
|
||||
MAIL_HOST=smtp.mailtrap.io
|
||||
MAIL_PORT=2525
|
||||
MAIL_FROM=changeme@example.com
|
||||
@@ -55,6 +63,12 @@ MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
|
||||
# Other mail drivers:
|
||||
MAILGUN_DOMAIN=
|
||||
MAILGUN_SECRET=
|
||||
MANDRILL_SECRET=
|
||||
SPARKPOST_SECRET=
|
||||
|
||||
# Firefly III can send you the following messages
|
||||
SEND_REGISTRATION_MAIL=true
|
||||
SEND_ERROR_MESSAGE=true
|
||||
@@ -62,6 +76,11 @@ SEND_ERROR_MESSAGE=true
|
||||
# Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places.
|
||||
MAPBOX_API_KEY=
|
||||
|
||||
# Set a Fixer IO API key here (see https://fixer.io) to enable live currency exchange rates.
|
||||
# Please note that this will only work for paid fixer.io accounts because they severly limited
|
||||
# the free API up to the point where you might as well offer nothing.
|
||||
FIXER_API_KEY=
|
||||
|
||||
# If you wish to track your own behavior over Firefly III, set a valid analytics tracker ID here.
|
||||
ANALYTICS_ID=
|
||||
|
||||
@@ -79,7 +98,6 @@ REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
CACHE_PREFIX=firefly
|
||||
SEARCH_RESULT_LIMIT=50
|
||||
EXCHANGE_RATE_SERVICE=fixerio
|
||||
PUSHER_KEY=
|
||||
PUSHER_SECRET=
|
||||
PUSHER_ID=
|
||||
@@ -87,4 +105,7 @@ DEMO_USERNAME=
|
||||
DEMO_PASSWORD=
|
||||
IS_DOCKER=false
|
||||
IS_SANDSTORM=false
|
||||
BUNQ_USE_SANDBOX=false
|
||||
IS_HEROKU=true
|
||||
MAILGUN_DOMAIN=
|
||||
MAILGUN_SECRET=
|
||||
|
@@ -13,10 +13,17 @@ SITE_OWNER=sandstorm@example.com
|
||||
# Change it to a string of exactly 32 chars or use command `php artisan key:generate` to generate it
|
||||
APP_KEY=SomeRandomStringOf32CharsExactly
|
||||
|
||||
# Change this value to your preferred time zone.
|
||||
# Example: Europe/Amsterdam
|
||||
TZ=UTC
|
||||
|
||||
# APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy.
|
||||
APP_URL=http://localhost
|
||||
TRUSTED_PROXIES=
|
||||
|
||||
# The log channel defines where your log entries go to.
|
||||
LOG_CHANNEL=syslog
|
||||
|
||||
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
|
||||
# If you use SQLite, set connection to `sqlite` and remove the database, username and password settings.
|
||||
DB_CONNECTION=mysql
|
||||
@@ -47,7 +54,8 @@ COOKIE_DOMAIN=
|
||||
COOKIE_SECURE=false
|
||||
|
||||
# If you want Firefly III to mail you, update these settings
|
||||
MAIL_DRIVER=smtp
|
||||
# For instructions, see: https://firefly-iii.readthedocs.io/en/latest/installation/mail.html
|
||||
MAIL_DRIVER=log
|
||||
MAIL_HOST=smtp.mailtrap.io
|
||||
MAIL_PORT=2525
|
||||
MAIL_FROM=changeme@example.com
|
||||
@@ -55,6 +63,12 @@ MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
|
||||
# Other mail drivers:
|
||||
MAILGUN_DOMAIN=
|
||||
MAILGUN_SECRET=
|
||||
MANDRILL_SECRET=
|
||||
SPARKPOST_SECRET=
|
||||
|
||||
# Firefly III can send you the following messages
|
||||
SEND_REGISTRATION_MAIL=true
|
||||
SEND_ERROR_MESSAGE=true
|
||||
@@ -62,6 +76,11 @@ SEND_ERROR_MESSAGE=true
|
||||
# Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places.
|
||||
MAPBOX_API_KEY=
|
||||
|
||||
# Set a Fixer IO API key here (see https://fixer.io) to enable live currency exchange rates.
|
||||
# Please note that this will only work for paid fixer.io accounts because they severly limited
|
||||
# the free API up to the point where you might as well offer nothing.
|
||||
FIXER_API_KEY=
|
||||
|
||||
# If you wish to track your own behavior over Firefly III, set a valid analytics tracker ID here.
|
||||
ANALYTICS_ID=
|
||||
|
||||
@@ -79,7 +98,6 @@ REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
CACHE_PREFIX=firefly
|
||||
SEARCH_RESULT_LIMIT=50
|
||||
EXCHANGE_RATE_SERVICE=fixerio
|
||||
PUSHER_KEY=
|
||||
PUSHER_SECRET=
|
||||
PUSHER_ID=
|
||||
@@ -87,4 +105,7 @@ DEMO_USERNAME=
|
||||
DEMO_PASSWORD=
|
||||
IS_DOCKER=false
|
||||
IS_SANDSTORM=true
|
||||
BUNQ_USE_SANDBOX=false
|
||||
IS_HEROKU=false
|
||||
MAILGUN_DOMAIN=
|
||||
MAILGUN_SECRET=
|
||||
|
95
.env.testing
95
.env.testing
@@ -1,32 +1,55 @@
|
||||
# You can leave this on "local". If you change it to production most console commands will ask for extra confirmation.
|
||||
# Never set it to "testing".
|
||||
APP_ENV=testing
|
||||
|
||||
# Set to true if you want to see debug information in error screens.
|
||||
APP_DEBUG=true
|
||||
APP_NAME=FireflyIII
|
||||
|
||||
# This should be your email address
|
||||
SITE_OWNER=thegrumpydictator+testing@gmail.com
|
||||
|
||||
# The encryption key for your database and sessions. Keep this very secure.
|
||||
# If you generate a new one all existing data must be considered LOST.
|
||||
# Change it to a string of exactly 32 chars or use command `php artisan key:generate` to generate it
|
||||
APP_KEY=TestTestTestTestTestTestTestTest
|
||||
APP_LOG=daily
|
||||
APP_LOG_LEVEL=debug
|
||||
|
||||
# Change this value to your preferred time zone.
|
||||
# Example: Europe/Amsterdam
|
||||
TZ=Europe/Amsterdam
|
||||
|
||||
# APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy.
|
||||
APP_URL=http://localhost
|
||||
TRUSTED_PROXIES=
|
||||
|
||||
DB_CONNECTION=sqlite
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
#DB_DATABASE=firefly
|
||||
DB_USERNAME=homestead
|
||||
DB_PASSWORD=
|
||||
# The log channel defines where your log entries go to.
|
||||
LOG_CHANNEL=dailytest
|
||||
|
||||
BROADCAST_DRIVER=log
|
||||
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
|
||||
# For other database types, please see the FAQ: http://firefly-iii.readthedocs.io/en/latest/support/faq.html
|
||||
DB_CONNECTION=sqlite
|
||||
|
||||
# 'daily' is the default logging mode giving you 5 daily rotated log files in /storage/logs/.
|
||||
# Several other options exist. You can use 'single' for one big fat error log (not recommended).
|
||||
# Also available are 'syslog' and 'errorlog' which will log to the system itself.
|
||||
APP_LOG=daily
|
||||
|
||||
# Log level. You can set this from least severe to most severe:
|
||||
# debug, info, notice, warning, error, critical, alert, emergency
|
||||
# If you set it to debug your logs will grow large, and fast. If you set it to emergency probably
|
||||
# nothing will get logged, ever.
|
||||
APP_LOG_LEVEL=debug
|
||||
|
||||
# If you're looking for performance improvements, you could install memcached.
|
||||
CACHE_DRIVER=file
|
||||
SESSION_DRIVER=file
|
||||
QUEUE_DRIVER=sync
|
||||
|
||||
# Cookie settings. Should not be necessary to change these.
|
||||
COOKIE_PATH="/"
|
||||
COOKIE_DOMAIN=
|
||||
COOKIE_SECURE=false
|
||||
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
# If you want Firefly III to mail you, update these settings
|
||||
# For instructions, see: https://firefly-iii.readthedocs.io/en/latest/installation/mail.html
|
||||
MAIL_DRIVER=log
|
||||
MAIL_HOST=smtp.mailtrap.io
|
||||
MAIL_PORT=2525
|
||||
@@ -35,26 +58,46 @@ MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
|
||||
SEND_REGISTRATION_MAIL=true
|
||||
SEND_ERROR_MESSAGE=false
|
||||
# Other mail drivers:
|
||||
MAILGUN_DOMAIN=
|
||||
MAILGUN_SECRET=
|
||||
MANDRILL_SECRET=
|
||||
SPARKPOST_SECRET=
|
||||
|
||||
CACHE_PREFIX=firefly
|
||||
|
||||
SEARCH_RESULT_LIMIT=50
|
||||
EXCHANGE_RATE_SERVICE=fixerio
|
||||
|
||||
# Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places.
|
||||
MAPBOX_API_KEY=
|
||||
ANALYTICS_ID=
|
||||
SITE_OWNER=mail@example.com
|
||||
USE_ENCRYPTION=true
|
||||
|
||||
# Set a Fixer IO API key here (see https://fixer.io) to enable live currency exchange rates.
|
||||
# Please note that this will only work for paid fixer.io accounts because they severly limited
|
||||
# the free API up to the point where you might as well offer nothing.
|
||||
FIXER_API_KEY=
|
||||
|
||||
# If you wish to track your own behavior over Firefly III, set a valid analytics tracker ID here.
|
||||
ANALYTICS_ID=
|
||||
|
||||
# Most parts of the database are encrypted by default, but you can turn this off if you want to.
|
||||
# This makes it easier to migrate your database. Not that some fields will never be decrypted.
|
||||
USE_ENCRYPTION=false
|
||||
|
||||
# Leave the following configuration vars as is.
|
||||
# Unless you like to tinker and know what you're doing.
|
||||
APP_NAME=FireflyIII
|
||||
BROADCAST_DRIVER=log
|
||||
QUEUE_DRIVER=sync
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
CACHE_PREFIX=firefly_tst
|
||||
SEARCH_RESULT_LIMIT=50
|
||||
PUSHER_KEY=
|
||||
PUSHER_SECRET=
|
||||
PUSHER_ID=
|
||||
|
||||
DEMO_USERNAME=
|
||||
DEMO_PASSWORD=
|
||||
|
||||
IS_DOCKER=false
|
||||
IS_SANDSTORM=false
|
||||
BUNQ_USE_SANDBOX=true
|
||||
IS_HEROKU=false
|
||||
MAILGUN_DOMAIN=
|
||||
MAILGUN_SECRET=
|
||||
|
22
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
Normal file
22
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help Firefly III improve
|
||||
|
||||
---
|
||||
|
||||
**Bug description**
|
||||
I am running Firefly III version x.x.x
|
||||
|
||||
(please give a clear and concise description of what the bug is)
|
||||
|
||||
**Steps to reproduce**
|
||||
What do you need to do to trigger this bug?
|
||||
|
||||
**Extra info**
|
||||
Please add extra info here, such as OS, browser, and the output from the /debug page of your Firefly III installation (click the version at the bottom).
|
||||
|
||||
**Bonus points**
|
||||
Earn bonus points by:
|
||||
|
||||
- Post a stacktrace from your log files
|
||||
- Add a screenshot
|
27
.github/ISSUE_TEMPLATE/Custom.md
vendored
Normal file
27
.github/ISSUE_TEMPLATE/Custom.md
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
name: I have a question or a problem
|
||||
about: Ask away!
|
||||
|
||||
---
|
||||
|
||||
I am running Firefly III version x.x.x
|
||||
|
||||
**Description**
|
||||
|
||||
|
||||
|
||||
**Steps to reproduce**
|
||||
(if relevant of course)
|
||||
|
||||
|
||||
|
||||
**Extra info**
|
||||
Please add extra info here, such as OS, browser, and the output from the `/debug`-page of your Firefly III installation (click the version at the bottom).
|
||||
|
||||
|
||||
|
||||
**Bonus points**
|
||||
Earn bonus points by:
|
||||
|
||||
- Add a screenshot
|
||||
- Replicate the problem on the demo site https://demo.firefly-iii.org/
|
21
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
Normal file
21
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea or feature for Firefly III
|
||||
|
||||
---
|
||||
|
||||
**Description**
|
||||
Please describe your feature request:
|
||||
|
||||
- I would like Firefly III to do X.
|
||||
- What if you would add feature Y?
|
||||
- Firefly III doesn't do Z.
|
||||
|
||||
**Solution**
|
||||
Describe what your feature would add to Firefly III.
|
||||
|
||||
**What are alternatives?**
|
||||
Please describe what alternatives currently exist.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
11
.github/issue_template.md
vendored
11
.github/issue_template.md
vendored
@@ -1,11 +0,0 @@
|
||||
I am running Firefly III version x.x.x
|
||||
|
||||
#### Description of my issue:
|
||||
|
||||
#### Steps to reproduce
|
||||
|
||||
(please include if this problem also exists on the demo site)
|
||||
|
||||
#### Other important details (log files, system info):
|
||||
|
||||
Please click the version number in the right corner of any Firefly III page to get debug information.
|
56
.github/stale.yml
vendored
Normal file
56
.github/stale.yml
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
# Configuration for probot-stale - https://github.com/probot/stale
|
||||
|
||||
# Number of days of inactivity before an Issue or Pull Request becomes stale
|
||||
daysUntilStale: 14
|
||||
|
||||
# Number of days of inactivity before a stale Issue or Pull Request is closed.
|
||||
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
|
||||
daysUntilClose: 7
|
||||
|
||||
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
|
||||
# - "[Status] Maybe Later"
|
||||
exemptLabels:
|
||||
- enhancement
|
||||
- feature
|
||||
- bug
|
||||
|
||||
# Set to true to ignore issues in a project (defaults to false)
|
||||
exemptProjects: false
|
||||
|
||||
# Set to true to ignore issues in a milestone (defaults to false)
|
||||
exemptMilestones: false
|
||||
|
||||
# Label to use when marking as stale
|
||||
staleLabel: stale
|
||||
|
||||
# Comment to post when marking as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
|
||||
# Comment to post when removing the stale label.
|
||||
# unmarkComment: >
|
||||
# Your comment here.
|
||||
|
||||
# Comment to post when closing a stale Issue or Pull Request.
|
||||
# closeComment: >
|
||||
# Your comment here.
|
||||
|
||||
# Limit the number of actions per hour, from 1-30. Default is 30
|
||||
limitPerRun: 30
|
||||
|
||||
# Limit to only `issues` or `pulls`
|
||||
# only: issues
|
||||
|
||||
# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
|
||||
# pulls:
|
||||
# daysUntilStale: 30
|
||||
# markComment: >
|
||||
# This pull request has been automatically marked as stale because it has not had
|
||||
# recent activity. It will be closed if no further activity occurs. Thank you
|
||||
# for your contributions.
|
||||
|
||||
# issues:
|
||||
# exemptLabels:
|
||||
# - confirmed
|
@@ -1,3 +1,136 @@
|
||||
# 4.7.5
|
||||
- A new feature called "recurring transactions" that will make Firefly III automatically create transactions for you.
|
||||
- New API end points for attachments, available budgets, budgets, budget limits, categories, configuration, currency exchange rates, journal links, link types, piggy banks, preferences, recurring transactions, rules, rule groups and tags.
|
||||
- Added support for YunoHost.
|
||||
- The 2FA secret is visible so you can type it into 2FA apps.
|
||||
- Bunq and Spectre imports will now ask to apply rules.
|
||||
- Sandstorm users can now make API keys.
|
||||
- Various typo's in the English translations. [issue 1493](https://github.com/firefly-iii/firefly-iii/issues/1493)
|
||||
- Bug where Spectre was never called [issue 1492](https://github.com/firefly-iii/firefly-iii/issues/1492)
|
||||
- Clear cache after journal is created through API [issue 1483](https://github.com/firefly-iii/firefly-iii/issues/1483)
|
||||
- Make sure docker directories exist [issue 1500](https://github.com/firefly-iii/firefly-iii/issues/1500)
|
||||
- Broken link to bill edit [issue 1505](https://github.com/firefly-iii/firefly-iii/issues/1505)
|
||||
- Several bugs in the editing of split transactions [issue 1509](https://github.com/firefly-iii/firefly-iii/issues/1509)
|
||||
- Import routine ignored formatting of several date fields [issue 1510](https://github.com/firefly-iii/firefly-iii/issues/1510)
|
||||
- Piggy bank events now show the correct currency [issue 1446](https://github.com/firefly-iii/firefly-iii/issues/1446)
|
||||
- Inactive accounts are no longer suggested [issue 1463](https://github.com/firefly-iii/firefly-iii/issues/1463)
|
||||
- Some income / expense charts are less confusing [issue 1518](https://github.com/firefly-iii/firefly-iii/issues/1518)
|
||||
- Validation bug in multi-currency create view [issue 1521](https://github.com/firefly-iii/firefly-iii/issues/1521)
|
||||
|
||||
# 4.7.4
|
||||
- [Issue 1409](https://github.com/firefly-iii/firefly-iii/issues/1409), add Indian Rupee and explain that users can do this themselves [issue 1413](https://github.com/firefly-iii/firefly-iii/issues/1413)
|
||||
- [Issue 1445](https://github.com/firefly-iii/firefly-iii/issues/1445), upgrade Curl in Docker image.
|
||||
- [Issue 1386](https://github.com/firefly-iii/firefly-iii/issues/1386), quick links to often used pages.
|
||||
- [Issue 1405](https://github.com/firefly-iii/firefly-iii/issues/1405), show proposed amount to piggy banks.
|
||||
- [Issue 1416](https://github.com/firefly-iii/firefly-iii/issues/1416), ability to delete lost attachments.
|
||||
- A completely rewritten import routine that can handle bunq (thanks everybody for testing!), CSV files and Spectre. Please make sure you read about this at http://bit.ly/FF3-new-import
|
||||
- [Issue 1392](https://github.com/firefly-iii/firefly-iii/issues/1392), explicitly mention rules are inactive (when they are).
|
||||
- [Issue 1406](https://github.com/firefly-iii/firefly-iii/issues/1406), bill conversion to rules will be smarter about the rules they create.
|
||||
- [Issue 1369](https://github.com/firefly-iii/firefly-iii/issues/1369), you can now properly order piggy banks again.
|
||||
- [Issue 1389](https://github.com/firefly-iii/firefly-iii/issues/1389), null-pointer in the import routine.
|
||||
- [Issue 1400](https://github.com/firefly-iii/firefly-iii/issues/1400), missing translation.
|
||||
- [Issue 1403](https://github.com/firefly-iii/firefly-iii/issues/1403), bill would always be marked as inactive in edit screen.
|
||||
- [Issue 1418](https://github.com/firefly-iii/firefly-iii/issues/1418), missing note text on bill page.
|
||||
- Export routine would break when encountering un-decryptable files.
|
||||
- [Issue 1425](https://github.com/firefly-iii/firefly-iii/issues/1425), empty fields when edit multiple transactions at once.
|
||||
- [Issue 1449](https://github.com/firefly-iii/firefly-iii/issues/1449), bad calculations in "budget left to spend" view.
|
||||
- [Issue 1451](https://github.com/firefly-iii/firefly-iii/issues/1451), same but in another view.
|
||||
- [Issue 1453](https://github.com/firefly-iii/firefly-iii/issues/1453), same as [issue 1403](https://github.com/firefly-iii/firefly-iii/issues/1403).
|
||||
- [Issue 1455](https://github.com/firefly-iii/firefly-iii/issues/1455), could add income to a budget.
|
||||
- [Issue 1442](https://github.com/firefly-iii/firefly-iii/issues/1442), issues with editing a split deposit.
|
||||
- [Issue 1452](https://github.com/firefly-iii/firefly-iii/issues/1452), date range problems with tags.
|
||||
- [Issue 1458](https://github.com/firefly-iii/firefly-iii/issues/1458), same for transactions.
|
||||
- [Issue 1415](https://github.com/firefly-iii/firefly-iii/issues/1415), will email you when OAuth2 keys are generated.
|
||||
|
||||
# 4.7.3.2
|
||||
- Forgot to increase the version number :(.
|
||||
|
||||
# 4.7.3.1
|
||||
- Fixed a critical bug where the rules-engine would fire inadvertently.
|
||||
|
||||
# 4.7.3
|
||||
- Currency added to API
|
||||
- Firfely III will also generate a cash wallet for new users.
|
||||
- Can now reset Spectre and bunq settings
|
||||
- Docker file has a time zone
|
||||
- Allow database connection to be configured in Docker file
|
||||
- Can now view and edit attachments in edit-screen
|
||||
- User can visit hidden `/attachments` page
|
||||
- [Issue 1356](https://github.com/firefly-iii/firefly-iii/issues/1356): Budgets will show the remaining amount per day
|
||||
- [Issue 1367](https://github.com/firefly-iii/firefly-iii/issues/1367): Rules now come in strict and non-strict mode.
|
||||
- Added a security.txt
|
||||
- More support for trusted proxies
|
||||
- Improved edit routine for split transactions.
|
||||
- Upgrade routine can handle `proc_close` being disabled.
|
||||
- Bills now use rules to match transactions, making it more flexible.
|
||||
- [Issue 1328](https://github.com/firefly-iii/firefly-iii/issues/1328): piggy banks no have a more useful chart.
|
||||
- Spectre API upgraded to v4
|
||||
- Move to MariaDB ([issue 1366](https://github.com/firefly-iii/firefly-iii/issues/1366))
|
||||
- Piggy banks take currency from parent account ([issue 1334](https://github.com/firefly-iii/firefly-iii/issues/1334))
|
||||
- [Issue 1341](https://github.com/firefly-iii/firefly-iii/issues/1341): Removed depricated command from dockerfile
|
||||
- Several issues with docker image ([issue 1320](https://github.com/firefly-iii/firefly-iii/issues/1320), [issue 1382](https://github.com/firefly-iii/firefly-iii/issues/1382)).
|
||||
- Fix giant tags and division by zero ([issue 1325](https://github.com/firefly-iii/firefly-iii/issues/1325) and others)
|
||||
- Several issues with bunq import ([issue 1352](https://github.com/firefly-iii/firefly-iii/issues/1352), [issue 1330](https://github.com/firefly-iii/firefly-iii/issues/1330), [issue 1378](https://github.com/firefly-iii/firefly-iii/issues/1378), [issue 1380](https://github.com/firefly-iii/firefly-iii/issues/1380))
|
||||
- [Issue 1246](https://github.com/firefly-iii/firefly-iii/issues/1246): date picker is internationalised
|
||||
- [Issue 1327](https://github.com/firefly-iii/firefly-iii/issues/1327): fix formattting issues in piggy banks
|
||||
- [Issue 1348](https://github.com/firefly-iii/firefly-iii/issues/1348): 500 error in API
|
||||
- [Issue 1349](https://github.com/firefly-iii/firefly-iii/issues/1349): Errors in import routine
|
||||
- Several fixes for (multi-currency) reconciliation ([issue 1336](https://github.com/firefly-iii/firefly-iii/issues/1336), [issue 1363](https://github.com/firefly-iii/firefly-iii/issues/1363))
|
||||
- [Issue 1353](https://github.com/firefly-iii/firefly-iii/issues/1353): return NULL values in range-indicator
|
||||
- Bug in split transaction edit routine
|
||||
- Piggy bank percentage was very specific.
|
||||
- Logging in Slack is easier to config.
|
||||
- [Issue 1312](https://github.com/firefly-iii/firefly-iii/issues/1312) Import broken for ING accounts
|
||||
- [Issue 1313](https://github.com/firefly-iii/firefly-iii/issues/1313) Error when creating new asset account
|
||||
- [Issue 1317](https://github.com/firefly-iii/firefly-iii/issues/1317) Forgot an include :(
|
||||
- Null pointer exception in transaction overview.
|
||||
- Installations running in subdirs were incapable of creating OAuth tokens.
|
||||
- OAuth keys were not created in all cases.
|
||||
|
||||
# 4.7.2
|
||||
- [Issue 1123](https://github.com/firefly-iii/firefly-iii/issues/1123) First browser based update routine.
|
||||
- Add support for Italian.
|
||||
- [Issue 1232](https://github.com/firefly-iii/firefly-iii/issues/1232) Allow user to specify Docker database port.
|
||||
- [Issue 1197](https://github.com/firefly-iii/firefly-iii/issues/1197) Beter account list overview
|
||||
- [Issue 1202](https://github.com/firefly-iii/firefly-iii/issues/1202) Some budgetary warnings
|
||||
- [Issue 1284](https://github.com/firefly-iii/firefly-iii/issues/1284) Experimental support for bunq import
|
||||
- [Issue 1248](https://github.com/firefly-iii/firefly-iii/issues/1248) Ability to import BIC, ability to import SEPA fields.
|
||||
- [Issue 1102](https://github.com/firefly-iii/firefly-iii/issues/1102) Summary line for bills
|
||||
- More info to debug page.
|
||||
- [Issue 1186](https://github.com/firefly-iii/firefly-iii/issues/1186) You can see the latest account balance in CRUD forms
|
||||
- Add Kubernetes YAML files, kindly created by a FF3 user.
|
||||
- [Issue 1244](https://github.com/firefly-iii/firefly-iii/issues/1244) Better line for "today" marker and add it to other chart as well ([issue 1214](https://github.com/firefly-iii/firefly-iii/issues/1214))
|
||||
- [Issue 1219](https://github.com/firefly-iii/firefly-iii/issues/1219) Languages in dropdown
|
||||
- [Issue 1189](https://github.com/firefly-iii/firefly-iii/issues/1189) Inactive accounts get removed from net worth
|
||||
- [Issue 1220](https://github.com/firefly-iii/firefly-iii/issues/1220) Attachment description and notes migrated to just "notes".
|
||||
- [Issue 1236](https://github.com/firefly-iii/firefly-iii/issues/1236) Multi currency balance box
|
||||
- [Issue 1240](https://github.com/firefly-iii/firefly-iii/issues/1240) Better overview for accounts.
|
||||
- [Issue 1292](https://github.com/firefly-iii/firefly-iii/issues/1292) Removed some charts from the "all"-overview of budgets and categories
|
||||
- [Issue 1245](https://github.com/firefly-iii/firefly-iii/issues/1245) Improved recognition of IBANs
|
||||
- Improved import routine.
|
||||
- Update notifier will wait three days before notifying users.
|
||||
- [Issue 1300](https://github.com/firefly-iii/firefly-iii/issues/1300) Virtual balance of credit cards does not count for net worth
|
||||
- [Issue 1247](https://github.com/firefly-iii/firefly-iii/issues/1247) Can now see overspent amount
|
||||
- [Issue 1221](https://github.com/firefly-iii/firefly-iii/issues/1221) Upgrade to Laravel 5.6
|
||||
- [Issue 1187](https://github.com/firefly-iii/firefly-iii/issues/1187) Updated the password verifier to use Troy Hunt's new API
|
||||
- Revenue chart is now on frontpage permanently
|
||||
- [Issue 1153](https://github.com/firefly-iii/firefly-iii/issues/1153) 2FA settings are in your profile now
|
||||
- [Issue 1227](https://github.com/firefly-iii/firefly-iii/issues/1227) Can set the timezone in config or in Docker
|
||||
- [Issue 1294](https://github.com/firefly-iii/firefly-iii/issues/1294) Ability to link a transaction to itself
|
||||
- Correct reference to journal description in split form.
|
||||
- [Issue 1234](https://github.com/firefly-iii/firefly-iii/issues/1234) Fix budget page issues in SQLite
|
||||
- [Issue 1262](https://github.com/firefly-iii/firefly-iii/issues/1262) Can now use double and epty headers in CSV files
|
||||
- [Issue 1258](https://github.com/firefly-iii/firefly-iii/issues/1258) Fixed a possible date mismatch in piggy banks
|
||||
- [Issue 1283](https://github.com/firefly-iii/firefly-iii/issues/1283) Bulk delete was broken
|
||||
- [Issue 1293](https://github.com/firefly-iii/firefly-iii/issues/1293) Layout problem with notes
|
||||
- [Issue 1257](https://github.com/firefly-iii/firefly-iii/issues/1257) Improve transaction lists query count
|
||||
- [Issue 1291](https://github.com/firefly-iii/firefly-iii/issues/1291) Fixer IO problems
|
||||
- [Issue 1239](https://github.com/firefly-iii/firefly-iii/issues/1239) Could not edit expense or revenue accounts ([issue 1298](https://github.com/firefly-iii/firefly-iii/issues/1298))
|
||||
- [Issue 1297](https://github.com/firefly-iii/firefly-iii/issues/1297) Could not convert to withdrawal
|
||||
- [Issue 1226](https://github.com/firefly-iii/firefly-iii/issues/1226) Category overview in default report shows no income.
|
||||
- Various other bugs and problems ([issue 1198](https://github.com/firefly-iii/firefly-iii/issues/1198), [issue 1213](https://github.com/firefly-iii/firefly-iii/issues/1213), [issue 1237](https://github.com/firefly-iii/firefly-iii/issues/1237), [issue 1238](https://github.com/firefly-iii/firefly-iii/issues/1238), [issue 1199](https://github.com/firefly-iii/firefly-iii/issues/1199), [issue 1200](https://github.com/firefly-iii/firefly-iii/issues/1200))
|
||||
- Fixed an issue with token validation on the command line.
|
||||
|
||||
# 4.7.1
|
||||
- A brand new API. Read about it in the [documentation](http://firefly-iii.readthedocs.io/en/latest/).
|
||||
- Add support for Spanish. [issue 1194](https://github.com/firefly-iii/firefly-iii/issues/1194)
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -15,8 +15,8 @@ const pkgdef :Spk.PackageDefinition = (
|
||||
|
||||
manifest = (
|
||||
appTitle = (defaultText = "Firefly III"),
|
||||
appVersion = 9,
|
||||
appMarketingVersion = (defaultText = "4.7.1"),
|
||||
appVersion = 14,
|
||||
appMarketingVersion = (defaultText = "4.7.5"),
|
||||
|
||||
actions = [
|
||||
# Define your "new document" handlers here.
|
||||
@@ -65,9 +65,9 @@ const pkgdef :Spk.PackageDefinition = (
|
||||
# Sizes are given in device-independent pixels, so if you took these
|
||||
# screenshots on a Retina-style high DPI screen, divide each dimension by two.
|
||||
|
||||
(width = 1291, height = 800, png = embed "screenshots/screenshot-1.png"),
|
||||
(width = 1291, height = 800, png = embed "screenshots/screenshot-2.png"),
|
||||
(width = 1291, height = 800, png = embed "screenshots/screenshot-3.png"),
|
||||
(width = 1290, height = 800, png = embed "screenshots/screenshot-1.png"),
|
||||
(width = 1290, height = 800, png = embed "screenshots/screenshot-2.png"),
|
||||
(width = 1290, height = 800, png = embed "screenshots/screenshot-3.png"),
|
||||
|
||||
],
|
||||
changeLog = (defaultText = embed "changelog.md"),
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 173 KiB |
Binary file not shown.
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 171 KiB |
Binary file not shown.
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 163 KiB |
@@ -14,12 +14,17 @@ apt-get install -y python-software-properties software-properties-common
|
||||
|
||||
# install all languages
|
||||
sed -i 's/# de_DE.UTF-8 UTF-8/de_DE.UTF-8 UTF-8/g' /etc/locale.gen
|
||||
|
||||
sed -i 's/# es_ES.UTF-8 UTF-8/es_ES.UTF-8 UTF-8/g' /etc/locale.gen
|
||||
sed -i 's/# fr_FR.UTF-8 UTF-8/fr_FR.UTF-8 UTF-8/g' /etc/locale.gen
|
||||
sed -i 's/# id_ID.UTF-8 UTF-8/id_ID.UTF-8 UTF-8/g' /etc/locale.gen
|
||||
sed -i 's/# it_IT.UTF-8 UTF-8/it_IT.UTF-8 UTF-8/g' /etc/locale.gen
|
||||
sed -i 's/# nl_NL.UTF-8 UTF-8/nl_NL.UTF-8 UTF-8/g' /etc/locale.gen
|
||||
sed -i 's/# pl_PL.UTF-8 UTF-8/pl_PL.UTF-8 UTF-8/g' /etc/locale.gen
|
||||
sed -i 's/# pt_BR.UTF-8 UTF-8/pt_BR.UTF-8 UTF-8/g' /etc/locale.gen
|
||||
sed -i 's/# ru_RU.UTF-8 UTF-8/ru_RU.UTF-8 UTF-8/g' /etc/locale.gen
|
||||
sed -i 's/# tr_TR.UTF-8 UTF-8/tr_TR.UTF-8 UTF-8/g' /etc/locale.gen
|
||||
|
||||
dpkg-reconfigure --frontend=noninteractive locales
|
||||
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
language: php
|
||||
php:
|
||||
- 7.1
|
||||
- 7.1.18
|
||||
|
||||
cache:
|
||||
directories:
|
||||
@@ -12,21 +12,18 @@ install:
|
||||
- composer update --no-scripts
|
||||
- cp .env.testing .env
|
||||
- php artisan clear-compiled
|
||||
- php artisan optimize
|
||||
- php artisan env
|
||||
- cp .env.testing .env
|
||||
- wget -q https://github.com/firefly-iii/test-data/raw/master/storage/database.sqlite -O storage/database/database.sqlite
|
||||
- mkdir -p build/logs
|
||||
|
||||
script:
|
||||
- phpunit -c phpunit.coverage.xml
|
||||
- ./vendor/bin/phpunit -c phpunit.coverage.xml
|
||||
|
||||
after_success:
|
||||
- travis_retry php vendor/bin/php-coveralls -x storage/build/clover-all.xml
|
||||
- bash <(curl -s https://codecov.io/bash) -f storage/build/clover-all.xml
|
||||
|
||||
# safelist
|
||||
branches:
|
||||
only:
|
||||
- develop
|
||||
- master
|
||||
- master
|
||||
|
48
Dockerfile
48
Dockerfile
@@ -3,6 +3,8 @@ FROM php:7.1-apache
|
||||
|
||||
# set working dir
|
||||
ENV FIREFLY_PATH /var/www/firefly-iii
|
||||
ENV CURL_VERSION 7.60.0
|
||||
ENV OPENSSL_VERSION 1.1.1-pre6
|
||||
WORKDIR $FIREFLY_PATH
|
||||
ADD . $FIREFLY_PATH
|
||||
|
||||
@@ -11,7 +13,8 @@ RUN apt-get update -y && \
|
||||
apt-get install -y --no-install-recommends libcurl4-openssl-dev \
|
||||
zlib1g-dev \
|
||||
libjpeg62-turbo-dev \
|
||||
libpng12-dev \
|
||||
wget \
|
||||
libpng-dev \
|
||||
libicu-dev \
|
||||
libedit-dev \
|
||||
libtidy-dev \
|
||||
@@ -20,18 +23,46 @@ RUN apt-get update -y && \
|
||||
libpq-dev \
|
||||
libbz2-dev \
|
||||
gettext-base \
|
||||
cron \
|
||||
locales && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Setup the Composer installer
|
||||
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
||||
|
||||
# Install latest curl
|
||||
RUN cd /tmp && \
|
||||
wget https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz && \
|
||||
tar -xvf openssl-${OPENSSL_VERSION}.tar.gz && \
|
||||
cd openssl-${OPENSSL_VERSION} && \
|
||||
./config && \
|
||||
make && \
|
||||
make install
|
||||
|
||||
RUN cd /tmp && \
|
||||
wget https://curl.haxx.se/download/curl-${CURL_VERSION}.tar.gz && \
|
||||
tar -xvf curl-${CURL_VERSION}.tar.gz && \
|
||||
cd curl-${CURL_VERSION} && \
|
||||
./configure --with-ssl && \
|
||||
make && \
|
||||
make install
|
||||
|
||||
|
||||
# Create the log file to be able to run tail
|
||||
RUN touch /var/log/cron.log
|
||||
|
||||
# Setup cron job
|
||||
RUN (crontab -l ; echo "* * * * * root $FIREFLY_PATH/artisan schedule:run >> /var/log/cron.log") | crontab
|
||||
|
||||
# Install PHP exentions.
|
||||
RUN docker-php-ext-install -j$(nproc) curl gd intl json readline tidy zip bcmath xml mbstring pdo_sqlite pdo_mysql bz2 pdo_pgsql
|
||||
|
||||
# Generate locales supported by Firefly III
|
||||
RUN echo "de_DE.UTF-8 UTF-8\nen_US.UTF-8 UTF-8\nfr_FR.UTF-8 UTF-8\nid_ID.UTF-8 UTF-8\nnl_NL.UTF-8 UTF-8\npl_PL.UTF-8 UTF-8" > /etc/locale.gen && locale-gen
|
||||
RUN echo "de_DE.UTF-8 UTF-8\nen_US.UTF-8 UTF-8\nes_ES.UTF-8 UTF-8\nfr_FR.UTF-8 UTF-8\nid_ID.UTF-8 UTF-8\nit_IT.UTF-8 UTF-8\nnl_NL.UTF-8 UTF-8\npl_PL.UTF-8 UTF-8pt_BR.UTF-8 UTF-8ru_RU.UTF-8 UTF-8\ntr_TR.UTF-8 UTF-8\n\n" > /etc/locale.gen && locale-gen
|
||||
|
||||
# copy Apache config to correct spot.
|
||||
COPY ./docker/apache2.conf /etc/apache2/apache2.conf
|
||||
COPY ./.deploy/docker/apache2.conf /etc/apache2/apache2.conf
|
||||
|
||||
# Enable apache mod rewrite..
|
||||
RUN a2enmod rewrite
|
||||
@@ -42,11 +73,8 @@ RUN a2enmod ssl
|
||||
# Create volumes for several directories:
|
||||
VOLUME $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload
|
||||
|
||||
# Setup the Composer installer
|
||||
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
||||
|
||||
# Enable default site (Firefly III)
|
||||
COPY ./docker/apache-firefly.conf /etc/apache2/sites-available/000-default.conf
|
||||
COPY ./.deploy/docker/apache-firefly.conf /etc/apache2/sites-available/000-default.conf
|
||||
|
||||
# Make sure we own Firefly III directory
|
||||
RUN chown -R www-data:www-data /var/www && chmod -R 775 $FIREFLY_PATH/storage
|
||||
@@ -57,5 +85,9 @@ RUN composer install --prefer-dist --no-dev --no-scripts --no-suggest
|
||||
# Expose port 80
|
||||
EXPOSE 80
|
||||
|
||||
# Run the command on container startup
|
||||
CMD cron
|
||||
|
||||
# Run entrypoint thing
|
||||
ENTRYPOINT ["docker/entrypoint.sh"]
|
||||
ENTRYPOINT [".deploy/docker/entrypoint.sh"]
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* AboutController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -25,37 +26,30 @@ namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use DB;
|
||||
use FireflyIII\Transformers\UserTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
|
||||
/**
|
||||
* Returns basic information about this installation.
|
||||
*
|
||||
* Class AboutController
|
||||
*/
|
||||
class AboutController extends Controller
|
||||
{
|
||||
/**
|
||||
* AccountController constructor.
|
||||
* Returns system information.
|
||||
*
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function about()
|
||||
public function about(): JsonResponse
|
||||
{
|
||||
$search = ['~', '#'];
|
||||
$replace = ['\~', '# '];
|
||||
$phpVersion = str_replace($search, $replace, PHP_VERSION);
|
||||
$phpOs = str_replace($search, $replace, php_uname());
|
||||
$phpOs = str_replace($search, $replace, PHP_OS);
|
||||
$currentDriver = DB::getDriverName();
|
||||
$data
|
||||
= [
|
||||
@@ -64,18 +58,19 @@ class AboutController extends Controller
|
||||
'php_version' => $phpVersion,
|
||||
'os' => $phpOs,
|
||||
'driver' => $currentDriver,
|
||||
|
||||
];
|
||||
|
||||
return response()->json(['data' => $data], 200)->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about the user.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function user(Request $request)
|
||||
public function user(Request $request): JsonResponse
|
||||
{
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
@@ -84,5 +79,4 @@ class AboutController extends Controller
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* AccountController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -29,6 +30,8 @@ use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Transformers\AccountTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use League\Fractal\Manager;
|
||||
@@ -36,14 +39,12 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
use Preferences;
|
||||
|
||||
/**
|
||||
* Class AccountController
|
||||
*/
|
||||
class AccountController extends Controller
|
||||
{
|
||||
|
||||
/** @var CurrencyRepositoryInterface */
|
||||
private $currencyRepository;
|
||||
/** @var AccountRepositoryInterface */
|
||||
@@ -51,20 +52,20 @@ class AccountController extends Controller
|
||||
|
||||
/**
|
||||
* AccountController constructor.
|
||||
*
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var AccountRepositoryInterface repository */
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
// @var AccountRepositoryInterface repository
|
||||
$this->repository = app(AccountRepositoryInterface::class);
|
||||
$this->repository->setUser(auth()->user());
|
||||
$this->repository->setUser($user);
|
||||
|
||||
$this->currencyRepository = app(CurrencyRepositoryInterface::class);
|
||||
$this->currencyRepository->setUser(auth()->user());
|
||||
$this->currencyRepository->setUser($user);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
@@ -74,11 +75,11 @@ class AccountController extends Controller
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \FireflyIII\Models\Account $account
|
||||
* @param \FireflyIII\Models\Account $account
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function delete(Account $account)
|
||||
public function delete(Account $account): JsonResponse
|
||||
{
|
||||
$this->repository->destroy($account, null);
|
||||
|
||||
@@ -90,21 +91,21 @@ class AccountController extends Controller
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
// create some objects:
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
|
||||
// read type from URI
|
||||
$type = $request->get('type') ?? 'all';
|
||||
$this->parameters->set('type', $type);
|
||||
|
||||
// types to get, page size:
|
||||
$types = $this->mapTypes($this->parameters->get('type'));
|
||||
$pageSize = intval(Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data);
|
||||
$types = $this->mapTypes($this->parameters->get('type'));
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
// get list of accounts. Count it and split it.
|
||||
$collection = $this->repository->getAccountsByType($types);
|
||||
@@ -129,9 +130,9 @@ class AccountController extends Controller
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function show(Request $request, Account $account)
|
||||
public function show(Request $request, Account $account): JsonResponse
|
||||
{
|
||||
$manager = new Manager();
|
||||
$manager = new Manager;
|
||||
|
||||
// add include parameter:
|
||||
$include = $request->get('include') ?? '';
|
||||
@@ -149,23 +150,22 @@ class AccountController extends Controller
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function store(AccountRequest $request)
|
||||
public function store(AccountRequest $request): JsonResponse
|
||||
{
|
||||
$data = $request->getAll();
|
||||
// if currency ID is 0, find the currency by the code:
|
||||
if ($data['currency_id'] === 0) {
|
||||
if (0 === $data['currency_id']) {
|
||||
$currency = $this->currencyRepository->findByCodeNull($data['currency_code']);
|
||||
$data['currency_id'] = is_null($currency) ? 0 : $currency->id;
|
||||
$data['currency_id'] = null === $currency ? 0 : $currency->id;
|
||||
}
|
||||
$account = $this->repository->store($data);
|
||||
$manager = new Manager();
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($account, new AccountTransformer($this->parameters), 'accounts');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -176,18 +176,18 @@ class AccountController extends Controller
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function update(AccountRequest $request, Account $account)
|
||||
public function update(AccountRequest $request, Account $account): JsonResponse
|
||||
{
|
||||
$data = $request->getAll();
|
||||
// if currency ID is 0, find the currency by the code:
|
||||
if ($data['currency_id'] === 0) {
|
||||
if (0 === $data['currency_id']) {
|
||||
$currency = $this->currencyRepository->findByCodeNull($data['currency_code']);
|
||||
$data['currency_id'] = is_null($currency) ? 0 : $currency->id;
|
||||
$data['currency_id'] = null === $currency ? 0 : $currency->id;
|
||||
}
|
||||
// set correct type:
|
||||
$data['type'] = config('firefly.shortNamesByFullName.' . $account->accountType->type);
|
||||
$this->repository->update($account, $data);
|
||||
$manager = new Manager();
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
@@ -260,4 +260,4 @@ class AccountController extends Controller
|
||||
|
||||
return $types['all']; // @codeCoverageIgnore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
229
app/Api/V1/Controllers/AttachmentController.php
Normal file
229
app/Api/V1/Controllers/AttachmentController.php
Normal file
@@ -0,0 +1,229 @@
|
||||
<?php
|
||||
/**
|
||||
* AttachmentController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Api\V1\Requests\AttachmentRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
|
||||
use FireflyIII\Transformers\AttachmentTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response as LaravelResponse;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
/**
|
||||
* Class AttachmentController
|
||||
*/
|
||||
class AttachmentController extends Controller
|
||||
{
|
||||
/** @var AttachmentRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* AccountController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$this->repository = app(AttachmentRepositoryInterface::class);
|
||||
$this->repository->setUser($user);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function delete(Attachment $attachment): JsonResponse
|
||||
{
|
||||
$this->repository->destroy($attachment);
|
||||
|
||||
return response()->json([], 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
* @return LaravelResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function download(Attachment $attachment): LaravelResponse
|
||||
{
|
||||
if ($attachment->uploaded === false) {
|
||||
throw new FireflyException('No file has been uploaded for this attachment (yet).');
|
||||
}
|
||||
if ($this->repository->exists($attachment)) {
|
||||
$content = $this->repository->getContent($attachment);
|
||||
$quoted = sprintf('"%s"', addcslashes(basename($attachment->filename), '"\\'));
|
||||
|
||||
/** @var LaravelResponse $response */
|
||||
$response = response($content, 200);
|
||||
$response
|
||||
->header('Content-Description', 'File Transfer')
|
||||
->header('Content-Type', 'application/octet-stream')
|
||||
->header('Content-Disposition', 'attachment; filename=' . $quoted)
|
||||
->header('Content-Transfer-Encoding', 'binary')
|
||||
->header('Connection', 'Keep-Alive')
|
||||
->header('Expires', '0')
|
||||
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
|
||||
->header('Pragma', 'public')
|
||||
->header('Content-Length', \strlen($content));
|
||||
|
||||
return $response;
|
||||
}
|
||||
throw new FireflyException('Could not find the indicated attachment. The file is no longer there.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
// create some objects:
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
|
||||
// types to get, page size:
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
// get list of accounts. Count it and split it.
|
||||
$collection = $this->repository->get();
|
||||
$count = $collection->count();
|
||||
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.attachments.index') . $this->buildParams());
|
||||
|
||||
// present to user.
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$resource = new FractalCollection($attachments, new AttachmentTransformer($this->parameters), 'attachments');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function show(Request $request, Attachment $attachment): JsonResponse
|
||||
{
|
||||
$manager = new Manager;
|
||||
|
||||
// add include parameter:
|
||||
$include = $request->get('include') ?? '';
|
||||
$manager->parseIncludes($include);
|
||||
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$resource = new Item($attachment, new AttachmentTransformer($this->parameters), 'attachments');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param AttachmentRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function store(AttachmentRequest $request): JsonResponse
|
||||
{
|
||||
$data = $request->getAll();
|
||||
$attachment = $this->repository->store($data);
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$resource = new Item($attachment, new AttachmentTransformer($this->parameters), 'attachments');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param AttachmentRequest $request
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function update(AttachmentRequest $request, Attachment $attachment): JsonResponse
|
||||
{
|
||||
$data = $request->getAll();
|
||||
$this->repository->update($attachment, $data);
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($attachment, new AttachmentTransformer($this->parameters), 'attachments');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function upload(Request $request, Attachment $attachment): JsonResponse
|
||||
{
|
||||
/** @var AttachmentHelperInterface $helper */
|
||||
$helper = app(AttachmentHelperInterface::class);
|
||||
$body = $request->getContent();
|
||||
$helper->saveAttachmentFromApi($attachment, $body);
|
||||
|
||||
return response()->json([], 204);
|
||||
}
|
||||
|
||||
}
|
183
app/Api/V1/Controllers/AvailableBudgetController.php
Normal file
183
app/Api/V1/Controllers/AvailableBudgetController.php
Normal file
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
/**
|
||||
* AvailableBudgetController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Api\V1\Requests\AvailableBudgetRequest;
|
||||
use FireflyIII\Models\AvailableBudget;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Transformers\AvailableBudgetTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
/**
|
||||
* Class AvailableBudgetController
|
||||
*/
|
||||
class AvailableBudgetController extends Controller
|
||||
{
|
||||
/** @var CurrencyRepositoryInterface */
|
||||
private $currencyRepository;
|
||||
/** @var BudgetRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* AccountController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$this->repository = app(BudgetRepositoryInterface::class);
|
||||
$this->currencyRepository = app(CurrencyRepositoryInterface::class);
|
||||
$this->repository->setUser($user);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param AvailableBudget $availableBudget
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function delete(AvailableBudget $availableBudget): JsonResponse
|
||||
{
|
||||
$this->repository->destroyAvailableBudget($availableBudget);
|
||||
|
||||
return response()->json([], 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
// create some objects:
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
|
||||
// types to get, page size:
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
// get list of available budgets. Count it and split it.
|
||||
$collection = $this->repository->getAvailableBudgets();
|
||||
$count = $collection->count();
|
||||
$availableBudgets = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($availableBudgets, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.available_budgets.index') . $this->buildParams());
|
||||
|
||||
// present to user.
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$resource = new FractalCollection($availableBudgets, new AvailableBudgetTransformer($this->parameters), 'available_budgets');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param AvailableBudget $availableBudget
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function show(Request $request, AvailableBudget $availableBudget): JsonResponse
|
||||
{
|
||||
|
||||
$manager = new Manager;
|
||||
|
||||
// add include parameter:
|
||||
$include = $request->get('include') ?? '';
|
||||
$manager->parseIncludes($include);
|
||||
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$resource = new Item($availableBudget, new AvailableBudgetTransformer($this->parameters), 'available_budgets');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param AvailableBudgetRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function store(AvailableBudgetRequest $request): JsonResponse
|
||||
{
|
||||
$data = $request->getAll();
|
||||
$currency = $this->currencyRepository->findNull($data['transaction_currency_id']);
|
||||
$availableBudget = $this->repository->setAvailableBudget($currency, $data['start_date'], $data['end_date'], $data['amount']);
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($availableBudget, new AvailableBudgetTransformer($this->parameters), 'available_budgets');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param AvailableBudgetRequest $request
|
||||
* @param AvailableBudget $availableBudget
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function update(AvailableBudgetRequest $request, AvailableBudget $availableBudget): JsonResponse
|
||||
{
|
||||
$data = $request->getAll();
|
||||
$this->repository->updateAvailableBudget($availableBudget, $data);
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($availableBudget, new AvailableBudgetTransformer($this->parameters), 'available_budgets');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
}
|
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* BillController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
@@ -27,6 +29,7 @@ use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Transformers\BillTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Collection;
|
||||
use League\Fractal\Manager;
|
||||
@@ -34,7 +37,6 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
use Preferences;
|
||||
|
||||
/**
|
||||
* Class BillController
|
||||
@@ -46,8 +48,6 @@ class BillController extends Controller
|
||||
|
||||
/**
|
||||
* BillController constructor.
|
||||
*
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
@@ -66,11 +66,11 @@ class BillController extends Controller
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \FireflyIII\Models\Bill $bill
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function delete(Bill $bill)
|
||||
public function delete(Bill $bill): JsonResponse
|
||||
{
|
||||
$this->repository->destroy($bill);
|
||||
|
||||
@@ -82,11 +82,11 @@ class BillController extends Controller
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$pageSize = intval(Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data);
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
$paginator = $this->repository->getPaginator($pageSize);
|
||||
/** @var Collection $bills */
|
||||
$bills = $paginator->getCollection();
|
||||
@@ -106,9 +106,9 @@ class BillController extends Controller
|
||||
* @param Request $request
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function show(Request $request, Bill $bill)
|
||||
public function show(Request $request, Bill $bill): JsonResponse
|
||||
{
|
||||
$manager = new Manager();
|
||||
// add include parameter:
|
||||
@@ -126,18 +126,22 @@ class BillController extends Controller
|
||||
/**
|
||||
* @param BillRequest $request
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function store(BillRequest $request)
|
||||
public function store(BillRequest $request): JsonResponse
|
||||
{
|
||||
$bill = $this->repository->store($request->getAll());
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$bill = $this->repository->store($request->getAll());
|
||||
if (null !== $bill) {
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($bill, new BillTransformer($this->parameters), 'bills');
|
||||
$resource = new Item($bill, new BillTransformer($this->parameters), 'bills');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
throw new FireflyException('Could not store new bill.'); // @codeCoverageIgnore
|
||||
|
||||
}
|
||||
|
||||
@@ -146,9 +150,9 @@ class BillController extends Controller
|
||||
* @param BillRequest $request
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function update(BillRequest $request, Bill $bill)
|
||||
public function update(BillRequest $request, Bill $bill): JsonResponse
|
||||
{
|
||||
$data = $request->getAll();
|
||||
$bill = $this->repository->update($bill, $data);
|
||||
|
176
app/Api/V1/Controllers/BudgetController.php
Normal file
176
app/Api/V1/Controllers/BudgetController.php
Normal file
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
/**
|
||||
* BudgetController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Api\V1\Requests\BudgetRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Transformers\BudgetTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
/**
|
||||
* Class BudgetController
|
||||
*/
|
||||
class BudgetController extends Controller
|
||||
{
|
||||
/** @var BudgetRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* BudgetController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var BudgetRepositoryInterface repository */
|
||||
$this->repository = app(BudgetRepositoryInterface::class);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param Budget $budget
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function delete(Budget $budget): JsonResponse
|
||||
{
|
||||
$this->repository->destroy($budget);
|
||||
|
||||
return response()->json([], 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
// create some objects:
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
|
||||
// types to get, page size:
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
// get list of budgets. Count it and split it.
|
||||
$collection = $this->repository->getBudgets();
|
||||
$count = $collection->count();
|
||||
$budgets = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($budgets, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.budgets.index') . $this->buildParams());
|
||||
|
||||
// present to user.
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$resource = new FractalCollection($budgets, new BudgetTransformer($this->parameters), 'budgets');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Budget $budget
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function show(Request $request, Budget $budget): JsonResponse
|
||||
{
|
||||
$manager = new Manager();
|
||||
// add include parameter:
|
||||
$include = $request->get('include') ?? '';
|
||||
$manager->parseIncludes($include);
|
||||
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($budget, new BudgetTransformer($this->parameters), 'budgets');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BudgetRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function store(BudgetRequest $request): JsonResponse
|
||||
{
|
||||
$budget = $this->repository->store($request->getAll());
|
||||
if (null !== $budget) {
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($budget, new BudgetTransformer($this->parameters), 'budgets');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
throw new FireflyException('Could not store new budget.'); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param BudgetRequest $request
|
||||
* @param Budget $budget
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function update(BudgetRequest $request, Budget $budget): JsonResponse
|
||||
{
|
||||
$data = $request->getAll();
|
||||
$budget = $this->repository->update($budget, $data);
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($budget, new BudgetTransformer($this->parameters), 'budgets');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
|
||||
}
|
232
app/Api/V1/Controllers/BudgetLimitController.php
Normal file
232
app/Api/V1/Controllers/BudgetLimitController.php
Normal file
@@ -0,0 +1,232 @@
|
||||
<?php
|
||||
/**
|
||||
* BudgetLimitController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
use FireflyIII\Api\V1\Requests\AvailableBudgetRequest;
|
||||
use FireflyIII\Api\V1\Requests\BudgetLimitRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Transformers\BudgetLimitTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
use InvalidArgumentException;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
use Log;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class BudgetLimitController
|
||||
*/
|
||||
class BudgetLimitController extends Controller
|
||||
{
|
||||
///** @var CurrencyRepositoryInterface */
|
||||
//private $currencyRepository;
|
||||
/** @var BudgetRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* AccountController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$this->repository = app(BudgetRepositoryInterface::class);
|
||||
//$this->currencyRepository = app(CurrencyRepositoryInterface::class);
|
||||
$this->repository->setUser($user);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param BudgetLimit $budgetLimit
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function delete(BudgetLimit $budgetLimit): JsonResponse
|
||||
{
|
||||
$this->repository->destroyBudgetLimit($budgetLimit);
|
||||
|
||||
return response()->json([], 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
// create some objects:
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
|
||||
// read budget from request
|
||||
$budgetId = (int)($request->get('budget_id') ?? 0);
|
||||
$budget = null;
|
||||
if ($budgetId > 0) {
|
||||
$budget = $this->repository->findNull($budgetId);
|
||||
}
|
||||
// read start date from request
|
||||
$start = null;
|
||||
try {
|
||||
$start = Carbon::createFromFormat('Y-m-d', $request->get('start'));
|
||||
$this->parameters->set('start', $start->format('Y-m-d'));
|
||||
} catch (InvalidArgumentException $e) {
|
||||
Log::debug(sprintf('Could not parse start date "%s": %s', $request->get('start'), $e->getMessage()));
|
||||
|
||||
}
|
||||
|
||||
// read end date from request
|
||||
$end = null;
|
||||
try {
|
||||
$end = Carbon::createFromFormat('Y-m-d', $request->get('end'));
|
||||
$this->parameters->set('end', $end->format('Y-m-d'));
|
||||
} catch (InvalidArgumentException $e) {
|
||||
Log::debug(sprintf('Could not parse end date "%s": %s', $request->get('end'), $e->getMessage()));
|
||||
}
|
||||
$this->parameters->set('budget_id', $budgetId);
|
||||
|
||||
// types to get, page size:
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
// get list of budget limits. Count it and split it.
|
||||
$collection = new Collection;
|
||||
if (null === $budget) {
|
||||
$collection = $this->repository->getAllBudgetLimits($start, $end);
|
||||
}
|
||||
if (null !== $budget) {
|
||||
$collection = $this->repository->getBudgetLimits($budget, $start, $end);
|
||||
}
|
||||
|
||||
$count = $collection->count();
|
||||
$budgetLimits = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.budget_limits.index') . $this->buildParams());
|
||||
|
||||
// present to user.
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$resource = new FractalCollection($budgetLimits, new BudgetLimitTransformer($this->parameters), 'budget_limits');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param BudgetLimit $budgetLimit
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function show(Request $request, BudgetLimit $budgetLimit): JsonResponse
|
||||
{
|
||||
$manager = new Manager;
|
||||
|
||||
// add include parameter:
|
||||
$include = $request->get('include') ?? '';
|
||||
$manager->parseIncludes($include);
|
||||
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$resource = new Item($budgetLimit, new BudgetLimitTransformer($this->parameters), 'budget_limits');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param BudgetLimitRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function store(BudgetLimitRequest $request): JsonResponse
|
||||
{
|
||||
$data = $request->getAll();
|
||||
$budget = $this->repository->findNull($data['budget_id']);
|
||||
if (null === $budget) {
|
||||
throw new FireflyException('Unknown budget.');
|
||||
}
|
||||
$data['budget'] = $budget;
|
||||
$budgetLimit = $this->repository->storeBudgetLimit($data);
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($budgetLimit, new BudgetLimitTransformer($this->parameters), 'budget_limits');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param AvailableBudgetRequest $request
|
||||
* @param BudgetLimit $budgetLimit
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function update(BudgetLimitRequest $request, BudgetLimit $budgetLimit): JsonResponse
|
||||
{
|
||||
$data = $request->getAll();
|
||||
$budget = $this->repository->findNull($data['budget_id']);
|
||||
if (null === $budget) {
|
||||
$budget = $budgetLimit->budget;
|
||||
}
|
||||
$data['budget'] = $budget;
|
||||
$budgetLimit = $this->repository->updateBudgetLimit($budgetLimit, $data);
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($budgetLimit, new BudgetLimitTransformer($this->parameters), 'budget_limits');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
}
|
176
app/Api/V1/Controllers/CategoryController.php
Normal file
176
app/Api/V1/Controllers/CategoryController.php
Normal file
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
/**
|
||||
* CategoryController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Api\V1\Requests\CategoryRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Transformers\CategoryTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
/**
|
||||
* Class CategoryController
|
||||
*/
|
||||
class CategoryController extends Controller
|
||||
{
|
||||
/** @var CategoryRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* CategoryController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var CategoryRepositoryInterface repository */
|
||||
$this->repository = app(CategoryRepositoryInterface::class);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param Category $category
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function delete(Category $category): JsonResponse
|
||||
{
|
||||
$this->repository->destroy($category);
|
||||
|
||||
return response()->json([], 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
// create some objects:
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
|
||||
// types to get, page size:
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
// get list of budgets. Count it and split it.
|
||||
$collection = $this->repository->getCategories();
|
||||
$count = $collection->count();
|
||||
$categories = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($categories, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.categories.index') . $this->buildParams());
|
||||
|
||||
// present to user.
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$resource = new FractalCollection($categories, new CategoryTransformer($this->parameters), 'categories');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Category $category
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function show(Request $request, Category $category): JsonResponse
|
||||
{
|
||||
$manager = new Manager();
|
||||
// add include parameter:
|
||||
$include = $request->get('include') ?? '';
|
||||
$manager->parseIncludes($include);
|
||||
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($category, new CategoryTransformer($this->parameters), 'categories');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CategoryRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function store(CategoryRequest $request): JsonResponse
|
||||
{
|
||||
$category = $this->repository->store($request->getAll());
|
||||
if (null !== $category) {
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($category, new CategoryTransformer($this->parameters), 'categories');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
throw new FireflyException('Could not store new category.'); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param CategoryRequest $request
|
||||
* @param Category $category
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function update(CategoryRequest $request, Category $category): JsonResponse
|
||||
{
|
||||
$data = $request->getAll();
|
||||
$category = $this->repository->update($category, $data);
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($category, new CategoryTransformer($this->parameters), 'categories');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
|
||||
}
|
105
app/Api/V1/Controllers/ConfigurationController.php
Normal file
105
app/Api/V1/Controllers/ConfigurationController.php
Normal file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
/**
|
||||
* ConfigurationController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Configuration;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* Class ConfigurationController
|
||||
*/
|
||||
class ConfigurationController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
if (!auth()->user()->hasRole('owner')) {
|
||||
throw new FireflyException('No access to method.'); // @codeCoverageIgnore
|
||||
}
|
||||
$configData = $this->getConfigData();
|
||||
|
||||
return response()->json(['data' => $configData], 200)->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function update(Request $request): JsonResponse
|
||||
{
|
||||
if (!auth()->user()->hasRole('owner')) {
|
||||
throw new FireflyException('No access to method.'); // @codeCoverageIgnore
|
||||
}
|
||||
$name = $request->get('name');
|
||||
$value = $request->get('value');
|
||||
$valid = ['is_demo_site', 'permission_update_check', 'single_user_mode'];
|
||||
if (!\in_array($name, $valid, true)) {
|
||||
throw new FireflyException('You cannot edit this configuration value.');
|
||||
}
|
||||
$configValue = '';
|
||||
switch ($name) {
|
||||
case 'is_demo_site':
|
||||
case 'single_user_mode':
|
||||
$configValue = $value === 'true';
|
||||
break;
|
||||
case 'permission_update_check':
|
||||
$configValue = (int)$value >= -1 && (int)$value <= 1 ? (int)$value : -1;
|
||||
break;
|
||||
}
|
||||
app('fireflyconfig')->set($name, $configValue);
|
||||
$configData = $this->getConfigData();
|
||||
|
||||
return response()->json(['data' => $configData], 200)->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function getConfigData(): array
|
||||
{
|
||||
/** @var Configuration $isDemoSite */
|
||||
$isDemoSite = app('fireflyconfig')->get('is_demo_site');
|
||||
/** @var Configuration $updateCheck */
|
||||
$updateCheck = app('fireflyconfig')->get('permission_update_check');
|
||||
/** @var Configuration $lastCheck */
|
||||
$lastCheck = app('fireflyconfig')->get('last_update_check');
|
||||
/** @var Configuration $singleUser */
|
||||
$singleUser = app('fireflyconfig')->get('single_user_mode');
|
||||
$data = [
|
||||
'is_demo_site' => null === $isDemoSite ? null : $isDemoSite->data,
|
||||
'permission_update_check' => null === $updateCheck ? null : (int)$updateCheck->data,
|
||||
'last_update_check' => null === $lastCheck ? null : (int)$lastCheck->data,
|
||||
'single_user_mode' => null === $singleUser ? null : $singleUser->data,
|
||||
];
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Controller.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -18,22 +19,23 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Carbon\Exceptions\InvalidDateException;
|
||||
use FireflyConfig;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Log;
|
||||
use Symfony\Component\HttpFoundation\ParameterBag;
|
||||
|
||||
/**
|
||||
* Class Controller.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class Controller extends BaseController
|
||||
@@ -46,18 +48,9 @@ class Controller extends BaseController
|
||||
/**
|
||||
* Controller constructor.
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// is site a demo site?
|
||||
$isDemoSite = FireflyConfig::get('is_demo_site', config('firefly.configuration.is_demo_site'))->data;
|
||||
|
||||
// do not expose API on demo site:
|
||||
if (true === $isDemoSite) {
|
||||
throw new FireflyException('The API is not available on the demo site.');
|
||||
}
|
||||
|
||||
// get global parameters
|
||||
$this->parameters = $this->getParameters();
|
||||
}
|
||||
@@ -70,7 +63,7 @@ class Controller extends BaseController
|
||||
$return = '?';
|
||||
$params = [];
|
||||
foreach ($this->parameters as $key => $value) {
|
||||
if($key === 'page') {
|
||||
if ($key === 'page') {
|
||||
continue;
|
||||
}
|
||||
if ($value instanceof Carbon) {
|
||||
@@ -81,7 +74,7 @@ class Controller extends BaseController
|
||||
}
|
||||
}
|
||||
$return .= http_build_query($params);
|
||||
if (strlen($return) === 1) {
|
||||
if (\strlen($return) === 1) {
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -105,11 +98,12 @@ class Controller extends BaseController
|
||||
foreach ($dates as $field) {
|
||||
$date = request()->get($field);
|
||||
$obj = null;
|
||||
if (!is_null($date)) {
|
||||
if (null !== $date) {
|
||||
try {
|
||||
$obj = new Carbon($date);
|
||||
} catch (InvalidDateException $e) {
|
||||
// don't care
|
||||
Log::error(sprintf('Invalid date exception in API controller: %s', $e->getMessage()));
|
||||
}
|
||||
}
|
||||
$bag->set($field, $obj);
|
||||
|
206
app/Api/V1/Controllers/CurrencyController.php
Normal file
206
app/Api/V1/Controllers/CurrencyController.php
Normal file
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
/**
|
||||
* CurrencyController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Api\V1\Requests\CurrencyRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\Transformers\CurrencyTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
/**
|
||||
* Class CurrencyController
|
||||
*/
|
||||
class CurrencyController extends Controller
|
||||
{
|
||||
/** @var CurrencyRepositoryInterface */
|
||||
private $repository;
|
||||
/** @var UserRepositoryInterface */
|
||||
private $userRepository;
|
||||
|
||||
/**
|
||||
* CurrencyRepository constructor.
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var CurrencyRepositoryInterface repository */
|
||||
$this->repository = app(CurrencyRepositoryInterface::class);
|
||||
$this->userRepository = app(UserRepositoryInterface::class);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param TransactionCurrency $currency
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function delete(TransactionCurrency $currency): JsonResponse
|
||||
{
|
||||
if (!$this->userRepository->hasRole(auth()->user(), 'owner')) {
|
||||
// access denied:
|
||||
throw new FireflyException('No access to method, user is not owner.'); // @codeCoverageIgnore
|
||||
}
|
||||
if (!$this->repository->canDeleteCurrency($currency)) {
|
||||
throw new FireflyException('No access to method, currency is in use.'); // @codeCoverageIgnore
|
||||
}
|
||||
$this->repository->destroy($currency);
|
||||
|
||||
return response()->json([], 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
$collection = $this->repository->get();
|
||||
$count = $collection->count();
|
||||
// slice them:
|
||||
$currencies = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
$paginator = new LengthAwarePaginator($currencies, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.currencies.index') . $this->buildParams());
|
||||
|
||||
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
|
||||
$this->parameters->set('defaultCurrency', $defaultCurrency);
|
||||
|
||||
$resource = new FractalCollection($currencies, new CurrencyTransformer($this->parameters), 'currencies');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param TransactionCurrency $currency
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function show(Request $request, TransactionCurrency $currency): JsonResponse
|
||||
{
|
||||
$manager = new Manager();
|
||||
// add include parameter:
|
||||
$include = $request->get('include') ?? '';
|
||||
$manager->parseIncludes($include);
|
||||
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
|
||||
$this->parameters->set('defaultCurrency', $defaultCurrency);
|
||||
|
||||
$resource = new Item($currency, new CurrencyTransformer($this->parameters), 'currencies');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CurrencyRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function store(CurrencyRequest $request): JsonResponse
|
||||
{
|
||||
$currency = $this->repository->store($request->getAll());
|
||||
|
||||
if ($request->boolean('default') === true) {
|
||||
app('preferences')->set('currencyPreference', $currency->code);
|
||||
app('preferences')->mark();
|
||||
}
|
||||
if (null !== $currency) {
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
|
||||
$this->parameters->set('defaultCurrency', $defaultCurrency);
|
||||
|
||||
$resource = new Item($currency, new CurrencyTransformer($this->parameters), 'currencies');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
throw new FireflyException('Could not store new currency.'); // @codeCoverageIgnore
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param CurrencyRequest $request
|
||||
* @param TransactionCurrency $currency
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function update(CurrencyRequest $request, TransactionCurrency $currency): JsonResponse
|
||||
{
|
||||
$data = $request->getAll();
|
||||
$currency = $this->repository->update($currency, $data);
|
||||
|
||||
if ($request->boolean('default') === true) {
|
||||
app('preferences')->set('currencyPreference', $currency->code);
|
||||
app('preferences')->mark();
|
||||
}
|
||||
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
|
||||
$this->parameters->set('defaultCurrency', $defaultCurrency);
|
||||
|
||||
$resource = new Item($currency, new CurrencyTransformer($this->parameters), 'currencies');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
}
|
115
app/Api/V1/Controllers/CurrencyExchangeRateController.php
Normal file
115
app/Api/V1/Controllers/CurrencyExchangeRateController.php
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/**
|
||||
* CurrencyExchangeRateController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Services\Currency\ExchangeRateInterface;
|
||||
use FireflyIII\Transformers\CurrencyExchangeRateTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use InvalidArgumentException;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Resource\Item;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class CurrencyExchangeRateController
|
||||
*/
|
||||
class CurrencyExchangeRateController extends Controller
|
||||
{
|
||||
/** @var CurrencyRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* CurrencyExchangeRateController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(CurrencyRepositoryInterface::class);
|
||||
$this->repository->setUser(auth()->user());
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
// create some objects:
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
|
||||
// currencies
|
||||
$fromCurrency = $this->repository->findByCodeNull($request->get('from') ?? 'EUR');
|
||||
$toCurrency = $this->repository->findByCodeNull($request->get('to') ?? 'USD');
|
||||
|
||||
if (null === $fromCurrency) {
|
||||
throw new FireflyException('Unknown source currency.');
|
||||
}
|
||||
if (null === $toCurrency) {
|
||||
throw new FireflyException('Unknown destination currency.');
|
||||
}
|
||||
|
||||
$dateObj = new Carbon;
|
||||
try {
|
||||
$dateObj = Carbon::createFromFormat('Y-m-d', $request->get('date') ?? date('Y-m-d'));
|
||||
} catch (InvalidArgumentException $e) {
|
||||
Log::debug($e->getMessage());
|
||||
}
|
||||
|
||||
|
||||
$this->parameters->set('from', $fromCurrency->code);
|
||||
$this->parameters->set('to', $toCurrency->code);
|
||||
$this->parameters->set('date', $dateObj->format('Y-m-d'));
|
||||
|
||||
// get the exchange rate.
|
||||
$rate = $this->repository->getExchangeRate($fromCurrency, $toCurrency, $dateObj);
|
||||
if (null === $rate) {
|
||||
// create service:
|
||||
/** @var ExchangeRateInterface $service */
|
||||
$service = app(ExchangeRateInterface::class);
|
||||
$service->setUser(auth()->user());
|
||||
|
||||
// get rate:
|
||||
$rate = $service->getRate($fromCurrency, $toCurrency, $dateObj);
|
||||
}
|
||||
|
||||
$resource = new Item($rate, new CurrencyExchangeRateTransformer($this->parameters), 'currency_exchange_rates');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
}
|
207
app/Api/V1/Controllers/JournalLinkController.php
Normal file
207
app/Api/V1/Controllers/JournalLinkController.php
Normal file
@@ -0,0 +1,207 @@
|
||||
<?php
|
||||
/**
|
||||
* JournalLinkController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Api\V1\Requests\JournalLinkRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\TransactionJournalLink;
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
|
||||
use FireflyIII\Transformers\JournalLinkTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
class JournalLinkController extends Controller
|
||||
{
|
||||
/** @var JournalRepositoryInterface */
|
||||
private $journalRepository;
|
||||
/** @var LinkTypeRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$this->repository = app(LinkTypeRepositoryInterface::class);
|
||||
$this->journalRepository = app(JournalRepositoryInterface::class);
|
||||
|
||||
$this->repository->setUser($user);
|
||||
$this->journalRepository->setUser($user);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the resource.
|
||||
*
|
||||
* @param TransactionJournalLink $link
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function delete(TransactionJournalLink $link): JsonResponse
|
||||
{
|
||||
$this->repository->destroyLink($link);
|
||||
|
||||
return response()->json([], 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* List all of them.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse]
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
// create some objects:
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
|
||||
// read type from URI
|
||||
$name = $request->get('name') ?? null;
|
||||
|
||||
// types to get, page size:
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
$linkType = $this->repository->findByName($name);
|
||||
|
||||
// get list of accounts. Count it and split it.
|
||||
$collection = $this->repository->getJournalLinks($linkType);
|
||||
$count = $collection->count();
|
||||
$journalLinks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($journalLinks, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.journal_links.index') . $this->buildParams());
|
||||
|
||||
// present to user.
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$resource = new FractalCollection($journalLinks, new JournalLinkTransformer($this->parameters), 'journal_links');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* List single resource.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param TransactionJournalLink $journalLink
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function show(Request $request, TransactionJournalLink $journalLink): JsonResponse
|
||||
{
|
||||
$manager = new Manager;
|
||||
|
||||
// add include parameter:
|
||||
$include = $request->get('include') ?? '';
|
||||
$manager->parseIncludes($include);
|
||||
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$resource = new Item($journalLink, new JournalLinkTransformer($this->parameters), 'journal_links');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Store new object.
|
||||
*
|
||||
* @param JournalLinkRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function store(JournalLinkRequest $request): JsonResponse
|
||||
{
|
||||
$manager = new Manager;
|
||||
|
||||
// add include parameter:
|
||||
$include = $request->get('include') ?? '';
|
||||
$manager->parseIncludes($include);
|
||||
|
||||
$data = $request->getAll();
|
||||
$inward = $this->journalRepository->findNull($data['inward_id'] ?? 0);
|
||||
$outward = $this->journalRepository->findNull($data['outward_id'] ?? 0);
|
||||
if (null === $inward || null === $outward) {
|
||||
throw new FireflyException('Source or destination is NULL.');
|
||||
}
|
||||
$data['direction'] = 'inward';
|
||||
|
||||
$journalLink = $this->repository->storeLink($data, $inward, $outward);
|
||||
|
||||
$resource = new Item($journalLink, new JournalLinkTransformer($this->parameters), 'journal_links');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param JournalLinkRequest $request
|
||||
* @param TransactionJournalLink $journalLink
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function update(JournalLinkRequest $request, TransactionJournalLink $journalLink): JsonResponse
|
||||
{
|
||||
$manager = new Manager;
|
||||
|
||||
// add include parameter:
|
||||
$include = $request->get('include') ?? '';
|
||||
$manager->parseIncludes($include);
|
||||
|
||||
|
||||
$data = $request->getAll();
|
||||
$data['inward'] = $this->journalRepository->findNull($data['inward_id'] ?? 0);
|
||||
$data['outward'] = $this->journalRepository->findNull($data['outward_id'] ?? 0);
|
||||
if (null === $data['inward'] || null === $data['outward']) {
|
||||
throw new FireflyException('Source or destination is NULL.');
|
||||
}
|
||||
$data['direction'] = 'inward';
|
||||
$journalLink = $this->repository->updateLink($journalLink, $data);
|
||||
|
||||
$resource = new Item($journalLink, new JournalLinkTransformer($this->parameters), 'journal_links');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
}
|
197
app/Api/V1/Controllers/LinkTypeController.php
Normal file
197
app/Api/V1/Controllers/LinkTypeController.php
Normal file
@@ -0,0 +1,197 @@
|
||||
<?php
|
||||
/**
|
||||
* LinkTypeController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Api\V1\Requests\LinkTypeRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\LinkType;
|
||||
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\Transformers\LinkTypeTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class LinkTypeController
|
||||
*/
|
||||
class LinkTypeController extends Controller
|
||||
{
|
||||
/** @var LinkTypeRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/** @var UserRepositoryInterface */
|
||||
private $userRepository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$this->repository = app(LinkTypeRepositoryInterface::class);
|
||||
$this->userRepository = app(UserRepositoryInterface::class);
|
||||
$this->repository->setUser($user);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the resource.
|
||||
*
|
||||
* @param LinkType $linkType
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function delete(LinkType $linkType): JsonResponse
|
||||
{
|
||||
if ($linkType->editable === false) {
|
||||
throw new FireflyException(sprintf('You cannot delete this link type (#%d, "%s")', $linkType->id, $linkType->name));
|
||||
}
|
||||
$this->repository->destroy($linkType, null);
|
||||
|
||||
return response()->json([], 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* List all of them.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse]
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
// create some objects:
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
// get list of accounts. Count it and split it.
|
||||
$collection = $this->repository->get();
|
||||
$count = $collection->count();
|
||||
$linkTypes = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($linkTypes, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.link_types.index') . $this->buildParams());
|
||||
|
||||
// present to user.
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$resource = new FractalCollection($linkTypes, new LinkTypeTransformer($this->parameters), 'link_types');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* List single resource.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param LinkType $linkType
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function show(Request $request, LinkType $linkType): JsonResponse
|
||||
{
|
||||
$manager = new Manager;
|
||||
|
||||
// add include parameter:
|
||||
$include = $request->get('include') ?? '';
|
||||
$manager->parseIncludes($include);
|
||||
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$resource = new Item($linkType, new LinkTypeTransformer($this->parameters), 'link_types');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Store new object.
|
||||
*
|
||||
* @param LinkTypeRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function store(LinkTypeRequest $request): JsonResponse
|
||||
{
|
||||
if (!$this->userRepository->hasRole(auth()->user(), 'owner')) {
|
||||
throw new FireflyException('You need the "owner"-role to do this.');
|
||||
}
|
||||
$data = $request->getAll();
|
||||
// if currency ID is 0, find the currency by the code:
|
||||
$linkType = $this->repository->store($data);
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($linkType, new LinkTypeTransformer($this->parameters), 'link_types');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param LinkTypeRequest $request
|
||||
* @param LinkType $linkType
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function update(LinkTypeRequest $request, LinkType $linkType): JsonResponse
|
||||
{
|
||||
if ($linkType->editable === false) {
|
||||
throw new FireflyException(sprintf('You cannot edit this link type (#%d, "%s")', $linkType->id, $linkType->name));
|
||||
}
|
||||
if (!$this->userRepository->hasRole(auth()->user(), 'owner')) {
|
||||
throw new FireflyException('You need the "owner"-role to do this.');
|
||||
}
|
||||
|
||||
$data = $request->getAll();
|
||||
$this->repository->update($linkType, $data);
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($linkType, new LinkTypeTransformer($this->parameters), 'link_types');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
}
|
180
app/Api/V1/Controllers/PiggyBankController.php
Normal file
180
app/Api/V1/Controllers/PiggyBankController.php
Normal file
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
/**
|
||||
* PiggyBankController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Api\V1\Requests\PiggyBankRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use FireflyIII\Transformers\PiggyBankTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
/**
|
||||
* TODO order up and down.
|
||||
* Class PiggyBankController
|
||||
*/
|
||||
class PiggyBankController extends Controller
|
||||
{
|
||||
|
||||
/** @var PiggyBankRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$this->repository = app(PiggyBankRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the resource.
|
||||
*
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function delete(PiggyBank $piggyBank): JsonResponse
|
||||
{
|
||||
$this->repository->destroy($piggyBank);
|
||||
|
||||
return response()->json([], 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* List all of them.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse]
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
// create some objects:
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
|
||||
// types to get, page size:
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
// get list of budgets. Count it and split it.
|
||||
$collection = $this->repository->getPiggyBanks();
|
||||
$count = $collection->count();
|
||||
$piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.piggy_banks.index') . $this->buildParams());
|
||||
|
||||
// present to user.
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$resource = new FractalCollection($piggyBanks, new PiggyBankTransformer($this->parameters), 'piggy_banks');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* List single resource.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function show(Request $request, PiggyBank $piggyBank): JsonResponse
|
||||
{
|
||||
$manager = new Manager();
|
||||
// add include parameter:
|
||||
$include = $request->get('include') ?? '';
|
||||
$manager->parseIncludes($include);
|
||||
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($piggyBank, new PiggyBankTransformer($this->parameters), 'piggy_banks');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Store new object.
|
||||
*
|
||||
* @param PiggyBankRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function store(PiggyBankRequest $request): JsonResponse
|
||||
{
|
||||
$piggyBank = $this->repository->store($request->getAll());
|
||||
if (null !== $piggyBank) {
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($piggyBank, new PiggyBankTransformer($this->parameters), 'piggy_banks');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
throw new FireflyException('Could not store new piggy bank.'); // @codeCoverageIgnore
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PiggyBankRequest $request
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function update(PiggyBankRequest $request, PiggyBank $piggyBank): JsonResponse
|
||||
{
|
||||
$piggyBank = $this->repository->update($piggyBank, $request->getAll());
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($piggyBank, new PiggyBankTransformer($this->parameters), 'piggy_banks');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
}
|
157
app/Api/V1/Controllers/PreferenceController.php
Normal file
157
app/Api/V1/Controllers/PreferenceController.php
Normal file
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
/**
|
||||
* PreferencesController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Api\V1\Requests\PreferenceRequest;
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\Transformers\PreferenceTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Collection;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
use Preferences;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class PreferenceController
|
||||
*/
|
||||
class PreferenceController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
// todo add local repositories.
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* List all of them.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse]
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$available = [
|
||||
'language', 'customFiscalYear', 'fiscalYearStart', 'currencyPreference',
|
||||
'transaction_journal_optional_fields', 'frontPageAccounts', 'viewRange',
|
||||
'listPageSize, twoFactorAuthEnabled',
|
||||
];
|
||||
$preferences = new Collection;
|
||||
foreach ($available as $name) {
|
||||
$pref = Preferences::getForUser($user, $name);
|
||||
if (null !== $pref) {
|
||||
$preferences->push($pref);
|
||||
}
|
||||
}
|
||||
|
||||
// create some objects:
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
|
||||
// present to user.
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$resource = new FractalCollection($preferences, new PreferenceTransformer($this->parameters), 'preferences');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* List single resource.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Preference $preference
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function show(Request $request, Preference $preference): JsonResponse
|
||||
{
|
||||
// create some objects:
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
|
||||
// present to user.
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$resource = new Item($preference, new PreferenceTransformer($this->parameters), 'preferences');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PreferenceRequest $request
|
||||
* @param Preference $preference
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function update(PreferenceRequest $request, Preference $preference): JsonResponse
|
||||
{
|
||||
|
||||
$data = $request->getAll();
|
||||
$newValue = $data['data'];
|
||||
switch ($preference->name) {
|
||||
default:
|
||||
break;
|
||||
case 'transaction_journal_optional_fields':
|
||||
case 'frontPageAccounts':
|
||||
$newValue = explode(',', $data['data']);
|
||||
break;
|
||||
case 'listPageSize':
|
||||
$newValue = (int)$data['data'];
|
||||
break;
|
||||
case 'customFiscalYear':
|
||||
case 'twoFactorAuthEnabled':
|
||||
$newValue = (int)$data['data'] === 1;
|
||||
break;
|
||||
}
|
||||
$result = Preferences::set($preference->name, $newValue);
|
||||
|
||||
// create some objects:
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
|
||||
// present to user.
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$resource = new Item($result, new PreferenceTransformer($this->parameters), 'preferences');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
}
|
179
app/Api/V1/Controllers/RecurrenceController.php
Normal file
179
app/Api/V1/Controllers/RecurrenceController.php
Normal file
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
/**
|
||||
* RecurrenceController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Api\V1\Requests\RecurrenceRequest;
|
||||
use FireflyIII\Models\Recurrence;
|
||||
use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface;
|
||||
use FireflyIII\Transformers\RecurrenceTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class RecurrenceController
|
||||
*/
|
||||
class RecurrenceController extends Controller
|
||||
{
|
||||
/** @var RecurringRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
/** @var RecurringRepositoryInterface repository */
|
||||
$this->repository = app(RecurringRepositoryInterface::class);
|
||||
$this->repository->setUser($user);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the resource.
|
||||
*
|
||||
* @param Recurrence $recurrence
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function delete(Recurrence $recurrence): JsonResponse
|
||||
{
|
||||
$this->repository->destroy($recurrence);
|
||||
|
||||
return response()->json([], 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* List all of them.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse]
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
// create some objects:
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
|
||||
// types to get, page size:
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
// get list of budgets. Count it and split it.
|
||||
$collection = $this->repository->getAll();
|
||||
$count = $collection->count();
|
||||
$piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.recurrences.index') . $this->buildParams());
|
||||
|
||||
// present to user.
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$resource = new FractalCollection($piggyBanks, new RecurrenceTransformer($this->parameters), 'recurrences');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* List single resource.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Recurrence $recurrence
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function show(Request $request, Recurrence $recurrence): JsonResponse
|
||||
{
|
||||
$manager = new Manager();
|
||||
// add include parameter:
|
||||
$include = $request->get('include') ?? '';
|
||||
$manager->parseIncludes($include);
|
||||
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($recurrence, new RecurrenceTransformer($this->parameters), 'recurrences');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Store new object.
|
||||
*
|
||||
* @param RecurrenceRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function store(RecurrenceRequest $request): JsonResponse
|
||||
{
|
||||
$recurrence = $this->repository->store($request->getAll());
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$resource = new Item($recurrence, new RecurrenceTransformer($this->parameters), 'recurrences');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RecurrenceRequest $request
|
||||
* @param Recurrence $recurrence
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function update(RecurrenceRequest $request, Recurrence $recurrence): JsonResponse
|
||||
{
|
||||
$data = $request->getAll();
|
||||
|
||||
//
|
||||
|
||||
$category = $this->repository->update($recurrence, $data);
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($category, new RecurrenceTransformer($this->parameters), 'recurrences');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
}
|
173
app/Api/V1/Controllers/RuleController.php
Normal file
173
app/Api/V1/Controllers/RuleController.php
Normal file
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
/**
|
||||
* RuleController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Api\V1\Requests\RuleRequest;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Repositories\Rule\RuleRepositoryInterface;
|
||||
use FireflyIII\Transformers\RuleTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
/**
|
||||
* Class RuleController
|
||||
*/
|
||||
class RuleController extends Controller
|
||||
{
|
||||
/** @var RuleRepositoryInterface */
|
||||
private $ruleRepository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$this->ruleRepository = app(RuleRepositoryInterface::class);
|
||||
$this->ruleRepository->setUser($user);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the resource.
|
||||
*
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function delete(Rule $rule): JsonResponse
|
||||
{
|
||||
$this->ruleRepository->destroy($rule);
|
||||
|
||||
return response()->json([], 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* List all of them.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse]
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
// create some objects:
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
|
||||
// types to get, page size:
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
// get list of budgets. Count it and split it.
|
||||
$collection = $this->ruleRepository->getAll();
|
||||
$count = $collection->count();
|
||||
$rules = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.piggy_banks.index') . $this->buildParams());
|
||||
|
||||
// present to user.
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$resource = new FractalCollection($rules, new RuleTransformer($this->parameters), 'rules');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* List single resource.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function show(Request $request, Rule $rule): JsonResponse
|
||||
{
|
||||
$manager = new Manager();
|
||||
// add include parameter:
|
||||
$include = $request->get('include') ?? '';
|
||||
$manager->parseIncludes($include);
|
||||
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($rule, new RuleTransformer($this->parameters), 'rules');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Store new object.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function store(RuleRequest $request): JsonResponse
|
||||
{
|
||||
$rule = $this->ruleRepository->store($request->getAll());
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($rule, new RuleTransformer($this->parameters), 'rules');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RuleRequest $request
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function update(RuleRequest $request, Rule $rule): JsonResponse
|
||||
{
|
||||
$rule = $this->ruleRepository->update($rule, $request->getAll());
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($rule, new RuleTransformer($this->parameters), 'rules');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
}
|
171
app/Api/V1/Controllers/RuleGroupController.php
Normal file
171
app/Api/V1/Controllers/RuleGroupController.php
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
/**
|
||||
* RuleGroupController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Api\V1\Requests\RuleGroupRequest;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
|
||||
use FireflyIII\Transformers\RuleGroupTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
|
||||
class RuleGroupController extends Controller
|
||||
{
|
||||
/** @var RuleGroupRepositoryInterface */
|
||||
private $ruleGroupRepository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$this->ruleGroupRepository = app(RuleGroupRepositoryInterface::class);
|
||||
$this->ruleGroupRepository->setUser($user);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the resource.
|
||||
*
|
||||
* @param string $object
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function delete(RuleGroup $ruleGroup): JsonResponse
|
||||
{
|
||||
$this->ruleGroupRepository->destroy($ruleGroup, null);
|
||||
|
||||
return response()->json([], 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* List all of them.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse]
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
// create some objects:
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
|
||||
// types to get, page size:
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
// get list of budgets. Count it and split it.
|
||||
$collection = $this->ruleGroupRepository->get();
|
||||
$count = $collection->count();
|
||||
$ruleGroups = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($ruleGroups, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.rule_groups.index') . $this->buildParams());
|
||||
|
||||
// present to user.
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$resource = new FractalCollection($ruleGroups, new RuleGroupTransformer($this->parameters), 'rule_groups');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* List single resource.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param RuleGroup $ruleGroup
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function show(Request $request, RuleGroup $ruleGroup): JsonResponse
|
||||
{
|
||||
$manager = new Manager();
|
||||
// add include parameter:
|
||||
$include = $request->get('include') ?? '';
|
||||
$manager->parseIncludes($include);
|
||||
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($ruleGroup, new RuleGroupTransformer($this->parameters), 'rule_groups');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Store new object.
|
||||
*
|
||||
* @param RuleGroupRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function store(RuleGroupRequest $request): JsonResponse
|
||||
{
|
||||
$ruleGroup = $this->ruleGroupRepository->store($request->getAll());
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($ruleGroup, new RuleGroupTransformer($this->parameters), 'rule_groups');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param string $object
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function update(RuleGroupRequest $request, RuleGroup $ruleGroup): JsonResponse
|
||||
{
|
||||
$ruleGroup = $this->ruleGroupRepository->update($ruleGroup, $request->getAll());
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($ruleGroup, new RuleGroupTransformer($this->parameters), 'rule_groups');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
}
|
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* TransactionController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -37,10 +38,8 @@ use Illuminate\Support\Collection;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
use Log;
|
||||
use Preferences;
|
||||
|
||||
/**
|
||||
* Class TransactionController
|
||||
@@ -92,7 +91,7 @@ class TransactionController extends Controller
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$pageSize = intval(Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data);
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
// read type from URI
|
||||
$type = $request->get('type') ?? 'default';
|
||||
@@ -112,11 +111,11 @@ class TransactionController extends Controller
|
||||
$collector->setAllAssetAccounts();
|
||||
|
||||
// remove internal transfer filter:
|
||||
if (in_array(TransactionType::TRANSFER, $types)) {
|
||||
if (\in_array(TransactionType::TRANSFER, $types)) {
|
||||
$collector->removeFilter(InternalTransferFilter::class);
|
||||
}
|
||||
|
||||
if (!is_null($this->parameters->get('start')) && !is_null($this->parameters->get('end'))) {
|
||||
if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
|
||||
$collector->setRange($this->parameters->get('start'), $this->parameters->get('end'));
|
||||
}
|
||||
$collector->setLimit($pageSize)->setPage($this->parameters->get('page'));
|
||||
@@ -136,17 +135,19 @@ class TransactionController extends Controller
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Transaction $transaction
|
||||
* @param string $include
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function show(Request $request, Transaction $transaction)
|
||||
public function show(Request $request, Transaction $transaction, string $include = null)
|
||||
{
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
// add include parameter:
|
||||
$include = $request->get('include') ?? '';
|
||||
$include = $include ?? '';
|
||||
$include = $request->get('include') ?? $include;
|
||||
$manager->parseIncludes($include);
|
||||
|
||||
// collect transactions using the journal collector
|
||||
@@ -166,13 +167,15 @@ class TransactionController extends Controller
|
||||
}
|
||||
|
||||
$transactions = $collector->getJournals();
|
||||
$resource = new Item($transactions->first(), new TransactionTransformer($this->parameters), 'transactions');
|
||||
$resource = new FractalCollection($transactions, new TransactionTransformer($this->parameters), 'transactions');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionRequest $request
|
||||
* @param TransactionRequest $request
|
||||
*
|
||||
* @param JournalRepositoryInterface $repository
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
@@ -330,4 +333,4 @@ class TransactionController extends Controller
|
||||
return $types['default']; // @codeCoverageIgnore
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* UserController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -24,6 +25,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Api\V1\Requests\UserRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\Transformers\UserTransformer;
|
||||
use FireflyIII\User;
|
||||
@@ -34,8 +36,7 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
use Preferences;
|
||||
use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
|
||||
|
||||
|
||||
/**
|
||||
* Class UserController
|
||||
@@ -70,6 +71,7 @@ class UserController extends Controller
|
||||
* @param \FireflyIII\User $user
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function delete(User $user)
|
||||
{
|
||||
@@ -78,7 +80,7 @@ class UserController extends Controller
|
||||
|
||||
return response()->json([], 204);
|
||||
}
|
||||
throw new AccessDeniedException(''); // @codeCoverageIgnore
|
||||
throw new FireflyException('No access to method.'); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,7 +93,7 @@ class UserController extends Controller
|
||||
public function index(Request $request)
|
||||
{
|
||||
// user preferences
|
||||
$pageSize = intval(Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data);
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
// make manager
|
||||
$manager = new Manager();
|
||||
@@ -189,4 +191,4 @@ class UserController extends Controller
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* AccountRequest.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -70,9 +71,9 @@ class AccountRequest extends Request
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$accountRoles = join(',', config('firefly.accountRoles'));
|
||||
$types = join(',', array_keys(config('firefly.subTitlesByIdentifier')));
|
||||
$ccPaymentTypes = join(',', array_keys(config('firefly.ccTypes')));
|
||||
$accountRoles = implode(',', config('firefly.accountRoles'));
|
||||
$types = implode(',', array_keys(config('firefly.subTitlesByIdentifier')));
|
||||
$ccPaymentTypes = implode(',', array_keys(config('firefly.ccTypes')));
|
||||
$rules = [
|
||||
'name' => 'required|min:1|uniqueAccountForUser',
|
||||
'opening_balance' => 'numeric|required_with:opening_balance_date|nullable',
|
||||
@@ -104,4 +105,4 @@ class AccountRequest extends Request
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
92
app/Api/V1/Requests/AttachmentRequest.php
Normal file
92
app/Api/V1/Requests/AttachmentRequest.php
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
/**
|
||||
* AttachmentRequest.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests;
|
||||
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Rules\IsBase64;
|
||||
use FireflyIII\Rules\IsValidAttachmentModel;
|
||||
|
||||
/**
|
||||
* Class AttachmentRequest
|
||||
*/
|
||||
class AttachmentRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
// Only allow authenticated users
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
return [
|
||||
'filename' => $this->string('filename'),
|
||||
'title' => $this->string('title'),
|
||||
'notes' => $this->string('notes'),
|
||||
'model' => $this->string('model'),
|
||||
'model_id' => $this->integer('model_id'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$models = implode(
|
||||
',', [
|
||||
Bill::class,
|
||||
ImportJob::class,
|
||||
TransactionJournal::class,
|
||||
]
|
||||
);
|
||||
$model = $this->string('model');
|
||||
$rules = [
|
||||
'filename' => 'required|between:1,255',
|
||||
'title' => 'between:1,255',
|
||||
'notes' => 'between:1,65000',
|
||||
'model' => sprintf('required|in:%s', $models),
|
||||
'model_id' => ['required', 'numeric', new IsValidAttachmentModel($model)],
|
||||
];
|
||||
switch ($this->method()) {
|
||||
default:
|
||||
break;
|
||||
case 'PUT':
|
||||
case 'PATCH':
|
||||
unset($rules['model'], $rules['model_id']);
|
||||
$rules['filename'] = 'between:1,255';
|
||||
break;
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
69
app/Api/V1/Requests/AvailableBudgetRequest.php
Normal file
69
app/Api/V1/Requests/AvailableBudgetRequest.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* AvailableBudgetRequest.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests;
|
||||
|
||||
/**
|
||||
* Class AvailableBudgetRequest
|
||||
*/
|
||||
class AvailableBudgetRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
// Only allow authenticated users
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
return [
|
||||
'transaction_currency_id' => $this->integer('transaction_currency_id'),
|
||||
'amount' => $this->string('amount'),
|
||||
'start_date' => $this->date('start_date'),
|
||||
'end_date' => $this->date('end_date'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'transaction_currency_id' => 'required|numeric|exists:transaction_currencies,id',
|
||||
'amount' => 'required|numeric|more:0',
|
||||
'start_date' => 'required|date|before:end_date',
|
||||
'end_date' => 'required|date|after:start_date',
|
||||
];
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* BillRequest.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -46,18 +47,17 @@ class BillRequest extends Request
|
||||
public function getAll(): array
|
||||
{
|
||||
$data = [
|
||||
'name' => $this->string('name'),
|
||||
'match' => $this->string('match'),
|
||||
'amount_min' => $this->string('amount_min'),
|
||||
'amount_max' => $this->string('amount_max'),
|
||||
//'currency_id' => $this->integer('currency_id'),
|
||||
//'currency_code' => $this->string('currency_code'),
|
||||
'date' => $this->date('date'),
|
||||
'repeat_freq' => $this->string('repeat_freq'),
|
||||
'skip' => $this->integer('skip'),
|
||||
'automatch' => $this->boolean('automatch'),
|
||||
'active' => $this->boolean('active'),
|
||||
'notes' => $this->string('notes'),
|
||||
'name' => $this->string('name'),
|
||||
'amount_min' => $this->string('amount_min'),
|
||||
'amount_max' => $this->string('amount_max'),
|
||||
'currency_id' => $this->integer('currency_id'),
|
||||
'currency_code' => $this->string('currency_code'),
|
||||
'date' => $this->date('date'),
|
||||
'repeat_freq' => $this->string('repeat_freq'),
|
||||
'skip' => $this->integer('skip'),
|
||||
'automatch' => $this->boolean('automatch'),
|
||||
'active' => $this->boolean('active'),
|
||||
'notes' => $this->string('notes'),
|
||||
];
|
||||
|
||||
return $data;
|
||||
@@ -69,27 +69,25 @@ class BillRequest extends Request
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'name' => 'required|between:1,255|uniqueObjectForUser:bills,name',
|
||||
'match' => 'required|between:1,255|uniqueObjectForUser:bills,match',
|
||||
'amount_min' => 'required|numeric|more:0',
|
||||
'amount_max' => 'required|numeric|more:0',
|
||||
//'currency_id' => 'numeric|exists:transaction_currencies,id|required_without:currency_code',
|
||||
//'currency_code' => 'min:3|max:3|exists:transaction_currencies,code|required_without:currency_id',
|
||||
'date' => 'required|date',
|
||||
'repeat_freq' => 'required|in:weekly,monthly,quarterly,half-year,yearly',
|
||||
'skip' => 'required|between:0,31',
|
||||
'automatch' => 'required|boolean',
|
||||
'active' => 'required|boolean',
|
||||
'notes' => 'between:1,65536',
|
||||
'name' => 'required|between:1,255|uniqueObjectForUser:bills,name',
|
||||
'amount_min' => 'required|numeric|more:0',
|
||||
'amount_max' => 'required|numeric|more:0',
|
||||
'currency_id' => 'numeric|exists:transaction_currencies,id|required_without:currency_code',
|
||||
'currency_code' => 'min:3|max:3|exists:transaction_currencies,code|required_without:currency_id',
|
||||
'date' => 'required|date',
|
||||
'repeat_freq' => 'required|in:weekly,monthly,quarterly,half-year,yearly',
|
||||
'skip' => 'required|between:0,31',
|
||||
'automatch' => 'required|boolean',
|
||||
'active' => 'required|boolean',
|
||||
'notes' => 'between:1,65536',
|
||||
];
|
||||
switch ($this->method()) {
|
||||
default:
|
||||
break;
|
||||
case 'PUT':
|
||||
case 'PATCH':
|
||||
$bill = $this->route()->parameter('bill');
|
||||
$rules['name'] .= ',' . $bill->id;
|
||||
$rules['match'] .= ',' . $bill->id;
|
||||
$bill = $this->route()->parameter('bill');
|
||||
$rules['name'] .= ',' . $bill->id;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -108,12 +106,12 @@ class BillRequest extends Request
|
||||
$validator->after(
|
||||
function (Validator $validator) {
|
||||
$data = $validator->getData();
|
||||
$min = floatval($data['amount_min'] ?? 0);
|
||||
$max = floatval($data['amount_max'] ?? 0);
|
||||
$min = (float)($data['amount_min'] ?? 0);
|
||||
$max = (float)($data['amount_max'] ?? 0);
|
||||
if ($min > $max) {
|
||||
$validator->errors()->add('amount_min', trans('validation.amount_min_over_max'));
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
77
app/Api/V1/Requests/BudgetLimitRequest.php
Normal file
77
app/Api/V1/Requests/BudgetLimitRequest.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/**
|
||||
* BudgetLimitRequest.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests;
|
||||
|
||||
|
||||
/**
|
||||
* Class BudgetLimitRequest
|
||||
*/
|
||||
class BudgetLimitRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
// Only allow authenticated users
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
return [
|
||||
'budget_id' => $this->integer('budget_id'),
|
||||
'start_date' => $this->date('start_date'),
|
||||
'end_date' => $this->date('end_date'),
|
||||
'amount' => $this->string('amount'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'budget_id' => 'required|exists:budgets,id|belongsToUser:budgets,id',
|
||||
'start_date' => 'required|before:end_date|date',
|
||||
'end_date' => 'required|after:start_date|date',
|
||||
'amount' => 'required|more:0',
|
||||
];
|
||||
switch ($this->method()) {
|
||||
default:
|
||||
break;
|
||||
case 'PUT':
|
||||
case 'PATCH':
|
||||
$rules['budget_id'] = 'required|exists:budgets,id|belongsToUser:budgets,id';
|
||||
break;
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
}
|
76
app/Api/V1/Requests/BudgetRequest.php
Normal file
76
app/Api/V1/Requests/BudgetRequest.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* BudgetRequest.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests;
|
||||
|
||||
use FireflyIII\Models\Budget;
|
||||
|
||||
/**
|
||||
* Class BudgetRequest
|
||||
*/
|
||||
class BudgetRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
// Only allow authenticated users
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
return [
|
||||
'name' => $this->string('name'),
|
||||
'active' => $this->boolean('active'),
|
||||
'order' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'name' => 'required|between:1,100|uniqueObjectForUser:budgets,name',
|
||||
'active' => 'required|boolean',
|
||||
];
|
||||
switch ($this->method()) {
|
||||
default:
|
||||
break;
|
||||
case 'PUT':
|
||||
case 'PATCH':
|
||||
/** @var Budget $budget */
|
||||
$budget = $this->route()->parameter('budget');
|
||||
$rules['name'] = sprintf('required|between:1,100|uniqueObjectForUser:budgets,name,%d', $budget->id);
|
||||
break;
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
75
app/Api/V1/Requests/CategoryRequest.php
Normal file
75
app/Api/V1/Requests/CategoryRequest.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* CategoryRequest.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests;
|
||||
|
||||
use FireflyIII\Models\Category;
|
||||
|
||||
/**
|
||||
* Class CategoryRequest
|
||||
*/
|
||||
class CategoryRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
// Only allow authenticated users
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
return [
|
||||
'name' => $this->string('name'),
|
||||
'active' => $this->boolean('active'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'name' => 'required|between:1,100|uniqueObjectForUser:categories,name',
|
||||
'active' => 'required|boolean',
|
||||
];
|
||||
switch ($this->method()) {
|
||||
default:
|
||||
break;
|
||||
case 'PUT':
|
||||
case 'PATCH':
|
||||
/** @var Category $category */
|
||||
$category = $this->route()->parameter('category');
|
||||
$rules['name'] = sprintf('required|between:1,100|uniqueObjectForUser:categories,name,%d', $category->id);
|
||||
break;
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
83
app/Api/V1/Requests/CurrencyRequest.php
Normal file
83
app/Api/V1/Requests/CurrencyRequest.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/**
|
||||
* CurrencyRequest.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests;
|
||||
|
||||
|
||||
/**
|
||||
* Class CurrencyRequest
|
||||
*/
|
||||
class CurrencyRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
// Only allow authenticated users
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
return [
|
||||
'name' => $this->string('name'),
|
||||
'code' => $this->string('code'),
|
||||
'symbol' => $this->string('symbol'),
|
||||
'decimal_places' => $this->integer('decimal_places'),
|
||||
'default' => $this->boolean('default'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'name' => 'required|between:1,255|unique:transaction_currencies,name',
|
||||
'code' => 'required|between:3,3|unique:transaction_currencies,code',
|
||||
'symbol' => 'required|between:1,5|unique:transaction_currencies,symbol',
|
||||
'decimal_places' => 'required|between:0,20|numeric|min:0|max:20',
|
||||
'default' => 'in:true,false',
|
||||
];
|
||||
|
||||
switch ($this->method()) {
|
||||
default:
|
||||
break;
|
||||
case 'PUT':
|
||||
case 'PATCH':
|
||||
$currency = $this->route()->parameter('currency');
|
||||
$rules['name'] = 'required|between:1,255|unique:transaction_currencies,name,' . $currency->id;
|
||||
$rules['code'] = 'required|between:1,255|unique:transaction_currencies,code,' . $currency->id;
|
||||
$rules['symbol'] = 'required|between:1,255|unique:transaction_currencies,symbol,' . $currency->id;
|
||||
break;
|
||||
}
|
||||
|
||||
return $rules;
|
||||
|
||||
}
|
||||
}
|
68
app/Api/V1/Requests/JournalLinkRequest.php
Normal file
68
app/Api/V1/Requests/JournalLinkRequest.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* JournalLinkRequest.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Class JournalLinkRequest
|
||||
*/
|
||||
class JournalLinkRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
// Only allow authenticated users
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
return [
|
||||
'link_type_id' => $this->integer('link_type_id'),
|
||||
'inward_id' => $this->integer('inward_id'),
|
||||
'outward_id' => $this->integer('outward_id'),
|
||||
'notes' => $this->string('notes'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'link_type_id' => 'required|exists:link_types,id',
|
||||
'inward_id' => 'required|belongsToUser:transaction_journals,id',
|
||||
'outward_id' => 'required|belongsToUser:transaction_journals,id',
|
||||
'notes' => 'between:0,65000',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
86
app/Api/V1/Requests/LinkTypeRequest.php
Normal file
86
app/Api/V1/Requests/LinkTypeRequest.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/**
|
||||
* LinkTypeRequest.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests;
|
||||
|
||||
use FireflyIII\Models\LinkType;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class LinkTypeRequest
|
||||
*/
|
||||
class LinkTypeRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
// Only allow authenticated users
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
return [
|
||||
'name' => $this->string('name'),
|
||||
'outward' => $this->string('outward'),
|
||||
'inward' => $this->string('inward'),
|
||||
];
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'name' => 'required|unique:link_types,name|min:1',
|
||||
'outward' => 'required|unique:link_types,outward|min:1|different:inward',
|
||||
'inward' => 'required|unique:link_types,inward|min:1|different:outward',
|
||||
];
|
||||
// Rule::unique('users')->ignore($user->id),
|
||||
|
||||
|
||||
switch ($this->method()) {
|
||||
default:
|
||||
break;
|
||||
case 'PUT':
|
||||
case 'PATCH':
|
||||
/** @var LinkType $linkType */
|
||||
$linkType = $this->route()->parameter('linkType');
|
||||
$rules['name'] = ['required', Rule::unique('link_types', 'name')->ignore($linkType->id), 'min:1'];
|
||||
$rules['outward'] = ['required', 'different:inward', Rule::unique('link_types', 'outward')->ignore($linkType->id), 'min:1'];
|
||||
$rules['inward'] = ['required', 'different:outward', Rule::unique('link_types', 'inward')->ignore($linkType->id), 'min:1'];
|
||||
break;
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
90
app/Api/V1/Requests/PiggyBankRequest.php
Normal file
90
app/Api/V1/Requests/PiggyBankRequest.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/**
|
||||
* PiggyBankRequest.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests;
|
||||
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Rules\IsAssetAccountId;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class PiggyBankRequest
|
||||
*/
|
||||
class PiggyBankRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
// Only allow authenticated users
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
return [
|
||||
'name' => $this->string('name'),
|
||||
'account_id' => $this->integer('account_id'),
|
||||
'targetamount' => $this->string('target_amount'),
|
||||
'current_amount' => $this->string('current_amount'),
|
||||
'start_date' => $this->date('start_date'),
|
||||
'target_date' => $this->date('target_date'),
|
||||
'note' => $this->string('notes'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'name' => 'required|between:1,255|uniquePiggyBankForUser',
|
||||
'account_id' => ['required', 'belongsToUser:accounts', new IsAssetAccountId],
|
||||
'target_amount' => 'required|numeric|more:0',
|
||||
'current_amount' => 'numeric|more:0|lte:target_amount',
|
||||
'start_date' => 'date|nullable',
|
||||
'target_date' => 'date|nullable',
|
||||
'notes' => 'max:65000',
|
||||
];
|
||||
|
||||
switch ($this->method()) {
|
||||
default:
|
||||
break;
|
||||
case 'PUT':
|
||||
case 'PATCH':
|
||||
/** @var PiggyBank $piggyBank */
|
||||
$piggyBank = $this->route()->parameter('piggyBank');
|
||||
$rules['name'] = 'required|between:1,255|uniquePiggyBankForUser:' . $piggyBank->id;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
}
|
57
app/Api/V1/Requests/PreferenceRequest.php
Normal file
57
app/Api/V1/Requests/PreferenceRequest.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* PreferenceRequest.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class PreferenceRequest
|
||||
*/
|
||||
class PreferenceRequest extends Request
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
// Only allow authenticated users
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
public function getAll(): array
|
||||
{
|
||||
return [
|
||||
'data' => $this->get('data'),
|
||||
];
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'data' => 'required|between:1,65000',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
482
app/Api/V1/Requests/RecurrenceRequest.php
Normal file
482
app/Api/V1/Requests/RecurrenceRequest.php
Normal file
@@ -0,0 +1,482 @@
|
||||
<?php
|
||||
/**
|
||||
* RecurrenceRequest.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Rules\BelongsUser;
|
||||
use Illuminate\Validation\Validator;
|
||||
use InvalidArgumentException;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class RecurrenceRequest
|
||||
*/
|
||||
class RecurrenceRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
// Only allow authenticated users
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
$return = [
|
||||
'recurrence' => [
|
||||
'type' => $this->string('type'),
|
||||
'title' => $this->string('title'),
|
||||
'description' => $this->string('description'),
|
||||
'first_date' => $this->date('first_date'),
|
||||
'repeat_until' => $this->date('repeat_until'),
|
||||
'repetitions' => $this->integer('nr_of_repetitions'),
|
||||
'apply_rules' => $this->boolean('apply_rules'),
|
||||
'active' => $this->boolean('active'),
|
||||
],
|
||||
'meta' => [
|
||||
'piggy_bank_id' => $this->integer('piggy_bank_id'),
|
||||
'piggy_bank_name' => $this->string('piggy_bank_name'),
|
||||
'tags' => explode(',', $this->string('tags')),
|
||||
],
|
||||
'transactions' => [],
|
||||
'repetitions' => [],
|
||||
];
|
||||
|
||||
// repetition data:
|
||||
/** @var array $repetitions */
|
||||
$repetitions = $this->get('repetitions');
|
||||
/** @var array $repetition */
|
||||
foreach ($repetitions as $repetition) {
|
||||
$return['repetitions'][] = [
|
||||
'type' => $repetition['type'],
|
||||
'moment' => $repetition['moment'],
|
||||
'skip' => (int)$repetition['skip'],
|
||||
'weekend' => (int)$repetition['weekend'],
|
||||
];
|
||||
}
|
||||
// transaction data:
|
||||
/** @var array $transactions */
|
||||
$transactions = $this->get('transactions');
|
||||
/** @var array $transaction */
|
||||
foreach ($transactions as $transaction) {
|
||||
$return['transactions'][] = [
|
||||
'amount' => $transaction['amount'],
|
||||
|
||||
'currency_id' => isset($transaction['currency_id']) ? (int)$transaction['currency_id'] : null,
|
||||
'currency_code' => $transaction['currency_code'] ?? null,
|
||||
|
||||
'foreign_amount' => $transaction['foreign_amount'] ?? null,
|
||||
'foreign_currency_id' => isset($transaction['foreign_currency_id']) ? (int)$transaction['foreign_currency_id'] : null,
|
||||
'foreign_currency_code' => $transaction['foreign_currency_code'] ?? null,
|
||||
|
||||
'budget_id' => isset($transaction['budget_id']) ? (int)$transaction['budget_id'] : null,
|
||||
'budget_name' => $transaction['budget_name'] ?? null,
|
||||
'category_id' => isset($transaction['category_id']) ? (int)$transaction['category_id'] : null,
|
||||
'category_name' => $transaction['category_name'] ?? null,
|
||||
|
||||
'source_id' => isset($transaction['source_id']) ? (int)$transaction['source_id'] : null,
|
||||
'source_name' => isset($transaction['source_name']) ? (string)$transaction['source_name'] : null,
|
||||
'destination_id' => isset($transaction['destination_id']) ? (int)$transaction['destination_id'] : null,
|
||||
'destination_name' => isset($transaction['destination_name']) ? (string)$transaction['destination_name'] : null,
|
||||
|
||||
'description' => $transaction['description'],
|
||||
];
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$today = new Carbon;
|
||||
$today->addDay();
|
||||
|
||||
return [
|
||||
'type' => 'required|in:withdrawal,transfer,deposit',
|
||||
'title' => 'required|between:1,255|uniqueObjectForUser:recurrences,title',
|
||||
'description' => 'between:1,65000',
|
||||
'first_date' => sprintf('required|date|after:%s', $today->format('Y-m-d')),
|
||||
'repeat_until' => sprintf('date|after:%s', $today->format('Y-m-d')),
|
||||
'nr_of_repetitions' => 'numeric|between:1,31',
|
||||
'apply_rules' => 'required|boolean',
|
||||
'active' => 'required|boolean',
|
||||
|
||||
// rules for meta values:
|
||||
'tags' => 'between:1,64000',
|
||||
'piggy_bank_id' => 'numeric',
|
||||
|
||||
// rules for repetitions.
|
||||
'repetitions.*.type' => 'required|in:daily,weekly,ndom,monthly,yearly',
|
||||
'repetitions.*.moment' => 'between:0,10',
|
||||
'repetitions.*.skip' => 'required|numeric|between:0,31',
|
||||
'repetitions.*.weekend' => 'required|numeric|min:1|max:4',
|
||||
|
||||
// rules for transactions.
|
||||
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id|required_without:transactions.*.currency_code',
|
||||
'transactions.*.currency_code' => 'min:3|max:3|exists:transaction_currencies,code|required_without:transactions.*.currency_id',
|
||||
'transactions.*.foreign_amount' => 'numeric|more:0',
|
||||
'transactions.*.foreign_currency_id' => 'numeric|exists:transaction_currencies,id',
|
||||
'transactions.*.foreign_currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
|
||||
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser],
|
||||
'transactions.*.category_name' => 'between:1,255|nullable',
|
||||
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser],
|
||||
'transactions.*.source_name' => 'between:1,255|nullable',
|
||||
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser],
|
||||
'transactions.*.destination_name' => 'between:1,255|nullable',
|
||||
'transactions.*.amount' => 'required|numeric|more:0',
|
||||
'transactions.*.description' => 'required|between:1,255',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the validator instance.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function withValidator(Validator $validator): void
|
||||
{
|
||||
$validator->after(
|
||||
function (Validator $validator) {
|
||||
$this->atLeastOneTransaction($validator);
|
||||
$this->atLeastOneRepetition($validator);
|
||||
$this->validRepeatsUntil($validator);
|
||||
$this->validRepetitionMoment($validator);
|
||||
$this->foreignCurrencyInformation($validator);
|
||||
$this->validateAccountInformation($validator);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an error when this asset account is invalid.
|
||||
*
|
||||
* @noinspection MoreThanThreeArgumentsInspection
|
||||
*
|
||||
* @param Validator $validator
|
||||
* @param int|null $accountId
|
||||
* @param null|string $accountName
|
||||
* @param string $idField
|
||||
* @param string $nameField
|
||||
*
|
||||
* @return null|Account
|
||||
*/
|
||||
protected function assetAccountExists(Validator $validator, ?int $accountId, ?string $accountName, string $idField, string $nameField): ?Account
|
||||
{
|
||||
$accountId = (int)$accountId;
|
||||
$accountName = (string)$accountName;
|
||||
// both empty? hard exit.
|
||||
if ($accountId < 1 && '' === $accountName) {
|
||||
$validator->errors()->add($idField, trans('validation.filled', ['attribute' => $idField]));
|
||||
|
||||
return null;
|
||||
}
|
||||
// ID belongs to user and is asset account:
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$repository->setUser(auth()->user());
|
||||
$set = $repository->getAccountsById([$accountId]);
|
||||
Log::debug(sprintf('Count of accounts found by ID %d is: %d', $accountId, $set->count()));
|
||||
if ($set->count() === 1) {
|
||||
/** @var Account $first */
|
||||
$first = $set->first();
|
||||
if ($first->accountType->type !== AccountType::ASSET) {
|
||||
$validator->errors()->add($idField, trans('validation.belongs_user'));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// we ignore the account name at this point.
|
||||
return $first;
|
||||
}
|
||||
|
||||
$account = $repository->findByName($accountName, [AccountType::ASSET]);
|
||||
if (null === $account) {
|
||||
$validator->errors()->add($nameField, trans('validation.belongs_user'));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the validator when there are no repetitions in the array of data.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*/
|
||||
protected function atLeastOneRepetition(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$repetitions = $data['repetitions'] ?? [];
|
||||
// need at least one transaction
|
||||
if (\count($repetitions) === 0) {
|
||||
$validator->errors()->add('description', trans('validation.at_least_one_repetition'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the validator when there are no transactions in the array of data.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*/
|
||||
protected function atLeastOneTransaction(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$transactions = $data['transactions'] ?? [];
|
||||
// need at least one transaction
|
||||
if (\count($transactions) === 0) {
|
||||
$validator->errors()->add('description', trans('validation.at_least_one_transaction'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO can be made a rule?
|
||||
* If the transactions contain foreign amounts, there must also be foreign currency information.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*/
|
||||
protected function foreignCurrencyInformation(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$transactions = $data['transactions'] ?? [];
|
||||
foreach ($transactions as $index => $transaction) {
|
||||
// must have currency info.
|
||||
if (isset($transaction['foreign_amount'])
|
||||
&& !(isset($transaction['foreign_currency_id'])
|
||||
|| isset($transaction['foreign_currency_code']))) {
|
||||
$validator->errors()->add(
|
||||
'transactions.' . $index . '.foreign_amount',
|
||||
trans('validation.require_currency_info')
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an error when the given opposing account (of type $type) is invalid.
|
||||
* Empty data is allowed, system will default to cash.
|
||||
*
|
||||
* @noinspection MoreThanThreeArgumentsInspection
|
||||
*
|
||||
* @param Validator $validator
|
||||
* @param string $type
|
||||
* @param int|null $accountId
|
||||
* @param null|string $accountName
|
||||
* @param string $idField
|
||||
*
|
||||
* @return null|Account
|
||||
*/
|
||||
protected function opposingAccountExists(Validator $validator, string $type, ?int $accountId, ?string $accountName, string $idField): ?Account
|
||||
{
|
||||
$accountId = (int)$accountId;
|
||||
$accountName = (string)$accountName;
|
||||
// both empty? done!
|
||||
if ($accountId < 1 && \strlen($accountName) === 0) {
|
||||
return null;
|
||||
}
|
||||
if ($accountId !== 0) {
|
||||
// ID belongs to user and is $type account:
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$repository->setUser(auth()->user());
|
||||
$set = $repository->getAccountsById([$accountId]);
|
||||
if ($set->count() === 1) {
|
||||
/** @var Account $first */
|
||||
$first = $set->first();
|
||||
if ($first->accountType->type !== $type) {
|
||||
$validator->errors()->add($idField, trans('validation.belongs_user'));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// we ignore the account name at this point.
|
||||
return $first;
|
||||
}
|
||||
}
|
||||
|
||||
// not having an opposing account by this name is NOT a problem.
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO can be a rule?
|
||||
*
|
||||
* Validates the given account information. Switches on given transaction type.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*/
|
||||
protected function validateAccountInformation(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$transactions = $data['transactions'] ?? [];
|
||||
$idField = 'description';
|
||||
$transactionType = $data['type'] ?? 'false';
|
||||
foreach ($transactions as $index => $transaction) {
|
||||
$sourceId = isset($transaction['source_id']) ? (int)$transaction['source_id'] : null;
|
||||
$sourceName = $transaction['source_name'] ?? null;
|
||||
$destinationId = isset($transaction['destination_id']) ? (int)$transaction['destination_id'] : null;
|
||||
$destinationName = $transaction['destination_name'] ?? null;
|
||||
$sourceAccount = null;
|
||||
$destinationAccount = null;
|
||||
switch ($transactionType) {
|
||||
case 'withdrawal':
|
||||
$idField = 'transactions.' . $index . '.source_id';
|
||||
$nameField = 'transactions.' . $index . '.source_name';
|
||||
$sourceAccount = $this->assetAccountExists($validator, $sourceId, $sourceName, $idField, $nameField);
|
||||
$idField = 'transactions.' . $index . '.destination_id';
|
||||
$destinationAccount = $this->opposingAccountExists($validator, AccountType::EXPENSE, $destinationId, $destinationName, $idField);
|
||||
break;
|
||||
case 'deposit':
|
||||
$idField = 'transactions.' . $index . '.source_id';
|
||||
$sourceAccount = $this->opposingAccountExists($validator, AccountType::REVENUE, $sourceId, $sourceName, $idField);
|
||||
|
||||
$idField = 'transactions.' . $index . '.destination_id';
|
||||
$nameField = 'transactions.' . $index . '.destination_name';
|
||||
$destinationAccount = $this->assetAccountExists($validator, $destinationId, $destinationName, $idField, $nameField);
|
||||
break;
|
||||
case 'transfer':
|
||||
$idField = 'transactions.' . $index . '.source_id';
|
||||
$nameField = 'transactions.' . $index . '.source_name';
|
||||
$sourceAccount = $this->assetAccountExists($validator, $sourceId, $sourceName, $idField, $nameField);
|
||||
|
||||
$idField = 'transactions.' . $index . '.destination_id';
|
||||
$nameField = 'transactions.' . $index . '.destination_name';
|
||||
$destinationAccount = $this->assetAccountExists($validator, $destinationId, $destinationName, $idField, $nameField);
|
||||
break;
|
||||
default:
|
||||
$validator->errors()->add($idField, trans('validation.invalid_account_info'));
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
// add some errors in case of same account submitted:
|
||||
if (null !== $sourceAccount && null !== $destinationAccount && $sourceAccount->id === $destinationAccount->id) {
|
||||
$validator->errors()->add($idField, trans('validation.source_equals_destination'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Validator $validator
|
||||
*/
|
||||
private function validRepeatsUntil(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$repetitions = $data['nr_of_repetitions'] ?? null;
|
||||
$repeatUntil = $data['repeat_until'] ?? null;
|
||||
if (null !== $repetitions && null !== $repeatUntil) {
|
||||
// expect a date OR count:
|
||||
$validator->errors()->add('repeat_until', trans('validation.require_repeat_until'));
|
||||
$validator->errors()->add('nr_of_repetitions', trans('validation.require_repeat_until'));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO merge this in a rule somehow.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*/
|
||||
private function validRepetitionMoment(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$repetitions = $data['repetitions'] ?? [];
|
||||
/**
|
||||
* @var int $index
|
||||
* @var array $repetition
|
||||
*/
|
||||
foreach ($repetitions as $index => $repetition) {
|
||||
switch ($repetition['type']) {
|
||||
default:
|
||||
$validator->errors()->add(sprintf('repetitions.%d.type', $index), trans('validation.valid_recurrence_rep_type'));
|
||||
|
||||
return;
|
||||
case 'daily':
|
||||
if ('' !== (string)$repetition['moment']) {
|
||||
$validator->errors()->add(sprintf('repetitions.%d.moment', $index), trans('validation.valid_recurrence_rep_moment'));
|
||||
}
|
||||
|
||||
return;
|
||||
case 'monthly':
|
||||
$dayOfMonth = (int)$repetition['moment'];
|
||||
if ($dayOfMonth < 1 || $dayOfMonth > 31) {
|
||||
$validator->errors()->add(sprintf('repetitions.%d.moment', $index), trans('validation.valid_recurrence_rep_moment'));
|
||||
}
|
||||
|
||||
return;
|
||||
case 'ndom':
|
||||
$parameters = explode(',', $repetition['moment']);
|
||||
if (\count($parameters) !== 2) {
|
||||
$validator->errors()->add(sprintf('repetitions.%d.moment', $index), trans('validation.valid_recurrence_rep_moment'));
|
||||
|
||||
return;
|
||||
}
|
||||
$nthDay = (int)($parameters[0] ?? 0.0);
|
||||
$dayOfWeek = (int)($parameters[1] ?? 0.0);
|
||||
if ($nthDay < 1 || $nthDay > 5) {
|
||||
$validator->errors()->add(sprintf('repetitions.%d.moment', $index), trans('validation.valid_recurrence_rep_moment'));
|
||||
|
||||
return;
|
||||
}
|
||||
if ($dayOfWeek < 1 || $dayOfWeek > 7) {
|
||||
$validator->errors()->add(sprintf('repetitions.%d.moment', $index), trans('validation.valid_recurrence_rep_moment'));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
case 'weekly':
|
||||
$dayOfWeek = (int)$repetition['moment'];
|
||||
if ($dayOfWeek < 1 || $dayOfWeek > 7) {
|
||||
$validator->errors()->add(sprintf('repetitions.%d.moment', $index), trans('validation.valid_recurrence_rep_moment'));
|
||||
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 'yearly':
|
||||
try {
|
||||
Carbon::createFromFormat('Y-m-d', $repetition['moment']);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
$validator->errors()->add(sprintf('repetitions.%d.moment', $index), trans('validation.valid_recurrence_rep_moment'));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Request.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -18,11 +19,13 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests;
|
||||
|
||||
use FireflyIII\Http\Requests\Request as FireflyIIIRequest;
|
||||
|
||||
/**
|
||||
* Class Request.
|
||||
*/
|
||||
|
79
app/Api/V1/Requests/RuleGroupRequest.php
Normal file
79
app/Api/V1/Requests/RuleGroupRequest.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/**
|
||||
* RuleGroupRequest.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests;
|
||||
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Class RuleGroupRequest
|
||||
*/
|
||||
class RuleGroupRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
// Only allow authenticated users
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
return [
|
||||
'title' => $this->string('title'),
|
||||
'description' => $this->string('description'),
|
||||
'active' => $this->boolean('active'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'title' => 'required|between:1,100|uniqueObjectForUser:rule_groups,title',
|
||||
'description' => 'between:1,5000|nullable',
|
||||
'active' => 'required|boolean',
|
||||
];
|
||||
switch ($this->method()) {
|
||||
default:
|
||||
break;
|
||||
case 'PUT':
|
||||
case 'PATCH':
|
||||
/** @var RuleGroup $ruleGroup */
|
||||
$ruleGroup = $this->route()->parameter('ruleGroup');
|
||||
$rules['title'] = 'required|between:1,100|uniqueObjectForUser:rule_groups,title,' . $ruleGroup->id;
|
||||
break;
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
156
app/Api/V1/Requests/RuleRequest.php
Normal file
156
app/Api/V1/Requests/RuleRequest.php
Normal file
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
/**
|
||||
* RuleRequest.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests;
|
||||
|
||||
use Illuminate\Validation\Validator;
|
||||
|
||||
|
||||
/**
|
||||
* Class RuleRequest
|
||||
*/
|
||||
class RuleRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
// Only allow authenticated users
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
$data = [
|
||||
'title' => $this->string('title'),
|
||||
'description' => $this->string('description'),
|
||||
'rule_group_id' => $this->integer('rule_group_id'),
|
||||
'rule_group_title' => $this->string('rule_group_title'),
|
||||
'trigger' => $this->string('trigger'),
|
||||
'strict' => $this->boolean('strict'),
|
||||
'stop-processing' => $this->boolean('stop_processing'),
|
||||
'active' => $this->boolean('active'),
|
||||
'rule-triggers' => [],
|
||||
'rule-actions' => [],
|
||||
];
|
||||
|
||||
foreach ($this->get('rule-triggers') as $trigger) {
|
||||
$data['rule-triggers'][] = [
|
||||
'name' => $trigger['name'],
|
||||
'value' => $trigger['value'],
|
||||
'stop-processing' => (int)($trigger['stop-processing'] ?? 0) === 1,
|
||||
];
|
||||
}
|
||||
foreach ($this->get('rule-actions') as $action) {
|
||||
$data['rule-actions'][] = [
|
||||
'name' => $action['name'],
|
||||
'value' => $action['value'],
|
||||
'stop-processing' => (int)($action['stop-processing'] ?? 0) === 1,
|
||||
];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$validTriggers = array_keys(config('firefly.rule-triggers'));
|
||||
$validActions = array_keys(config('firefly.rule-actions'));
|
||||
|
||||
// some actions require text:
|
||||
$contextActions = implode(',', config('firefly.rule-actions-text'));
|
||||
|
||||
$rules = [
|
||||
'title' => 'required|between:1,100|uniqueObjectForUser:rules,title',
|
||||
'description' => 'between:1,5000|nullable',
|
||||
'rule_group_id' => 'required|belongsToUser:rule_groups|required_without:rule_group_title',
|
||||
'rule_group_title' => 'nullable|between:1,255|required_without:rule_group_id|belongsToUser:rule_groups,title',
|
||||
'trigger' => 'required|in:store-journal,update-journal',
|
||||
'rule-triggers.*.name' => 'required|in:' . implode(',', $validTriggers),
|
||||
'rule-triggers.*.stop-processing' => 'boolean',
|
||||
'rule-triggers.*.value' => 'required|min:1|ruleTriggerValue', //
|
||||
'rule-actions.*.name' => 'required|in:' . implode(',', $validActions),
|
||||
'rule-actions.*.value' => 'required_if:rule-action.*.type,' . $contextActions . '|ruleActionValue',
|
||||
'rule-actions.*.stop-processing' => 'boolean',
|
||||
'strict' => 'required|boolean',
|
||||
'stop_processing' => 'required|boolean',
|
||||
'active' => 'required|boolean',
|
||||
];
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the validator instance.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function withValidator(Validator $validator): void
|
||||
{
|
||||
$validator->after(
|
||||
function (Validator $validator) {
|
||||
$this->atLeastOneTrigger($validator);
|
||||
$this->atLeastOneAction($validator);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the validator when there are no repetitions in the array of data.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*/
|
||||
protected function atLeastOneAction(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$repetitions = $data['rule-actions'] ?? [];
|
||||
// need at least one transaction
|
||||
if (\count($repetitions) === 0) {
|
||||
$validator->errors()->add('title', trans('validation.at_least_one_action'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the validator when there are no repetitions in the array of data.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*/
|
||||
protected function atLeastOneTrigger(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$repetitions = $data['rule-triggers'] ?? [];
|
||||
// need at least one transaction
|
||||
if (\count($repetitions) === 0) {
|
||||
$validator->errors()->add('title', trans('validation.at_least_one_trigger'));
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* TransactionRequest.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -80,19 +81,19 @@ class TransactionRequest extends Request
|
||||
$array = [
|
||||
'description' => $transaction['description'] ?? null,
|
||||
'amount' => $transaction['amount'],
|
||||
'currency_id' => isset($transaction['currency_id']) ? intval($transaction['currency_id']) : null,
|
||||
'currency_code' => isset($transaction['currency_code']) ? $transaction['currency_code'] : null,
|
||||
'currency_id' => isset($transaction['currency_id']) ? (int)$transaction['currency_id'] : null,
|
||||
'currency_code' => $transaction['currency_code'] ?? null,
|
||||
'foreign_amount' => $transaction['foreign_amount'] ?? null,
|
||||
'foreign_currency_id' => isset($transaction['foreign_currency_id']) ? intval($transaction['foreign_currency_id']) : null,
|
||||
'foreign_currency_id' => isset($transaction['foreign_currency_id']) ? (int)$transaction['foreign_currency_id'] : null,
|
||||
'foreign_currency_code' => $transaction['foreign_currency_code'] ?? null,
|
||||
'budget_id' => isset($transaction['budget_id']) ? intval($transaction['budget_id']) : null,
|
||||
'budget_id' => isset($transaction['budget_id']) ? (int)$transaction['budget_id'] : null,
|
||||
'budget_name' => $transaction['budget_name'] ?? null,
|
||||
'category_id' => isset($transaction['category_id']) ? intval($transaction['category_id']) : null,
|
||||
'category_id' => isset($transaction['category_id']) ? (int)$transaction['category_id'] : null,
|
||||
'category_name' => $transaction['category_name'] ?? null,
|
||||
'source_id' => isset($transaction['source_id']) ? intval($transaction['source_id']) : null,
|
||||
'source_name' => isset($transaction['source_name']) ? strval($transaction['source_name']) : null,
|
||||
'destination_id' => isset($transaction['destination_id']) ? intval($transaction['destination_id']) : null,
|
||||
'destination_name' => isset($transaction['destination_name']) ? strval($transaction['destination_name']) : null,
|
||||
'source_id' => isset($transaction['source_id']) ? (int)$transaction['source_id'] : null,
|
||||
'source_name' => isset($transaction['source_name']) ? (string)$transaction['source_name'] : null,
|
||||
'destination_id' => isset($transaction['destination_id']) ? (int)$transaction['destination_id'] : null,
|
||||
'destination_name' => isset($transaction['destination_name']) ? (string)$transaction['destination_name'] : null,
|
||||
'reconciled' => $transaction['reconciled'] ?? false,
|
||||
'identifier' => $index,
|
||||
];
|
||||
@@ -187,22 +188,26 @@ class TransactionRequest extends Request
|
||||
/**
|
||||
* Throws an error when this asset account is invalid.
|
||||
*
|
||||
* @noinspection MoreThanThreeArgumentsInspection
|
||||
*
|
||||
* @param Validator $validator
|
||||
* @param int|null $accountId
|
||||
* @param null|string $accountName
|
||||
* @param string $idField
|
||||
* @param string $nameField
|
||||
*
|
||||
* @return null|Account
|
||||
*/
|
||||
protected function assetAccountExists(Validator $validator, ?int $accountId, ?string $accountName, string $idField, string $nameField): void
|
||||
protected function assetAccountExists(Validator $validator, ?int $accountId, ?string $accountName, string $idField, string $nameField): ?Account
|
||||
{
|
||||
|
||||
$accountId = intval($accountId);
|
||||
$accountName = strval($accountName);
|
||||
$accountId = (int)$accountId;
|
||||
$accountName = (string)$accountName;
|
||||
// both empty? hard exit.
|
||||
if ($accountId < 1 && strlen($accountName) === 0) {
|
||||
if ($accountId < 1 && \strlen($accountName) === 0) {
|
||||
$validator->errors()->add($idField, trans('validation.filled', ['attribute' => $idField]));
|
||||
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
// ID belongs to user and is asset account:
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
@@ -215,19 +220,21 @@ class TransactionRequest extends Request
|
||||
if ($first->accountType->type !== AccountType::ASSET) {
|
||||
$validator->errors()->add($idField, trans('validation.belongs_user'));
|
||||
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
// we ignore the account name at this point.
|
||||
return;
|
||||
return $first;
|
||||
}
|
||||
|
||||
$account = $repository->findByName($accountName, [AccountType::ASSET]);
|
||||
if (is_null($account)) {
|
||||
if (null === $account) {
|
||||
$validator->errors()->add($nameField, trans('validation.belongs_user'));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return;
|
||||
return $account;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -240,7 +247,7 @@ class TransactionRequest extends Request
|
||||
$data = $validator->getData();
|
||||
$transactions = $data['transactions'] ?? [];
|
||||
// need at least one transaction
|
||||
if (count($transactions) === 0) {
|
||||
if (\count($transactions) === 0) {
|
||||
$validator->errors()->add('description', trans('validation.at_least_one_transaction'));
|
||||
}
|
||||
}
|
||||
@@ -251,20 +258,20 @@ class TransactionRequest extends Request
|
||||
*
|
||||
* @param Validator $validator
|
||||
*/
|
||||
protected function checkValidDescriptions(Validator $validator)
|
||||
protected function checkValidDescriptions(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$transactions = $data['transactions'] ?? [];
|
||||
$journalDescription = strval($data['description'] ?? '');
|
||||
$journalDescription = (string)($data['description'] ?? '');
|
||||
$validDescriptions = 0;
|
||||
foreach ($transactions as $index => $transaction) {
|
||||
if (strlen(strval($transaction['description'] ?? '')) > 0) {
|
||||
if (\strlen((string)($transaction['description'] ?? '')) > 0) {
|
||||
$validDescriptions++;
|
||||
}
|
||||
}
|
||||
|
||||
// no valid descriptions and empty journal description? error.
|
||||
if ($validDescriptions === 0 && strlen($journalDescription) === 0) {
|
||||
if ($validDescriptions === 0 && \strlen($journalDescription) === 0) {
|
||||
$validator->errors()->add('description', trans('validation.filled', ['attribute' => trans('validation.attributes.description')]));
|
||||
}
|
||||
|
||||
@@ -281,9 +288,9 @@ class TransactionRequest extends Request
|
||||
$data = $validator->getData();
|
||||
$transactions = $data['transactions'] ?? [];
|
||||
foreach ($transactions as $index => $transaction) {
|
||||
$description = strval($transaction['description'] ?? '');
|
||||
$description = (string)($transaction['description'] ?? '');
|
||||
// filled description is mandatory for split transactions.
|
||||
if (count($transactions) > 1 && strlen($description) === 0) {
|
||||
if (\count($transactions) > 1 && \strlen($description) === 0) {
|
||||
$validator->errors()->add(
|
||||
'transactions.' . $index . '.description',
|
||||
trans('validation.filled', ['attribute' => trans('validation.attributes.transaction_description')])
|
||||
@@ -301,9 +308,9 @@ class TransactionRequest extends Request
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$transactions = $data['transactions'] ?? [];
|
||||
$journalDescription = strval($data['description'] ?? '');
|
||||
$journalDescription = (string)($data['description'] ?? '');
|
||||
foreach ($transactions as $index => $transaction) {
|
||||
$description = strval($transaction['description'] ?? '');
|
||||
$description = (string)($transaction['description'] ?? '');
|
||||
// description cannot be equal to journal description.
|
||||
if ($description === $journalDescription) {
|
||||
$validator->errors()->add('transactions.' . $index . '.description', trans('validation.equal_description'));
|
||||
@@ -312,6 +319,8 @@ class TransactionRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO can be made a rule?
|
||||
*
|
||||
* If the transactions contain foreign amounts, there must also be foreign currency information.
|
||||
*
|
||||
* @param Validator $validator
|
||||
@@ -337,18 +346,23 @@ class TransactionRequest extends Request
|
||||
* Throws an error when the given opposing account (of type $type) is invalid.
|
||||
* Empty data is allowed, system will default to cash.
|
||||
*
|
||||
* @noinspection MoreThanThreeArgumentsInspection
|
||||
*
|
||||
* @param Validator $validator
|
||||
* @param string $type
|
||||
* @param int|null $accountId
|
||||
* @param null|string $accountName
|
||||
* @param string $idField
|
||||
*
|
||||
* @return null|Account
|
||||
*/
|
||||
protected function opposingAccountExists(Validator $validator, string $type, ?int $accountId, ?string $accountName, string $idField): void {
|
||||
$accountId = intval($accountId);
|
||||
$accountName = strval($accountName);
|
||||
protected function opposingAccountExists(Validator $validator, string $type, ?int $accountId, ?string $accountName, string $idField): ?Account
|
||||
{
|
||||
$accountId = (int)$accountId;
|
||||
$accountName = (string)$accountName;
|
||||
// both empty? done!
|
||||
if ($accountId < 1 && strlen($accountName) === 0) {
|
||||
return;
|
||||
if ($accountId < 1 && \strlen($accountName) === 0) {
|
||||
return null;
|
||||
}
|
||||
if ($accountId !== 0) {
|
||||
// ID belongs to user and is $type account:
|
||||
@@ -362,16 +376,16 @@ class TransactionRequest extends Request
|
||||
if ($first->accountType->type !== $type) {
|
||||
$validator->errors()->add($idField, trans('validation.belongs_user'));
|
||||
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
// we ignore the account name at this point.
|
||||
return;
|
||||
return $first;
|
||||
}
|
||||
}
|
||||
|
||||
// not having an opposing account by this name is NOT a problem.
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -389,47 +403,55 @@ class TransactionRequest extends Request
|
||||
// the journal may exist in the request:
|
||||
/** @var Transaction $transaction */
|
||||
$transaction = $this->route()->parameter('transaction');
|
||||
if (is_null($transaction)) {
|
||||
if (null === $transaction) {
|
||||
return; // @codeCoverageIgnore
|
||||
}
|
||||
$data['type'] = strtolower($transaction->transactionJournal->transactionType->type);
|
||||
}
|
||||
foreach ($transactions as $index => $transaction) {
|
||||
$sourceId = isset($transaction['source_id']) ? intval($transaction['source_id']) : null;
|
||||
$sourceName = $transaction['source_name'] ?? null;
|
||||
$destinationId = isset($transaction['destination_id']) ? intval($transaction['destination_id']) : null;
|
||||
$destinationName = $transaction['destination_name'] ?? null;
|
||||
|
||||
$sourceId = isset($transaction['source_id']) ? (int)$transaction['source_id'] : null;
|
||||
$sourceName = $transaction['source_name'] ?? null;
|
||||
$destinationId = isset($transaction['destination_id']) ? (int)$transaction['destination_id'] : null;
|
||||
$destinationName = $transaction['destination_name'] ?? null;
|
||||
$sourceAccount = null;
|
||||
$destinationAccount = null;
|
||||
switch ($data['type']) {
|
||||
case 'withdrawal':
|
||||
$idField = 'transactions.' . $index . '.source_id';
|
||||
$nameField = 'transactions.' . $index . '.source_name';
|
||||
$this->assetAccountExists($validator, $sourceId, $sourceName, $idField, $nameField);
|
||||
|
||||
$idField = 'transactions.' . $index . '.destination_id';
|
||||
$this->opposingAccountExists($validator, AccountType::EXPENSE, $destinationId, $destinationName, $idField);
|
||||
$idField = 'transactions.' . $index . '.source_id';
|
||||
$nameField = 'transactions.' . $index . '.source_name';
|
||||
$sourceAccount = $this->assetAccountExists($validator, $sourceId, $sourceName, $idField, $nameField);
|
||||
$idField = 'transactions.' . $index . '.destination_id';
|
||||
$destinationAccount = $this->opposingAccountExists($validator, AccountType::EXPENSE, $destinationId, $destinationName, $idField);
|
||||
break;
|
||||
case 'deposit':
|
||||
$idField = 'transactions.' . $index . '.source_id';
|
||||
$this->opposingAccountExists($validator, AccountType::REVENUE, $sourceId, $sourceName, $idField);
|
||||
$idField = 'transactions.' . $index . '.source_id';
|
||||
$sourceAccount = $this->opposingAccountExists($validator, AccountType::REVENUE, $sourceId, $sourceName, $idField);
|
||||
|
||||
$idField = 'transactions.' . $index . '.destination_id';
|
||||
$nameField = 'transactions.' . $index . '.destination_name';
|
||||
$this->assetAccountExists($validator, $destinationId, $destinationName, $idField, $nameField);
|
||||
$idField = 'transactions.' . $index . '.destination_id';
|
||||
$nameField = 'transactions.' . $index . '.destination_name';
|
||||
$destinationAccount = $this->assetAccountExists($validator, $destinationId, $destinationName, $idField, $nameField);
|
||||
break;
|
||||
case 'transfer':
|
||||
$idField = 'transactions.' . $index . '.source_id';
|
||||
$nameField = 'transactions.' . $index . '.source_name';
|
||||
$this->assetAccountExists($validator, $sourceId, $sourceName, $idField, $nameField);
|
||||
$idField = 'transactions.' . $index . '.source_id';
|
||||
$nameField = 'transactions.' . $index . '.source_name';
|
||||
$sourceAccount = $this->assetAccountExists($validator, $sourceId, $sourceName, $idField, $nameField);
|
||||
|
||||
$idField = 'transactions.' . $index . '.destination_id';
|
||||
$nameField = 'transactions.' . $index . '.destination_name';
|
||||
$this->assetAccountExists($validator, $destinationId, $destinationName, $idField, $nameField);
|
||||
$idField = 'transactions.' . $index . '.destination_id';
|
||||
$nameField = 'transactions.' . $index . '.destination_name';
|
||||
$destinationAccount = $this->assetAccountExists($validator, $destinationId, $destinationName, $idField, $nameField);
|
||||
break;
|
||||
default:
|
||||
throw new FireflyException(sprintf('The validator cannot handle transaction type "%s" in validateAccountInformation().', $data['type']));
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new FireflyException(
|
||||
sprintf('The validator cannot handle transaction type "%s" in validateAccountInformation().', $data['type'])
|
||||
);
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
}
|
||||
// add some errors in case of same account submitted:
|
||||
if (null !== $sourceAccount && null !== $destinationAccount && $sourceAccount->id === $destinationAccount->id) {
|
||||
$validator->errors()->add($idField, trans('validation.source_equals_destination'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,10 +460,10 @@ class TransactionRequest extends Request
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
protected function validateSplitAccounts(Validator $validator)
|
||||
protected function validateSplitAccounts(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$count = isset($data['transactions']) ? count($data['transactions']) : 0;
|
||||
$count = isset($data['transactions']) ? \count($data['transactions']) : 0;
|
||||
if ($count < 2) {
|
||||
return;
|
||||
}
|
||||
@@ -451,7 +473,7 @@ class TransactionRequest extends Request
|
||||
// the journal may exist in the request:
|
||||
/** @var Transaction $transaction */
|
||||
$transaction = $this->route()->parameter('transaction');
|
||||
if (is_null($transaction)) {
|
||||
if (null === $transaction) {
|
||||
return;
|
||||
}
|
||||
$data['type'] = strtolower($transaction->transactionJournal->transactionType->type);
|
||||
@@ -463,25 +485,25 @@ class TransactionRequest extends Request
|
||||
$destinations = [];
|
||||
|
||||
foreach ($data['transactions'] as $transaction) {
|
||||
$sources[] = isset($transaction['source_id']) ? intval($transaction['source_id']) : 0;
|
||||
$destinations[] = isset($transaction['destination_id']) ? intval($transaction['destination_id']) : 0;
|
||||
$sources[] = isset($transaction['source_id']) ? (int)$transaction['source_id'] : 0;
|
||||
$destinations[] = isset($transaction['destination_id']) ? (int)$transaction['destination_id'] : 0;
|
||||
}
|
||||
$destinations = array_unique($destinations);
|
||||
$sources = array_unique($sources);
|
||||
// switch on type:
|
||||
switch ($data['type']) {
|
||||
case 'withdrawal':
|
||||
if (count($sources) > 1) {
|
||||
if (\count($sources) > 1) {
|
||||
$validator->errors()->add('transactions.0.source_id', trans('validation.all_accounts_equal'));
|
||||
}
|
||||
break;
|
||||
case 'deposit':
|
||||
if (count($destinations) > 1) {
|
||||
if (\count($destinations) > 1) {
|
||||
$validator->errors()->add('transactions.0.destination_id', trans('validation.all_accounts_equal'));
|
||||
}
|
||||
break;
|
||||
case 'transfer':
|
||||
if (count($sources) > 1 || count($destinations) > 1) {
|
||||
if (\count($sources) > 1 || \count($destinations) > 1) {
|
||||
$validator->errors()->add('transactions.0.source_id', trans('validation.all_accounts_equal'));
|
||||
$validator->errors()->add('transactions.0.destination_id', trans('validation.all_accounts_equal'));
|
||||
}
|
||||
@@ -493,8 +515,6 @@ class TransactionRequest extends Request
|
||||
);
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* UserRequest.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -86,4 +87,4 @@ class UserRequest extends Request
|
||||
return $rules;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* CreateExport.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
@@ -60,17 +62,6 @@ class CreateExport extends Command
|
||||
{--with_uploads : Include user\'s uploads?}';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's five its fine.
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
@@ -80,7 +71,7 @@ class CreateExport extends Command
|
||||
if (!$this->verifyAccessToken()) {
|
||||
$this->error('Invalid access token.');
|
||||
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
$this->line('Full export is running...');
|
||||
// make repositories
|
||||
@@ -94,15 +85,15 @@ class CreateExport extends Command
|
||||
$journalRepository = app(JournalRepositoryInterface::class);
|
||||
|
||||
// set user
|
||||
$user = $userRepository->find(intval($this->option('user')));
|
||||
$user = $userRepository->findNull((int)$this->option('user'));
|
||||
$jobRepository->setUser($user);
|
||||
$journalRepository->setUser($user);
|
||||
$accountRepository->setUser($user);
|
||||
|
||||
// first date
|
||||
$firstJournal = $journalRepository->first();
|
||||
$firstJournal = $journalRepository->firstNull();
|
||||
$first = new Carbon;
|
||||
if (null !== $firstJournal->id) {
|
||||
if (null !== $firstJournal) {
|
||||
$first = $firstJournal->date;
|
||||
}
|
||||
|
||||
@@ -141,6 +132,6 @@ class CreateExport extends Command
|
||||
$this->line('The export has finished! You can find the ZIP file in this location:');
|
||||
$this->line(storage_path(sprintf('export/%s', $fileName)));
|
||||
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* CreateImport.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,20 +19,20 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
|
||||
use Artisan;
|
||||
use Exception;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Import\Logging\CommandHandler;
|
||||
use FireflyIII\Import\Prerequisites\PrerequisitesInterface;
|
||||
use FireflyIII\Import\Routine\RoutineInterface;
|
||||
use FireflyIII\Import\Storage\ImportArrayStorage;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
use Monolog\Formatter\LineFormatter;
|
||||
use Preferences;
|
||||
|
||||
/**
|
||||
@@ -54,150 +55,239 @@ class CreateImport extends Command
|
||||
*/
|
||||
protected $signature
|
||||
= 'firefly:create-import
|
||||
{file : The file to import.}
|
||||
{configuration : The configuration file to use for the import.}
|
||||
{file? : The file to import.}
|
||||
{configuration? : The configuration file to use for the import.}
|
||||
{--type=csv : The file type of the import.}
|
||||
{--user= : The user ID that the import should import for.}
|
||||
{--provider=file : The file type of the import.}
|
||||
{--user=1 : The user ID that the import should import for.}
|
||||
{--token= : The user\'s access token.}
|
||||
{--start : Starts the job immediately.}';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the command.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength) // cannot be helped
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's five exactly.
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): int
|
||||
{
|
||||
if (!$this->verifyAccessToken()) {
|
||||
$this->error('Invalid access token.');
|
||||
$this->errorLine('Invalid access token.');
|
||||
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
/** @var UserRepositoryInterface $userRepository */
|
||||
$userRepository = app(UserRepositoryInterface::class);
|
||||
$file = $this->argument('file');
|
||||
$configuration = $this->argument('configuration');
|
||||
$user = $userRepository->find(intval($this->option('user')));
|
||||
$cwd = getcwd();
|
||||
$type = strtolower($this->option('type'));
|
||||
$userRepository = app(UserRepositoryInterface::class);
|
||||
$file = (string)$this->argument('file');
|
||||
$configuration = (string)$this->argument('configuration');
|
||||
$user = $userRepository->findNull((int)$this->option('user'));
|
||||
$cwd = getcwd();
|
||||
$type = strtolower((string)$this->option('type'));
|
||||
$provider = strtolower((string)$this->option('provider'));
|
||||
$configurationData = [];
|
||||
|
||||
if (!$this->validArguments()) {
|
||||
return;
|
||||
$this->errorLine('Invalid arguments.');
|
||||
|
||||
return 1;
|
||||
}
|
||||
if (\strlen($configuration) > 0) {
|
||||
$configurationData = json_decode(file_get_contents($configuration), true);
|
||||
if (null === $configurationData) {
|
||||
$this->errorLine(sprintf('Firefly III cannot read the contents of configuration file "%s" (working directory: "%s").', $configuration, $cwd));
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
$configurationData = json_decode(file_get_contents($configuration), true);
|
||||
if (null === $configurationData) {
|
||||
$this->error(sprintf('Firefly III cannot read the contents of configuration file "%s" (working directory: "%s").', $configuration, $cwd));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->line(sprintf('Going to create a job to import file: %s', $file));
|
||||
$this->line(sprintf('Using configuration file: %s', $configuration));
|
||||
$this->line(sprintf('Import into user: #%d (%s)', $user->id, $user->email));
|
||||
$this->line(sprintf('Type of import: %s', $type));
|
||||
$this->infoLine(sprintf('Going to create a job to import file: %s', $file));
|
||||
$this->infoLine(sprintf('Using configuration file: %s', $configuration));
|
||||
$this->infoLine(sprintf('Import into user: #%d (%s)', $user->id, $user->email));
|
||||
$this->infoLine(sprintf('Type of import: %s', $provider));
|
||||
|
||||
/** @var ImportJobRepositoryInterface $jobRepository */
|
||||
$jobRepository = app(ImportJobRepositoryInterface::class);
|
||||
$jobRepository->setUser($user);
|
||||
$job = $jobRepository->create($type);
|
||||
$this->line(sprintf('Created job "%s"', $job->key));
|
||||
$importJob = $jobRepository->create($provider);
|
||||
$this->infoLine(sprintf('Created job "%s"', $importJob->key));
|
||||
|
||||
Artisan::call('firefly:encrypt-file', ['file' => $file, 'key' => $job->key]);
|
||||
$this->line('Stored import data...');
|
||||
|
||||
$jobRepository->setConfiguration($job, $configurationData);
|
||||
$jobRepository->updateStatus($job, 'configured');
|
||||
$this->line('Stored configuration...');
|
||||
|
||||
if (true === $this->option('start')) {
|
||||
$this->line('The import will start in a moment. This process is not visible...');
|
||||
Log::debug('Go for import!');
|
||||
|
||||
// normally would refer to other firefly:start-import but that doesn't seem to work all to well...
|
||||
$monolog = Log::getMonolog();
|
||||
$handler = new CommandHandler($this);
|
||||
$formatter = new LineFormatter(null, null, false, true);
|
||||
$handler->setFormatter($formatter);
|
||||
$monolog->pushHandler($handler);
|
||||
|
||||
// start the actual routine:
|
||||
$type = 'csv' === $job->file_type ? 'file' : $job->file_type;
|
||||
$key = sprintf('import.routine.%s', $type);
|
||||
$className = config($key);
|
||||
if (null === $className || !class_exists($className)) {
|
||||
throw new FireflyException(sprintf('Cannot find import routine class for job of type "%s".', $type)); // @codeCoverageIgnore
|
||||
// make sure that job has no prerequisites.
|
||||
if ((bool)config(sprintf('import.has_prereq.%s', $provider))) {
|
||||
// make prerequisites thing.
|
||||
$class = (string)config(sprintf('import.prerequisites.%s', $provider));
|
||||
if (!class_exists($class)) {
|
||||
throw new FireflyException(sprintf('No class to handle prerequisites for "%s".', $provider)); // @codeCoverageIgnore
|
||||
}
|
||||
/** @var RoutineInterface $routine */
|
||||
$routine = app($className);
|
||||
$routine->setJob($job);
|
||||
$routine->run();
|
||||
/** @var PrerequisitesInterface $object */
|
||||
$object = app($class);
|
||||
$object->setUser($user);
|
||||
if (!$object->isComplete()) {
|
||||
$this->errorLine(sprintf('Import provider "%s" has prerequisites that can only be filled in using the browser.', $provider));
|
||||
|
||||
// give feedback.
|
||||
/** @var MessageBag $error */
|
||||
foreach ($routine->getErrors() as $index => $error) {
|
||||
$this->error(sprintf('Error importing line #%d: %s', $index, $error));
|
||||
return 1;
|
||||
}
|
||||
$this->line(
|
||||
sprintf(
|
||||
'The import has finished. %d transactions have been imported out of %d records.', $routine->getJournals()->count(), $routine->getLines()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// store file as attachment.
|
||||
if (\strlen($file) > 0) {
|
||||
$messages = $jobRepository->storeCLIUpload($importJob, 'import_file', $file);
|
||||
if ($messages->count() > 0) {
|
||||
$this->errorLine($messages->first());
|
||||
|
||||
return 1;
|
||||
}
|
||||
$this->infoLine('File content saved.');
|
||||
}
|
||||
|
||||
$this->infoLine('Job configuration saved.');
|
||||
$jobRepository->setConfiguration($importJob, $configurationData);
|
||||
$jobRepository->setStatus($importJob, 'ready_to_run');
|
||||
|
||||
|
||||
if (true === $this->option('start')) {
|
||||
$this->infoLine('The has started. The process is not visible. Please wait.');
|
||||
Log::debug('Go for import!');
|
||||
|
||||
// run it!
|
||||
$key = sprintf('import.routine.%s', $provider);
|
||||
$className = config($key);
|
||||
if (null === $className || !class_exists($className)) {
|
||||
// @codeCoverageIgnoreStart
|
||||
$this->errorLine(sprintf('No routine for provider "%s"', $provider));
|
||||
|
||||
return 1;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
// keep repeating this call until job lands on "provider_finished"
|
||||
$valid = ['provider_finished'];
|
||||
$count = 0;
|
||||
while (!\in_array($importJob->status, $valid, true) && $count < 6) {
|
||||
Log::debug(sprintf('Now in loop #%d.', $count + 1));
|
||||
/** @var RoutineInterface $routine */
|
||||
$routine = app($className);
|
||||
$routine->setImportJob($importJob);
|
||||
try {
|
||||
$routine->run();
|
||||
} catch (FireflyException|Exception $e) {
|
||||
$message = 'The import routine crashed: ' . $e->getMessage();
|
||||
Log::error($message);
|
||||
Log::error($e->getTraceAsString());
|
||||
|
||||
// set job errored out:
|
||||
$jobRepository->setStatus($importJob, 'error');
|
||||
$this->errorLine($message);
|
||||
|
||||
return 1;
|
||||
}
|
||||
$count++;
|
||||
}
|
||||
if ($importJob->status === 'provider_finished') {
|
||||
$this->infoLine('Import has finished. Please wait for storage of data.');
|
||||
// set job to be storing data:
|
||||
$jobRepository->setStatus($importJob, 'storing_data');
|
||||
|
||||
/** @var ImportArrayStorage $storage */
|
||||
$storage = app(ImportArrayStorage::class);
|
||||
$storage->setImportJob($importJob);
|
||||
|
||||
try {
|
||||
$storage->store();
|
||||
} catch (FireflyException|Exception $e) {
|
||||
$message = 'The import routine crashed: ' . $e->getMessage();
|
||||
Log::error($message);
|
||||
Log::error($e->getTraceAsString());
|
||||
|
||||
// set job errored out:
|
||||
$jobRepository->setStatus($importJob, 'error');
|
||||
$this->errorLine($message);
|
||||
|
||||
return 1;
|
||||
}
|
||||
// set storage to be finished:
|
||||
$jobRepository->setStatus($importJob, 'storage_finished');
|
||||
}
|
||||
|
||||
// give feedback:
|
||||
$this->infoLine('Job has finished.');
|
||||
if (null !== $importJob->tag) {
|
||||
$this->infoLine(sprintf('%d transaction(s) have been imported.', $importJob->tag->transactionJournals->count()));
|
||||
$this->infoLine(sprintf('You can find your transactions under tag "%s"', $importJob->tag->tag));
|
||||
}
|
||||
|
||||
if (null === $importJob->tag) {
|
||||
$this->errorLine('No transactions have been imported :(.');
|
||||
}
|
||||
if (\count($importJob->errors) > 0) {
|
||||
$this->infoLine(sprintf('%d error(s) occurred:', \count($importJob->errors)));
|
||||
foreach ($importJob->errors as $err) {
|
||||
$this->errorLine('- ' . $err);
|
||||
}
|
||||
}
|
||||
}
|
||||
// clear cache for user:
|
||||
Preferences::setForUser($user, 'lastActivity', microtime());
|
||||
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param array|null $data
|
||||
*/
|
||||
private function errorLine(string $message, array $data = null): void
|
||||
{
|
||||
Log::error($message, $data ?? []);
|
||||
$this->error($message);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param array $data
|
||||
*/
|
||||
private function infoLine(string $message, array $data = null): void
|
||||
{
|
||||
Log::info($message, $data ?? []);
|
||||
$this->line($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify user inserts correct arguments.
|
||||
*
|
||||
* @noinspection MultipleReturnStatementsInspection
|
||||
* @return bool
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's five exactly.
|
||||
*/
|
||||
private function validArguments(): bool
|
||||
{
|
||||
/** @var UserRepositoryInterface $userRepository */
|
||||
$userRepository = app(UserRepositoryInterface::class);
|
||||
$file = $this->argument('file');
|
||||
$configuration = $this->argument('configuration');
|
||||
$user = $userRepository->find(intval($this->option('user')));
|
||||
$cwd = getcwd();
|
||||
$validTypes = config('import.options.file.import_formats');
|
||||
$type = strtolower($this->option('type'));
|
||||
if (null === $user) {
|
||||
$this->error(sprintf('There is no user with ID %d.', $this->option('user')));
|
||||
$file = $this->argument('file');
|
||||
$configuration = $this->argument('configuration');
|
||||
$cwd = getcwd();
|
||||
$validTypes = config('import.options.file.import_formats');
|
||||
$type = strtolower($this->option('type'));
|
||||
$provider = strtolower($this->option('provider'));
|
||||
$enabled = (bool)config(sprintf('import.enabled.%s', $provider));
|
||||
|
||||
if (false === $enabled) {
|
||||
$this->errorLine(sprintf('Provider "%s" is not enabled.', $provider));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!in_array($type, $validTypes)) {
|
||||
$this->error(sprintf('Cannot import file of type "%s"', $type));
|
||||
if ($provider === 'file' && !\in_array($type, $validTypes, true)) {
|
||||
$this->errorLine(sprintf('Cannot import file of type "%s"', $type));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file_exists($file)) {
|
||||
$this->error(sprintf('Firefly III cannot find file "%s" (working directory: "%s").', $file, $cwd));
|
||||
if ($provider === 'file' && !file_exists($file)) {
|
||||
$this->errorLine(sprintf('Firefly III cannot find file "%s" (working directory: "%s").', $file, $cwd));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file_exists($configuration)) {
|
||||
$this->error(sprintf('Firefly III cannot find configuration file "%s" (working directory: "%s").', $configuration, $cwd));
|
||||
if ($provider === 'file' && !file_exists($configuration)) {
|
||||
$this->errorLine(sprintf('Firefly III cannot find configuration file "%s" (working directory: "%s").', $configuration, $cwd));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* DecryptAttachment.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
@@ -47,14 +49,6 @@ class DecryptAttachment extends Command
|
||||
= 'firefly:decrypt-attachment {id:The ID of the attachment.} {name:The file name of the attachment.}
|
||||
{directory:Where the file must be stored.}';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
@@ -65,7 +59,7 @@ class DecryptAttachment extends Command
|
||||
{
|
||||
/** @var AttachmentRepositoryInterface $repository */
|
||||
$repository = app(AttachmentRepositoryInterface::class);
|
||||
$attachmentId = intval($this->argument('id'));
|
||||
$attachmentId = (int)$this->argument('id');
|
||||
$attachment = $repository->findWithoutUser($attachmentId);
|
||||
$attachmentName = trim($this->argument('name'));
|
||||
$storagePath = realpath(trim($this->argument('directory')));
|
||||
@@ -108,6 +102,5 @@ class DecryptAttachment extends Command
|
||||
}
|
||||
$this->info(sprintf('%d bytes written. Exiting now..', $result));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* EncryptFile.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,11 +19,13 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
|
||||
use Crypt;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Services\Internal\File\EncryptService;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
@@ -44,31 +47,26 @@ class EncryptFile extends Command
|
||||
*/
|
||||
protected $signature = 'firefly:encrypt-file {file} {key}';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Encryption\EncryptException
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): int
|
||||
{
|
||||
$file = e(strval($this->argument('file')));
|
||||
if (!file_exists($file)) {
|
||||
$this->error(sprintf('File "%s" does not seem to exist.', $file));
|
||||
$code = 0;
|
||||
$file = (string)$this->argument('file');
|
||||
$key = (string)$this->argument('key');
|
||||
/** @var EncryptService $service */
|
||||
$service = app(EncryptService::class);
|
||||
|
||||
return;
|
||||
try {
|
||||
$service->encrypt($file, $key);
|
||||
} catch (FireflyException $e) {
|
||||
$this->error($e->getMessage());
|
||||
$code = 1;
|
||||
}
|
||||
$content = file_get_contents($file);
|
||||
$content = Crypt::encrypt($content);
|
||||
$newName = e(strval($this->argument('key'))) . '.upload';
|
||||
|
||||
$path = storage_path('upload') . '/' . $newName;
|
||||
file_put_contents($path, $content);
|
||||
$this->line(sprintf('Encrypted "%s" and put it in "%s"', $file, $path));
|
||||
return $code;
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Import.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,12 +19,12 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Import\Logging\CommandHandler;
|
||||
use FireflyIII\Import\Routine\RoutineInterface;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use Illuminate\Console\Command;
|
||||
@@ -49,14 +50,6 @@ class Import extends Command
|
||||
*/
|
||||
protected $signature = 'firefly:start-import {key}';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the import routine.
|
||||
*
|
||||
@@ -68,21 +61,17 @@ class Import extends Command
|
||||
$jobKey = $this->argument('key');
|
||||
$job = ImportJob::where('key', $jobKey)->first();
|
||||
if (null === $job) {
|
||||
$this->error(sprintf('No job found with key "%s"', $jobKey));
|
||||
$this->errorLine(sprintf('No job found with key "%s"', $jobKey));
|
||||
|
||||
return;
|
||||
}
|
||||
if (!$this->isValid($job)) {
|
||||
Log::error('Job is not valid for some reason. Exit.');
|
||||
$this->errorLine('Job is not valid for some reason. Exit.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->line(sprintf('Going to import job with key "%s" of type "%s"', $job->key, $job->file_type));
|
||||
|
||||
$monolog = Log::getMonolog();
|
||||
$handler = new CommandHandler($this);
|
||||
$monolog->pushHandler($handler);
|
||||
$this->infoLine(sprintf('Going to import job with key "%s" of type "%s"', $job->key, $job->file_type));
|
||||
|
||||
// actually start job:
|
||||
$type = 'csv' === $job->file_type ? 'file' : $job->file_type;
|
||||
@@ -99,14 +88,34 @@ class Import extends Command
|
||||
|
||||
/** @var MessageBag $error */
|
||||
foreach ($routine->getErrors() as $index => $error) {
|
||||
$this->error(sprintf('Error importing line #%d: %s', $index, $error));
|
||||
$this->errorLine(sprintf('Error importing line #%d: %s', $index, $error));
|
||||
}
|
||||
|
||||
$this->line(
|
||||
$this->infoLine(
|
||||
sprintf('The import has finished. %d transactions have been imported out of %d records.', $routine->getJournals()->count(), $routine->getLines())
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param array|null $data
|
||||
*/
|
||||
private function errorLine(string $message, array $data = null): void
|
||||
{
|
||||
Log::error($message, $data ?? []);
|
||||
$this->error($message);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param array $data
|
||||
*/
|
||||
private function infoLine(string $message, array $data = null): void
|
||||
{
|
||||
Log::info($message, $data ?? []);
|
||||
$this->line($message);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,15 +128,14 @@ class Import extends Command
|
||||
private function isValid(ImportJob $job): bool
|
||||
{
|
||||
if (null === $job) {
|
||||
Log::error('This job does not seem to exist.');
|
||||
$this->error('This job does not seem to exist.');
|
||||
$this->errorLine('This job does not seem to exist.');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ('configured' !== $job->status) {
|
||||
Log::error(sprintf('This job is not ready to be imported (status is %s).', $job->status));
|
||||
$this->error('This job is not ready to be imported.');
|
||||
$this->errorLine('This job is not ready to be imported.');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ScanAttachments.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
@@ -48,14 +50,6 @@ class ScanAttachments extends Command
|
||||
*/
|
||||
protected $signature = 'firefly:scan-attachments';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* UpgradeDatabase.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,21 +19,31 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
|
||||
use DB;
|
||||
use Exception;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountMeta;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Models\RuleAction;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
use FireflyIII\Models\RuleTrigger;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionJournalMeta;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Collection;
|
||||
@@ -63,18 +74,8 @@ class UpgradeDatabase extends Command
|
||||
*/
|
||||
protected $signature = 'firefly:upgrade-database';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
@@ -86,9 +87,142 @@ class UpgradeDatabase extends Command
|
||||
$this->updateOtherCurrencies();
|
||||
$this->line('Done updating currency information..');
|
||||
$this->migrateNotes();
|
||||
$this->info('Firefly III database is up to date.');
|
||||
$this->migrateAttachmentData();
|
||||
$this->migrateBillsToRules();
|
||||
|
||||
return;
|
||||
$this->info('Firefly III database is up to date.');
|
||||
}
|
||||
|
||||
public function migrateBillsToRules()
|
||||
{
|
||||
foreach (User::get() as $user) {
|
||||
/** @var Preference $lang */
|
||||
$lang = Preferences::getForUser($user, 'language', 'en_US');
|
||||
$groupName = (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data);
|
||||
$ruleGroup = $user->ruleGroups()->where('title', $groupName)->first();
|
||||
$currencyPreference = Preferences::getForUser($user, 'currencyPreference', config('firefly.default_currency', 'EUR'));
|
||||
$currency = TransactionCurrency::where('code', $currencyPreference->data)->first();
|
||||
if (null === $currency) {
|
||||
$currency = app('amount')->getDefaultCurrency();
|
||||
}
|
||||
|
||||
if ($ruleGroup === null) {
|
||||
$array = RuleGroup::get(['order'])->pluck('order')->toArray();
|
||||
$order = \count($array) > 0 ? max($array) + 1 : 1;
|
||||
$ruleGroup = RuleGroup::create(
|
||||
[
|
||||
'user_id' => $user->id,
|
||||
'title' => (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data),
|
||||
'description' => (string)trans('firefly.rulegroup_for_bills_description', [], $lang->data),
|
||||
'order' => $order,
|
||||
'active' => 1,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
// loop bills.
|
||||
$order = 1;
|
||||
/** @var Collection $collection */
|
||||
$collection = $user->bills()->get();
|
||||
/** @var Bill $bill */
|
||||
foreach ($collection as $bill) {
|
||||
if ($bill->match !== 'MIGRATED_TO_RULES') {
|
||||
$rule = Rule::create(
|
||||
[
|
||||
'user_id' => $user->id,
|
||||
'rule_group_id' => $ruleGroup->id,
|
||||
'title' => (string)trans('firefly.rule_for_bill_title', ['name' => $bill->name], $lang->data),
|
||||
'description' => (string)trans('firefly.rule_for_bill_description', ['name' => $bill->name], $lang->data),
|
||||
'order' => $order,
|
||||
'active' => $bill->active,
|
||||
'stop_processing' => 1,
|
||||
]
|
||||
);
|
||||
// add default trigger
|
||||
RuleTrigger::create(
|
||||
[
|
||||
'rule_id' => $rule->id,
|
||||
'trigger_type' => 'user_action',
|
||||
'trigger_value' => 'store-journal',
|
||||
'active' => 1,
|
||||
'stop_processing' => 0,
|
||||
'order' => 1,
|
||||
]
|
||||
);
|
||||
// add trigger for description
|
||||
$match = implode(' ', explode(',', $bill->match));
|
||||
RuleTrigger::create(
|
||||
[
|
||||
'rule_id' => $rule->id,
|
||||
'trigger_type' => 'description_contains',
|
||||
'trigger_value' => $match,
|
||||
'active' => 1,
|
||||
'stop_processing' => 0,
|
||||
'order' => 2,
|
||||
]
|
||||
);
|
||||
if ($bill->amount_max !== $bill->amount_min) {
|
||||
// add triggers for amounts:
|
||||
RuleTrigger::create(
|
||||
[
|
||||
'rule_id' => $rule->id,
|
||||
'trigger_type' => 'amount_less',
|
||||
'trigger_value' => round($bill->amount_max, $currency->decimal_places),
|
||||
'active' => 1,
|
||||
'stop_processing' => 0,
|
||||
'order' => 3,
|
||||
]
|
||||
);
|
||||
RuleTrigger::create(
|
||||
[
|
||||
'rule_id' => $rule->id,
|
||||
'trigger_type' => 'amount_more',
|
||||
'trigger_value' => round($bill->amount_min, $currency->decimal_places),
|
||||
'active' => 1,
|
||||
'stop_processing' => 0,
|
||||
'order' => 4,
|
||||
]
|
||||
);
|
||||
}
|
||||
if ($bill->amount_max === $bill->amount_min) {
|
||||
RuleTrigger::create(
|
||||
[
|
||||
'rule_id' => $rule->id,
|
||||
'trigger_type' => 'amount_exactly',
|
||||
'trigger_value' => round($bill->amount_min, $currency->decimal_places),
|
||||
'active' => 1,
|
||||
'stop_processing' => 0,
|
||||
'order' => 3,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
// create action
|
||||
RuleAction::create(
|
||||
[
|
||||
'rule_id' => $rule->id,
|
||||
'action_type' => 'link_to_bill',
|
||||
'action_value' => $bill->name,
|
||||
'order' => 1,
|
||||
'active' => 1,
|
||||
'stop_processing' => 0,
|
||||
]
|
||||
);
|
||||
|
||||
$order++;
|
||||
$bill->match = 'MIGRATED_TO_RULES';
|
||||
$bill->save();
|
||||
$this->line(sprintf('Updated bill #%d ("%s") so it will use rules.', $bill->id, $bill->name));
|
||||
}
|
||||
|
||||
// give bills a currency when they dont have one.
|
||||
if (null === $bill->transaction_currency_id) {
|
||||
$this->line(sprintf('Gave bill #%d ("%s") a currency (%s).', $bill->id, $bill->name, $currency->name));
|
||||
$bill->transactionCurrency()->associate($currency);
|
||||
$bill->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -118,10 +252,9 @@ class UpgradeDatabase extends Command
|
||||
$journalIds = array_unique($result->pluck('id')->toArray());
|
||||
|
||||
foreach ($journalIds as $journalId) {
|
||||
$this->updateJournalidentifiers(intval($journalId));
|
||||
$this->updateJournalidentifiers((int)$journalId);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,9 +273,9 @@ class UpgradeDatabase extends Command
|
||||
// get users preference, fall back to system pref.
|
||||
$defaultCurrencyCode = Preferences::getForUser($account->user, 'currencyPreference', config('firefly.default_currency', 'EUR'))->data;
|
||||
$defaultCurrency = TransactionCurrency::where('code', $defaultCurrencyCode)->first();
|
||||
$accountCurrency = intval($account->getMeta('currency_id'));
|
||||
$accountCurrency = (int)$account->getMeta('currency_id');
|
||||
$openingBalance = $account->getOpeningBalance();
|
||||
$obCurrency = intval($openingBalance->transaction_currency_id);
|
||||
$obCurrency = (int)$openingBalance->transaction_currency_id;
|
||||
|
||||
// both 0? set to default currency:
|
||||
if (0 === $accountCurrency && 0 === $obCurrency) {
|
||||
@@ -175,7 +308,6 @@ class UpgradeDatabase extends Command
|
||||
}
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -209,7 +341,7 @@ class UpgradeDatabase extends Command
|
||||
}
|
||||
/** @var Account $account */
|
||||
$account = $transaction->account;
|
||||
$currency = $repository->find(intval($account->getMeta('currency_id')));
|
||||
$currency = $repository->find((int)$account->getMeta('currency_id'));
|
||||
$transactions = $journal->transactions()->get();
|
||||
$transactions->each(
|
||||
function (Transaction $transaction) use ($currency) {
|
||||
@@ -219,8 +351,8 @@ class UpgradeDatabase extends Command
|
||||
}
|
||||
|
||||
// when mismatch in transaction:
|
||||
if (!(intval($transaction->transaction_currency_id) === intval($currency->id))) {
|
||||
$transaction->foreign_currency_id = intval($transaction->transaction_currency_id);
|
||||
if (!((int)$transaction->transaction_currency_id === (int)$currency->id)) {
|
||||
$transaction->foreign_currency_id = (int)$transaction->transaction_currency_id;
|
||||
$transaction->foreign_amount = $transaction->amount;
|
||||
$transaction->transaction_currency_id = $currency->id;
|
||||
$transaction->save();
|
||||
@@ -233,7 +365,6 @@ class UpgradeDatabase extends Command
|
||||
}
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -272,19 +403,49 @@ class UpgradeDatabase extends Command
|
||||
{
|
||||
// create transaction type "Reconciliation".
|
||||
$type = TransactionType::where('type', TransactionType::RECONCILIATION)->first();
|
||||
if (is_null($type)) {
|
||||
if (null === $type) {
|
||||
TransactionType::create(['type' => TransactionType::RECONCILIATION]);
|
||||
}
|
||||
$account = AccountType::where('type', AccountType::RECONCILIATION)->first();
|
||||
if (is_null($account)) {
|
||||
if (null === $account) {
|
||||
AccountType::create(['type' => AccountType::RECONCILIATION]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the description of each attachment (when not NULL) to the notes or to a new note object
|
||||
* for all attachments.
|
||||
*/
|
||||
private function migrateAttachmentData(): void
|
||||
{
|
||||
$attachments = Attachment::get();
|
||||
|
||||
/** @var Attachment $att */
|
||||
foreach ($attachments as $att) {
|
||||
|
||||
// move description:
|
||||
$description = (string)$att->description;
|
||||
if (\strlen($description) > 0) {
|
||||
// find or create note:
|
||||
$note = $att->notes()->first();
|
||||
if (null === $note) {
|
||||
$note = new Note;
|
||||
$note->noteable()->associate($att);
|
||||
}
|
||||
$note->text = $description;
|
||||
$note->save();
|
||||
|
||||
// clear description:
|
||||
$att->description = '';
|
||||
$att->save();
|
||||
|
||||
Log::debug(sprintf('Migrated attachment #%s description to note #%d', $att->id, $note->id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move all the journal_meta notes to their note object counter parts.
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function migrateNotes(): void
|
||||
{
|
||||
@@ -301,7 +462,11 @@ class UpgradeDatabase extends Command
|
||||
$note->text = $meta->data;
|
||||
$note->save();
|
||||
Log::debug(sprintf('Migrated meta note #%d to Note #%d', $meta->id, $note->id));
|
||||
$meta->delete();
|
||||
try {
|
||||
$meta->delete();
|
||||
} catch (Exception $e) {
|
||||
Log::error(sprintf('Could not delete old meta entry #%d: %s', $meta->id, $e->getMessage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,10 +479,10 @@ class UpgradeDatabase extends Command
|
||||
{
|
||||
/** @var CurrencyRepositoryInterface $repository */
|
||||
$repository = app(CurrencyRepositoryInterface::class);
|
||||
$currency = $repository->find(intval($transaction->account->getMeta('currency_id')));
|
||||
$currency = $repository->find((int)$transaction->account->getMeta('currency_id'));
|
||||
$journal = $transaction->transactionJournal;
|
||||
|
||||
if (!(intval($currency->id) === intval($journal->transaction_currency_id))) {
|
||||
if (!((int)$currency->id === (int)$journal->transaction_currency_id)) {
|
||||
$this->line(
|
||||
sprintf(
|
||||
'Transfer #%d ("%s") has been updated to use %s instead of %s.',
|
||||
@@ -331,7 +496,6 @@ class UpgradeDatabase extends Command
|
||||
$journal->save();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -348,7 +512,7 @@ class UpgradeDatabase extends Command
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($transactions as $transaction) {
|
||||
// find opposing:
|
||||
$amount = bcmul(strval($transaction->amount), '-1');
|
||||
$amount = bcmul((string)$transaction->amount, '-1');
|
||||
|
||||
try {
|
||||
/** @var Transaction $opposing */
|
||||
@@ -377,7 +541,6 @@ class UpgradeDatabase extends Command
|
||||
++$identifier;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -398,18 +561,24 @@ class UpgradeDatabase extends Command
|
||||
{
|
||||
/** @var CurrencyRepositoryInterface $repository */
|
||||
$repository = app(CurrencyRepositoryInterface::class);
|
||||
$currency = $repository->find(intval($transaction->account->getMeta('currency_id')));
|
||||
$currency = $repository->findNull((int)$transaction->account->getMeta('currency_id'));
|
||||
|
||||
if (null === $currency) {
|
||||
Log::error(sprintf('Account #%d ("%s") must have currency preference but has none.', $transaction->account->id, $transaction->account->name));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// has no currency ID? Must have, so fill in using account preference:
|
||||
if (null === $transaction->transaction_currency_id) {
|
||||
$transaction->transaction_currency_id = intval($currency->id);
|
||||
$transaction->transaction_currency_id = (int)$currency->id;
|
||||
Log::debug(sprintf('Transaction #%d has no currency setting, now set to %s', $transaction->id, $currency->code));
|
||||
$transaction->save();
|
||||
}
|
||||
|
||||
// does not match the source account (see above)? Can be fixed
|
||||
// when mismatch in transaction and NO foreign amount is set:
|
||||
if (!(intval($transaction->transaction_currency_id) === intval($currency->id)) && null === $transaction->foreign_amount) {
|
||||
if (!((int)$transaction->transaction_currency_id === (int)$currency->id) && null === $transaction->foreign_amount) {
|
||||
Log::debug(
|
||||
sprintf(
|
||||
'Transaction #%d has a currency setting #%d that should be #%d. Amount remains %s, currency is changed.',
|
||||
@@ -419,7 +588,7 @@ class UpgradeDatabase extends Command
|
||||
$transaction->amount
|
||||
)
|
||||
);
|
||||
$transaction->transaction_currency_id = intval($currency->id);
|
||||
$transaction->transaction_currency_id = (int)$currency->id;
|
||||
$transaction->save();
|
||||
}
|
||||
|
||||
@@ -428,16 +597,16 @@ class UpgradeDatabase extends Command
|
||||
$journal = $transaction->transactionJournal;
|
||||
/** @var Transaction $opposing */
|
||||
$opposing = $journal->transactions()->where('amount', '>', 0)->where('identifier', $transaction->identifier)->first();
|
||||
$opposingCurrency = $repository->find(intval($opposing->account->getMeta('currency_id')));
|
||||
$opposingCurrency = $repository->findNull((int)$opposing->account->getMeta('currency_id'));
|
||||
|
||||
if (null === $opposingCurrency->id) {
|
||||
if (null === $opposingCurrency) {
|
||||
Log::error(sprintf('Account #%d ("%s") must have currency preference but has none.', $opposing->account->id, $opposing->account->name));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// if the destination account currency is the same, both foreign_amount and foreign_currency_id must be NULL for both transactions:
|
||||
if (intval($opposingCurrency->id) === intval($currency->id)) {
|
||||
if ((int)$opposingCurrency->id === (int)$currency->id) {
|
||||
// update both transactions to match:
|
||||
$transaction->foreign_amount = null;
|
||||
$transaction->foreign_currency_id = null;
|
||||
@@ -446,12 +615,21 @@ class UpgradeDatabase extends Command
|
||||
$opposing->transaction_currency_id = $currency->id;
|
||||
$transaction->save();
|
||||
$opposing->save();
|
||||
Log::debug(sprintf('Cleaned up transaction #%d and #%d', $transaction->id, $opposing->id));
|
||||
Log::debug(
|
||||
sprintf(
|
||||
'Currency for account "%s" is %s, and currency for account "%s" is also
|
||||
%s, so %s #%d (#%d and #%d) has been verified to be to %s exclusively.',
|
||||
$opposing->account->name, $opposingCurrency->code,
|
||||
$transaction->account->name, $transaction->transactionCurrency->code,
|
||||
$journal->transactionType->type, $journal->id,
|
||||
$transaction->id, $opposing->id, $currency->code
|
||||
)
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
// if destination account currency is different, both transactions must have this currency as foreign currency id.
|
||||
if (!(intval($opposingCurrency->id) === intval($currency->id))) {
|
||||
if (!((int)$opposingCurrency->id === (int)$currency->id)) {
|
||||
$transaction->foreign_currency_id = $opposingCurrency->id;
|
||||
$opposing->foreign_currency_id = $opposingCurrency->id;
|
||||
$transaction->save();
|
||||
@@ -461,14 +639,14 @@ class UpgradeDatabase extends Command
|
||||
|
||||
// if foreign amount of one is null and the other is not, use this to restore:
|
||||
if (null === $transaction->foreign_amount && null !== $opposing->foreign_amount) {
|
||||
$transaction->foreign_amount = bcmul(strval($opposing->foreign_amount), '-1');
|
||||
$transaction->foreign_amount = bcmul((string)$opposing->foreign_amount, '-1');
|
||||
$transaction->save();
|
||||
Log::debug(sprintf('Restored foreign amount of transaction (1) #%d to %s', $transaction->id, $transaction->foreign_amount));
|
||||
}
|
||||
|
||||
// if foreign amount of one is null and the other is not, use this to restore (other way around)
|
||||
if (null === $opposing->foreign_amount && null !== $transaction->foreign_amount) {
|
||||
$opposing->foreign_amount = bcmul(strval($transaction->foreign_amount), '-1');
|
||||
$opposing->foreign_amount = bcmul((string)$transaction->foreign_amount, '-1');
|
||||
$opposing->save();
|
||||
Log::debug(sprintf('Restored foreign amount of transaction (2) #%d to %s', $opposing->id, $opposing->foreign_amount));
|
||||
}
|
||||
@@ -478,14 +656,14 @@ class UpgradeDatabase extends Command
|
||||
$foreignAmount = $journal->getMeta('foreign_amount');
|
||||
if (null === $foreignAmount) {
|
||||
Log::debug(sprintf('Journal #%d has missing foreign currency data, forced to do 1:1 conversion :(.', $transaction->transaction_journal_id));
|
||||
$transaction->foreign_amount = bcmul(strval($transaction->amount), '-1');
|
||||
$opposing->foreign_amount = bcmul(strval($opposing->amount), '-1');
|
||||
$transaction->foreign_amount = bcmul((string)$transaction->amount, '-1');
|
||||
$opposing->foreign_amount = bcmul((string)$opposing->amount, '-1');
|
||||
$transaction->save();
|
||||
$opposing->save();
|
||||
|
||||
return;
|
||||
}
|
||||
$foreignPositive = app('steam')->positive(strval($foreignAmount));
|
||||
$foreignPositive = app('steam')->positive((string)$foreignAmount);
|
||||
Log::debug(
|
||||
sprintf(
|
||||
'Journal #%d has missing foreign currency info, try to restore from meta-data ("%s").',
|
||||
@@ -499,7 +677,6 @@ class UpgradeDatabase extends Command
|
||||
$opposing->save();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* UpgradeFireflyInstructions.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
@@ -42,14 +44,6 @@ class UpgradeFireflyInstructions extends Command
|
||||
*/
|
||||
protected $signature = 'firefly:instructions {task}';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
@@ -100,7 +94,7 @@ class UpgradeFireflyInstructions extends Command
|
||||
$text = '';
|
||||
foreach (array_keys($config) as $compare) {
|
||||
// if string starts with:
|
||||
$len = strlen($compare);
|
||||
$len = \strlen($compare);
|
||||
if (substr($version, 0, $len) === $compare) {
|
||||
$text = $config[$compare];
|
||||
}
|
||||
@@ -147,7 +141,7 @@ class UpgradeFireflyInstructions extends Command
|
||||
$text = '';
|
||||
foreach (array_keys($config) as $compare) {
|
||||
// if string starts with:
|
||||
$len = strlen($compare);
|
||||
$len = \strlen($compare);
|
||||
if (substr($version, 0, $len) === $compare) {
|
||||
$text = $config[$compare];
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
/**
|
||||
* UseEncryption.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -19,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
@@ -44,14 +45,6 @@ class UseEncryption extends Command
|
||||
*/
|
||||
protected $signature = 'firefly:use-encryption';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* VerifiesAccessToken.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
@@ -49,11 +51,11 @@ trait VerifiesAccessToken
|
||||
*/
|
||||
protected function verifyAccessToken(): bool
|
||||
{
|
||||
$userId = intval($this->option('user'));
|
||||
$token = strval($this->option('token'));
|
||||
$userId = (int)$this->option('user');
|
||||
$token = (string)$this->option('token');
|
||||
/** @var UserRepositoryInterface $repository */
|
||||
$repository = app(UserRepositoryInterface::class);
|
||||
$user = $repository->find($userId);
|
||||
$user = $repository->findNull($userId);
|
||||
|
||||
if (null === $user) {
|
||||
Log::error(sprintf('verifyAccessToken(): no such user for input "%d"', $userId));
|
||||
@@ -68,7 +70,7 @@ trait VerifiesAccessToken
|
||||
}
|
||||
if (!($accessToken->data === $token)) {
|
||||
Log::error(sprintf('Invalid access token for user #%d.', $userId));
|
||||
Log::error(sprintf('Token given is "%s", expected "%s".', $token, $accessToken->data));
|
||||
Log::error(sprintf('Token given is "%s", expected something else.', $token));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* VerifyDatabase.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
@@ -61,14 +63,6 @@ class VerifyDatabase extends Command
|
||||
*/
|
||||
protected $signature = 'firefly:verify';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
@@ -95,12 +89,14 @@ class VerifyDatabase extends Command
|
||||
$this->createLinkTypes();
|
||||
$this->createAccessTokens();
|
||||
$this->fixDoubleAmounts();
|
||||
$this->fixBadMeta();
|
||||
$this->removeBills();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create user access tokens, if not present already.
|
||||
*/
|
||||
private function createAccessTokens()
|
||||
private function createAccessTokens(): void
|
||||
{
|
||||
$count = 0;
|
||||
$users = User::get();
|
||||
@@ -122,7 +118,7 @@ class VerifyDatabase extends Command
|
||||
/**
|
||||
* Create default link types if necessary.
|
||||
*/
|
||||
private function createLinkTypes()
|
||||
private function createLinkTypes(): void
|
||||
{
|
||||
$count = 0;
|
||||
$set = [
|
||||
@@ -148,7 +144,71 @@ class VerifyDatabase extends Command
|
||||
}
|
||||
}
|
||||
|
||||
private function fixDoubleAmounts()
|
||||
/**
|
||||
* Fix the situation where the matching transactions
|
||||
* of a journal somehow have non-matching categories
|
||||
* or budgets
|
||||
*/
|
||||
private function fixBadMeta(): void
|
||||
{
|
||||
// categories
|
||||
$set = Transaction
|
||||
::leftJoin('category_transaction', 'category_transaction.transaction_id', '=', 'transactions.id')
|
||||
->whereNull('transactions.deleted_at')
|
||||
->get(['transactions.id', 'transaction_journal_id', 'identifier', 'category_transaction.category_id', 'category_transaction.id as ct_id']);
|
||||
$results = [];
|
||||
foreach ($set as $obj) {
|
||||
$key = $obj->transaction_journal_id . '-' . $obj->identifier;
|
||||
$category = (int)$obj->category_id;
|
||||
|
||||
// value exists and is not category:
|
||||
if (isset($results[$key]) && $results[$key] !== $category) {
|
||||
$this->error(
|
||||
sprintf(
|
||||
'Transaction #%d referred to the wrong category. Was category #%d but is fixed to be category #%d.', $obj->transaction_journal_id,
|
||||
$category, $results[$key]
|
||||
)
|
||||
);
|
||||
DB::table('category_transaction')->where('id', $obj->ct_id)->update(['category_id' => $results[$key]]);
|
||||
|
||||
}
|
||||
|
||||
// value does not exist:
|
||||
if ($category > 0 && !isset($results[$key])) {
|
||||
$results[$key] = $category;
|
||||
}
|
||||
}
|
||||
|
||||
// budgets
|
||||
$set = Transaction
|
||||
::leftJoin('budget_transaction', 'budget_transaction.transaction_id', '=', 'transactions.id')
|
||||
->whereNull('transactions.deleted_at')
|
||||
->get(['transactions.id', 'transaction_journal_id', 'identifier', 'budget_transaction.budget_id', 'budget_transaction.id as ct_id']);
|
||||
$results = [];
|
||||
foreach ($set as $obj) {
|
||||
$key = $obj->transaction_journal_id . '-' . $obj->identifier;
|
||||
$budget = (int)$obj->budget_id;
|
||||
|
||||
// value exists and is not budget:
|
||||
if (isset($results[$key]) && $results[$key] !== $budget) {
|
||||
$this->error(
|
||||
sprintf(
|
||||
'Transaction #%d referred to the wrong budget. Was budget #%d but is fixed to be budget #%d.', $obj->transaction_journal_id, $budget,
|
||||
$results[$key]
|
||||
)
|
||||
);
|
||||
DB::table('budget_transaction')->where('id', $obj->ct_id)->update(['budget_id' => $results[$key]]);
|
||||
|
||||
}
|
||||
|
||||
// value does not exist:
|
||||
if ($budget > 0 && !isset($results[$key])) {
|
||||
$results[$key] = $budget;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function fixDoubleAmounts(): void
|
||||
{
|
||||
$count = 0;
|
||||
// get invalid journals
|
||||
@@ -158,7 +218,7 @@ class VerifyDatabase extends Command
|
||||
->get(['transaction_journal_id', DB::raw('SUM(amount) AS the_sum')]);
|
||||
/** @var stdClass $entry */
|
||||
foreach ($journals as $entry) {
|
||||
if (0 !== bccomp(strval($entry->the_sum), '0')) {
|
||||
if (0 !== bccomp((string)$entry->the_sum, '0')) {
|
||||
$errored[] = $entry->transaction_journal_id;
|
||||
}
|
||||
}
|
||||
@@ -171,7 +231,7 @@ class VerifyDatabase extends Command
|
||||
// report about it
|
||||
/** @var TransactionJournal $journal */
|
||||
$journal = TransactionJournal::find($journalId);
|
||||
if (is_null($journal)) {
|
||||
if (null === $journal) {
|
||||
continue;
|
||||
}
|
||||
if (TransactionType::OPENING_BALANCE === $journal->transactionType->type) {
|
||||
@@ -194,8 +254,23 @@ class VerifyDatabase extends Command
|
||||
if (0 === $count) {
|
||||
$this->info('Amount integrity OK!');
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function removeBills(): void
|
||||
{
|
||||
/** @var TransactionType $withdrawal */
|
||||
$withdrawal = TransactionType::where('type', TransactionType::WITHDRAWAL)->first();
|
||||
$journals = TransactionJournal::whereNotNull('bill_id')
|
||||
->where('transaction_type_id', '!=', $withdrawal->id)->get();
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($journals as $journal) {
|
||||
$this->line(sprintf('Transaction journal #%d should not be linked to bill #%d.', $journal->id, $journal->bill_id));
|
||||
$journal->bill_id = null;
|
||||
$journal->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -225,8 +300,6 @@ class VerifyDatabase extends Command
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -254,7 +327,7 @@ class VerifyDatabase extends Command
|
||||
/**
|
||||
* Reports on budgets with no budget limits (which makes them pointless).
|
||||
*/
|
||||
private function reportBudgetLimits()
|
||||
private function reportBudgetLimits(): void
|
||||
{
|
||||
$set = Budget::leftJoin('budget_limits', 'budget_limits.budget_id', '=', 'budgets.id')
|
||||
->leftJoin('users', 'budgets.user_id', '=', 'users.id')
|
||||
@@ -278,7 +351,7 @@ class VerifyDatabase extends Command
|
||||
/**
|
||||
* Reports on deleted accounts that still have not deleted transactions or journals attached to them.
|
||||
*/
|
||||
private function reportDeletedAccounts()
|
||||
private function reportDeletedAccounts(): void
|
||||
{
|
||||
$set = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
@@ -297,7 +370,7 @@ class VerifyDatabase extends Command
|
||||
);
|
||||
/** @var stdClass $entry */
|
||||
foreach ($set as $entry) {
|
||||
$date = null === $entry->transaction_deleted_at ? $entry->journal_deleted_at : $entry->transaction_deleted_at;
|
||||
$date = $entry->transaction_deleted_at ?? $entry->journal_deleted_at;
|
||||
$this->error(
|
||||
'Error: Account #' . $entry->account_id . ' should have been deleted, but has not.' .
|
||||
' Find it in the table called "accounts" and change the "deleted_at" field to: "' . $date . '"'
|
||||
@@ -308,7 +381,7 @@ class VerifyDatabase extends Command
|
||||
/**
|
||||
* Report on journals with bad account types linked to them.
|
||||
*/
|
||||
private function reportIncorrectJournals()
|
||||
private function reportIncorrectJournals(): void
|
||||
{
|
||||
$configuration = [
|
||||
// a withdrawal can not have revenue account:
|
||||
@@ -350,7 +423,7 @@ class VerifyDatabase extends Command
|
||||
/**
|
||||
* Any deleted transaction journals that have transactions that are NOT deleted:.
|
||||
*/
|
||||
private function reportJournals()
|
||||
private function reportJournals(): void
|
||||
{
|
||||
$count = 0;
|
||||
$set = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
@@ -381,7 +454,7 @@ class VerifyDatabase extends Command
|
||||
/**
|
||||
* Report on journals without transactions.
|
||||
*/
|
||||
private function reportNoTransactions()
|
||||
private function reportNoTransactions(): void
|
||||
{
|
||||
$count = 0;
|
||||
$set = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
@@ -405,7 +478,7 @@ class VerifyDatabase extends Command
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
private function reportObject(string $name)
|
||||
private function reportObject(string $name): void
|
||||
{
|
||||
$plural = str_plural($name);
|
||||
$class = sprintf('FireflyIII\Models\%s', ucfirst($name));
|
||||
@@ -441,14 +514,14 @@ class VerifyDatabase extends Command
|
||||
/**
|
||||
* Reports for each user when the sum of their transactions is not zero.
|
||||
*/
|
||||
private function reportSum()
|
||||
private function reportSum(): void
|
||||
{
|
||||
/** @var UserRepositoryInterface $userRepository */
|
||||
$userRepository = app(UserRepositoryInterface::class);
|
||||
|
||||
/** @var User $user */
|
||||
foreach ($userRepository->all() as $user) {
|
||||
$sum = strval($user->transactions()->sum('amount'));
|
||||
$sum = (string)$user->transactions()->sum('amount');
|
||||
if (0 !== bccomp($sum, '0')) {
|
||||
$this->error('Error: Transactions for user #' . $user->id . ' (' . $user->email . ') are off by ' . $sum . '!');
|
||||
} else {
|
||||
@@ -460,7 +533,7 @@ class VerifyDatabase extends Command
|
||||
/**
|
||||
* Reports on deleted transactions that are connected to a not deleted journal.
|
||||
*/
|
||||
private function reportTransactions()
|
||||
private function reportTransactions(): void
|
||||
{
|
||||
$set = Transaction::leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->whereNotNull('transactions.deleted_at')
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Kernel.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,15 +19,18 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Jobs\CreateRecurringTransactions;
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
/**
|
||||
* File to make sure commnds work.
|
||||
* File to make sure commands work.
|
||||
*/
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
@@ -42,7 +46,7 @@ class Kernel extends ConsoleKernel
|
||||
/**
|
||||
* Register the commands for the application.
|
||||
*/
|
||||
protected function commands()
|
||||
protected function commands(): void
|
||||
{
|
||||
$this->load(__DIR__ . '/Commands');
|
||||
|
||||
@@ -53,10 +57,9 @@ class Kernel extends ConsoleKernel
|
||||
* Define the application's command schedule.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
protected function schedule(Schedule $schedule): void
|
||||
{
|
||||
$schedule->job(new CreateRecurringTransactions(new Carbon))->daily();
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* AdminRequestedTestMessage.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Event.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* RegisteredUser.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* RequestedNewPassword.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
|
46
app/Events/RequestedReportOnJournals.php
Normal file
46
app/Events/RequestedReportOnJournals.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class RequestedReportOnJournals
|
||||
*/
|
||||
class RequestedReportOnJournals
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
/** @var Collection */
|
||||
public $journals;
|
||||
/** @var int */
|
||||
public $userId;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param int $userId
|
||||
* @param Collection $journals
|
||||
*/
|
||||
public function __construct(int $userId, Collection $journals)
|
||||
{
|
||||
Log::debug('In event RequestedReportOnJournals.');
|
||||
$this->userId = $userId;
|
||||
$this->journals = $journals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return \Illuminate\Broadcasting\Channel|array
|
||||
*/
|
||||
public function broadcastOn()
|
||||
{
|
||||
return new PrivateChannel('channel-name');
|
||||
}
|
||||
}
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* RequestedVersionCheckStatus.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -49,4 +50,4 @@ class RequestedVersionCheckStatus extends Event
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* StoredTransactionJournal.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
@@ -26,6 +28,7 @@ use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* Class StoredTransactionJournal.
|
||||
*/
|
||||
class StoredTransactionJournal extends Event
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* UpdatedTransactionJournal.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
@@ -27,6 +29,9 @@ use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class UpdatedTransactionJournal.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
*/
|
||||
class UpdatedTransactionJournal extends Event
|
||||
{
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* UserChangedEmail.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* FireflyException.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,13 +19,16 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class FireflyException.
|
||||
*/
|
||||
class FireflyException extends \Exception
|
||||
class FireflyException extends Exception
|
||||
{
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Handler.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Exceptions;
|
||||
@@ -28,6 +30,7 @@ use FireflyIII\Jobs\MailError;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||
use Request;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
@@ -70,13 +73,19 @@ class Handler extends ExceptionHandler
|
||||
return parent::render($request, $exception);
|
||||
}
|
||||
if ($exception instanceof NotFoundHttpException && $request->expectsJson()) {
|
||||
// JSON error:
|
||||
return response()->json(['message' => 'Resource not found', 'exception' => 'NotFoundHttpException'], 404);
|
||||
}
|
||||
|
||||
if ($exception instanceof AuthenticationException && $request->expectsJson()) {
|
||||
// somehow Laravel handler does not catch this:
|
||||
return response()->json(['message' => 'Unauthenticated', 'exception' => 'AuthenticationException'], 401);
|
||||
}
|
||||
|
||||
if ($exception instanceof OAuthServerException && $request->expectsJson()) {
|
||||
// somehow Laravel handler does not catch this:
|
||||
return response()->json(['message' => $exception->getMessage(), 'exception' => 'OAuthServerException'], 401);
|
||||
}
|
||||
|
||||
if ($request->expectsJson()) {
|
||||
$isDebug = config('app.debug', false);
|
||||
@@ -84,7 +93,7 @@ class Handler extends ExceptionHandler
|
||||
return response()->json(
|
||||
[
|
||||
'message' => $exception->getMessage(),
|
||||
'exception' => get_class($exception),
|
||||
'exception' => \get_class($exception),
|
||||
'line' => $exception->getLine(),
|
||||
'file' => $exception->getFile(),
|
||||
'trace' => $exception->getTrace(),
|
||||
@@ -92,10 +101,10 @@ class Handler extends ExceptionHandler
|
||||
);
|
||||
}
|
||||
|
||||
return response()->json(['message' => 'Internal Firefly III Exception. See log files.', 'exception' => get_class($exception)], 500);
|
||||
return response()->json(['message' => 'Internal Firefly III Exception. See log files.', 'exception' => \get_class($exception)], 500);
|
||||
}
|
||||
|
||||
if ($exception instanceof FireflyException || $exception instanceof ErrorException) {
|
||||
if ($exception instanceof FireflyException || $exception instanceof ErrorException || $exception instanceof OAuthServerException) {
|
||||
$isDebug = env('APP_DEBUG', false);
|
||||
|
||||
return response()->view('errors.FireflyException', ['exception' => $exception, 'debug' => $isDebug], 500);
|
||||
@@ -119,8 +128,20 @@ class Handler extends ExceptionHandler
|
||||
*/
|
||||
public function report(Exception $exception)
|
||||
{
|
||||
|
||||
$doMailError = env('SEND_ERROR_MESSAGE', true);
|
||||
if (($exception instanceof FireflyException || $exception instanceof ErrorException) && $doMailError) {
|
||||
if (
|
||||
// if the user wants us to mail:
|
||||
$doMailError === true
|
||||
&& (
|
||||
// and if is one of these error instances
|
||||
$exception instanceof FireflyException
|
||||
|| $exception instanceof ErrorException
|
||||
|| $exception instanceof OAuthServerException
|
||||
|
||||
)
|
||||
) {
|
||||
// then, send email
|
||||
$userData = [
|
||||
'id' => 0,
|
||||
'email' => 'unknown@example.com',
|
||||
@@ -130,7 +151,7 @@ class Handler extends ExceptionHandler
|
||||
$userData['email'] = auth()->user()->email;
|
||||
}
|
||||
$data = [
|
||||
'class' => get_class($exception),
|
||||
'class' => \get_class($exception),
|
||||
'errorMessage' => $exception->getMessage(),
|
||||
'time' => date('r'),
|
||||
'stackTrace' => $exception->getTraceAsString(),
|
||||
@@ -138,6 +159,9 @@ class Handler extends ExceptionHandler
|
||||
'line' => $exception->getLine(),
|
||||
'code' => $exception->getCode(),
|
||||
'version' => config('firefly.version'),
|
||||
'url' => Request::fullUrl(),
|
||||
'userAgent' => Request::userAgent(),
|
||||
'json' => Request::acceptsJson(),
|
||||
];
|
||||
|
||||
// create job that will mail.
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* NotImplementedException.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Exceptions;
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ValidationException.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Exceptions;
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* AttachmentCollector.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Export\Collector;
|
||||
@@ -94,17 +96,23 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
|
||||
*/
|
||||
private function exportAttachment(Attachment $attachment): bool
|
||||
{
|
||||
$file = $attachment->fileName();
|
||||
$file = $attachment->fileName();
|
||||
$decrypted = false;
|
||||
if ($this->uploadDisk->exists($file)) {
|
||||
try {
|
||||
$decrypted = Crypt::decrypt($this->uploadDisk->get($file));
|
||||
$exportFile = $this->exportFileName($attachment);
|
||||
$this->exportDisk->put($exportFile, $decrypted);
|
||||
$this->getEntries()->push($exportFile);
|
||||
$decrypted = Crypt::decrypt($this->uploadDisk->get($file));
|
||||
} catch (DecryptException $e) {
|
||||
Log::error('Catchable error: could not decrypt attachment #' . $attachment->id . ' because: ' . $e->getMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ($decrypted === false) {
|
||||
return false;
|
||||
}
|
||||
$exportFile = $this->exportFileName($attachment);
|
||||
$this->exportDisk->put($exportFile, $decrypted);
|
||||
$this->getEntries()->push($exportFile);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -118,7 +126,7 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
|
||||
*/
|
||||
private function exportFileName($attachment): string
|
||||
{
|
||||
return sprintf('%s-Attachment nr. %s - %s', $this->job->key, strval($attachment->id), $attachment->filename);
|
||||
return sprintf('%s-Attachment nr. %s - %s', $this->job->key, (string)$attachment->id, $attachment->filename);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,8 +135,7 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
|
||||
private function getAttachments(): Collection
|
||||
{
|
||||
$this->repository->setUser($this->user);
|
||||
$attachments = $this->repository->getBetween($this->start, $this->end);
|
||||
|
||||
return $attachments;
|
||||
return $this->repository->getBetween($this->start, $this->end);
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* BasicCollector.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Export\Collector;
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* CollectorInterface.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Export\Collector;
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* UploadCollector.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,13 +19,14 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Export\Collector;
|
||||
|
||||
use Crypt;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
use Illuminate\Contracts\Filesystem\FileNotFoundException;
|
||||
use Log;
|
||||
use Storage;
|
||||
|
||||
@@ -99,11 +101,11 @@ class UploadCollector extends BasicCollector implements CollectorInterface
|
||||
$content = '';
|
||||
try {
|
||||
$content = Crypt::decrypt($this->uploadDisk->get(sprintf('%s.upload', $key)));
|
||||
} catch (FileNotFoundException | DecryptException $e) {
|
||||
} catch (Exception | DecryptException $e) {
|
||||
Log::error(sprintf('Could not decrypt old import file "%s". Skipped because: %s', $key, $e->getMessage()));
|
||||
}
|
||||
|
||||
if (strlen($content) > 0) {
|
||||
if (\strlen($content) > 0) {
|
||||
// add to export disk.
|
||||
$date = $job->created_at->format('Y-m-d');
|
||||
$file = sprintf('%s-Old %s import dated %s.%s', $this->job->key, strtoupper($job->file_type), $date, $job->file_type);
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Entry.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Export\Entry;
|
||||
@@ -199,31 +201,29 @@ final class Entry
|
||||
$entry->transaction_id = $transaction->id;
|
||||
$entry->date = $transaction->date->format('Ymd');
|
||||
$entry->description = $transaction->description;
|
||||
if (strlen(strval($transaction->transaction_description)) > 0) {
|
||||
if (\strlen((string)$transaction->transaction_description) > 0) {
|
||||
$entry->description = $transaction->transaction_description . '(' . $transaction->description . ')';
|
||||
}
|
||||
$entry->currency_code = $transaction->transactionCurrency->code;
|
||||
$entry->amount = strval(round($transaction->transaction_amount, $transaction->transactionCurrency->decimal_places));
|
||||
$entry->amount = (string)round($transaction->transaction_amount, $transaction->transactionCurrency->decimal_places);
|
||||
|
||||
$entry->foreign_currency_code = null === $transaction->foreign_currency_id ? null : $transaction->foreignCurrency->code;
|
||||
$entry->foreign_amount = null === $transaction->foreign_currency_id
|
||||
? null
|
||||
: strval(
|
||||
round(
|
||||
$transaction->transaction_foreign_amount,
|
||||
$transaction->foreignCurrency->decimal_places
|
||||
)
|
||||
: (string)round(
|
||||
$transaction->transaction_foreign_amount,
|
||||
$transaction->foreignCurrency->decimal_places
|
||||
);
|
||||
|
||||
$entry->transaction_type = $transaction->transaction_type_type;
|
||||
$entry->asset_account_id = strval($transaction->account_id);
|
||||
$entry->asset_account_id = (string)$transaction->account_id;
|
||||
$entry->asset_account_name = app('steam')->tryDecrypt($transaction->account_name);
|
||||
$entry->asset_account_iban = $transaction->account_iban;
|
||||
$entry->asset_account_number = $transaction->account_number;
|
||||
$entry->asset_account_bic = $transaction->account_bic;
|
||||
$entry->asset_currency_code = $transaction->account_currency_code;
|
||||
|
||||
$entry->opposing_account_id = strval($transaction->opposing_account_id);
|
||||
$entry->opposing_account_id = (string)$transaction->opposing_account_id;
|
||||
$entry->opposing_account_name = app('steam')->tryDecrypt($transaction->opposing_account_name);
|
||||
$entry->opposing_account_iban = $transaction->opposing_account_iban;
|
||||
$entry->opposing_account_number = $transaction->opposing_account_number;
|
||||
@@ -231,7 +231,7 @@ final class Entry
|
||||
$entry->opposing_currency_code = $transaction->opposing_currency_code;
|
||||
|
||||
// budget
|
||||
$entry->budget_id = strval($transaction->transaction_budget_id);
|
||||
$entry->budget_id = (string)$transaction->transaction_budget_id;
|
||||
$entry->budget_name = app('steam')->tryDecrypt($transaction->transaction_budget_name);
|
||||
if (null === $transaction->transaction_budget_id) {
|
||||
$entry->budget_id = $transaction->transaction_journal_budget_id;
|
||||
@@ -239,7 +239,7 @@ final class Entry
|
||||
}
|
||||
|
||||
// category
|
||||
$entry->category_id = strval($transaction->transaction_category_id);
|
||||
$entry->category_id = (string)$transaction->transaction_category_id;
|
||||
$entry->category_name = app('steam')->tryDecrypt($transaction->transaction_category_name);
|
||||
if (null === $transaction->transaction_category_id) {
|
||||
$entry->category_id = $transaction->transaction_journal_category_id;
|
||||
@@ -247,7 +247,7 @@ final class Entry
|
||||
}
|
||||
|
||||
// budget
|
||||
$entry->bill_id = strval($transaction->bill_id);
|
||||
$entry->bill_id = (string)$transaction->bill_id;
|
||||
$entry->bill_name = app('steam')->tryDecrypt($transaction->bill_name);
|
||||
|
||||
$entry->tags = $transaction->tags;
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ExpandedProcessor.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Export;
|
||||
@@ -34,6 +36,7 @@ use FireflyIII\Models\AccountMeta;
|
||||
use FireflyIII\Models\ExportJob;
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
@@ -118,13 +121,13 @@ class ExpandedProcessor implements ProcessorInterface
|
||||
$currencies = $this->getAccountCurrencies($ibans);
|
||||
$transactions->each(
|
||||
function (Transaction $transaction) use ($notes, $tags, $ibans, $currencies) {
|
||||
$journalId = intval($transaction->journal_id);
|
||||
$accountId = intval($transaction->account_id);
|
||||
$opposingId = intval($transaction->opposing_account_id);
|
||||
$currencyId = $ibans[$accountId]['currency_id'] ?? 0;
|
||||
$opposingCurrencyId = $ibans[$opposingId]['currency_id'] ?? 0;
|
||||
$journalId = (int)$transaction->journal_id;
|
||||
$accountId = (int)$transaction->account_id;
|
||||
$opposingId = (int)$transaction->opposing_account_id;
|
||||
$currencyId = (int)($ibans[$accountId]['currency_id'] ?? 0.0);
|
||||
$opposingCurrencyId = (int)($ibans[$opposingId]['currency_id'] ?? 0.0);
|
||||
$transaction->notes = $notes[$journalId] ?? '';
|
||||
$transaction->tags = join(',', $tags[$journalId] ?? []);
|
||||
$transaction->tags = implode(',', $tags[$journalId] ?? []);
|
||||
$transaction->account_number = $ibans[$accountId]['accountNumber'] ?? '';
|
||||
$transaction->account_bic = $ibans[$accountId]['BIC'] ?? '';
|
||||
$transaction->account_currency_code = $currencies[$currencyId] ?? '';
|
||||
@@ -263,7 +266,7 @@ class ExpandedProcessor implements ProcessorInterface
|
||||
$ids = [];
|
||||
$repository->setUser($this->job->user);
|
||||
foreach ($array as $value) {
|
||||
$ids[] = $value['currency_id'] ?? 0;
|
||||
$ids[] = (int)($value['currency_id'] ?? 0.0);
|
||||
}
|
||||
$ids = array_unique($ids);
|
||||
$result = $repository->getByIds($ids);
|
||||
@@ -293,7 +296,7 @@ class ExpandedProcessor implements ProcessorInterface
|
||||
->get(['account_meta.id', 'account_meta.account_id', 'account_meta.name', 'account_meta.data']);
|
||||
/** @var AccountMeta $meta */
|
||||
foreach ($set as $meta) {
|
||||
$id = intval($meta->account_id);
|
||||
$id = (int)$meta->account_id;
|
||||
$return[$id][$meta->name] = $meta->data;
|
||||
}
|
||||
|
||||
@@ -310,14 +313,14 @@ class ExpandedProcessor implements ProcessorInterface
|
||||
private function getNotes(array $array): array
|
||||
{
|
||||
$array = array_unique($array);
|
||||
$notes = Note::where('notes.noteable_type', 'FireflyIII\\Models\\TransactionJournal')
|
||||
$notes = Note::where('notes.noteable_type', TransactionJournal::class)
|
||||
->whereIn('notes.noteable_id', $array)
|
||||
->get(['notes.*']);
|
||||
$return = [];
|
||||
/** @var Note $note */
|
||||
foreach ($notes as $note) {
|
||||
if (strlen(trim(strval($note->text))) > 0) {
|
||||
$id = intval($note->noteable_id);
|
||||
if (\strlen(trim((string)$note->text)) > 0) {
|
||||
$id = (int)$note->noteable_id;
|
||||
$return[$id] = $note->text;
|
||||
}
|
||||
}
|
||||
@@ -331,6 +334,7 @@ class ExpandedProcessor implements ProcessorInterface
|
||||
* @param array $array
|
||||
*
|
||||
* @return array
|
||||
* @throws \Illuminate\Contracts\Encryption\DecryptException
|
||||
*/
|
||||
private function getTags(array $array): array
|
||||
{
|
||||
@@ -342,8 +346,8 @@ class ExpandedProcessor implements ProcessorInterface
|
||||
->get(['tag_transaction_journal.transaction_journal_id', 'tags.tag']);
|
||||
$result = [];
|
||||
foreach ($set as $entry) {
|
||||
$id = intval($entry->transaction_journal_id);
|
||||
$result[$id] = isset($result[$id]) ? $result[$id] : [];
|
||||
$id = (int)$entry->transaction_journal_id;
|
||||
$result[$id] = $result[$id] ?? [];
|
||||
$result[$id][] = Crypt::decrypt($entry->tag);
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* BasicExporter.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Export\Exporter;
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* CsvExporter.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Export\Exporter;
|
||||
@@ -34,14 +36,6 @@ class CsvExporter extends BasicExporter implements ExporterInterface
|
||||
/** @var string */
|
||||
private $fileName;
|
||||
|
||||
/**
|
||||
* CsvExporter constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
@@ -53,7 +47,6 @@ class CsvExporter extends BasicExporter implements ExporterInterface
|
||||
/**
|
||||
* @return bool
|
||||
*
|
||||
* @throws \TypeError
|
||||
*/
|
||||
public function run(): bool
|
||||
{
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ExporterInterface.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Export\Exporter;
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ProcessorInterface.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
@@ -18,6 +19,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Export;
|
||||
|
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* AccountFactory.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -63,8 +64,8 @@ class AccountFactory
|
||||
'user_id' => $this->user->id,
|
||||
'account_type_id' => $type->id,
|
||||
'name' => $data['name'],
|
||||
'virtual_balance' => strlen(strval($data['virtualBalance'])) === 0 ? '0' : $data['virtualBalance'],
|
||||
'active' => true === $data['active'] ? true : false,
|
||||
'virtual_balance' => $data['virtualBalance'] ?? '0',
|
||||
'active' => true === $data['active'],
|
||||
'iban' => $data['iban'],
|
||||
];
|
||||
|
||||
@@ -73,8 +74,13 @@ class AccountFactory
|
||||
$databaseData['virtual_balance'] = '0';
|
||||
}
|
||||
|
||||
// fix virtual balance when it's empty
|
||||
if ($databaseData['virtual_balance'] === '') {
|
||||
$databaseData['virtual_balance'] = '0';
|
||||
}
|
||||
|
||||
$newAccount = Account::create($databaseData);
|
||||
$this->updateMetadata($newAccount, $data);
|
||||
$this->updateMetaData($newAccount, $data);
|
||||
|
||||
if ($this->validIBData($data) && $type->type === AccountType::ASSET) {
|
||||
$this->updateIB($newAccount, $data);
|
||||
@@ -158,14 +164,19 @@ class AccountFactory
|
||||
*/
|
||||
protected function getAccountType(?int $accountTypeId, ?string $accountType): ?AccountType
|
||||
{
|
||||
$accountTypeId = intval($accountTypeId);
|
||||
$accountTypeId = (int)$accountTypeId;
|
||||
if ($accountTypeId > 0) {
|
||||
return AccountType::find($accountTypeId);
|
||||
}
|
||||
$type = config('firefly.accountTypeByIdentifier.' . strval($accountType));
|
||||
$type = config('firefly.accountTypeByIdentifier.' . (string)$accountType);
|
||||
$result = AccountType::whereType($type)->first();
|
||||
if (null === $result && null !== $accountType) {
|
||||
// try as full name:
|
||||
$result = AccountType::whereType($accountType)->first();
|
||||
}
|
||||
|
||||
return AccountType::whereType($type)->first();
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user