mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 18:54:58 +00:00 
			
		
		
		
	Compare commits
	
		
			661 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | a4cb2c1cb1 | ||
|  | bd31b7e943 | ||
|  | b2e7c767df | ||
|  | bb9f763729 | ||
|  | fb61229bf3 | ||
|  | fc30d41ee5 | ||
|  | 7666147f3c | ||
|  | 52f8b24041 | ||
|  | eaf2667abb | ||
|  | de754ca4e0 | ||
|  | 96dd89fbeb | ||
|  | bae40e2cbc | ||
|  | 6a647dab8b | ||
|  | ebcf5b71d2 | ||
|  | 02370fb65d | ||
|  | 1e4f4907e3 | ||
|  | 13f72c73fb | ||
|  | 69b4632ef6 | ||
|  | ede8c293fc | ||
|  | 0cfe991482 | ||
|  | 6377459e2f | ||
|  | 33fe6dbfa3 | ||
|  | e158b9b64e | ||
|  | dfa9e537b3 | ||
|  | 6d28ece616 | ||
|  | 59f4ecdaa6 | ||
|  | 10d953f336 | ||
|  | 5b771f7def | ||
|  | 4a8e3ee845 | ||
|  | 9a1f559dd2 | ||
|  | 62321a03ca | ||
|  | 40ca72c656 | ||
|  | 34fcff7a9d | ||
|  | e1c829f4fa | ||
|  | 46136d94e9 | ||
|  | 0e2e8d1be5 | ||
|  | 1d1aa5dd3a | ||
|  | 0d82589916 | ||
|  | 4fc13037d2 | ||
|  | 3764499714 | ||
|  | c4bbbc49b4 | ||
|  | 503158ab97 | ||
|  | 8c1d1d1db0 | ||
|  | 7dc72a2894 | ||
|  | 07cfba1b3a | ||
|  | c55b80f467 | ||
|  | 2099da7142 | ||
|  | ea125936e7 | ||
|  | 5de01628a6 | ||
|  | 2834aca597 | ||
|  | 88bab888d8 | ||
|  | dfdbace298 | ||
|  | a9590d2bb6 | ||
|  | 29a81eb05e | ||
|  | 20490fcd80 | ||
|  | e775927f60 | ||
|  | 835a421909 | ||
|  | 850a0ae17e | ||
|  | 2b54363dd7 | ||
|  | b174a06b86 | ||
|  | d4096103cb | ||
|  | 3f493aceb2 | ||
|  | 05309da76d | ||
|  | 179f720806 | ||
|  | 7c34144ccd | ||
|  | cc234b594d | ||
|  | 024cf610a8 | ||
|  | a1896a6336 | ||
|  | d30da7bf5d | ||
|  | f8e914416d | ||
|  | 433da921bb | ||
|  | 4876053018 | ||
|  | 0c3a580b33 | ||
|  | 7689b7b4b0 | ||
|  | 21bff39e31 | ||
|  | ba09901228 | ||
|  | 90bf2e58b2 | ||
|  | 004807aa32 | ||
|  | 35bacf2ad0 | ||
|  | 81d17409d4 | ||
|  | a8080f55f0 | ||
|  | 379c540bd8 | ||
|  | f319005357 | ||
|  | df0e2dd2a2 | ||
|  | 219a0cd612 | ||
|  | 3ca3ce0726 | ||
|  | 566be8dc63 | ||
|  | 6bd4fa1c0a | ||
|  | c767ee04f4 | ||
|  | a5f89e0967 | ||
|  | 7355d14159 | ||
|  | efd5ceb405 | ||
|  | 035dc8ceb4 | ||
|  | 11be33e942 | ||
|  | e125254687 | ||
|  | a2b997ba20 | ||
|  | 7327941c77 | ||
|  | 6c9eb1b699 | ||
|  | 60e262dece | ||
|  | 9c5463e515 | ||
|  | 6941176519 | ||
|  | cb2c52cddb | ||
|  | dd95776144 | ||
|  | b95ca98be9 | ||
|  | 67b090b4d8 | ||
|  | 54b76a03ce | ||
|  | cd6c727730 | ||
|  | a35c6e29b6 | ||
|  | 95ce72fce7 | ||
|  | a803dfc7fa | ||
|  | c465d1c059 | ||
|  | 9914c0791e | ||
|  | 96baf5d3c7 | ||
|  | a205367b62 | ||
|  | 6218fa90de | ||
|  | 51a770cfdc | ||
|  | 16fba15b5c | ||
|  | ec2463a3ba | ||
|  | b605ede74e | ||
|  | b1b13d3696 | ||
|  | 51b11e5188 | ||
|  | eefa84a77b | ||
|  | 5908b4b000 | ||
|  | 2ed433c96d | ||
|  | 9865800e39 | ||
|  | 4f697e77d5 | ||
|  | c957aded98 | ||
|  | aa0758cd2b | ||
|  | 0c2093753d | ||
|  | 136f983353 | ||
|  | 7943164375 | ||
|  | 32e58d0a60 | ||
|  | bc807965ab | ||
|  | 477788658b | ||
|  | 723abf44bd | ||
|  | fd1298d4d2 | ||
|  | 42f39536a1 | ||
|  | 6f0ac91bd2 | ||
|  | 6dea9156ab | ||
|  | c5051b3e46 | ||
|  | 229d033e1a | ||
|  | f494ba7065 | ||
|  | 201bc7db53 | ||
|  | cd2a251f22 | ||
|  | ff44ad4994 | ||
|  | b496ca6a2c | ||
|  | 5908c0ce8c | ||
|  | f7eef25fed | ||
|  | 049c93465a | ||
|  | 33294dd9f0 | ||
|  | 0a89f4000d | ||
|  | 422e80530b | ||
|  | 07a8c69ba8 | ||
|  | 5449879a7d | ||
|  | 8dbc846314 | ||
|  | f0d3ca5d53 | ||
|  | 5af026674f | ||
|  | 2ebb4778cd | ||
|  | bf3c57d26b | ||
|  | cb9c87102f | ||
|  | c73b003de4 | ||
|  | 771d448a7b | ||
|  | de12db5f05 | ||
|  | dd49926cc2 | ||
|  | 7a9ab190eb | ||
|  | 2290fcde22 | ||
|  | ae85876965 | ||
|  | f07d8e958f | ||
|  | 610af45dee | ||
|  | 138a5bc3fe | ||
|  | 427e9c5637 | ||
|  | e3e8336602 | ||
|  | 194073e49a | ||
|  | 1af45aff73 | ||
|  | 56518ea028 | ||
|  | c1ac2bb156 | ||
|  | a004f27361 | ||
|  | 7843c55409 | ||
|  | 41da7d9f9a | ||
|  | 2add644706 | ||
|  | dfd9cf0874 | ||
|  | 7ad09da4e9 | ||
|  | 8efbeb14d2 | ||
|  | a1005d91df | ||
|  | a681f1ce3c | ||
|  | 5a0714ca1a | ||
|  | bd5c790043 | ||
|  | 2ae3cf79e4 | ||
|  | fb122ba097 | ||
|  | 0c104cd86c | ||
|  | a687f4ad68 | ||
|  | 228f42cf04 | ||
|  | 6d4956b574 | ||
|  | 0c7b652a70 | ||
|  | d35470a79e | ||
|  | 719d610be3 | ||
|  | 07ae64693e | ||
|  | 0ccc1271a6 | ||
|  | 26fa2b0b74 | ||
|  | 6f64c19c32 | ||
|  | e3e0e12fef | ||
|  | 0312ba8ad7 | ||
|  | 2ad8e7f343 | ||
|  | d6298d9f05 | ||
|  | 89be30c4b9 | ||
|  | 6bcfea1de4 | ||
|  | e8c9554dd6 | ||
|  | 02272f7db0 | ||
|  | 5a73e79475 | ||
|  | 7f4ecd40ce | ||
|  | 7c950c3022 | ||
|  | dbf019135a | ||
|  | e504ee82e5 | ||
|  | 780a15fe4f | ||
|  | abb249643f | ||
|  | 086eccaf4a | ||
|  | 871033501a | ||
|  | ccd727488f | ||
|  | aa59d0f082 | ||
|  | 5d12f53283 | ||
|  | 59c005875a | ||
|  | 06d22e843a | ||
|  | 4fa5f4e5a3 | ||
|  | 67ea825d4a | ||
|  | a616e06f9d | ||
|  | b7752928a4 | ||
|  | ca096852a5 | ||
|  | ea2c48bca5 | ||
|  | a722dc4235 | ||
|  | dbbf0ff5e4 | ||
|  | a941519db5 | ||
|  | d4ba014a8a | ||
|  | d193a6aec4 | ||
|  | 1f0fdf3da7 | ||
|  | b705240faa | ||
|  | 662b832274 | ||
|  | aed7e6d289 | ||
|  | f7a1201d02 | ||
|  | 4d5bdd25a8 | ||
|  | 4a90ce35f2 | ||
|  | 02f5eddd14 | ||
|  | 5ca4f1b181 | ||
|  | ec7ef3a813 | ||
|  | 49ff6febe5 | ||
|  | 2d66a9212f | ||
|  | 44fb307da4 | ||
|  | cfc2181a48 | ||
|  | cf4a846312 | ||
|  | 633b357d7b | ||
|  | b96d67a54e | ||
|  | 5b83931b01 | ||
|  | f22b54de30 | ||
|  | a3306bb26f | ||
|  | 0adacac269 | ||
|  | 7359ed2ba2 | ||
|  | 5a5f4e8161 | ||
|  | b886cc1333 | ||
|  | 9299efd086 | ||
|  | 1502aa3b20 | ||
|  | 73e32ecdcb | ||
|  | ac8776aea4 | ||
|  | 7b41c5b301 | ||
|  | 369839e012 | ||
|  | 8fde16422e | ||
|  | f1462dbd3d | ||
|  | 5dad569d62 | ||
|  | c424bb097d | ||
|  | e4b1760b20 | ||
|  | 780e365a78 | ||
|  | 3d1523a060 | ||
|  | ff403dfa2e | ||
|  | 89834baf01 | ||
|  | b8699422c8 | ||
|  | 6bc772d640 | ||
|  | 0712f30a51 | ||
|  | 9116796d90 | ||
|  | a95fdb903b | ||
|  | 2ca6421206 | ||
|  | cd076cc069 | ||
|  | 46482bdae1 | ||
|  | 5189c897be | ||
|  | 2c7d25d472 | ||
|  | 0da370c42d | ||
|  | 6f036d9120 | ||
|  | 260bbd79fd | ||
|  | 37ad6a3a62 | ||
|  | aa25007431 | ||
|  | 8b33ec1339 | ||
|  | cede11ecea | ||
|  | 2b4088c5f7 | ||
|  | d872484607 | ||
|  | f3f2160d96 | ||
|  | bcdb849b46 | ||
|  | 5846431b34 | ||
|  | 0217d9396a | ||
|  | c99e233026 | ||
|  | f670d930f3 | ||
|  | 0237d78f61 | ||
|  | 5665f127aa | ||
|  | 76386dad7d | ||
|  | 42072fdda4 | ||
|  | fc80f828be | ||
|  | d05a1e0260 | ||
|  | b315882f58 | ||
|  | 2f2f907ffe | ||
|  | 10492e3b2f | ||
|  | 8e08ff2d39 | ||
|  | e78a59a8a8 | ||
|  | cbe47a9dcc | ||
|  | a1056147d8 | ||
|  | 8692590600 | ||
|  | 57345113b5 | ||
|  | 52f02cb9eb | ||
|  | 5d4dcd7e4b | ||
|  | 7d1f4d8907 | ||
|  | a76241c7ba | ||
|  | bdc6678341 | ||
|  | c99b7e927d | ||
|  | 1675a0d442 | ||
|  | c0d2cd8962 | ||
|  | 146c9fd947 | ||
|  | 666e9897ea | ||
|  | 81d70bd811 | ||
|  | f6f8bb7fd1 | ||
|  | 7c3aaf7b7c | ||
|  | 32ea28f783 | ||
|  | 17f365941b | ||
|  | 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 | ||
|  | 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 | 
							
								
								
									
										11
									
								
								.deploy/docker/cronjob.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								.deploy/docker/cronjob.conf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | [program:cron] | ||||||
|  | command=/usr/sbin/cron -f -L 15 | ||||||
|  | user=root | ||||||
|  | autostart=true | ||||||
|  | autorestart=true | ||||||
|  | stdout_events_enabled=true | ||||||
|  | stderr_events_enabled=true | ||||||
|  | stdout_logfile=/dev/stdout | ||||||
|  | stdout_logfile_maxbytes=0 | ||||||
|  | startsecs=10 | ||||||
|  | startretries=3 | ||||||
| @@ -1,14 +1,29 @@ | |||||||
| #!/bin/bash | #!/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: | # 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/cache | chown -R www-data:www-data -R $FIREFLY_PATH/storage | ||||||
| chmod -R 775 $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload $FIREFLY_PATH/storage/upload $FIREFLY_PATH/storage/logs $FIREFLY_PATH/storage/cache | chmod -R 775 $FIREFLY_PATH/storage | ||||||
|  |  | ||||||
| # remove any lingering files that may break upgrades: | # remove any lingering files that may break upgrades: | ||||||
| rm -f $FIREFLY_PATH/storage/logs/laravel.log | rm -f $FIREFLY_PATH/storage/logs/laravel.log | ||||||
|  |  | ||||||
| cat .env.docker | envsubst > .env && cat .env | cat .env.docker | envsubst > .env | ||||||
| composer dump-autoload | composer dump-autoload | ||||||
| php artisan package:discover | php artisan package:discover | ||||||
| php artisan firefly:instructions install | php artisan firefly:instructions install | ||||||
| exec apache2-foreground | exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf --nodaemon | ||||||
							
								
								
									
										6
									
								
								.deploy/docker/firefly-iii.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								.deploy/docker/firefly-iii.conf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | [program:apache2] | ||||||
|  | command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2 -DFOREGROUND" | ||||||
|  | stdout_events_enabled=true | ||||||
|  | stderr_events_enabled=true | ||||||
|  | stdout_logfile=/dev/stdout | ||||||
|  | stdout_logfile_maxbytes=0 | ||||||
							
								
								
									
										30
									
								
								.deploy/docker/supervisord.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								.deploy/docker/supervisord.conf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | # supervisor config file | ||||||
|  | # Adapted from the config file distributed with the supervisor package on Debian | ||||||
|  | # Jessie | ||||||
|  |  | ||||||
|  | # Enable supervisord in non-daemon mode. Disable the logfile as we receive | ||||||
|  | # log messages via stdout/err. Set up the child process log directory in case | ||||||
|  | # the user doesn't set logging to stdout/err. | ||||||
|  | [supervisord] | ||||||
|  | nodaemon = true | ||||||
|  | logfile = NONE | ||||||
|  | pidfile = /var/run/supervisord.pid | ||||||
|  | childlogdir = /var/log/supervisor | ||||||
|  | loglevel=debug | ||||||
|  |  | ||||||
|  | # Enable supervisorctl via RPC interface over Unix socket | ||||||
|  | [unix_http_server] | ||||||
|  | file = /var/run/supervisor.sock | ||||||
|  | chmod = 0700 | ||||||
|  |  | ||||||
|  | [rpcinterface:supervisor] | ||||||
|  | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface | ||||||
|  |  | ||||||
|  | [supervisorctl] | ||||||
|  | serverurl = unix:///var/run/supervisor.sock | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # Include conf files for child processes | ||||||
|  | # Debian/Ubuntu packages use /etc/supervisor/conf.d | ||||||
|  | [include] | ||||||
|  | files = /etc/supervisor/conf.d/*.conf | ||||||
							
								
								
									
										26
									
								
								.deploy/docker/vhost.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								.deploy/docker/vhost.conf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | |||||||
|  | server { | ||||||
|  |     listen 80 default_server; | ||||||
|  |  | ||||||
|  |     server_name  _ *.vm docker; | ||||||
|  |  | ||||||
|  |     root "/app/public"; | ||||||
|  |     index index.php; | ||||||
|  |  | ||||||
|  |     include /opt/docker/etc/nginx/vhost.common.d/*.conf; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ############## | ||||||
|  | # SSL | ||||||
|  | ############## | ||||||
|  |  | ||||||
|  | server { | ||||||
|  |     listen 443 default_server; | ||||||
|  |  | ||||||
|  |     server_name  _ *.vm docker; | ||||||
|  |  | ||||||
|  |     root "/app/public"; | ||||||
|  |     index index.php; | ||||||
|  |  | ||||||
|  |     include /opt/docker/etc/nginx/vhost.common.d/*.conf; | ||||||
|  |     include /opt/docker/etc/nginx/vhost.ssl.conf; | ||||||
|  | } | ||||||
| @@ -1,4 +1,3 @@ | |||||||
| # Ignore composer specific files and vendor folder | # Ignore composer specific files and vendor folder | ||||||
| composer.phar | composer.phar | ||||||
| composer.lock |  | ||||||
| vendor | vendor | ||||||
|   | |||||||
							
								
								
									
										44
									
								
								.env.docker
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								.env.docker
									
									
									
									
									
								
							| @@ -13,15 +13,31 @@ SITE_OWNER=${SITE_OWNER} | |||||||
| # Change it to a string of exactly 32 chars or use command `php artisan key:generate` to generate it | # Change it to a string of exactly 32 chars or use command `php artisan key:generate` to generate it | ||||||
| APP_KEY=${FF_APP_KEY} | APP_KEY=${FF_APP_KEY} | ||||||
|  |  | ||||||
| # APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy. | # Change this value to your preferred time zone. | ||||||
|  | # Example: Europe/Amsterdam | ||||||
|  | TZ=${TZ} | ||||||
|  |  | ||||||
|  | # This variable must match your installation's external address but keep in mind that | ||||||
|  | # it's only used on the command line as a fallback value. | ||||||
| APP_URL=${APP_URL} | APP_URL=${APP_URL} | ||||||
|  |  | ||||||
|  | # TRUSTED_PROXIES is a useful variable when using Docker and/or a reverse proxy. | ||||||
| TRUSTED_PROXIES=${TRUSTED_PROXIES} | TRUSTED_PROXIES=${TRUSTED_PROXIES} | ||||||
|  |  | ||||||
| # The log channel defines where your log entries go to. | # The log channel defines where your log entries go to. | ||||||
| LOG_CHANNEL=${LOG_CHANNEL} | # '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', 'errorlog' and 'stdout' which will log to the system itself. | ||||||
|  | LOG_CHANNEL=stdout | ||||||
|  |  | ||||||
|  | # 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=${APP_LOG_LEVEL} | ||||||
|  |  | ||||||
| # Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III | # 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=${FF_DB_CONNECTION} | DB_CONNECTION=${FF_DB_CONNECTION} | ||||||
| DB_HOST=${FF_DB_HOST} | DB_HOST=${FF_DB_HOST} | ||||||
| DB_PORT=${FF_DB_PORT} | DB_PORT=${FF_DB_PORT} | ||||||
| @@ -29,17 +45,6 @@ DB_DATABASE=${FF_DB_NAME} | |||||||
| DB_USERNAME=${FF_DB_USER} | DB_USERNAME=${FF_DB_USER} | ||||||
| DB_PASSWORD=${FF_DB_PASSWORD} | DB_PASSWORD=${FF_DB_PASSWORD} | ||||||
|  |  | ||||||
| # '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=syslog |  | ||||||
|  |  | ||||||
| # 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=info |  | ||||||
|  |  | ||||||
| # If you're looking for performance improvements, you could install memcached. | # If you're looking for performance improvements, you could install memcached. | ||||||
| CACHE_DRIVER=file | CACHE_DRIVER=file | ||||||
| SESSION_DRIVER=file | SESSION_DRIVER=file | ||||||
| @@ -50,6 +55,7 @@ COOKIE_DOMAIN= | |||||||
| COOKIE_SECURE=false | COOKIE_SECURE=false | ||||||
|  |  | ||||||
| # If you want Firefly III to mail you, update these settings | # 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_DRIVER=${MAIL_DRIVER} | ||||||
| MAIL_HOST=${MAIL_HOST} | MAIL_HOST=${MAIL_HOST} | ||||||
| MAIL_PORT=${MAIL_PORT} | MAIL_PORT=${MAIL_PORT} | ||||||
| @@ -58,6 +64,12 @@ MAIL_USERNAME=${MAIL_USERNAME} | |||||||
| MAIL_PASSWORD=${MAIL_PASSWORD} | MAIL_PASSWORD=${MAIL_PASSWORD} | ||||||
| MAIL_ENCRYPTION=${MAIL_ENCRYPTION} | 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 | # Firefly III can send you the following messages | ||||||
| SEND_REGISTRATION_MAIL=true | SEND_REGISTRATION_MAIL=true | ||||||
| SEND_ERROR_MESSAGE=false | SEND_ERROR_MESSAGE=false | ||||||
| @@ -95,4 +107,6 @@ DEMO_PASSWORD= | |||||||
| IS_DOCKER=true | IS_DOCKER=true | ||||||
| IS_SANDSTORM=false | IS_SANDSTORM=false | ||||||
| IS_HEROKU=false | IS_HEROKU=false | ||||||
| TZ=${TZ} | BUNQ_USE_SANDBOX=false | ||||||
|  | MAILGUN_DOMAIN= | ||||||
|  | MAILGUN_SECRET= | ||||||
|   | |||||||
							
								
								
									
										37
									
								
								.env.example
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								.env.example
									
									
									
									
									
								
							| @@ -15,15 +15,27 @@ APP_KEY=SomeRandomStringOf32CharsExactly | |||||||
|  |  | ||||||
| # Change this value to your preferred time zone. | # Change this value to your preferred time zone. | ||||||
| # Example: Europe/Amsterdam | # Example: Europe/Amsterdam | ||||||
| TZ=UTC | TZ=Europe/Amsterdam | ||||||
|  |  | ||||||
| # APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy. | # This variable must match your installation's external address but keep in mind that | ||||||
|  | # it's only used on the command line as a fallback value. | ||||||
| APP_URL=http://localhost | APP_URL=http://localhost | ||||||
|  |  | ||||||
|  | # TRUSTED_PROXIES is a useful variable when using Docker and/or a reverse proxy. | ||||||
| TRUSTED_PROXIES= | TRUSTED_PROXIES= | ||||||
|  |  | ||||||
| # The log channel defines where your log entries go to. | # The log channel defines where your log entries go to. | ||||||
|  | # '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', 'errorlog' and 'stdout' which will log to the system itself. | ||||||
| LOG_CHANNEL=daily | LOG_CHANNEL=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=notice | ||||||
|  |  | ||||||
| # Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III | # 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 | # For other database types, please see the FAQ: http://firefly-iii.readthedocs.io/en/latest/support/faq.html | ||||||
| DB_CONNECTION=mysql | DB_CONNECTION=mysql | ||||||
| @@ -33,17 +45,6 @@ DB_DATABASE=homestead | |||||||
| DB_USERNAME=homestead | DB_USERNAME=homestead | ||||||
| DB_PASSWORD=secret | DB_PASSWORD=secret | ||||||
|  |  | ||||||
| # '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=notice |  | ||||||
|  |  | ||||||
| # If you're looking for performance improvements, you could install memcached. | # If you're looking for performance improvements, you could install memcached. | ||||||
| CACHE_DRIVER=file | CACHE_DRIVER=file | ||||||
| SESSION_DRIVER=file | SESSION_DRIVER=file | ||||||
| @@ -54,6 +55,7 @@ COOKIE_DOMAIN= | |||||||
| COOKIE_SECURE=false | COOKIE_SECURE=false | ||||||
|  |  | ||||||
| # If you want Firefly III to mail you, update these settings | # 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_DRIVER=log | ||||||
| MAIL_HOST=smtp.mailtrap.io | MAIL_HOST=smtp.mailtrap.io | ||||||
| MAIL_PORT=2525 | MAIL_PORT=2525 | ||||||
| @@ -62,6 +64,12 @@ MAIL_USERNAME=null | |||||||
| MAIL_PASSWORD=null | MAIL_PASSWORD=null | ||||||
| MAIL_ENCRYPTION=null | MAIL_ENCRYPTION=null | ||||||
|  |  | ||||||
|  | # Other mail drivers: | ||||||
|  | MAILGUN_DOMAIN= | ||||||
|  | MAILGUN_SECRET= | ||||||
|  | MANDRILL_SECRET= | ||||||
|  | SPARKPOST_SECRET= | ||||||
|  |  | ||||||
| # Firefly III can send you the following messages | # Firefly III can send you the following messages | ||||||
| SEND_REGISTRATION_MAIL=true | SEND_REGISTRATION_MAIL=true | ||||||
| SEND_ERROR_MESSAGE=true | SEND_ERROR_MESSAGE=true | ||||||
| @@ -99,3 +107,6 @@ DEMO_PASSWORD= | |||||||
| IS_DOCKER=false | IS_DOCKER=false | ||||||
| IS_SANDSTORM=false | IS_SANDSTORM=false | ||||||
| IS_HEROKU=false | IS_HEROKU=false | ||||||
|  | BUNQ_USE_SANDBOX=false | ||||||
|  | MAILGUN_DOMAIN= | ||||||
|  | MAILGUN_SECRET= | ||||||
|   | |||||||
							
								
								
									
										39
									
								
								.env.heroku
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								.env.heroku
									
									
									
									
									
								
							| @@ -17,12 +17,24 @@ APP_KEY=7ahyYVPVsmxjdhsweWCauGeJfwc92NP2 | |||||||
| # Example: Europe/Amsterdam | # Example: Europe/Amsterdam | ||||||
| TZ=UTC | TZ=UTC | ||||||
|  |  | ||||||
| # APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy. | # This variable must match your installation's external address but keep in mind that | ||||||
|  | # it's only used on the command line as a fallback value. | ||||||
| APP_URL=http://localhost | APP_URL=http://localhost | ||||||
| TRUSTED_PROXIES= |  | ||||||
|  | # TRUSTED_PROXIES is a useful variable when using Docker and/or a reverse proxy. | ||||||
|  | TRUSTED_PROXIES=** | ||||||
|  |  | ||||||
| # The log channel defines where your log entries go to. | # The log channel defines where your log entries go to. | ||||||
| LOG_CHANNEL=syslog | # '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', 'errorlog' and 'stdout' which will log to the system itself. | ||||||
|  | LOG_CHANNEL=stdout | ||||||
|  |  | ||||||
|  | # 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 | ||||||
|  |  | ||||||
| # Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III | # 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. | # If you use SQLite, set connection to `sqlite` and remove the database, username and password settings. | ||||||
| @@ -33,17 +45,6 @@ DB_CONNECTION=pgsql | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| # '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=errorlog |  | ||||||
|  |  | ||||||
| # 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. | # If you're looking for performance improvements, you could install memcached. | ||||||
| CACHE_DRIVER=file | CACHE_DRIVER=file | ||||||
| SESSION_DRIVER=file | SESSION_DRIVER=file | ||||||
| @@ -54,6 +55,7 @@ COOKIE_DOMAIN= | |||||||
| COOKIE_SECURE=false | COOKIE_SECURE=false | ||||||
|  |  | ||||||
| # If you want Firefly III to mail you, update these settings | # 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_DRIVER=log | ||||||
| MAIL_HOST=smtp.mailtrap.io | MAIL_HOST=smtp.mailtrap.io | ||||||
| MAIL_PORT=2525 | MAIL_PORT=2525 | ||||||
| @@ -62,6 +64,12 @@ MAIL_USERNAME=null | |||||||
| MAIL_PASSWORD=null | MAIL_PASSWORD=null | ||||||
| MAIL_ENCRYPTION=null | MAIL_ENCRYPTION=null | ||||||
|  |  | ||||||
|  | # Other mail drivers: | ||||||
|  | MAILGUN_DOMAIN= | ||||||
|  | MAILGUN_SECRET= | ||||||
|  | MANDRILL_SECRET= | ||||||
|  | SPARKPOST_SECRET= | ||||||
|  |  | ||||||
| # Firefly III can send you the following messages | # Firefly III can send you the following messages | ||||||
| SEND_REGISTRATION_MAIL=true | SEND_REGISTRATION_MAIL=true | ||||||
| SEND_ERROR_MESSAGE=true | SEND_ERROR_MESSAGE=true | ||||||
| @@ -99,3 +107,6 @@ DEMO_PASSWORD= | |||||||
| IS_DOCKER=false | IS_DOCKER=false | ||||||
| IS_SANDSTORM=false | IS_SANDSTORM=false | ||||||
| IS_HEROKU=true | IS_HEROKU=true | ||||||
|  | BUNQ_USE_SANDBOX=false | ||||||
|  | MAILGUN_DOMAIN= | ||||||
|  | MAILGUN_SECRET= | ||||||
|   | |||||||
| @@ -17,12 +17,24 @@ APP_KEY=SomeRandomStringOf32CharsExactly | |||||||
| # Example: Europe/Amsterdam | # Example: Europe/Amsterdam | ||||||
| TZ=UTC | TZ=UTC | ||||||
|  |  | ||||||
| # APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy. | # This variable must match your installation's external address but keep in mind that | ||||||
|  | # it's only used on the command line as a fallback value. | ||||||
| APP_URL=http://localhost | APP_URL=http://localhost | ||||||
|  |  | ||||||
|  | # TRUSTED_PROXIES is a useful variable when using Docker and/or a reverse proxy. | ||||||
| TRUSTED_PROXIES= | TRUSTED_PROXIES= | ||||||
|  |  | ||||||
| # The log channel defines where your log entries go to. | # The log channel defines where your log entries go to. | ||||||
| LOG_CHANNEL=syslog | # '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', 'errorlog' and 'stdout' which will log to the system itself. | ||||||
|  | LOG_CHANNEL=stdout | ||||||
|  |  | ||||||
|  | # 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 | ||||||
|  |  | ||||||
| # Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III | # 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. | # If you use SQLite, set connection to `sqlite` and remove the database, username and password settings. | ||||||
| @@ -33,17 +45,6 @@ DB_DATABASE=firefly | |||||||
| DB_USERNAME=firefly | DB_USERNAME=firefly | ||||||
| DB_PASSWORD=firefly | DB_PASSWORD=firefly | ||||||
|  |  | ||||||
| # '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=syslog |  | ||||||
|  |  | ||||||
| # 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=info |  | ||||||
|  |  | ||||||
| # If you're looking for performance improvements, you could install memcached. | # If you're looking for performance improvements, you could install memcached. | ||||||
| CACHE_DRIVER=file | CACHE_DRIVER=file | ||||||
| SESSION_DRIVER=file | SESSION_DRIVER=file | ||||||
| @@ -54,6 +55,7 @@ COOKIE_DOMAIN= | |||||||
| COOKIE_SECURE=false | COOKIE_SECURE=false | ||||||
|  |  | ||||||
| # If you want Firefly III to mail you, update these settings | # 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_DRIVER=log | ||||||
| MAIL_HOST=smtp.mailtrap.io | MAIL_HOST=smtp.mailtrap.io | ||||||
| MAIL_PORT=2525 | MAIL_PORT=2525 | ||||||
| @@ -62,6 +64,12 @@ MAIL_USERNAME=null | |||||||
| MAIL_PASSWORD=null | MAIL_PASSWORD=null | ||||||
| MAIL_ENCRYPTION=null | MAIL_ENCRYPTION=null | ||||||
|  |  | ||||||
|  | # Other mail drivers: | ||||||
|  | MAILGUN_DOMAIN= | ||||||
|  | MAILGUN_SECRET= | ||||||
|  | MANDRILL_SECRET= | ||||||
|  | SPARKPOST_SECRET= | ||||||
|  |  | ||||||
| # Firefly III can send you the following messages | # Firefly III can send you the following messages | ||||||
| SEND_REGISTRATION_MAIL=true | SEND_REGISTRATION_MAIL=true | ||||||
| SEND_ERROR_MESSAGE=true | SEND_ERROR_MESSAGE=true | ||||||
| @@ -99,3 +107,6 @@ DEMO_PASSWORD= | |||||||
| IS_DOCKER=false | IS_DOCKER=false | ||||||
| IS_SANDSTORM=true | IS_SANDSTORM=true | ||||||
| IS_HEROKU=false | IS_HEROKU=false | ||||||
|  | BUNQ_USE_SANDBOX=false | ||||||
|  | MAILGUN_DOMAIN= | ||||||
|  | MAILGUN_SECRET= | ||||||
|   | |||||||
							
								
								
									
										35
									
								
								.env.testing
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								.env.testing
									
									
									
									
									
								
							| @@ -17,21 +17,18 @@ APP_KEY=TestTestTestTestTestTestTestTest | |||||||
| # Example: Europe/Amsterdam | # Example: Europe/Amsterdam | ||||||
| TZ=Europe/Amsterdam | TZ=Europe/Amsterdam | ||||||
|  |  | ||||||
| # APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy. | # This variable must match your installation's external address but keep in mind that | ||||||
|  | # it's only used on the command line as a fallback value. | ||||||
| APP_URL=http://localhost | APP_URL=http://localhost | ||||||
|  |  | ||||||
|  | # TRUSTED_PROXIES is a useful variable when using Docker and/or a reverse proxy. | ||||||
| TRUSTED_PROXIES= | TRUSTED_PROXIES= | ||||||
|  |  | ||||||
| # The log channel defines where your log entries go to. | # The log channel defines where your log entries go to. | ||||||
| LOG_CHANNEL=dailytest |  | ||||||
|  |  | ||||||
| # 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/. | # '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). | # 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. | # Also available are 'syslog', 'errorlog' and 'stdout' which will log to the system itself. | ||||||
| APP_LOG=daily | LOG_CHANNEL=dailytest | ||||||
|  |  | ||||||
| # Log level. You can set this from least severe to most severe: | # Log level. You can set this from least severe to most severe: | ||||||
| # debug, info, notice, warning, error, critical, alert, emergency | # debug, info, notice, warning, error, critical, alert, emergency | ||||||
| @@ -39,6 +36,15 @@ APP_LOG=daily | |||||||
| # nothing will get logged, ever. | # nothing will get logged, ever. | ||||||
| APP_LOG_LEVEL=debug | APP_LOG_LEVEL=debug | ||||||
|  |  | ||||||
|  | # 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 | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| # If you're looking for performance improvements, you could install memcached. | # If you're looking for performance improvements, you could install memcached. | ||||||
| CACHE_DRIVER=file | CACHE_DRIVER=file | ||||||
| SESSION_DRIVER=file | SESSION_DRIVER=file | ||||||
| @@ -49,6 +55,7 @@ COOKIE_DOMAIN= | |||||||
| COOKIE_SECURE=false | COOKIE_SECURE=false | ||||||
|  |  | ||||||
| # If you want Firefly III to mail you, update these settings | # 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_DRIVER=log | ||||||
| MAIL_HOST=smtp.mailtrap.io | MAIL_HOST=smtp.mailtrap.io | ||||||
| MAIL_PORT=2525 | MAIL_PORT=2525 | ||||||
| @@ -57,11 +64,16 @@ MAIL_USERNAME=null | |||||||
| MAIL_PASSWORD=null | MAIL_PASSWORD=null | ||||||
| MAIL_ENCRYPTION=null | MAIL_ENCRYPTION=null | ||||||
|  |  | ||||||
|  | # Other mail drivers: | ||||||
|  | MAILGUN_DOMAIN= | ||||||
|  | MAILGUN_SECRET= | ||||||
|  | MANDRILL_SECRET= | ||||||
|  | SPARKPOST_SECRET= | ||||||
|  |  | ||||||
| # Firefly III can send you the following messages | # Firefly III can send you the following messages | ||||||
| SEND_REGISTRATION_MAIL=true | SEND_REGISTRATION_MAIL=true | ||||||
| SEND_ERROR_MESSAGE=false | SEND_ERROR_MESSAGE=false | ||||||
|  |  | ||||||
|  |  | ||||||
| # Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places. | # 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= | ||||||
|  |  | ||||||
| @@ -95,3 +107,6 @@ DEMO_PASSWORD= | |||||||
| IS_DOCKER=false | IS_DOCKER=false | ||||||
| IS_SANDSTORM=false | IS_SANDSTORM=false | ||||||
| IS_HEROKU=false | IS_HEROKU=false | ||||||
|  | BUNQ_USE_SANDBOX=true | ||||||
|  | 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.  |  | ||||||
							
								
								
									
										3
									
								
								.github/stale.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.github/stale.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,7 +1,7 @@ | |||||||
| # Configuration for probot-stale - https://github.com/probot/stale | # Configuration for probot-stale - https://github.com/probot/stale | ||||||
|  |  | ||||||
| # Number of days of inactivity before an Issue or Pull Request becomes stale | # Number of days of inactivity before an Issue or Pull Request becomes stale | ||||||
| daysUntilStale: 30 | daysUntilStale: 14 | ||||||
|  |  | ||||||
| # Number of days of inactivity before a stale Issue or Pull Request is closed. | # 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. | # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. | ||||||
| @@ -12,6 +12,7 @@ daysUntilClose: 7 | |||||||
| exemptLabels: | exemptLabels: | ||||||
|   - enhancement |   - enhancement | ||||||
|   - feature |   - feature | ||||||
|  |   - bug | ||||||
|  |  | ||||||
| # Set to true to ignore issues in a project (defaults to false) | # Set to true to ignore issues in a project (defaults to false) | ||||||
| exemptProjects: false | exemptProjects: false | ||||||
|   | |||||||
							
								
								
									
										9
									
								
								.sandstorm/Vagrantfile
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.sandstorm/Vagrantfile
									
									
									
									
										vendored
									
									
								
							| @@ -9,9 +9,16 @@ VM_NAME = File.basename(File.dirname(File.dirname(__FILE__))) + "_sandstorm_#{Ti | |||||||
| # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! | # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! | ||||||
| VAGRANTFILE_API_VERSION = "2" | VAGRANTFILE_API_VERSION = "2" | ||||||
|  |  | ||||||
|  | # ugly hack to prevent hashicorp's bitrot. See https://github.com/hashicorp/vagrant/issues/9442 | ||||||
|  | # this setting is required for pre-2.0 vagrant, but causes an error as of 2.0.3, | ||||||
|  | # remove entirely when confident nobody uses vagrant 1.x for anything. | ||||||
|  | unless Vagrant::DEFAULT_SERVER_URL.frozen? | ||||||
|  |   Vagrant::DEFAULT_SERVER_URL.replace('https://vagrantcloud.com') | ||||||
|  | end | ||||||
|  |  | ||||||
| Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| | ||||||
|   # Base on the Sandstorm snapshots of the official Debian 8 (jessie) box. |   # Base on the Sandstorm snapshots of the official Debian 8 (jessie) box. | ||||||
|   config.vm.box = "sandstorm/debian-jessie64" |   config.vm.box = "debian/contrib-jessie64" | ||||||
|  |  | ||||||
|   if Vagrant.has_plugin?("vagrant-vbguest") then |   if Vagrant.has_plugin?("vagrant-vbguest") then | ||||||
|     # vagrant-vbguest is a Vagrant plugin that upgrades |     # vagrant-vbguest is a Vagrant plugin that upgrades | ||||||
|   | |||||||
| @@ -1,3 +1,124 @@ | |||||||
|  | # 4.7.6.1 | ||||||
|  | - An issue where I switched variables from the Docker `.env` file to the normal `.env` file and vice versa -- breaking both. | ||||||
|  | - [Issue 1649](https://github.com/firefly-iii/firefly-iii/issues/1649) 2FA QR code would not show up due to very strict security policy headers | ||||||
|  | - Docker build gave a cURL error whenever it runs PHP commands. | ||||||
|  |  | ||||||
|  | # 4.7.6 | ||||||
|  | - [Issue 145](https://github.com/firefly-iii/firefly-iii/issues/145) You can now download transactions from YNAB. | ||||||
|  | - [Issue 306](https://github.com/firefly-iii/firefly-iii/issues/306) You can now add liabilities to Firefly III. | ||||||
|  | - [Issue 740](https://github.com/firefly-iii/firefly-iii/issues/740) Various charts are now currency aware. | ||||||
|  | - [Issue 833](https://github.com/firefly-iii/firefly-iii/issues/833) Bills can use non-default currencies. | ||||||
|  | - [Issue 1578](https://github.com/firefly-iii/firefly-iii/issues/1578) Firefly III will notify you if the cron job hasn't fired. | ||||||
|  | - [Issue 1623](https://github.com/firefly-iii/firefly-iii/issues/1623) New transactions will link back from the success message. | ||||||
|  | - [Issue 1624](https://github.com/firefly-iii/firefly-iii/issues/1624) transactions will link to the object. | ||||||
|  | - You can call the cron job over the web now (see docs). | ||||||
|  | - You don't need to call the cron job every minute any more. | ||||||
|  | - Various charts are now red/green to signify income and expenses. | ||||||
|  | - Option to add or remove accounts from the net worth calculations. | ||||||
|  | - This will be the last release on PHP 7.1. Future versions will require PHP 7.2. | ||||||
|  | - [Issue 1460](https://github.com/firefly-iii/firefly-iii/issues/1460) Downloading transactions from bunq should go more smoothly. | ||||||
|  | - [Issue 1464](https://github.com/firefly-iii/firefly-iii/issues/1464) Fixed the docker file to work on Raspberry Pi's. | ||||||
|  | - [Issue 1540](https://github.com/firefly-iii/firefly-iii/issues/1540) The Docker file now has a working cron job for recurring transactions. | ||||||
|  | - [Issue 1564](https://github.com/firefly-iii/firefly-iii/issues/1564) Fix double transfers when importing from bunq. | ||||||
|  | - [Issue 1575](https://github.com/firefly-iii/firefly-iii/issues/1575) Some views would give a XSRF token warning | ||||||
|  | - [Issue 1576](https://github.com/firefly-iii/firefly-iii/issues/1576) Fix assigning budgets | ||||||
|  | - [Issue 1580](https://github.com/firefly-iii/firefly-iii/issues/1580) Missing string for translation | ||||||
|  | - [Issue 1581](https://github.com/firefly-iii/firefly-iii/issues/1581) Expand help text | ||||||
|  | - [Issue 1584](https://github.com/firefly-iii/firefly-iii/issues/1584) Link to administration is back. | ||||||
|  | - [Issue 1586](https://github.com/firefly-iii/firefly-iii/issues/1586) Date fields in import were mislabeled. | ||||||
|  | - [Issue 1593](https://github.com/firefly-iii/firefly-iii/issues/1593) Link types are translatable. | ||||||
|  | - [Issue 1594](https://github.com/firefly-iii/firefly-iii/issues/1594) Very long breadcrumbs are weird. | ||||||
|  | - [Issue 1598](https://github.com/firefly-iii/firefly-iii/issues/1598) Fix budget calculations. | ||||||
|  | - [Issue 1597](https://github.com/firefly-iii/firefly-iii/issues/1597) Piggy banks are always inactive. | ||||||
|  | - [Issue 1605](https://github.com/firefly-iii/firefly-iii/issues/1605) System will ignore foreign currency setting if user doesn't indicate the amount. | ||||||
|  | - [Issue 1608](https://github.com/firefly-iii/firefly-iii/issues/1608) Spelling error in command line import. | ||||||
|  | - [Issue 1609](https://github.com/firefly-iii/firefly-iii/issues/1609) Link to budgets page was absolute. | ||||||
|  | - [Issue 1615](https://github.com/firefly-iii/firefly-iii/issues/1615) Fix currency bug in transactions. | ||||||
|  | - [Issue 1616](https://github.com/firefly-iii/firefly-iii/issues/1616) Fix null pointer exception in pie charts. | ||||||
|  | - [Issue 1617](https://github.com/firefly-iii/firefly-iii/issues/1617) Fix for complex tag names in URL's. | ||||||
|  | - [Issue 1620](https://github.com/firefly-iii/firefly-iii/issues/1620) Fixed index reference in API. | ||||||
|  | - [Issue 1639](https://github.com/firefly-iii/firefly-iii/issues/1639) Firefly III trusts the Heroku load balancer, fixing deployment on Heroku. | ||||||
|  | - [Issue 1642](https://github.com/firefly-iii/firefly-iii/issues/1642) Fix issue with split journals. | ||||||
|  | - [Issue 1643](https://github.com/firefly-iii/firefly-iii/issues/1643) Fix reconciliation issue. | ||||||
|  | - Users can no longer give expenses a budget. | ||||||
|  | - Fix bug in Spectre import. | ||||||
|  | - Heroku would not make you owner. | ||||||
|  | - Add `.htaccess` files to all public directories. | ||||||
|  | - New secure headers will make Firefly III slightly more secure. | ||||||
|  |  | ||||||
|  | # 4.7.5.3 | ||||||
|  | - [Issue 1527](https://github.com/firefly-iii/firefly-iii/issues/1527), fixed views for transactions without a budget. | ||||||
|  | - [Issue 1553](https://github.com/firefly-iii/firefly-iii/issues/1553), report could not handle transactions before the first one in the system. | ||||||
|  | - [Issue 1549](https://github.com/firefly-iii/firefly-iii/issues/1549) update a budget will also update any rules that refer to that budget. | ||||||
|  | - [Issue 1530](https://github.com/firefly-iii/firefly-iii/issues/1530), fix issue with bill chart. | ||||||
|  | - [Issue 1563](https://github.com/firefly-iii/firefly-iii/issues/1563), fix piggy bank suggested amount | ||||||
|  | - [Issue 1571](https://github.com/firefly-iii/firefly-iii/issues/1571), fix OAuth in Sandstorm | ||||||
|  | - [Issue 1568](https://github.com/firefly-iii/firefly-iii/issues/1568), bug in Sandstorm user code. | ||||||
|  | - [Issue 1569](https://github.com/firefly-iii/firefly-iii/issues/1569), optimized Sandstorm build by [ocdtrekkie](https://github.com/ocdtrekkie) | ||||||
|  | - Fixed a bug where transfers would be stored inversely when using the CSV import. | ||||||
|  | - Retired the "Rabobank description"-fix, because it is no longer necessary. | ||||||
|  | - Fixed a bug where users could not delete budget limits in the API. | ||||||
|  | - Piggy bank notes are visible again. | ||||||
|  |  | ||||||
|  | # 4.7.5.1 | ||||||
|  | - [Issue 1531](https://github.com/firefly-iii/firefly-iii/issues/1531), the database routine incorrectly reports empty categories. | ||||||
|  | - [Issue 1532](https://github.com/firefly-iii/firefly-iii/issues/1532), broken dropdown for autosuggest things. | ||||||
|  | - [Issue 1533](https://github.com/firefly-iii/firefly-iii/issues/1533), fix where the import could not import category names. | ||||||
|  | - [Issue 1538](https://github.com/firefly-iii/firefly-iii/issues/1538), fix a bug where Spectre would not work when ignoring rules. | ||||||
|  | - [Issue 1542](https://github.com/firefly-iii/firefly-iii/issues/1542), fix a bug where the importer was incapable of generating new currencies. | ||||||
|  | - [Issue 1541](https://github.com/firefly-iii/firefly-iii/issues/1541), no longer ignore composer.lock in Docker ignore. | ||||||
|  | - Bills are stored inactive. | ||||||
|  |  | ||||||
|  | # 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 | # 4.7.3 | ||||||
| - Currency added to API | - Currency added to API | ||||||
| - Firfely III will also generate a cash wallet for new users. | - Firfely III will also generate a cash wallet for new users. | ||||||
|   | |||||||
| @@ -9,6 +9,10 @@ CURL_OPTS="--silent --show-error" | |||||||
| echo localhost > /etc/hostname | echo localhost > /etc/hostname | ||||||
| hostname localhost | hostname localhost | ||||||
|  |  | ||||||
|  | # Install curl that is needed below. | ||||||
|  | apt-get update | ||||||
|  | apt-get install -y curl | ||||||
|  |  | ||||||
| # The following line copies stderr through stderr to cat without accidentally leaving it in the | # The following line copies stderr through stderr to cat without accidentally leaving it in the | ||||||
| # output file. Be careful when changing. See: https://github.com/sandstorm-io/vagrant-spk/pull/159 | # output file. Be careful when changing. See: https://github.com/sandstorm-io/vagrant-spk/pull/159 | ||||||
| curl $CURL_OPTS https://install.sandstorm.io/ 2>&1 > /host-dot-sandstorm/caches/install.sh | cat | curl $CURL_OPTS https://install.sandstorm.io/ 2>&1 > /host-dot-sandstorm/caches/install.sh | cat | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -15,8 +15,8 @@ const pkgdef :Spk.PackageDefinition = ( | |||||||
|  |  | ||||||
|   manifest = ( |   manifest = ( | ||||||
|     appTitle = (defaultText = "Firefly III"), |     appTitle = (defaultText = "Firefly III"), | ||||||
|     appVersion = 11, |     appVersion = 16, | ||||||
|     appMarketingVersion = (defaultText = "4.7.3"), |     appMarketingVersion = (defaultText = "4.7.6.1"), | ||||||
|  |  | ||||||
|     actions = [ |     actions = [ | ||||||
|       # Define your "new document" handlers here. |       # 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 |         # 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. |         # screenshots on a Retina-style high DPI screen, divide each dimension by two. | ||||||
|  |  | ||||||
|         (width = 1291, height = 800, png = embed "screenshots/screenshot-1.png"), |         (width = 1290, height = 800, png = embed "screenshots/screenshot-1.png"), | ||||||
|         (width = 1291, height = 800, png = embed "screenshots/screenshot-2.png"), |         (width = 1290, 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-3.png"), | ||||||
|  |  | ||||||
|       ], |       ], | ||||||
|       changeLog = (defaultText = embed "changelog.md"), |       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,10 +14,7 @@ apt-get install -y python-software-properties software-properties-common | |||||||
|  |  | ||||||
| # install all languages | # 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/# 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/# 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/# 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/# 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/# pl_PL.UTF-8 UTF-8/pl_PL.UTF-8 UTF-8/g' /etc/locale.gen | ||||||
| @@ -35,7 +32,7 @@ apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E9C74FEEA2098A6E | |||||||
| add-apt-repository "deb http://packages.dotdeb.org jessie all" | add-apt-repository "deb http://packages.dotdeb.org jessie all" | ||||||
|  |  | ||||||
| # add another repos | # add another repos | ||||||
| apt-get install apt-transport-https lsb-release ca-certificates | apt-get install -y apt-transport-https lsb-release ca-certificates | ||||||
| wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg | wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg | ||||||
| echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list | echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,7 +1,6 @@ | |||||||
| language: php | language: php | ||||||
| php: | php: | ||||||
|   - 7.1 |   - 7.1.18 | ||||||
|   - 7.2 |  | ||||||
|  |  | ||||||
| cache: | cache: | ||||||
|     directories: |     directories: | ||||||
| @@ -14,7 +13,6 @@ install: | |||||||
|   - cp .env.testing .env |   - cp .env.testing .env | ||||||
|   - php artisan clear-compiled |   - php artisan clear-compiled | ||||||
|   - php artisan env |   - 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 |   - wget -q https://github.com/firefly-iii/test-data/raw/master/storage/database.sqlite -O storage/database/database.sqlite | ||||||
|   - mkdir -p build/logs |   - mkdir -p build/logs | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										81
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										81
									
								
								Dockerfile
									
									
									
									
									
								
							| @@ -1,34 +1,87 @@ | |||||||
| # use PHP 7.1 and Apache as a base. |  | ||||||
| FROM php:7.1-apache | FROM php:7.1-apache | ||||||
|  |  | ||||||
| # set working dir | # If building on a RPi, use --build-arg cores=3 to use all cores when compiling | ||||||
| ENV FIREFLY_PATH /var/www/firefly-iii | # to speed up the image build | ||||||
| WORKDIR $FIREFLY_PATH | ARG CORES | ||||||
| ADD . $FIREFLY_PATH | ENV CORES ${CORES:-1} | ||||||
|  |  | ||||||
|  | ENV FIREFLY_PATH /var/www/firefly-iii/ | ||||||
|  | ENV CURL_VERSION 7.60.0 | ||||||
|  | ENV OPENSSL_VERSION 1.1.1-pre6 | ||||||
|  |  | ||||||
|  | LABEL version="1.0" maintainer="thegrumpydictator@gmail.com" | ||||||
|  |  | ||||||
|  |  | ||||||
| # install packages | # install packages | ||||||
| RUN apt-get update -y && \ | RUN apt-get update -y && \ | ||||||
|     apt-get install -y --no-install-recommends libcurl4-openssl-dev \ |     apt-get install -y --no-install-recommends libcurl4-openssl-dev \ | ||||||
|                                                zlib1g-dev \ |                                                zlib1g-dev \ | ||||||
|                                                libjpeg62-turbo-dev \ |                                                libjpeg62-turbo-dev \ | ||||||
|                                                libpng12-dev \ |                                                wget \ | ||||||
|  |                                                libpng-dev \ | ||||||
|                                                libicu-dev \ |                                                libicu-dev \ | ||||||
|                                                libedit-dev \ |                                                libedit-dev \ | ||||||
|                                                libtidy-dev \ |                                                libtidy-dev \ | ||||||
|                                                libxml2-dev \ |                                                libxml2-dev \ | ||||||
|  |                                                unzip \ | ||||||
|                                                libsqlite3-dev \ |                                                libsqlite3-dev \ | ||||||
|  |                                                nano \ | ||||||
|                                                libpq-dev \ |                                                libpq-dev \ | ||||||
|                                                libbz2-dev \ |                                                libbz2-dev \ | ||||||
|                                                gettext-base \ |                                                gettext-base \ | ||||||
|  |                                                cron \ | ||||||
|  |                                                rsyslog \ | ||||||
|  |                                                supervisor \ | ||||||
|                                                locales && \ |                                                locales && \ | ||||||
|                                                apt-get clean && \ |                                                apt-get clean && \ | ||||||
|                                                rm -rf /var/lib/apt/lists/* |                                                rm -rf /var/lib/apt/lists/* | ||||||
|  |  | ||||||
|  | # 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 -j${CORES} && \ | ||||||
|  |     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 --host=$(gcc -dumpmachine) && \ | ||||||
|  |     make -j${CORES} && \ | ||||||
|  |     make install | ||||||
|  |  | ||||||
|  | # Make sure that libcurl is using the newer curl libaries | ||||||
|  | RUN echo "/usr/local/lib" >> /etc/ld.so.conf.d/00-curl.conf && ldconfig | ||||||
|  |  | ||||||
|  | # Mimic the Debian/Ubuntu config file structure for supervisor | ||||||
|  | COPY .deploy/docker/supervisord.conf /etc/supervisor/supervisord.conf | ||||||
|  | RUN mkdir -p /etc/supervisor/conf.d /var/log/supervisor | ||||||
|  |  | ||||||
|  | # Fix the link to curl: | ||||||
|  | RUN rm -rf /usr/local/lib/libcurl.so.4 && ln -s /usr/lib/x86_64-linux-gnu/libcurl.so.4.4.0 /usr/local/lib/libcurl.so.4 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # copy Firefly III supervisor conf file. | ||||||
|  | COPY ./.deploy/docker/firefly-iii.conf /etc/supervisor/conf.d/firefly-iii.conf | ||||||
|  |  | ||||||
|  | # copy cron job supervisor conf file. | ||||||
|  | COPY ./.deploy/docker/cronjob.conf /etc/supervisor/conf.d/cronjob.conf | ||||||
|  |  | ||||||
|  | # test crons added via crontab | ||||||
|  | RUN echo "0 3 * * * /usr/local/bin/php /var/www/firefly-iii/artisan firefly:cron" | crontab - | ||||||
|  | #RUN (crontab -l ; echo "*/1 * * * * free >> /var/www/firefly-iii/public/cron.html") 2>&1 | crontab - | ||||||
| # Install PHP exentions. | # 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 | RUN docker-php-ext-install -j$(nproc) gd intl tidy zip bcmath pdo_mysql bz2 pdo_pgsql | ||||||
|  |  | ||||||
|  | # Install composer | ||||||
|  | RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer | ||||||
|  |  | ||||||
| # Generate locales supported by Firefly III | # Generate locales supported by Firefly III | ||||||
| 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 | RUN echo "en_US.UTF-8 UTF-8\nde_DE.UTF-8 UTF-8\nfr_FR.UTF-8 UTF-8\nit_IT.UTF-8 UTF-8\nnl_NL.UTF-8 UTF-8\npl_PL.UTF-8 UTF-8\npt_BR.UTF-8 UTF-8\nru_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 Apache config to correct spot. | ||||||
| COPY ./.deploy/docker/apache2.conf /etc/apache2/apache2.conf | COPY ./.deploy/docker/apache2.conf /etc/apache2/apache2.conf | ||||||
| @@ -39,23 +92,25 @@ RUN a2enmod rewrite | |||||||
| # Enable apache mod ssl.. | # Enable apache mod ssl.. | ||||||
| RUN a2enmod ssl | RUN a2enmod ssl | ||||||
|  |  | ||||||
| # Create volumes for several directories: | # Create volumes | ||||||
| VOLUME $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload | 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) | # Enable default site (Firefly III) | ||||||
| COPY ./.deploy/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 | # Make sure we own Firefly III directory | ||||||
| RUN chown -R www-data:www-data /var/www && chmod -R 775 $FIREFLY_PATH/storage | RUN chown -R www-data:www-data /var/www && chmod -R 775 $FIREFLY_PATH/storage | ||||||
|  |  | ||||||
|  | # Copy in Firefly Source | ||||||
|  | WORKDIR $FIREFLY_PATH | ||||||
|  | ADD . $FIREFLY_PATH | ||||||
|  |  | ||||||
| # Run composer | # Run composer | ||||||
|  | ENV COMPOSER_ALLOW_SUPERUSER 1 | ||||||
| RUN composer install --prefer-dist --no-dev --no-scripts --no-suggest | RUN composer install --prefer-dist --no-dev --no-scripts --no-suggest | ||||||
|  |  | ||||||
| # Expose port 80 | # Expose port 80 | ||||||
| EXPOSE 80 | EXPOSE 80 | ||||||
|  |  | ||||||
| # Run entrypoint thing | # Run entrypoint thing | ||||||
| ENTRYPOINT [".deploy/docker/entrypoint.sh"] | ENTRYPOINT [".deploy/docker/entrypoint.sh"] | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * AboutController.php |  * AboutController.php | ||||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
| @@ -20,25 +20,31 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Api\V1\Controllers; | namespace FireflyIII\Api\V1\Controllers; | ||||||
|  |  | ||||||
| use DB; | use DB; | ||||||
| use FireflyIII\Transformers\UserTransformer; | use FireflyIII\Transformers\UserTransformer; | ||||||
|  | use Illuminate\Http\JsonResponse; | ||||||
| use Illuminate\Http\Request; | use Illuminate\Http\Request; | ||||||
| use League\Fractal\Manager; | use League\Fractal\Manager; | ||||||
| use League\Fractal\Resource\Item; | use League\Fractal\Resource\Item; | ||||||
| use League\Fractal\Serializer\JsonApiSerializer; | use League\Fractal\Serializer\JsonApiSerializer; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class AboutController |  * Returns basic information about this installation. | ||||||
|  |  * | ||||||
|  |  * Class AboutController. | ||||||
|  */ |  */ | ||||||
| class AboutController extends Controller | class AboutController extends Controller | ||||||
| { | { | ||||||
|     /** |     /** | ||||||
|      * @return \Illuminate\Http\JsonResponse |      * Returns system information. | ||||||
|  |      * | ||||||
|  |      * @return JsonResponse | ||||||
|      */ |      */ | ||||||
|     public function about() |     public function about(): JsonResponse | ||||||
|     { |     { | ||||||
|         $search        = ['~', '#']; |         $search        = ['~', '#']; | ||||||
|         $replace       = ['\~', '# ']; |         $replace       = ['\~', '# ']; | ||||||
| @@ -58,11 +64,13 @@ class AboutController extends Controller | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Returns information about the user. | ||||||
|  |      * | ||||||
|      * @param Request $request |      * @param Request $request | ||||||
|      * |      * | ||||||
|      * @return \Illuminate\Http\JsonResponse |      * @return JsonResponse | ||||||
|      */ |      */ | ||||||
|     public function user(Request $request) |     public function user(Request $request): JsonResponse | ||||||
|     { |     { | ||||||
|         $manager = new Manager(); |         $manager = new Manager(); | ||||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; |         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||||
|   | |||||||
| @@ -1,5 +1,4 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * AccountController.php |  * AccountController.php | ||||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
| @@ -20,6 +19,7 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Api\V1\Controllers; | namespace FireflyIII\Api\V1\Controllers; | ||||||
|  |  | ||||||
| @@ -29,6 +29,8 @@ use FireflyIII\Models\AccountType; | |||||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||||
| use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | ||||||
| use FireflyIII\Transformers\AccountTransformer; | use FireflyIII\Transformers\AccountTransformer; | ||||||
|  | use FireflyIII\User; | ||||||
|  | use Illuminate\Http\JsonResponse; | ||||||
| use Illuminate\Http\Request; | use Illuminate\Http\Request; | ||||||
| use Illuminate\Pagination\LengthAwarePaginator; | use Illuminate\Pagination\LengthAwarePaginator; | ||||||
| use League\Fractal\Manager; | use League\Fractal\Manager; | ||||||
| @@ -36,34 +38,35 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter; | |||||||
| use League\Fractal\Resource\Collection as FractalCollection; | use League\Fractal\Resource\Collection as FractalCollection; | ||||||
| use League\Fractal\Resource\Item; | use League\Fractal\Resource\Item; | ||||||
| use League\Fractal\Serializer\JsonApiSerializer; | use League\Fractal\Serializer\JsonApiSerializer; | ||||||
| use Preferences; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class AccountController |  * Class AccountController. | ||||||
|  |  * | ||||||
|  |  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||||
|  */ |  */ | ||||||
| class AccountController extends Controller | class AccountController extends Controller | ||||||
| { | { | ||||||
|     /** @var CurrencyRepositoryInterface */ |     /** @var CurrencyRepositoryInterface The currency repository */ | ||||||
|     private $currencyRepository; |     private $currencyRepository; | ||||||
|     /** @var AccountRepositoryInterface */ |     /** @var AccountRepositoryInterface The account repository */ | ||||||
|     private $repository; |     private $repository; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * AccountController constructor. |      * AccountController constructor. | ||||||
|      * |  | ||||||
|      * @throws \FireflyIII\Exceptions\FireflyException |  | ||||||
|      */ |      */ | ||||||
|     public function __construct() |     public function __construct() | ||||||
|     { |     { | ||||||
|         parent::__construct(); |         parent::__construct(); | ||||||
|         $this->middleware( |         $this->middleware( | ||||||
|             function ($request, $next) { |             function ($request, $next) { | ||||||
|  |                 /** @var User $user */ | ||||||
|  |                 $user = auth()->user(); | ||||||
|                 // @var AccountRepositoryInterface repository |                 // @var AccountRepositoryInterface repository | ||||||
|                 $this->repository = app(AccountRepositoryInterface::class); |                 $this->repository = app(AccountRepositoryInterface::class); | ||||||
|                 $this->repository->setUser(auth()->user()); |                 $this->repository->setUser($user); | ||||||
|  |  | ||||||
|                 $this->currencyRepository = app(CurrencyRepositoryInterface::class); |                 $this->currencyRepository = app(CurrencyRepositoryInterface::class); | ||||||
|                 $this->currencyRepository->setUser(auth()->user()); |                 $this->currencyRepository->setUser($user); | ||||||
|  |  | ||||||
|                 return $next($request); |                 return $next($request); | ||||||
|             } |             } | ||||||
| @@ -75,9 +78,9 @@ class AccountController extends Controller | |||||||
|      * |      * | ||||||
|      * @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); |         $this->repository->destroy($account, null); | ||||||
|  |  | ||||||
| @@ -89,12 +92,12 @@ class AccountController extends Controller | |||||||
|      * |      * | ||||||
|      * @param Request $request |      * @param Request $request | ||||||
|      * |      * | ||||||
|      * @return \Illuminate\Http\JsonResponse |      * @return JsonResponse | ||||||
|      */ |      */ | ||||||
|     public function index(Request $request) |     public function index(Request $request): JsonResponse | ||||||
|     { |     { | ||||||
|         // create some objects: |         // create some objects: | ||||||
|         $manager = new Manager(); |         $manager = new Manager; | ||||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; |         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||||
|  |  | ||||||
|         // read type from URI |         // read type from URI | ||||||
| @@ -103,7 +106,7 @@ class AccountController extends Controller | |||||||
|  |  | ||||||
|         // types to get, page size: |         // types to get, page size: | ||||||
|         $types    = $this->mapTypes($this->parameters->get('type')); |         $types    = $this->mapTypes($this->parameters->get('type')); | ||||||
|         $pageSize = (int)Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data; |         $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||||
|  |  | ||||||
|         // get list of accounts. Count it and split it. |         // get list of accounts. Count it and split it. | ||||||
|         $collection = $this->repository->getAccountsByType($types); |         $collection = $this->repository->getAccountsByType($types); | ||||||
| @@ -123,14 +126,16 @@ class AccountController extends Controller | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Show single instance. | ||||||
|  |      * | ||||||
|      * @param Request $request |      * @param Request $request | ||||||
|      * @param Account $account |      * @param Account $account | ||||||
|      * |      * | ||||||
|      * @return \Illuminate\Http\JsonResponse |      * @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: |         // add include parameter: | ||||||
|         $include = $request->get('include') ?? ''; |         $include = $request->get('include') ?? ''; | ||||||
| @@ -144,11 +149,13 @@ class AccountController extends Controller | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Store a new instance. | ||||||
|  |      * | ||||||
|      * @param AccountRequest $request |      * @param AccountRequest $request | ||||||
|      * |      * | ||||||
|      * @return \Illuminate\Http\JsonResponse |      * @return \Illuminate\Http\JsonResponse | ||||||
|      */ |      */ | ||||||
|     public function store(AccountRequest $request) |     public function store(AccountRequest $request): JsonResponse | ||||||
|     { |     { | ||||||
|         $data = $request->getAll(); |         $data = $request->getAll(); | ||||||
|         // if currency ID is 0, find the currency by the code: |         // if currency ID is 0, find the currency by the code: | ||||||
| @@ -157,7 +164,7 @@ class AccountController extends Controller | |||||||
|             $data['currency_id'] = null === $currency ? 0 : $currency->id; |             $data['currency_id'] = null === $currency ? 0 : $currency->id; | ||||||
|         } |         } | ||||||
|         $account = $this->repository->store($data); |         $account = $this->repository->store($data); | ||||||
|         $manager = new Manager(); |         $manager = new Manager; | ||||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; |         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); |         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||||
|  |  | ||||||
| @@ -174,7 +181,7 @@ class AccountController extends Controller | |||||||
|      * |      * | ||||||
|      * @return \Illuminate\Http\JsonResponse |      * @return \Illuminate\Http\JsonResponse | ||||||
|      */ |      */ | ||||||
|     public function update(AccountRequest $request, Account $account) |     public function update(AccountRequest $request, Account $account): JsonResponse | ||||||
|     { |     { | ||||||
|         $data = $request->getAll(); |         $data = $request->getAll(); | ||||||
|         // if currency ID is 0, find the currency by the code: |         // if currency ID is 0, find the currency by the code: | ||||||
| @@ -185,7 +192,7 @@ class AccountController extends Controller | |||||||
|         // set correct type: |         // set correct type: | ||||||
|         $data['type'] = config('firefly.shortNamesByFullName.' . $account->accountType->type); |         $data['type'] = config('firefly.shortNamesByFullName.' . $account->accountType->type); | ||||||
|         $this->repository->update($account, $data); |         $this->repository->update($account, $data); | ||||||
|         $manager = new Manager(); |         $manager = new Manager; | ||||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; |         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); |         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||||
|  |  | ||||||
| @@ -195,52 +202,30 @@ class AccountController extends Controller | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * All the available types. | ||||||
|  |      * | ||||||
|      * @param string $type |      * @param string $type | ||||||
|      * |      * | ||||||
|      * @return array |      * @return array | ||||||
|      */ |      */ | ||||||
|     private function mapTypes(string $type): array |     private function mapTypes(string $type): array | ||||||
|     { |     { | ||||||
|         $types = [ |         $types  = [ | ||||||
|             'all'                        => [ |             'all'                        => [AccountType::DEFAULT, AccountType::CASH, AccountType::ASSET, AccountType::EXPENSE, AccountType::REVENUE, | ||||||
|                 AccountType::DEFAULT, |                                              AccountType::INITIAL_BALANCE, AccountType::BENEFICIARY, AccountType::IMPORT, AccountType::RECONCILIATION, | ||||||
|                 AccountType::CASH, |                                              AccountType::LOAN,], | ||||||
|                 AccountType::ASSET, |             'asset'                      => [AccountType::DEFAULT, AccountType::ASSET,], | ||||||
|                 AccountType::EXPENSE, |             'cash'                       => [AccountType::CASH,], | ||||||
|                 AccountType::REVENUE, |             'expense'                    => [AccountType::EXPENSE, AccountType::BENEFICIARY,], | ||||||
|                 AccountType::INITIAL_BALANCE, |             'revenue'                    => [AccountType::REVENUE,], | ||||||
|                 AccountType::BENEFICIARY, |             'special'                    => [AccountType::CASH, AccountType::INITIAL_BALANCE, AccountType::IMPORT, AccountType::RECONCILIATION, | ||||||
|                 AccountType::IMPORT, |                                              AccountType::LOAN,], | ||||||
|                 AccountType::RECONCILIATION, |             'hidden'                     => [AccountType::INITIAL_BALANCE, AccountType::IMPORT, AccountType::RECONCILIATION, AccountType::LOAN,], | ||||||
|                 AccountType::LOAN, |             'liability'                  => [AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::CREDITCARD], | ||||||
|             ], |             'liabilities'                => [AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::CREDITCARD], | ||||||
|             'asset'                      => [ |             'cc'                         => [AccountType::CREDITCARD], | ||||||
|                 AccountType::DEFAULT, |             'creditcard'                 => [AccountType::CREDITCARD], | ||||||
|                 AccountType::ASSET, |             'credit_card'                => [AccountType::CREDITCARD], | ||||||
|             ], |  | ||||||
|             'cash'                       => [ |  | ||||||
|                 AccountType::CASH, |  | ||||||
|             ], |  | ||||||
|             'expense'                    => [ |  | ||||||
|                 AccountType::EXPENSE, |  | ||||||
|                 AccountType::BENEFICIARY, |  | ||||||
|             ], |  | ||||||
|             'revenue'                    => [ |  | ||||||
|                 AccountType::REVENUE, |  | ||||||
|             ], |  | ||||||
|             'special'                    => [ |  | ||||||
|                 AccountType::CASH, |  | ||||||
|                 AccountType::INITIAL_BALANCE, |  | ||||||
|                 AccountType::IMPORT, |  | ||||||
|                 AccountType::RECONCILIATION, |  | ||||||
|                 AccountType::LOAN, |  | ||||||
|             ], |  | ||||||
|             'hidden'                     => [ |  | ||||||
|                 AccountType::INITIAL_BALANCE, |  | ||||||
|                 AccountType::IMPORT, |  | ||||||
|                 AccountType::RECONCILIATION, |  | ||||||
|                 AccountType::LOAN, |  | ||||||
|             ], |  | ||||||
|             AccountType::DEFAULT         => [AccountType::DEFAULT], |             AccountType::DEFAULT         => [AccountType::DEFAULT], | ||||||
|             AccountType::CASH            => [AccountType::CASH], |             AccountType::CASH            => [AccountType::CASH], | ||||||
|             AccountType::ASSET           => [AccountType::ASSET], |             AccountType::ASSET           => [AccountType::ASSET], | ||||||
| @@ -251,11 +236,16 @@ class AccountController extends Controller | |||||||
|             AccountType::IMPORT          => [AccountType::IMPORT], |             AccountType::IMPORT          => [AccountType::IMPORT], | ||||||
|             AccountType::RECONCILIATION  => [AccountType::RECONCILIATION], |             AccountType::RECONCILIATION  => [AccountType::RECONCILIATION], | ||||||
|             AccountType::LOAN            => [AccountType::LOAN], |             AccountType::LOAN            => [AccountType::LOAN], | ||||||
|  |             AccountType::MORTGAGE        => [AccountType::MORTGAGE], | ||||||
|  |             AccountType::DEBT            => [AccountType::DEBT], | ||||||
|  |             AccountType::CREDITCARD      => [AccountType::CREDITCARD], | ||||||
|  |  | ||||||
|         ]; |         ]; | ||||||
|  |         $return = $types['all']; | ||||||
|         if (isset($types[$type])) { |         if (isset($types[$type])) { | ||||||
|             return $types[$type]; |             $return = $types[$type]; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return $types['all']; // @codeCoverageIgnore |         return $return; // @codeCoverageIgnore | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										235
									
								
								app/Api/V1/Controllers/AttachmentController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										235
									
								
								app/Api/V1/Controllers/AttachmentController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,235 @@ | |||||||
|  | <?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. | ||||||
|  |  * | ||||||
|  |  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||||
|  |  */ | ||||||
|  | class AttachmentController extends Controller | ||||||
|  | { | ||||||
|  |     /** @var AttachmentRepositoryInterface The attachment repository */ | ||||||
|  |     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); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Download an attachment. | ||||||
|  |      * | ||||||
|  |      * @param Attachment $attachment | ||||||
|  |      * | ||||||
|  |      * @return LaravelResponse | ||||||
|  |      * @throws FireflyException | ||||||
|  |      */ | ||||||
|  |     public function download(Attachment $attachment): LaravelResponse | ||||||
|  |     { | ||||||
|  |         if (false === $attachment->uploaded) { | ||||||
|  |             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'); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Upload an attachment. | ||||||
|  |      * | ||||||
|  |      * @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); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										195
									
								
								app/Api/V1/Controllers/AvailableBudgetController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										195
									
								
								app/Api/V1/Controllers/AvailableBudgetController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,195 @@ | |||||||
|  | <?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\Exceptions\FireflyException; | ||||||
|  | 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. | ||||||
|  |  * | ||||||
|  |  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||||
|  |  */ | ||||||
|  | class AvailableBudgetController extends Controller | ||||||
|  | { | ||||||
|  |     /** @var CurrencyRepositoryInterface The currency repository */ | ||||||
|  |     private $currencyRepository; | ||||||
|  |     /** @var BudgetRepositoryInterface The budget repository */ | ||||||
|  |     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 | ||||||
|  |      * @throws FireflyException | ||||||
|  |      */ | ||||||
|  |     public function store(AvailableBudgetRequest $request): JsonResponse | ||||||
|  |     { | ||||||
|  |         $data     = $request->getAll(); | ||||||
|  |         $currency = $this->currencyRepository->findNull($data['currency_id']); | ||||||
|  |         if (null === $currency) { | ||||||
|  |             $currency = $this->currencyRepository->findByCodeNull($data['currency_code']); | ||||||
|  |         } | ||||||
|  |         if (null === $currency) { | ||||||
|  |             throw new FireflyException('Could not find the indicated currency.'); | ||||||
|  |         } | ||||||
|  |         $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,5 +1,5 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * BillController.php |  * BillController.php | ||||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Api\V1\Controllers; | namespace FireflyIII\Api\V1\Controllers; | ||||||
|  |  | ||||||
| use FireflyIII\Api\V1\Requests\BillRequest; | use FireflyIII\Api\V1\Requests\BillRequest; | ||||||
| @@ -27,6 +29,7 @@ use FireflyIII\Exceptions\FireflyException; | |||||||
| use FireflyIII\Models\Bill; | use FireflyIII\Models\Bill; | ||||||
| use FireflyIII\Repositories\Bill\BillRepositoryInterface; | use FireflyIII\Repositories\Bill\BillRepositoryInterface; | ||||||
| use FireflyIII\Transformers\BillTransformer; | use FireflyIII\Transformers\BillTransformer; | ||||||
|  | use FireflyIII\User; | ||||||
| use Illuminate\Http\JsonResponse; | use Illuminate\Http\JsonResponse; | ||||||
| use Illuminate\Http\Request; | use Illuminate\Http\Request; | ||||||
| use Illuminate\Support\Collection; | use Illuminate\Support\Collection; | ||||||
| @@ -35,29 +38,29 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter; | |||||||
| use League\Fractal\Resource\Collection as FractalCollection; | use League\Fractal\Resource\Collection as FractalCollection; | ||||||
| use League\Fractal\Resource\Item; | use League\Fractal\Resource\Item; | ||||||
| use League\Fractal\Serializer\JsonApiSerializer; | use League\Fractal\Serializer\JsonApiSerializer; | ||||||
| use Preferences; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class BillController |  * Class BillController. | ||||||
|  */ |  */ | ||||||
| class BillController extends Controller | class BillController extends Controller | ||||||
| { | { | ||||||
|     /** @var BillRepositoryInterface */ |     /** @var BillRepositoryInterface The bill repository */ | ||||||
|     private $repository; |     private $repository; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * BillController constructor. |      * BillController constructor. | ||||||
|      * |  | ||||||
|      * @throws FireflyException |  | ||||||
|      */ |      */ | ||||||
|     public function __construct() |     public function __construct() | ||||||
|     { |     { | ||||||
|         parent::__construct(); |         parent::__construct(); | ||||||
|         $this->middleware( |         $this->middleware( | ||||||
|             function ($request, $next) { |             function ($request, $next) { | ||||||
|  |                 /** @var User $admin */ | ||||||
|  |                 $admin = auth()->user(); | ||||||
|  |  | ||||||
|                 /** @var BillRepositoryInterface repository */ |                 /** @var BillRepositoryInterface repository */ | ||||||
|                 $this->repository = app(BillRepositoryInterface::class); |                 $this->repository = app(BillRepositoryInterface::class); | ||||||
|                 $this->repository->setUser(auth()->user()); |                 $this->repository->setUser($admin); | ||||||
|  |  | ||||||
|                 return $next($request); |                 return $next($request); | ||||||
|             } |             } | ||||||
| @@ -87,7 +90,7 @@ class BillController extends Controller | |||||||
|      */ |      */ | ||||||
|     public function index(Request $request): JsonResponse |     public function index(Request $request): JsonResponse | ||||||
|     { |     { | ||||||
|         $pageSize  = (int)Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data; |         $pageSize  = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||||
|         $paginator = $this->repository->getPaginator($pageSize); |         $paginator = $this->repository->getPaginator($pageSize); | ||||||
|         /** @var Collection $bills */ |         /** @var Collection $bills */ | ||||||
|         $bills = $paginator->getCollection(); |         $bills = $paginator->getCollection(); | ||||||
| @@ -104,6 +107,8 @@ class BillController extends Controller | |||||||
|  |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Show the specified bill. | ||||||
|  |      * | ||||||
|      * @param Request $request |      * @param Request $request | ||||||
|      * @param Bill    $bill |      * @param Bill    $bill | ||||||
|      * |      * | ||||||
| @@ -125,6 +130,8 @@ class BillController extends Controller | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Store a bill. | ||||||
|  |      * | ||||||
|      * @param BillRequest $request |      * @param BillRequest $request | ||||||
|      * |      * | ||||||
|      * @return JsonResponse |      * @return JsonResponse | ||||||
| @@ -148,6 +155,8 @@ class BillController extends Controller | |||||||
|  |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Update a bill. | ||||||
|  |      * | ||||||
|      * @param BillRequest $request |      * @param BillRequest $request | ||||||
|      * @param Bill        $bill |      * @param Bill        $bill | ||||||
|      * |      * | ||||||
|   | |||||||
							
								
								
									
										188
									
								
								app/Api/V1/Controllers/BudgetController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								app/Api/V1/Controllers/BudgetController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,188 @@ | |||||||
|  | <?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 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 BudgetController. | ||||||
|  |  * | ||||||
|  |  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||||
|  |  */ | ||||||
|  | class BudgetController extends Controller | ||||||
|  | { | ||||||
|  |     /** @var BudgetRepositoryInterface The budget repository */ | ||||||
|  |     private $repository; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * BudgetController constructor. | ||||||
|  |      */ | ||||||
|  |     public function __construct() | ||||||
|  |     { | ||||||
|  |         parent::__construct(); | ||||||
|  |         $this->middleware( | ||||||
|  |             function ($request, $next) { | ||||||
|  |                 /** @var User $admin */ | ||||||
|  |                 $admin = auth()->user(); | ||||||
|  |  | ||||||
|  |                 /** @var BudgetRepositoryInterface repository */ | ||||||
|  |                 $this->repository = app(BudgetRepositoryInterface::class); | ||||||
|  |                 $this->repository->setUser($admin); | ||||||
|  |  | ||||||
|  |                 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'); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Show a budget. | ||||||
|  |      * | ||||||
|  |      * @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'); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Store a budget. | ||||||
|  |      * | ||||||
|  |      * @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 | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Update a budget. | ||||||
|  |      * | ||||||
|  |      * @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'); | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										197
									
								
								app/Api/V1/Controllers/BudgetLimitController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								app/Api/V1/Controllers/BudgetLimitController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,197 @@ | |||||||
|  | <?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 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 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 BudgetLimitController. | ||||||
|  |  * | ||||||
|  |  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||||
|  |  */ | ||||||
|  | class BudgetLimitController extends Controller | ||||||
|  | { | ||||||
|  |     /** @var BudgetRepositoryInterface The budget repository */ | ||||||
|  |     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->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 | ||||||
|  |     { | ||||||
|  |         $manager  = new Manager; | ||||||
|  |         $baseUrl  = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||||
|  |         $budgetId = (int)($request->get('budget_id') ?? 0); | ||||||
|  |         $budget   = $this->repository->findNull($budgetId); | ||||||
|  |         $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||||
|  |         $this->parameters->set('budget_id', $budgetId); | ||||||
|  |  | ||||||
|  |         $collection = new Collection; | ||||||
|  |         if (null === $budget) { | ||||||
|  |             $collection = $this->repository->getAllBudgetLimits($this->parameters->get('start'), $this->parameters->get('end')); | ||||||
|  |         } | ||||||
|  |         if (null !== $budget) { | ||||||
|  |             $collection = $this->repository->getBudgetLimits($budget, $this->parameters->get('start'), $this->parameters->get('end')); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         $count        = $collection->count(); | ||||||
|  |         $budgetLimits = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||||
|  |         $paginator    = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page')); | ||||||
|  |         $paginator->setPath(route('api.v1.budget_limits.index') . $this->buildParams()); | ||||||
|  |  | ||||||
|  |         $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 BudgetLimitRequest $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'); | ||||||
|  |  | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										188
									
								
								app/Api/V1/Controllers/CategoryController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								app/Api/V1/Controllers/CategoryController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,188 @@ | |||||||
|  | <?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 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 CategoryController. | ||||||
|  |  * | ||||||
|  |  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||||
|  |  */ | ||||||
|  | class CategoryController extends Controller | ||||||
|  | { | ||||||
|  |     /** @var CategoryRepositoryInterface The category repository */ | ||||||
|  |     private $repository; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * CategoryController constructor. | ||||||
|  |      */ | ||||||
|  |     public function __construct() | ||||||
|  |     { | ||||||
|  |         parent::__construct(); | ||||||
|  |         $this->middleware( | ||||||
|  |             function ($request, $next) { | ||||||
|  |                 /** @var User $admin */ | ||||||
|  |                 $admin = auth()->user(); | ||||||
|  |  | ||||||
|  |                 /** @var CategoryRepositoryInterface repository */ | ||||||
|  |                 $this->repository = app(CategoryRepositoryInterface::class); | ||||||
|  |                 $this->repository->setUser($admin); | ||||||
|  |  | ||||||
|  |                 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'); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Show the category. | ||||||
|  |      * | ||||||
|  |      * @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'); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Store new category. | ||||||
|  |      * | ||||||
|  |      * @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 | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Update the category. | ||||||
|  |      * | ||||||
|  |      * @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'); | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										136
									
								
								app/Api/V1/Controllers/ConfigurationController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								app/Api/V1/Controllers/ConfigurationController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,136 @@ | |||||||
|  | <?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 FireflyIII\Repositories\User\UserRepositoryInterface; | ||||||
|  | use FireflyIII\User; | ||||||
|  | use Illuminate\Http\JsonResponse; | ||||||
|  | use Illuminate\Http\Request; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Class ConfigurationController. | ||||||
|  |  */ | ||||||
|  | class ConfigurationController extends Controller | ||||||
|  | { | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /** @var UserRepositoryInterface The user repository */ | ||||||
|  |     private $repository; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * BudgetController constructor. | ||||||
|  |      */ | ||||||
|  |     public function __construct() | ||||||
|  |     { | ||||||
|  |         parent::__construct(); | ||||||
|  |         $this->middleware( | ||||||
|  |             function ($request, $next) { | ||||||
|  |                 /** @noinspection UnusedConstructorDependenciesInspection */ | ||||||
|  |                 $this->repository = app(UserRepositoryInterface::class); | ||||||
|  |                 /** @var User $admin */ | ||||||
|  |                 $admin = auth()->user(); | ||||||
|  |  | ||||||
|  |                 if (!$this->repository->hasRole($admin, 'owner')) { | ||||||
|  |                     /** @noinspection ExceptionsAnnotatingAndHandlingInspection */ | ||||||
|  |                     throw new FireflyException('No access to method.'); // @codeCoverageIgnore | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 return $next($request); | ||||||
|  |             } | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Show all configuration. | ||||||
|  |      * | ||||||
|  |      * @return JsonResponse | ||||||
|  |      */ | ||||||
|  |     public function index(): JsonResponse | ||||||
|  |     { | ||||||
|  |         $configData = $this->getConfigData(); | ||||||
|  |  | ||||||
|  |         return response()->json(['data' => $configData], 200)->header('Content-Type', 'application/vnd.api+json'); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Update the configuration. | ||||||
|  |      * | ||||||
|  |      * @param Request $request | ||||||
|  |      * | ||||||
|  |      * @return JsonResponse | ||||||
|  |      * @throws FireflyException | ||||||
|  |      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||||
|  |      */ | ||||||
|  |     public function update(Request $request): JsonResponse | ||||||
|  |     { | ||||||
|  |         $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 = 'true' === $value; | ||||||
|  |                 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'); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get all config values. | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||||
|  |      */ | ||||||
|  |     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,5 +1,5 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * Controller.php |  * Controller.php | ||||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
| @@ -20,12 +20,12 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Api\V1\Controllers; | namespace FireflyIII\Api\V1\Controllers; | ||||||
|  |  | ||||||
| use Carbon\Carbon; | use Carbon\Carbon; | ||||||
| use Carbon\Exceptions\InvalidDateException; | use Carbon\Exceptions\InvalidDateException; | ||||||
| use FireflyConfig; |  | ||||||
| use FireflyIII\Exceptions\FireflyException; |  | ||||||
| use Illuminate\Foundation\Auth\Access\AuthorizesRequests; | use Illuminate\Foundation\Auth\Access\AuthorizesRequests; | ||||||
| use Illuminate\Foundation\Bus\DispatchesJobs; | use Illuminate\Foundation\Bus\DispatchesJobs; | ||||||
| use Illuminate\Foundation\Validation\ValidatesRequests; | use Illuminate\Foundation\Validation\ValidatesRequests; | ||||||
| @@ -37,12 +37,13 @@ use Symfony\Component\HttpFoundation\ParameterBag; | |||||||
|  * Class Controller. |  * Class Controller. | ||||||
|  * |  * | ||||||
|  * @codeCoverageIgnore |  * @codeCoverageIgnore | ||||||
|  |  * @SuppressWarnings(PHPMD.NumberOfChildren) | ||||||
|  */ |  */ | ||||||
| class Controller extends BaseController | class Controller extends BaseController | ||||||
| { | { | ||||||
|     use AuthorizesRequests, DispatchesJobs, ValidatesRequests; |     use AuthorizesRequests, DispatchesJobs, ValidatesRequests; | ||||||
|  |  | ||||||
|     /** @var ParameterBag */ |     /** @var ParameterBag Parameters from the URI are stored here. */ | ||||||
|     protected $parameters; |     protected $parameters; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -56,39 +57,42 @@ class Controller extends BaseController | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Method to help build URI's. | ||||||
|  |      * | ||||||
|      * @return string |      * @return string | ||||||
|  |      * | ||||||
|  |      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||||
|      */ |      */ | ||||||
|     protected function buildParams(): string |     protected function buildParams(): string | ||||||
|     { |     { | ||||||
|         $return = '?'; |         $return = '?'; | ||||||
|         $params = []; |         $params = []; | ||||||
|         foreach ($this->parameters as $key => $value) { |         foreach ($this->parameters as $key => $value) { | ||||||
|             if ($key === 'page') { |             if ('page' === $key) { | ||||||
|                 continue; |                 continue; | ||||||
|             } |             } | ||||||
|             if ($value instanceof Carbon) { |             if ($value instanceof Carbon) { | ||||||
|                 $params[$key] = $value->format('Y-m-d'); |                 $params[$key] = $value->format('Y-m-d'); | ||||||
|  |                 continue; | ||||||
|             } |             } | ||||||
|             if (!$value instanceof Carbon) { |             $params[$key] = $value; | ||||||
|                 $params[$key] = $value; |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|         $return .= http_build_query($params); |         $return .= http_build_query($params); | ||||||
|         if (\strlen($return) === 1) { |  | ||||||
|             return ''; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return $return; |         return $return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Method to grab all parameters from the URI. | ||||||
|  |      * | ||||||
|      * @return ParameterBag |      * @return ParameterBag | ||||||
|  |      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||||
|      */ |      */ | ||||||
|     private function getParameters(): ParameterBag |     private function getParameters(): ParameterBag | ||||||
|     { |     { | ||||||
|         $bag  = new ParameterBag; |         $bag  = new ParameterBag; | ||||||
|         $page = (int)request()->get('page'); |         $page = (int)request()->get('page'); | ||||||
|         if ($page === 0) { |         if (0 === $page) { | ||||||
|             $page = 1; |             $page = 1; | ||||||
|         } |         } | ||||||
|         $bag->set('page', $page); |         $bag->set('page', $page); | ||||||
|   | |||||||
| @@ -24,13 +24,13 @@ declare(strict_types=1); | |||||||
|  |  | ||||||
| namespace FireflyIII\Api\V1\Controllers; | namespace FireflyIII\Api\V1\Controllers; | ||||||
|  |  | ||||||
| use FireflyIII\Api\V1\Requests\BillRequest; |  | ||||||
| use FireflyIII\Api\V1\Requests\CurrencyRequest; | use FireflyIII\Api\V1\Requests\CurrencyRequest; | ||||||
| use FireflyIII\Exceptions\FireflyException; | use FireflyIII\Exceptions\FireflyException; | ||||||
| use FireflyIII\Models\TransactionCurrency; | use FireflyIII\Models\TransactionCurrency; | ||||||
| use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | ||||||
| use FireflyIII\Repositories\User\UserRepositoryInterface; | use FireflyIII\Repositories\User\UserRepositoryInterface; | ||||||
| use FireflyIII\Transformers\CurrencyTransformer; | use FireflyIII\Transformers\CurrencyTransformer; | ||||||
|  | use FireflyIII\User; | ||||||
| use Illuminate\Http\JsonResponse; | use Illuminate\Http\JsonResponse; | ||||||
| use Illuminate\Http\Request; | use Illuminate\Http\Request; | ||||||
| use Illuminate\Pagination\LengthAwarePaginator; | use Illuminate\Pagination\LengthAwarePaginator; | ||||||
| @@ -39,32 +39,34 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter; | |||||||
| use League\Fractal\Resource\Collection as FractalCollection; | use League\Fractal\Resource\Collection as FractalCollection; | ||||||
| use League\Fractal\Resource\Item; | use League\Fractal\Resource\Item; | ||||||
| use League\Fractal\Serializer\JsonApiSerializer; | use League\Fractal\Serializer\JsonApiSerializer; | ||||||
| use Preferences; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class CurrencyController |  * Class CurrencyController. | ||||||
|  |  * | ||||||
|  |  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||||
|  */ |  */ | ||||||
| class CurrencyController extends Controller | class CurrencyController extends Controller | ||||||
| { | { | ||||||
|     /** @var CurrencyRepositoryInterface */ |     /** @var CurrencyRepositoryInterface The currency repository */ | ||||||
|     private $repository; |     private $repository; | ||||||
|     /** @var UserRepositoryInterface */ |     /** @var UserRepositoryInterface The user repository */ | ||||||
|     private $userRepository; |     private $userRepository; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * CurrencyRepository constructor. |      * CurrencyRepository constructor. | ||||||
|      * |  | ||||||
|      * @throws FireflyException |  | ||||||
|      */ |      */ | ||||||
|     public function __construct() |     public function __construct() | ||||||
|     { |     { | ||||||
|         parent::__construct(); |         parent::__construct(); | ||||||
|         $this->middleware( |         $this->middleware( | ||||||
|             function ($request, $next) { |             function ($request, $next) { | ||||||
|  |                 /** @var User $admin */ | ||||||
|  |                 $admin = auth()->user(); | ||||||
|  |  | ||||||
|                 /** @var CurrencyRepositoryInterface repository */ |                 /** @var CurrencyRepositoryInterface repository */ | ||||||
|                 $this->repository     = app(CurrencyRepositoryInterface::class); |                 $this->repository     = app(CurrencyRepositoryInterface::class); | ||||||
|                 $this->userRepository = app(UserRepositoryInterface::class); |                 $this->userRepository = app(UserRepositoryInterface::class); | ||||||
|                 $this->repository->setUser(auth()->user()); |                 $this->repository->setUser($admin); | ||||||
|  |  | ||||||
|                 return $next($request); |                 return $next($request); | ||||||
|             } |             } | ||||||
| @@ -81,7 +83,10 @@ class CurrencyController extends Controller | |||||||
|      */ |      */ | ||||||
|     public function delete(TransactionCurrency $currency): JsonResponse |     public function delete(TransactionCurrency $currency): JsonResponse | ||||||
|     { |     { | ||||||
|         if (!$this->userRepository->hasRole(auth()->user(), 'owner')) { |         /** @var User $admin */ | ||||||
|  |         $admin = auth()->user(); | ||||||
|  |  | ||||||
|  |         if (!$this->userRepository->hasRole($admin, 'owner')) { | ||||||
|             // access denied: |             // access denied: | ||||||
|             throw new FireflyException('No access to method, user is not owner.'); // @codeCoverageIgnore |             throw new FireflyException('No access to method, user is not owner.'); // @codeCoverageIgnore | ||||||
|         } |         } | ||||||
| @@ -102,7 +107,7 @@ class CurrencyController extends Controller | |||||||
|      */ |      */ | ||||||
|     public function index(Request $request): JsonResponse |     public function index(Request $request): JsonResponse | ||||||
|     { |     { | ||||||
|         $pageSize   = (int)Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data; |         $pageSize   = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||||
|         $collection = $this->repository->get(); |         $collection = $this->repository->get(); | ||||||
|         $count      = $collection->count(); |         $count      = $collection->count(); | ||||||
|         // slice them: |         // slice them: | ||||||
| @@ -125,6 +130,8 @@ class CurrencyController extends Controller | |||||||
|  |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Show a currency. | ||||||
|  |      * | ||||||
|      * @param Request             $request |      * @param Request             $request | ||||||
|      * @param TransactionCurrency $currency |      * @param TransactionCurrency $currency | ||||||
|      * |      * | ||||||
| @@ -148,6 +155,8 @@ class CurrencyController extends Controller | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Store new currency. | ||||||
|  |      * | ||||||
|      * @param CurrencyRequest $request |      * @param CurrencyRequest $request | ||||||
|      * |      * | ||||||
|      * @return JsonResponse |      * @return JsonResponse | ||||||
| @@ -157,11 +166,11 @@ class CurrencyController extends Controller | |||||||
|     { |     { | ||||||
|         $currency = $this->repository->store($request->getAll()); |         $currency = $this->repository->store($request->getAll()); | ||||||
|  |  | ||||||
|         if ($request->boolean('default') === true) { |  | ||||||
|             Preferences::set('currencyPreference', $currency->code); |  | ||||||
|             Preferences::mark(); |  | ||||||
|         } |  | ||||||
|         if (null !== $currency) { |         if (null !== $currency) { | ||||||
|  |             if (true === $request->boolean('default')) { | ||||||
|  |                 app('preferences')->set('currencyPreference', $currency->code); | ||||||
|  |                 app('preferences')->mark(); | ||||||
|  |             } | ||||||
|             $manager = new Manager(); |             $manager = new Manager(); | ||||||
|             $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; |             $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||||
|             $manager->setSerializer(new JsonApiSerializer($baseUrl)); |             $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||||
| @@ -178,7 +187,9 @@ class CurrencyController extends Controller | |||||||
|  |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * @param CurrencyRequest         $request |      * Update a currency. | ||||||
|  |      * | ||||||
|  |      * @param CurrencyRequest     $request | ||||||
|      * @param TransactionCurrency $currency |      * @param TransactionCurrency $currency | ||||||
|      * |      * | ||||||
|      * @return JsonResponse |      * @return JsonResponse | ||||||
| @@ -188,9 +199,9 @@ class CurrencyController extends Controller | |||||||
|         $data     = $request->getAll(); |         $data     = $request->getAll(); | ||||||
|         $currency = $this->repository->update($currency, $data); |         $currency = $this->repository->update($currency, $data); | ||||||
|  |  | ||||||
|         if ($request->boolean('default') === true) { |         if (true === $request->boolean('default')) { | ||||||
|             Preferences::set('currencyPreference', $currency->code); |             app('preferences')->set('currencyPreference', $currency->code); | ||||||
|             Preferences::mark(); |             app('preferences')->mark(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         $manager = new Manager(); |         $manager = new Manager(); | ||||||
|   | |||||||
							
								
								
									
										111
									
								
								app/Api/V1/Controllers/CurrencyExchangeRateController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								app/Api/V1/Controllers/CurrencyExchangeRateController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,111 @@ | |||||||
|  | <?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 FireflyIII\User; | ||||||
|  | use Illuminate\Http\JsonResponse; | ||||||
|  | use Illuminate\Http\Request; | ||||||
|  | use League\Fractal\Manager; | ||||||
|  | use League\Fractal\Resource\Item; | ||||||
|  | use League\Fractal\Serializer\JsonApiSerializer; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Class CurrencyExchangeRateController | ||||||
|  |  */ | ||||||
|  | class CurrencyExchangeRateController extends Controller | ||||||
|  | { | ||||||
|  |     /** @var CurrencyRepositoryInterface The currency repository */ | ||||||
|  |     private $repository; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * CurrencyExchangeRateController constructor. | ||||||
|  |      */ | ||||||
|  |     public function __construct() | ||||||
|  |     { | ||||||
|  |         parent::__construct(); | ||||||
|  |         $this->middleware( | ||||||
|  |             function ($request, $next) { | ||||||
|  |                 /** @var User $admin */ | ||||||
|  |                 $admin = auth()->user(); | ||||||
|  |  | ||||||
|  |                 $this->repository = app(CurrencyRepositoryInterface::class); | ||||||
|  |                 $this->repository->setUser($admin); | ||||||
|  |  | ||||||
|  |                 return $next($request); | ||||||
|  |             } | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Show an exchange rate. | ||||||
|  |      * | ||||||
|  |      * @param Request $request | ||||||
|  |      * | ||||||
|  |      * @return JsonResponse | ||||||
|  |      * @throws FireflyException | ||||||
|  |      */ | ||||||
|  |     public function index(Request $request): JsonResponse | ||||||
|  |     { | ||||||
|  |         // create some objects: | ||||||
|  |         $manager = new Manager; | ||||||
|  |         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||||
|  |         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||||
|  |  | ||||||
|  |         $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 = Carbon::createFromFormat('Y-m-d', $request->get('date') ?? date('Y-m-d')); | ||||||
|  |         $this->parameters->set('from', $fromCurrency->code); | ||||||
|  |         $this->parameters->set('to', $toCurrency->code); | ||||||
|  |         $this->parameters->set('date', $dateObj->format('Y-m-d')); | ||||||
|  |  | ||||||
|  |         $rate = $this->repository->getExchangeRate($fromCurrency, $toCurrency, $dateObj); | ||||||
|  |         if (null === $rate) { | ||||||
|  |             /** @var User $admin */ | ||||||
|  |             $admin = auth()->user(); | ||||||
|  |             // create service: | ||||||
|  |             /** @var ExchangeRateInterface $service */ | ||||||
|  |             $service = app(ExchangeRateInterface::class); | ||||||
|  |             $service->setUser($admin); | ||||||
|  |             $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'); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										216
									
								
								app/Api/V1/Controllers/JournalLinkController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										216
									
								
								app/Api/V1/Controllers/JournalLinkController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,216 @@ | |||||||
|  | <?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. | ||||||
|  |  * | ||||||
|  |  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||||
|  |  */ | ||||||
|  | class JournalLinkController extends Controller | ||||||
|  | { | ||||||
|  |     /** @var JournalRepositoryInterface The journal repository */ | ||||||
|  |     private $journalRepository; | ||||||
|  |     /** @var LinkTypeRepositoryInterface The link type repository */ | ||||||
|  |     private $repository; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * JournalLinkController constructor. | ||||||
|  |      */ | ||||||
|  |     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'); | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Update object. | ||||||
|  |      * | ||||||
|  |      * @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'); | ||||||
|  |  | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										210
									
								
								app/Api/V1/Controllers/LinkTypeController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								app/Api/V1/Controllers/LinkTypeController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,210 @@ | |||||||
|  | <?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. | ||||||
|  |  * | ||||||
|  |  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||||
|  |  */ | ||||||
|  | class LinkTypeController extends Controller | ||||||
|  | { | ||||||
|  |     /** @var LinkTypeRepositoryInterface The link type repository */ | ||||||
|  |     private $repository; | ||||||
|  |  | ||||||
|  |     /** @var UserRepositoryInterface The user repository */ | ||||||
|  |     private $userRepository; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * LinkTypeController constructor. | ||||||
|  |      */ | ||||||
|  |     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 (false === $linkType->editable) { | ||||||
|  |             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 | ||||||
|  |     { | ||||||
|  |         /** @var User $admin */ | ||||||
|  |         $admin = auth()->user(); | ||||||
|  |  | ||||||
|  |         if (!$this->userRepository->hasRole($admin, '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'); | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Update object. | ||||||
|  |      * | ||||||
|  |      * @param LinkTypeRequest $request | ||||||
|  |      * @param LinkType        $linkType | ||||||
|  |      * | ||||||
|  |      * @return JsonResponse | ||||||
|  |      * @throws FireflyException | ||||||
|  |      */ | ||||||
|  |     public function update(LinkTypeRequest $request, LinkType $linkType): JsonResponse | ||||||
|  |     { | ||||||
|  |         if (false === $linkType->editable) { | ||||||
|  |             throw new FireflyException(sprintf('You cannot edit this link type (#%d, "%s")', $linkType->id, $linkType->name)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /** @var User $admin */ | ||||||
|  |         $admin = auth()->user(); | ||||||
|  |  | ||||||
|  |         if (!$this->userRepository->hasRole($admin, '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'); | ||||||
|  |  | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										188
									
								
								app/Api/V1/Controllers/PiggyBankController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								app/Api/V1/Controllers/PiggyBankController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,188 @@ | |||||||
|  | <?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; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Class PiggyBankController. | ||||||
|  |  * | ||||||
|  |  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||||
|  |  */ | ||||||
|  | class PiggyBankController extends Controller | ||||||
|  | { | ||||||
|  |  | ||||||
|  |     /** @var PiggyBankRepositoryInterface The piggy bank repository */ | ||||||
|  |     private $repository; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * PiggyBankController constructor. | ||||||
|  |      */ | ||||||
|  |     public function __construct() | ||||||
|  |     { | ||||||
|  |         parent::__construct(); | ||||||
|  |         $this->middleware( | ||||||
|  |             function ($request, $next) { | ||||||
|  |                 /** @var User $admin */ | ||||||
|  |                 $admin = auth()->user(); | ||||||
|  |  | ||||||
|  |                 $this->repository = app(PiggyBankRepositoryInterface::class); | ||||||
|  |                 $this->repository->setUser($admin); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |                 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.'); | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Update piggy bank. | ||||||
|  |      * | ||||||
|  |      * @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'); | ||||||
|  |  | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										145
									
								
								app/Api/V1/Controllers/PreferenceController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								app/Api/V1/Controllers/PreferenceController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,145 @@ | |||||||
|  | <?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; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * Class PreferenceController | ||||||
|  |  */ | ||||||
|  | class PreferenceController extends Controller | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * 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 = app('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'); | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Update a preference. | ||||||
|  |      * | ||||||
|  |      * @param PreferenceRequest $request | ||||||
|  |      * @param Preference        $preference | ||||||
|  |      * | ||||||
|  |      * @return JsonResponse | ||||||
|  |      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||||
|  |      */ | ||||||
|  |     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 = 1 === (int)$data['data']; | ||||||
|  |                 break; | ||||||
|  |         } | ||||||
|  |         $result = app('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'); | ||||||
|  |  | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										180
									
								
								app/Api/V1/Controllers/RecurrenceController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								app/Api/V1/Controllers/RecurrenceController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,180 @@ | |||||||
|  | <?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 The recurring transaction repository */ | ||||||
|  |     private $repository; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * RecurrenceController constructor. | ||||||
|  |      */ | ||||||
|  |     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'); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Update single recurrence. | ||||||
|  |      * | ||||||
|  |      * @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'); | ||||||
|  |  | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										178
									
								
								app/Api/V1/Controllers/RuleController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								app/Api/V1/Controllers/RuleController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,178 @@ | |||||||
|  | <?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 The rule repository */ | ||||||
|  |     private $ruleRepository; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * RuleController constructor. | ||||||
|  |      */ | ||||||
|  |     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.rules.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 RuleRequest $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'); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Update a rule. | ||||||
|  |      * | ||||||
|  |      * @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'); | ||||||
|  |  | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										179
									
								
								app/Api/V1/Controllers/RuleGroupController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								app/Api/V1/Controllers/RuleGroupController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,179 @@ | |||||||
|  | <?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 | ||||||
|  |  */ | ||||||
|  | class RuleGroupController extends Controller | ||||||
|  | { | ||||||
|  |     /** @var RuleGroupRepositoryInterface The rule group repository */ | ||||||
|  |     private $ruleGroupRepository; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * RuleGroupController constructor. | ||||||
|  |      */ | ||||||
|  |     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 RuleGroup $ruleGroup | ||||||
|  |      * | ||||||
|  |      * @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 rule groups. 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'); | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Update a rule group. | ||||||
|  |      * | ||||||
|  |      * @param RuleGroupRequest $request | ||||||
|  |      * @param RuleGroup        $ruleGroup | ||||||
|  |      * | ||||||
|  |      * @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,5 +1,5 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * TransactionController.php |  * TransactionController.php | ||||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
| @@ -20,11 +20,13 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Api\V1\Controllers; | namespace FireflyIII\Api\V1\Controllers; | ||||||
|  |  | ||||||
| use FireflyIII\Api\V1\Requests\TransactionRequest; | use FireflyIII\Api\V1\Requests\TransactionRequest; | ||||||
| use FireflyIII\Helpers\Collector\JournalCollectorInterface; | use FireflyIII\Exceptions\FireflyException; | ||||||
|  | use FireflyIII\Helpers\Collector\TransactionCollectorInterface; | ||||||
| use FireflyIII\Helpers\Filter\InternalTransferFilter; | use FireflyIII\Helpers\Filter\InternalTransferFilter; | ||||||
| use FireflyIII\Helpers\Filter\NegativeAmountFilter; | use FireflyIII\Helpers\Filter\NegativeAmountFilter; | ||||||
| use FireflyIII\Helpers\Filter\PositiveAmountFilter; | use FireflyIII\Helpers\Filter\PositiveAmountFilter; | ||||||
| @@ -32,37 +34,39 @@ use FireflyIII\Models\Transaction; | |||||||
| use FireflyIII\Models\TransactionType; | use FireflyIII\Models\TransactionType; | ||||||
| use FireflyIII\Repositories\Journal\JournalRepositoryInterface; | use FireflyIII\Repositories\Journal\JournalRepositoryInterface; | ||||||
| use FireflyIII\Transformers\TransactionTransformer; | use FireflyIII\Transformers\TransactionTransformer; | ||||||
|  | use FireflyIII\User; | ||||||
|  | use Illuminate\Http\JsonResponse; | ||||||
| use Illuminate\Http\Request; | use Illuminate\Http\Request; | ||||||
| use Illuminate\Support\Collection; | use Illuminate\Support\Collection; | ||||||
| use League\Fractal\Manager; | use League\Fractal\Manager; | ||||||
| use League\Fractal\Pagination\IlluminatePaginatorAdapter; | use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||||
| use League\Fractal\Resource\Collection as FractalCollection; | use League\Fractal\Resource\Collection as FractalCollection; | ||||||
| use League\Fractal\Serializer\JsonApiSerializer; | use League\Fractal\Serializer\JsonApiSerializer; | ||||||
| use Log; |  | ||||||
| use Preferences; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class TransactionController |  * Class TransactionController | ||||||
|  |  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||||
|  */ |  */ | ||||||
| class TransactionController extends Controller | class TransactionController extends Controller | ||||||
| { | { | ||||||
|  |  | ||||||
|     /** @var JournalRepositoryInterface */ |     /** @var JournalRepositoryInterface The journal repository */ | ||||||
|     private $repository; |     private $repository; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * TransactionController constructor. |      * TransactionController constructor. | ||||||
|      * |  | ||||||
|      * @throws \FireflyIII\Exceptions\FireflyException |  | ||||||
|      */ |      */ | ||||||
|     public function __construct() |     public function __construct() | ||||||
|     { |     { | ||||||
|         parent::__construct(); |         parent::__construct(); | ||||||
|         $this->middleware( |         $this->middleware( | ||||||
|             function ($request, $next) { |             function ($request, $next) { | ||||||
|  |                 /** @var User $admin */ | ||||||
|  |                 $admin = auth()->user(); | ||||||
|  |  | ||||||
|                 /** @var JournalRepositoryInterface repository */ |                 /** @var JournalRepositoryInterface repository */ | ||||||
|                 $this->repository = app(JournalRepositoryInterface::class); |                 $this->repository = app(JournalRepositoryInterface::class); | ||||||
|                 $this->repository->setUser(auth()->user()); |                 $this->repository->setUser($admin); | ||||||
|  |  | ||||||
|                 return $next($request); |                 return $next($request); | ||||||
|             } |             } | ||||||
| @@ -74,9 +78,9 @@ class TransactionController extends Controller | |||||||
|      * |      * | ||||||
|      * @param  \FireflyIII\Models\Transaction $transaction |      * @param  \FireflyIII\Models\Transaction $transaction | ||||||
|      * |      * | ||||||
|      * @return \Illuminate\Http\Response |      * @return JsonResponse | ||||||
|      */ |      */ | ||||||
|     public function delete(Transaction $transaction) |     public function delete(Transaction $transaction): JsonResponse | ||||||
|     { |     { | ||||||
|         $journal = $transaction->transactionJournal; |         $journal = $transaction->transactionJournal; | ||||||
|         $this->repository->destroy($journal); |         $this->repository->destroy($journal); | ||||||
| @@ -85,33 +89,32 @@ class TransactionController extends Controller | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Show all transactions. | ||||||
|  |      * | ||||||
|      * @param Request $request |      * @param Request $request | ||||||
|      * |      * | ||||||
|      * @return \Illuminate\Http\JsonResponse |      * @return JsonResponse | ||||||
|      */ |      */ | ||||||
|     public function index(Request $request) |     public function index(Request $request): JsonResponse | ||||||
|     { |     { | ||||||
|         $pageSize = (int)Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data; |         $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||||
|  |         $type     = $request->get('type') ?? 'default'; | ||||||
|         // read type from URI |  | ||||||
|         $type = $request->get('type') ?? 'default'; |  | ||||||
|         $this->parameters->set('type', $type); |         $this->parameters->set('type', $type); | ||||||
|  |  | ||||||
|         // types to get, page size: |         $types   = $this->mapTypes($this->parameters->get('type')); | ||||||
|         $types = $this->mapTypes($this->parameters->get('type')); |  | ||||||
|  |  | ||||||
|         $manager = new Manager(); |         $manager = new Manager(); | ||||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; |         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); |         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||||
|  |  | ||||||
|         // collect transactions using the journal collector |         /** @var User $admin */ | ||||||
|         $collector = app(JournalCollectorInterface::class); |         $admin = auth()->user(); | ||||||
|         $collector->setUser(auth()->user()); |         /** @var TransactionCollectorInterface $collector */ | ||||||
|  |         $collector = app(TransactionCollectorInterface::class); | ||||||
|  |         $collector->setUser($admin); | ||||||
|         $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); |         $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); | ||||||
|         $collector->setAllAssetAccounts(); |         $collector->setAllAssetAccounts(); | ||||||
|  |  | ||||||
|         // remove internal transfer filter: |         if (\in_array(TransactionType::TRANSFER, $types, true)) { | ||||||
|         if (\in_array(TransactionType::TRANSFER, $types)) { |  | ||||||
|             $collector->removeFilter(InternalTransferFilter::class); |             $collector->removeFilter(InternalTransferFilter::class); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -120,11 +123,10 @@ class TransactionController extends Controller | |||||||
|         } |         } | ||||||
|         $collector->setLimit($pageSize)->setPage($this->parameters->get('page')); |         $collector->setLimit($pageSize)->setPage($this->parameters->get('page')); | ||||||
|         $collector->setTypes($types); |         $collector->setTypes($types); | ||||||
|         $paginator = $collector->getPaginatedJournals(); |         $paginator = $collector->getPaginatedTransactions(); | ||||||
|         $paginator->setPath(route('api.v1.transactions.index') . $this->buildParams()); |         $paginator->setPath(route('api.v1.transactions.index') . $this->buildParams()); | ||||||
|         $transactions = $paginator->getCollection(); |         $transactions = $paginator->getCollection(); | ||||||
|  |  | ||||||
|  |  | ||||||
|         $resource = new FractalCollection($transactions, new TransactionTransformer($this->parameters), 'transactions'); |         $resource = new FractalCollection($transactions, new TransactionTransformer($this->parameters), 'transactions'); | ||||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); |         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||||
|  |  | ||||||
| @@ -133,23 +135,27 @@ class TransactionController extends Controller | |||||||
|  |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Show a single transaction. | ||||||
|  |      * | ||||||
|      * @param Request     $request |      * @param Request     $request | ||||||
|      * @param Transaction $transaction |      * @param Transaction $transaction | ||||||
|  |      * @param string      $include | ||||||
|      * |      * | ||||||
|      * @return \Illuminate\Http\JsonResponse |      * @return JsonResponse | ||||||
|      */ |      */ | ||||||
|     public function show(Request $request, Transaction $transaction) |     public function show(Request $request, Transaction $transaction, string $include = null): JsonResponse | ||||||
|     { |     { | ||||||
|         $manager = new Manager(); |         $manager = new Manager(); | ||||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; |         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); |         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||||
|  |  | ||||||
|         // add include parameter: |         // add include parameter: | ||||||
|         $include = $request->get('include') ?? ''; |         $include = $include ?? ''; | ||||||
|  |         $include = $request->get('include') ?? $include; | ||||||
|         $manager->parseIncludes($include); |         $manager->parseIncludes($include); | ||||||
|  |  | ||||||
|         // collect transactions using the journal collector |         // collect transactions using the journal collector | ||||||
|         $collector = app(JournalCollectorInterface::class); |         $collector = app(TransactionCollectorInterface::class); | ||||||
|         $collector->setUser(auth()->user()); |         $collector->setUser(auth()->user()); | ||||||
|         $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); |         $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); | ||||||
|         // filter on specific journals. |         // filter on specific journals. | ||||||
| @@ -164,20 +170,23 @@ class TransactionController extends Controller | |||||||
|             $collector->addFilter(NegativeAmountFilter::class); |             $collector->addFilter(NegativeAmountFilter::class); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         $transactions = $collector->getJournals(); |         $transactions = $collector->getTransactions(); | ||||||
|         $resource     = new FractalCollection($transactions, 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'); |         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Store a new transaction. | ||||||
|  |      * | ||||||
|      * @param TransactionRequest         $request |      * @param TransactionRequest         $request | ||||||
|      * |      * | ||||||
|      * @param JournalRepositoryInterface $repository |      * @param JournalRepositoryInterface $repository | ||||||
|      * |      * | ||||||
|      * @return \Illuminate\Http\JsonResponse |      * @throws FireflyException | ||||||
|  |      * @return JsonResponse | ||||||
|      */ |      */ | ||||||
|     public function store(TransactionRequest $request, JournalRepositoryInterface $repository) |     public function store(TransactionRequest $request, JournalRepositoryInterface $repository): JsonResponse | ||||||
|     { |     { | ||||||
|         $data         = $request->getAll(); |         $data         = $request->getAll(); | ||||||
|         $data['user'] = auth()->user()->id; |         $data['user'] = auth()->user()->id; | ||||||
| @@ -192,7 +201,7 @@ class TransactionController extends Controller | |||||||
|         $manager->parseIncludes($include); |         $manager->parseIncludes($include); | ||||||
|  |  | ||||||
|         // collect transactions using the journal collector |         // collect transactions using the journal collector | ||||||
|         $collector = app(JournalCollectorInterface::class); |         $collector = app(TransactionCollectorInterface::class); | ||||||
|         $collector->setUser(auth()->user()); |         $collector->setUser(auth()->user()); | ||||||
|         $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); |         $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); | ||||||
|         // filter on specific journals. |         // filter on specific journals. | ||||||
| @@ -207,7 +216,7 @@ class TransactionController extends Controller | |||||||
|             $collector->addFilter(NegativeAmountFilter::class); |             $collector->addFilter(NegativeAmountFilter::class); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         $transactions = $collector->getJournals(); |         $transactions = $collector->getTransactions(); | ||||||
|         $resource     = new FractalCollection($transactions, 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'); |         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||||
| @@ -215,23 +224,21 @@ class TransactionController extends Controller | |||||||
|  |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Update a transaction. | ||||||
|  |      * | ||||||
|      * @param TransactionRequest         $request |      * @param TransactionRequest         $request | ||||||
|      * @param JournalRepositoryInterface $repository |      * @param JournalRepositoryInterface $repository | ||||||
|      * @param Transaction                $transaction |      * @param Transaction                $transaction | ||||||
|      * |      * | ||||||
|      * @return \Illuminate\Http\JsonResponse |      * @return JsonResponse | ||||||
|      */ |      */ | ||||||
|     public function update(TransactionRequest $request, JournalRepositoryInterface $repository, Transaction $transaction) |     public function update(TransactionRequest $request, JournalRepositoryInterface $repository, Transaction $transaction): JsonResponse | ||||||
|     { |     { | ||||||
|         $data         = $request->getAll(); |         $data         = $request->getAll(); | ||||||
|         $data['user'] = auth()->user()->id; |         $data['user'] = auth()->user()->id; | ||||||
|  |         $journal      = $repository->update($transaction->transactionJournal, $data); | ||||||
|         Log::debug('Inside transaction update'); |         $manager      = new Manager(); | ||||||
|  |         $baseUrl      = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||||
|         $journal = $repository->update($transaction->transactionJournal, $data); |  | ||||||
|  |  | ||||||
|         $manager = new Manager(); |  | ||||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; |  | ||||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); |         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||||
|  |  | ||||||
|         // add include parameter: |         // add include parameter: | ||||||
| @@ -240,7 +247,7 @@ class TransactionController extends Controller | |||||||
|  |  | ||||||
|         // needs a lot of extra data to match the journal collector. Or just expand that one. |         // needs a lot of extra data to match the journal collector. Or just expand that one. | ||||||
|         // collect transactions using the journal collector |         // collect transactions using the journal collector | ||||||
|         $collector = app(JournalCollectorInterface::class); |         $collector = app(TransactionCollectorInterface::class); | ||||||
|         $collector->setUser(auth()->user()); |         $collector->setUser(auth()->user()); | ||||||
|         $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); |         $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); | ||||||
|         // filter on specific journals. |         // filter on specific journals. | ||||||
| @@ -255,7 +262,7 @@ class TransactionController extends Controller | |||||||
|             $collector->addFilter(NegativeAmountFilter::class); |             $collector->addFilter(NegativeAmountFilter::class); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         $transactions = $collector->getJournals(); |         $transactions = $collector->getTransactions(); | ||||||
|         $resource     = new FractalCollection($transactions, 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'); |         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||||
| @@ -263,72 +270,38 @@ class TransactionController extends Controller | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * All the types you can request. | ||||||
|  |      * | ||||||
|      * @param string $type |      * @param string $type | ||||||
|      * |      * | ||||||
|      * @return array |      * @return array | ||||||
|      */ |      */ | ||||||
|     private function mapTypes(string $type): array |     private function mapTypes(string $type): array | ||||||
|     { |     { | ||||||
|         $types = [ |         $types  = [ | ||||||
|             'all'             => [ |             'all'             => [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE, | ||||||
|                 TransactionType::WITHDRAWAL, |                                   TransactionType::RECONCILIATION,], | ||||||
|                 TransactionType::DEPOSIT, |             'withdrawal'      => [TransactionType::WITHDRAWAL,], | ||||||
|                 TransactionType::TRANSFER, |             'withdrawals'     => [TransactionType::WITHDRAWAL,], | ||||||
|                 TransactionType::OPENING_BALANCE, |             'expense'         => [TransactionType::WITHDRAWAL,], | ||||||
|                 TransactionType::RECONCILIATION, |             'income'          => [TransactionType::DEPOSIT,], | ||||||
|             ], |             'deposit'         => [TransactionType::DEPOSIT,], | ||||||
|             'withdrawal'      => [ |             'deposits'        => [TransactionType::DEPOSIT,], | ||||||
|                 TransactionType::WITHDRAWAL, |             'transfer'        => [TransactionType::TRANSFER,], | ||||||
|             ], |             'transfers'       => [TransactionType::TRANSFER,], | ||||||
|             'withdrawals'     => [ |             'opening_balance' => [TransactionType::OPENING_BALANCE,], | ||||||
|                 TransactionType::WITHDRAWAL, |             'reconciliation'  => [TransactionType::RECONCILIATION,], | ||||||
|             ], |             'reconciliations' => [TransactionType::RECONCILIATION,], | ||||||
|             'expense'         => [ |             'special'         => [TransactionType::OPENING_BALANCE, TransactionType::RECONCILIATION,], | ||||||
|                 TransactionType::WITHDRAWAL, |             'specials'        => [TransactionType::OPENING_BALANCE, TransactionType::RECONCILIATION,], | ||||||
|             ], |             'default'         => [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER,], | ||||||
|             'income'          => [ |  | ||||||
|                 TransactionType::DEPOSIT, |  | ||||||
|             ], |  | ||||||
|             'deposit'         => [ |  | ||||||
|                 TransactionType::DEPOSIT, |  | ||||||
|             ], |  | ||||||
|             'deposits'        => [ |  | ||||||
|                 TransactionType::DEPOSIT, |  | ||||||
|             ], |  | ||||||
|             'transfer'        => [ |  | ||||||
|                 TransactionType::TRANSFER, |  | ||||||
|             ], |  | ||||||
|             'transfers'       => [ |  | ||||||
|                 TransactionType::TRANSFER, |  | ||||||
|             ], |  | ||||||
|             'opening_balance' => [ |  | ||||||
|                 TransactionType::OPENING_BALANCE, |  | ||||||
|             ], |  | ||||||
|             'reconciliation'  => [ |  | ||||||
|                 TransactionType::RECONCILIATION, |  | ||||||
|             ], |  | ||||||
|             'reconciliations' => [ |  | ||||||
|                 TransactionType::RECONCILIATION, |  | ||||||
|             ], |  | ||||||
|             'special'         => [ |  | ||||||
|                 TransactionType::OPENING_BALANCE, |  | ||||||
|                 TransactionType::RECONCILIATION, |  | ||||||
|             ], |  | ||||||
|             'specials'        => [ |  | ||||||
|                 TransactionType::OPENING_BALANCE, |  | ||||||
|                 TransactionType::RECONCILIATION, |  | ||||||
|             ], |  | ||||||
|             'default'         => [ |  | ||||||
|                 TransactionType::WITHDRAWAL, |  | ||||||
|                 TransactionType::DEPOSIT, |  | ||||||
|                 TransactionType::TRANSFER, |  | ||||||
|             ], |  | ||||||
|         ]; |         ]; | ||||||
|  |         $return = $types['default']; | ||||||
|         if (isset($types[$type])) { |         if (isset($types[$type])) { | ||||||
|             return $types[$type]; |             $return = $types[$type]; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return $types['default']; // @codeCoverageIgnore |         return $return; | ||||||
|  |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * UserController.php |  * UserController.php | ||||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
| @@ -20,6 +20,7 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Api\V1\Controllers; | namespace FireflyIII\Api\V1\Controllers; | ||||||
|  |  | ||||||
| @@ -28,6 +29,7 @@ use FireflyIII\Exceptions\FireflyException; | |||||||
| use FireflyIII\Repositories\User\UserRepositoryInterface; | use FireflyIII\Repositories\User\UserRepositoryInterface; | ||||||
| use FireflyIII\Transformers\UserTransformer; | use FireflyIII\Transformers\UserTransformer; | ||||||
| use FireflyIII\User; | use FireflyIII\User; | ||||||
|  | use Illuminate\Http\JsonResponse; | ||||||
| use Illuminate\Http\Request; | use Illuminate\Http\Request; | ||||||
| use Illuminate\Pagination\LengthAwarePaginator; | use Illuminate\Pagination\LengthAwarePaginator; | ||||||
| use League\Fractal\Manager; | use League\Fractal\Manager; | ||||||
| @@ -35,22 +37,21 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter; | |||||||
| use League\Fractal\Resource\Collection as FractalCollection; | use League\Fractal\Resource\Collection as FractalCollection; | ||||||
| use League\Fractal\Resource\Item; | use League\Fractal\Resource\Item; | ||||||
| use League\Fractal\Serializer\JsonApiSerializer; | use League\Fractal\Serializer\JsonApiSerializer; | ||||||
| use Preferences; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class UserController |  * Class UserController. | ||||||
|  |  * | ||||||
|  |  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||||
|  */ |  */ | ||||||
| class UserController extends Controller | class UserController extends Controller | ||||||
| { | { | ||||||
|  |  | ||||||
|     /** @var UserRepositoryInterface */ |     /** @var UserRepositoryInterface The user repository */ | ||||||
|     private $repository; |     private $repository; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * UserController constructor. |      * UserController constructor. | ||||||
|      * |  | ||||||
|      * @throws \FireflyIII\Exceptions\FireflyException |  | ||||||
|      */ |      */ | ||||||
|     public function __construct() |     public function __construct() | ||||||
|     { |     { | ||||||
| @@ -70,12 +71,14 @@ class UserController extends Controller | |||||||
|      * |      * | ||||||
|      * @param  \FireflyIII\User $user |      * @param  \FireflyIII\User $user | ||||||
|      * |      * | ||||||
|      * @return \Illuminate\Http\Response |      * @return JsonResponse | ||||||
|      * @throws FireflyException |      * @throws FireflyException | ||||||
|      */ |      */ | ||||||
|     public function delete(User $user) |     public function delete(User $user): JsonResponse | ||||||
|     { |     { | ||||||
|         if (auth()->user()->hasRole('owner')) { |         /** @var User $admin */ | ||||||
|  |         $admin = auth()->user(); | ||||||
|  |         if ($this->repository->hasRole($admin, 'owner')) { | ||||||
|             $this->repository->destroy($user); |             $this->repository->destroy($user); | ||||||
|  |  | ||||||
|             return response()->json([], 204); |             return response()->json([], 204); | ||||||
| @@ -88,12 +91,12 @@ class UserController extends Controller | |||||||
|      * |      * | ||||||
|      * @param Request $request |      * @param Request $request | ||||||
|      * |      * | ||||||
|      * @return \Illuminate\Http\JsonResponse |      * @return JsonResponse | ||||||
|      */ |      */ | ||||||
|     public function index(Request $request) |     public function index(Request $request): JsonResponse | ||||||
|     { |     { | ||||||
|         // user preferences |         // user preferences | ||||||
|         $pageSize = (int)Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data; |         $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||||
|  |  | ||||||
|         // make manager |         // make manager | ||||||
|         $manager = new Manager(); |         $manager = new Manager(); | ||||||
| @@ -117,12 +120,14 @@ class UserController extends Controller | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Show a single user. | ||||||
|  |      * | ||||||
|      * @param Request $request |      * @param Request $request | ||||||
|      * @param User    $user |      * @param User    $user | ||||||
|      * |      * | ||||||
|      * @return \Illuminate\Http\JsonResponse |      * @return JsonResponse | ||||||
|      */ |      */ | ||||||
|     public function show(Request $request, User $user) |     public function show(Request $request, User $user): JsonResponse | ||||||
|     { |     { | ||||||
|         // make manager |         // make manager | ||||||
|         $manager = new Manager(); |         $manager = new Manager(); | ||||||
| @@ -140,11 +145,13 @@ class UserController extends Controller | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Store a new user. | ||||||
|  |      * | ||||||
|      * @param UserRequest $request |      * @param UserRequest $request | ||||||
|      * |      * | ||||||
|      * @return \Illuminate\Http\JsonResponse |      * @return JsonResponse | ||||||
|      */ |      */ | ||||||
|     public function store(UserRequest $request) |     public function store(UserRequest $request): JsonResponse | ||||||
|     { |     { | ||||||
|         $data = $request->getAll(); |         $data = $request->getAll(); | ||||||
|         $user = $this->repository->store($data); |         $user = $this->repository->store($data); | ||||||
| @@ -165,12 +172,14 @@ class UserController extends Controller | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Update a user. | ||||||
|  |      * | ||||||
|      * @param UserRequest $request |      * @param UserRequest $request | ||||||
|      * @param User        $user |      * @param User        $user | ||||||
|      * |      * | ||||||
|      * @return \Illuminate\Http\JsonResponse |      * @return JsonResponse | ||||||
|      */ |      */ | ||||||
|     public function update(UserRequest $request, User $user) |     public function update(UserRequest $request, User $user): JsonResponse | ||||||
|     { |     { | ||||||
|         $data = $request->getAll(); |         $data = $request->getAll(); | ||||||
|         $user = $this->repository->update($user, $data); |         $user = $this->repository->update($user, $data); | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * AccountRequest.php |  * AccountRequest.php | ||||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
| @@ -20,9 +20,9 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Api\V1\Requests; | namespace FireflyIII\Api\V1\Requests; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class AccountRequest |  * Class AccountRequest | ||||||
|  */ |  */ | ||||||
| @@ -30,6 +30,8 @@ class AccountRequest extends Request | |||||||
| { | { | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Authorize logged in users. | ||||||
|  |      * | ||||||
|      * @return bool |      * @return bool | ||||||
|      */ |      */ | ||||||
|     public function authorize(): bool |     public function authorize(): bool | ||||||
| @@ -39,6 +41,8 @@ class AccountRequest extends Request | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Get all data from the request. | ||||||
|  |      * | ||||||
|      * @return array |      * @return array | ||||||
|      */ |      */ | ||||||
|     public function getAll(): array |     public function getAll(): array | ||||||
| @@ -46,6 +50,7 @@ class AccountRequest extends Request | |||||||
|         $data = [ |         $data = [ | ||||||
|             'name'                 => $this->string('name'), |             'name'                 => $this->string('name'), | ||||||
|             'active'               => $this->boolean('active'), |             'active'               => $this->boolean('active'), | ||||||
|  |             'include_net_worth'    => $this->boolean('include_net_worth'), | ||||||
|             'accountType'          => $this->string('type'), |             'accountType'          => $this->string('type'), | ||||||
|             'account_type_id'      => null, |             'account_type_id'      => null, | ||||||
|             'currency_id'          => $this->integer('currency_id'), |             'currency_id'          => $this->integer('currency_id'), | ||||||
| @@ -60,12 +65,28 @@ class AccountRequest extends Request | |||||||
|             'ccType'               => $this->string('cc_type'), |             'ccType'               => $this->string('cc_type'), | ||||||
|             'ccMonthlyPaymentDate' => $this->string('cc_monthly_payment_date'), |             'ccMonthlyPaymentDate' => $this->string('cc_monthly_payment_date'), | ||||||
|             'notes'                => $this->string('notes'), |             'notes'                => $this->string('notes'), | ||||||
|  |             'interest'             => $this->string('interest'), | ||||||
|  |             'interest_period'      => $this->string('interest_period'), | ||||||
|         ]; |         ]; | ||||||
|  |         // new fields for liabilities | ||||||
|  |         //            'liability_type'       => $this->string('liability_type'), | ||||||
|  |         //            'liability_start_date' => $this->date('liability_start_date'), | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         //]; | ||||||
|  |         if ('liability' === $data['accountType']) { | ||||||
|  |             $data['openingBalance']     = bcmul($this->string('liability_amount'), '-1'); | ||||||
|  |             $data['openingBalanceDate'] = $this->date('liability_start_date'); | ||||||
|  |             $data['accountType']        = $this->string('liability_type'); | ||||||
|  |             $data['account_type_id']    = null; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         return $data; |         return $data; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * The rules that the incoming request must be matched against. | ||||||
|  |      * | ||||||
|      * @return array |      * @return array | ||||||
|      */ |      */ | ||||||
|     public function rules(): array |     public function rules(): array | ||||||
| @@ -85,10 +106,18 @@ class AccountRequest extends Request | |||||||
|             'account_number'          => 'between:1,255|nullable|uniqueAccountNumberForUser', |             'account_number'          => 'between:1,255|nullable|uniqueAccountNumberForUser', | ||||||
|             'account_role'            => 'in:' . $accountRoles . '|required_if:type,asset', |             'account_role'            => 'in:' . $accountRoles . '|required_if:type,asset', | ||||||
|             'active'                  => 'required|boolean', |             'active'                  => 'required|boolean', | ||||||
|  |             'include_net_worth'       => 'required|boolean', | ||||||
|             'cc_type'                 => 'in:' . $ccPaymentTypes . '|required_if:account_role,ccAsset', |             'cc_type'                 => 'in:' . $ccPaymentTypes . '|required_if:account_role,ccAsset', | ||||||
|             'cc_monthly_payment_date' => 'date' . '|required_if:account_role,ccAsset|required_if:cc_type,monthlyFull', |             'cc_monthly_payment_date' => 'date' . '|required_if:account_role,ccAsset|required_if:cc_type,monthlyFull', | ||||||
|             'type'                    => 'required|in:' . $types, |             'type'                    => 'required|in:' . $types, | ||||||
|             'notes'                   => 'min:0|max:65536', |             'notes'                   => 'min:0|max:65536', | ||||||
|  |             // required fields for liabilities: | ||||||
|  |             'liability_type'          => 'required_if:type,liability|in:loan,debt,mortgage,credit card', | ||||||
|  |             'liability_amount'        => 'required_if:type,liability|min:0|numeric', | ||||||
|  |             'liability_start_date'    => 'required_if:type,liability|date', | ||||||
|  |             'interest'                => 'required_if:type,liability|between:0,100|numeric', | ||||||
|  |             'interest_period'         => 'required_if:type,liability|in:daily,monthly,yearly', | ||||||
|  |  | ||||||
|         ]; |         ]; | ||||||
|         switch ($this->method()) { |         switch ($this->method()) { | ||||||
|             default: |             default: | ||||||
|   | |||||||
							
								
								
									
										97
									
								
								app/Api/V1/Requests/AttachmentRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								app/Api/V1/Requests/AttachmentRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,97 @@ | |||||||
|  | <?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\IsValidAttachmentModel; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Class AttachmentRequest | ||||||
|  |  */ | ||||||
|  | class AttachmentRequest extends Request | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Authorize logged in users. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize(): bool | ||||||
|  |     { | ||||||
|  |         // Only allow authenticated users | ||||||
|  |         return auth()->check(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get all data from the request. | ||||||
|  |      * | ||||||
|  |      * @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'), | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * The rules that the incoming request must be matched against. | ||||||
|  |      * | ||||||
|  |      * @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; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										77
									
								
								app/Api/V1/Requests/AvailableBudgetRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								app/Api/V1/Requests/AvailableBudgetRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | |||||||
|  | <?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 | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Authorize logged in users. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize(): bool | ||||||
|  |     { | ||||||
|  |         // Only allow authenticated users | ||||||
|  |         return auth()->check(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get all data from the request. | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function getAll(): array | ||||||
|  |     { | ||||||
|  |         return [ | ||||||
|  |             'currency_id'   => $this->integer('currency_id'), | ||||||
|  |             'currency_code' => $this->string('currency_code'), | ||||||
|  |             'amount'        => $this->string('amount'), | ||||||
|  |             'start_date'    => $this->date('start_date'), | ||||||
|  |             'end_date'      => $this->date('end_date'), | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * The rules that the incoming request must be matched against. | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function rules(): array | ||||||
|  |     { | ||||||
|  |         $rules = [ | ||||||
|  |             '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', | ||||||
|  |             'amount'        => 'required|numeric|more:0', | ||||||
|  |             'start_date'    => 'required|date|before:end_date', | ||||||
|  |             'end_date'      => 'required|date|after:start_date', | ||||||
|  |         ]; | ||||||
|  |  | ||||||
|  |         return $rules; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * BillRequest.php |  * BillRequest.php | ||||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
| @@ -20,6 +20,7 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Api\V1\Requests; | namespace FireflyIII\Api\V1\Requests; | ||||||
|  |  | ||||||
| @@ -32,6 +33,8 @@ class BillRequest extends Request | |||||||
| { | { | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Authorize logged in users. | ||||||
|  |      * | ||||||
|      * @return bool |      * @return bool | ||||||
|      */ |      */ | ||||||
|     public function authorize(): bool |     public function authorize(): bool | ||||||
| @@ -41,6 +44,8 @@ class BillRequest extends Request | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Get all data from the request. | ||||||
|  |      * | ||||||
|      * @return array |      * @return array | ||||||
|      */ |      */ | ||||||
|     public function getAll(): array |     public function getAll(): array | ||||||
| @@ -63,6 +68,8 @@ class BillRequest extends Request | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * The rules that the incoming request must be matched against. | ||||||
|  |      * | ||||||
|      * @return array |      * @return array | ||||||
|      */ |      */ | ||||||
|     public function rules(): array |     public function rules(): array | ||||||
| @@ -85,8 +92,8 @@ class BillRequest extends Request | |||||||
|                 break; |                 break; | ||||||
|             case 'PUT': |             case 'PUT': | ||||||
|             case 'PATCH': |             case 'PATCH': | ||||||
|                 $bill           = $this->route()->parameter('bill'); |                 $bill          = $this->route()->parameter('bill'); | ||||||
|                 $rules['name']  .= ',' . $bill->id; |                 $rules['name'] .= ',' . $bill->id; | ||||||
|                 break; |                 break; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -108,7 +115,7 @@ class BillRequest extends Request | |||||||
|                 $min  = (float)($data['amount_min'] ?? 0); |                 $min  = (float)($data['amount_min'] ?? 0); | ||||||
|                 $max  = (float)($data['amount_max'] ?? 0); |                 $max  = (float)($data['amount_max'] ?? 0); | ||||||
|                 if ($min > $max) { |                 if ($min > $max) { | ||||||
|                     $validator->errors()->add('amount_min', trans('validation.amount_min_over_max')); |                     $validator->errors()->add('amount_min', (string)trans('validation.amount_min_over_max')); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         ); |         ); | ||||||
|   | |||||||
							
								
								
									
										83
									
								
								app/Api/V1/Requests/BudgetLimitRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								app/Api/V1/Requests/BudgetLimitRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | |||||||
|  | <?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 | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Authorize logged in users. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize(): bool | ||||||
|  |     { | ||||||
|  |         // Only allow authenticated users | ||||||
|  |         return auth()->check(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get all data from the request. | ||||||
|  |      * | ||||||
|  |      * @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'), | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * The rules that the incoming request must be matched against. | ||||||
|  |      * | ||||||
|  |      * @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; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										82
									
								
								app/Api/V1/Requests/BudgetRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								app/Api/V1/Requests/BudgetRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | |||||||
|  | <?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 | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Authorize logged in users. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize(): bool | ||||||
|  |     { | ||||||
|  |         // Only allow authenticated users | ||||||
|  |         return auth()->check(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get all data from the request. | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function getAll(): array | ||||||
|  |     { | ||||||
|  |         return [ | ||||||
|  |             'name'   => $this->string('name'), | ||||||
|  |             'active' => $this->boolean('active'), | ||||||
|  |             'order'  => 0, | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * The rules that the incoming request must be matched against. | ||||||
|  |      * | ||||||
|  |      * @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; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										81
									
								
								app/Api/V1/Requests/CategoryRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								app/Api/V1/Requests/CategoryRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | |||||||
|  | <?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 | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Authorize logged in users. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize(): bool | ||||||
|  |     { | ||||||
|  |         // Only allow authenticated users | ||||||
|  |         return auth()->check(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get all data from the request. | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function getAll(): array | ||||||
|  |     { | ||||||
|  |         return [ | ||||||
|  |             'name'   => $this->string('name'), | ||||||
|  |             'active' => $this->boolean('active'), | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * The rules that the incoming request must be matched against. | ||||||
|  |      * | ||||||
|  |      * @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; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -30,6 +30,8 @@ namespace FireflyIII\Api\V1\Requests; | |||||||
| class CurrencyRequest extends Request | class CurrencyRequest extends Request | ||||||
| { | { | ||||||
|     /** |     /** | ||||||
|  |      * Authorize logged in users. | ||||||
|  |      * | ||||||
|      * @return bool |      * @return bool | ||||||
|      */ |      */ | ||||||
|     public function authorize(): bool |     public function authorize(): bool | ||||||
| @@ -39,9 +41,11 @@ class CurrencyRequest extends Request | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Get all data from the request. | ||||||
|  |      * | ||||||
|      * @return array |      * @return array | ||||||
|      */ |      */ | ||||||
|     public function getAll() |     public function getAll(): array | ||||||
|     { |     { | ||||||
|         return [ |         return [ | ||||||
|             'name'           => $this->string('name'), |             'name'           => $this->string('name'), | ||||||
| @@ -53,6 +57,8 @@ class CurrencyRequest extends Request | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * The rules that the incoming request must be matched against. | ||||||
|  |      * | ||||||
|      * @return array |      * @return array | ||||||
|      */ |      */ | ||||||
|     public function rules(): array |     public function rules(): array | ||||||
| @@ -62,7 +68,7 @@ class CurrencyRequest extends Request | |||||||
|             'code'           => 'required|between:3,3|unique:transaction_currencies,code', |             'code'           => 'required|between:3,3|unique:transaction_currencies,code', | ||||||
|             'symbol'         => 'required|between:1,5|unique:transaction_currencies,symbol', |             'symbol'         => 'required|between:1,5|unique:transaction_currencies,symbol', | ||||||
|             'decimal_places' => 'required|between:0,20|numeric|min:0|max:20', |             'decimal_places' => 'required|between:0,20|numeric|min:0|max:20', | ||||||
|             'default'        => 'in:true,false', |             'default'        => 'boolean', | ||||||
|         ]; |         ]; | ||||||
|  |  | ||||||
|         switch ($this->method()) { |         switch ($this->method()) { | ||||||
| @@ -80,4 +86,4 @@ class CurrencyRequest extends Request | |||||||
|         return $rules; |         return $rules; | ||||||
|  |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										131
									
								
								app/Api/V1/Requests/JournalLinkRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								app/Api/V1/Requests/JournalLinkRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,131 @@ | |||||||
|  | <?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; | ||||||
|  |  | ||||||
|  | use FireflyIII\Repositories\Journal\JournalRepositoryInterface; | ||||||
|  | use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface; | ||||||
|  | use Illuminate\Validation\Validator; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * Class JournalLinkRequest | ||||||
|  |  */ | ||||||
|  | class JournalLinkRequest extends Request | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Authorize logged in users. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize(): bool | ||||||
|  |     { | ||||||
|  |         // Only allow authenticated users | ||||||
|  |         return auth()->check(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get all data from the request. | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function getAll(): array | ||||||
|  |     { | ||||||
|  |         return [ | ||||||
|  |             'link_type_id'   => $this->integer('link_type_id'), | ||||||
|  |             'link_type_name' => $this->string('link_type_name'), | ||||||
|  |             'inward_id'      => $this->integer('inward_id'), | ||||||
|  |             'outward_id'     => $this->integer('outward_id'), | ||||||
|  |             'notes'          => $this->string('notes'), | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * | ||||||
|  |      * The rules that the incoming request must be matched against. | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function rules(): array | ||||||
|  |     { | ||||||
|  |         return [ | ||||||
|  |             'link_type_id'   => 'exists:link_types,id|required_without:link_type_name', | ||||||
|  |             'link_type_name' => 'exists:link_types,name|required_without:link_type_id', | ||||||
|  |             'inward_id'      => 'required|belongsToUser:transaction_journals,id', | ||||||
|  |             'outward_id'     => 'required|belongsToUser:transaction_journals,id', | ||||||
|  |             'notes'          => 'between:0,65000', | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Configure the validator instance. | ||||||
|  |      * | ||||||
|  |      * @param  Validator $validator | ||||||
|  |      * | ||||||
|  |      * @return void | ||||||
|  |      */ | ||||||
|  |     public function withValidator(Validator $validator): void | ||||||
|  |     { | ||||||
|  |         $validator->after( | ||||||
|  |             function (Validator $validator) { | ||||||
|  |                 $this->validateExistingLink($validator); | ||||||
|  |             } | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param Validator $validator | ||||||
|  |      */ | ||||||
|  |     private function validateExistingLink(Validator $validator): void | ||||||
|  |     { | ||||||
|  |         /** @var LinkTypeRepositoryInterface $repository */ | ||||||
|  |         $repository = app(LinkTypeRepositoryInterface::class); | ||||||
|  |         $repository->setUser(auth()->user()); | ||||||
|  |  | ||||||
|  |         /** @var JournalRepositoryInterface $journalRepos */ | ||||||
|  |         $journalRepos = app(JournalRepositoryInterface::class); | ||||||
|  |         $journalRepos->setUser(auth()->user()); | ||||||
|  |  | ||||||
|  |         $data      = $validator->getData(); | ||||||
|  |         $inwardId  = (int)($data['inward_id'] ?? 0); | ||||||
|  |         $outwardId = (int)($data['outward_id'] ?? 0); | ||||||
|  |         $inward    = $journalRepos->findNull($inwardId); | ||||||
|  |         $outward   = $journalRepos->findNull($outwardId); | ||||||
|  |  | ||||||
|  |         if (null === $inward) { | ||||||
|  |             $validator->errors()->add('inward_id', 'Invalid inward ID.'); | ||||||
|  |  | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         if (null === $outward) { | ||||||
|  |             $validator->errors()->add('outward_id', 'Invalid outward ID.'); | ||||||
|  |  | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if ($repository->findLink($inward, $outward)) { | ||||||
|  |             $validator->errors()->add('outward_id', 'Already have a link between inward and outward.'); | ||||||
|  |             $validator->errors()->add('inward_id', 'Already have a link between inward and outward.'); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										91
									
								
								app/Api/V1/Requests/LinkTypeRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								app/Api/V1/Requests/LinkTypeRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,91 @@ | |||||||
|  | <?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 | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Authorize logged in users. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize(): bool | ||||||
|  |     { | ||||||
|  |         // Only allow authenticated users | ||||||
|  |         return auth()->check(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get all data from the request. | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function getAll(): array | ||||||
|  |     { | ||||||
|  |         return [ | ||||||
|  |             'name'    => $this->string('name'), | ||||||
|  |             'outward' => $this->string('outward'), | ||||||
|  |             'inward'  => $this->string('inward'), | ||||||
|  |         ]; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * The rules that the incoming request must be matched against. | ||||||
|  |      * | ||||||
|  |      * @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', | ||||||
|  |         ]; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         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; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										96
									
								
								app/Api/V1/Requests/PiggyBankRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								app/Api/V1/Requests/PiggyBankRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | |||||||
|  | <?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 | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Authorize logged in users. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize(): bool | ||||||
|  |     { | ||||||
|  |         // Only allow authenticated users | ||||||
|  |         return auth()->check(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get all data from the request. | ||||||
|  |      * | ||||||
|  |      * @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'), | ||||||
|  |             'notes'           => $this->string('notes'), | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * The rules that the incoming request must be matched against. | ||||||
|  |      * | ||||||
|  |      * @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; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -1,8 +1,7 @@ | |||||||
| <?php | <?php | ||||||
| 
 |  | ||||||
| /** | /** | ||||||
|  * BunqId.php |  * PreferenceRequest.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -19,54 +18,52 @@ | |||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  | 
 | ||||||
| declare(strict_types=1); | declare(strict_types=1); | ||||||
| 
 | 
 | ||||||
| namespace FireflyIII\Services\Bunq\Id; | namespace FireflyIII\Api\V1\Requests; | ||||||
| 
 | 
 | ||||||
| use Log; |  | ||||||
| /** | /** | ||||||
|  * Class BunqId. |  * | ||||||
|  |  * Class PreferenceRequest | ||||||
|  */ |  */ | ||||||
| class BunqId | class PreferenceRequest extends Request | ||||||
| { | { | ||||||
|     /** @var int */ | 
 | ||||||
|     private $id = 0; |  | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * BunqId constructor. |      * Authorize logged in users. | ||||||
|      * |      * | ||||||
|      * @param null $data |      * @return bool | ||||||
|      */ |      */ | ||||||
|     public function __construct($data = null) |     public function authorize(): bool | ||||||
|     { |     { | ||||||
|         if (null !== $data) { |         // Only allow authenticated users
 | ||||||
|             $this->id = $data['id']; |         return auth()->check(); | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * @return int |  | ||||||
|      */ |  | ||||||
|     public function getId(): int |  | ||||||
|     { |  | ||||||
|         return $this->id; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * @param int $id |  | ||||||
|      */ |  | ||||||
|     public function setId(int $id) |  | ||||||
|     { |  | ||||||
|         $this->id = $id; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  |      * Get all data from the request. | ||||||
|  |      * | ||||||
|      * @return array |      * @return array | ||||||
|      */ |      */ | ||||||
|     public function toArray(): array |     public function getAll(): array | ||||||
|     { |     { | ||||||
|         return [ |         return [ | ||||||
|             'id' => $this->id, |             'data' => $this->get('data'), | ||||||
|         ]; |         ]; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * The rules that the incoming request must be matched against. | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function rules(): array | ||||||
|  |     { | ||||||
|  |         return [ | ||||||
|  |             'data' => 'required|between:1,65000', | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| } | } | ||||||
							
								
								
									
										203
									
								
								app/Api/V1/Requests/RecurrenceRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										203
									
								
								app/Api/V1/Requests/RecurrenceRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,203 @@ | |||||||
|  | <?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\Rules\BelongsUser; | ||||||
|  | use FireflyIII\Validation\RecurrenceValidation; | ||||||
|  | use FireflyIII\Validation\TransactionValidation; | ||||||
|  | use Illuminate\Validation\Validator; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Class RecurrenceRequest | ||||||
|  |  */ | ||||||
|  | class RecurrenceRequest extends Request | ||||||
|  | { | ||||||
|  |     use RecurrenceValidation, TransactionValidation; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Authorize logged in users. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize(): bool | ||||||
|  |     { | ||||||
|  |         // Only allow authenticated users | ||||||
|  |         return auth()->check(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get all data from the request. | ||||||
|  |      * | ||||||
|  |      * @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' => $this->getTransactionData(), | ||||||
|  |             'repetitions'  => $this->getRepetitionData(), | ||||||
|  |         ]; | ||||||
|  |  | ||||||
|  |         return $return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * The rules that the incoming request must be matched against. | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function rules(): array | ||||||
|  |     { | ||||||
|  |         $today = Carbon::now()->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', | ||||||
|  |             'tags'                                 => 'between:1,64000', | ||||||
|  |             'piggy_bank_id'                        => 'numeric', | ||||||
|  |             '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', | ||||||
|  |             '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->validateOneTransaction($validator); | ||||||
|  |                 $this->validateOneRepetition($validator); | ||||||
|  |                 $this->validateRecurrenceRepetition($validator); | ||||||
|  |                 $this->validateRepetitionMoment($validator); | ||||||
|  |                 $this->validateForeignCurrencyInformation($validator); | ||||||
|  |                 $this->validateAccountInformation($validator); | ||||||
|  |             } | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns the repetition data as it is found in the submitted data. | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     private function getRepetitionData(): array | ||||||
|  |     { | ||||||
|  |         $return = []; | ||||||
|  |         // repetition data: | ||||||
|  |         /** @var array $repetitions */ | ||||||
|  |         $repetitions = $this->get('repetitions'); | ||||||
|  |         /** @var array $repetition */ | ||||||
|  |         foreach ($repetitions as $repetition) { | ||||||
|  |             $return[] = [ | ||||||
|  |                 'type'    => $repetition['type'], | ||||||
|  |                 'moment'  => $repetition['moment'], | ||||||
|  |                 'skip'    => (int)$repetition['skip'], | ||||||
|  |                 'weekend' => (int)$repetition['weekend'], | ||||||
|  |             ]; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return $return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns the transaction data as it is found in the submitted data. It's a complex method according to code | ||||||
|  |      * standards but it just has a lot of ??-statements because of the fields that may or may not exist. | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      * @SuppressWarnings(PHPMD.NPathComplexity) | ||||||
|  |      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||||
|  |      */ | ||||||
|  |     private function getTransactionData(): array | ||||||
|  |     { | ||||||
|  |         $return = []; | ||||||
|  |         // transaction data: | ||||||
|  |         /** @var array $transactions */ | ||||||
|  |         $transactions = $this->get('transactions'); | ||||||
|  |         /** @var array $transaction */ | ||||||
|  |         foreach ($transactions as $transaction) { | ||||||
|  |             $return[] = [ | ||||||
|  |                 '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; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * Request.php |  * Request.php | ||||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
| @@ -20,12 +20,18 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Api\V1\Requests; | namespace FireflyIII\Api\V1\Requests; | ||||||
|  |  | ||||||
| use FireflyIII\Http\Requests\Request as FireflyIIIRequest; | use FireflyIII\Http\Requests\Request as FireflyIIIRequest; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class Request. |  * Class Request. | ||||||
|  |  * | ||||||
|  |  * Technically speaking this class does not have to be extended like this but who knows what the future brings. | ||||||
|  |  * | ||||||
|  |  * @SuppressWarnings(PHPMD.NumberOfChildren) | ||||||
|  */ |  */ | ||||||
| class Request extends FireflyIIIRequest | class Request extends FireflyIIIRequest | ||||||
| { | { | ||||||
|   | |||||||
							
								
								
									
										85
									
								
								app/Api/V1/Requests/RuleGroupRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								app/Api/V1/Requests/RuleGroupRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | |||||||
|  | <?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 | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Authorize logged in users. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize(): bool | ||||||
|  |     { | ||||||
|  |         // Only allow authenticated users | ||||||
|  |         return auth()->check(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get all data from the request. | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function getAll(): array | ||||||
|  |     { | ||||||
|  |         return [ | ||||||
|  |             'title'       => $this->string('title'), | ||||||
|  |             'description' => $this->string('description'), | ||||||
|  |             'active'      => $this->boolean('active'), | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * The rules that the incoming request must be matched against. | ||||||
|  |      * | ||||||
|  |      * @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; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										187
									
								
								app/Api/V1/Requests/RuleRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								app/Api/V1/Requests/RuleRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,187 @@ | |||||||
|  | <?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 | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Authorize logged in users. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize(): bool | ||||||
|  |     { | ||||||
|  |         // Only allow authenticated users | ||||||
|  |         return auth()->check(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get all data from the request. | ||||||
|  |      * | ||||||
|  |      * @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'    => $this->getRuleTriggers(), | ||||||
|  |             'rule_actions'     => $this->getRuleActions(), | ||||||
|  |         ]; | ||||||
|  |  | ||||||
|  |         return $data; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * The rules that the incoming request must be matched against. | ||||||
|  |      * | ||||||
|  |      * @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_actions.*.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 (0 === \count($repetitions)) { | ||||||
|  |             $validator->errors()->add('title', (string)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 (0 === \count($repetitions)) { | ||||||
|  |             $validator->errors()->add('title', (string)trans('validation.at_least_one_trigger')); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     private function getRuleActions(): array | ||||||
|  |     { | ||||||
|  |         $actions = $this->get('rule_actions'); | ||||||
|  |         $return  = []; | ||||||
|  |         if (\is_array($actions)) { | ||||||
|  |             foreach ($actions as $action) { | ||||||
|  |                 $return[] = [ | ||||||
|  |                     'name'            => $action['name'], | ||||||
|  |                     'value'           => $action['value'], | ||||||
|  |                     'stop_processing' => 1 === (int)($action['stop-processing'] ?? '0'), | ||||||
|  |                 ]; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return $return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     private function getRuleTriggers(): array | ||||||
|  |     { | ||||||
|  |         $triggers = $this->get('rule_triggers'); | ||||||
|  |         $return   = []; | ||||||
|  |         if (\is_array($triggers)) { | ||||||
|  |             foreach ($triggers as $trigger) { | ||||||
|  |                 $return[] = [ | ||||||
|  |                     'name'            => $trigger['name'], | ||||||
|  |                     'value'           => $trigger['value'], | ||||||
|  |                     'stop_processing' => 1 === (int)($trigger['stop-processing'] ?? '0'), | ||||||
|  |                 ]; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return $return; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * TransactionRequest.php |  * TransactionRequest.php | ||||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
| @@ -20,15 +20,12 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Api\V1\Requests; | namespace FireflyIII\Api\V1\Requests; | ||||||
|  |  | ||||||
| use FireflyIII\Exceptions\FireflyException; |  | ||||||
| use FireflyIII\Models\Account; |  | ||||||
| use FireflyIII\Models\AccountType; |  | ||||||
| use FireflyIII\Models\Transaction; |  | ||||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; |  | ||||||
| use FireflyIII\Rules\BelongsUser; | use FireflyIII\Rules\BelongsUser; | ||||||
|  | use FireflyIII\Validation\TransactionValidation; | ||||||
| use Illuminate\Validation\Validator; | use Illuminate\Validation\Validator; | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -37,7 +34,11 @@ use Illuminate\Validation\Validator; | |||||||
|  */ |  */ | ||||||
| class TransactionRequest extends Request | class TransactionRequest extends Request | ||||||
| { | { | ||||||
|  |     use TransactionValidation; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Authorize logged in users. | ||||||
|  |      * | ||||||
|      * @return bool |      * @return bool | ||||||
|      */ |      */ | ||||||
|     public function authorize(): bool |     public function authorize(): bool | ||||||
| @@ -47,12 +48,15 @@ class TransactionRequest extends Request | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Get all data. Is pretty complex because of all the ??-statements. | ||||||
|  |      * | ||||||
|  |      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||||
|  |      * @SuppressWarnings(PHPMD.NPathComplexity) | ||||||
|      * @return array |      * @return array | ||||||
|      */ |      */ | ||||||
|     public function getAll(): array |     public function getAll(): array | ||||||
|     { |     { | ||||||
|         $data = [ |         $data = [ | ||||||
|             // basic fields for journal: |  | ||||||
|             'type'               => $this->string('type'), |             'type'               => $this->string('type'), | ||||||
|             'date'               => $this->date('date'), |             'date'               => $this->date('date'), | ||||||
|             'description'        => $this->string('description'), |             'description'        => $this->string('description'), | ||||||
| @@ -61,8 +65,6 @@ class TransactionRequest extends Request | |||||||
|             'bill_id'            => $this->integer('bill_id'), |             'bill_id'            => $this->integer('bill_id'), | ||||||
|             'bill_name'          => $this->string('bill_name'), |             'bill_name'          => $this->string('bill_name'), | ||||||
|             'tags'               => explode(',', $this->string('tags')), |             'tags'               => explode(',', $this->string('tags')), | ||||||
|  |  | ||||||
|             // then, custom fields for journal |  | ||||||
|             'interest_date'      => $this->date('interest_date'), |             'interest_date'      => $this->date('interest_date'), | ||||||
|             'book_date'          => $this->date('book_date'), |             'book_date'          => $this->date('book_date'), | ||||||
|             'process_date'       => $this->date('process_date'), |             'process_date'       => $this->date('process_date'), | ||||||
| @@ -71,39 +73,17 @@ class TransactionRequest extends Request | |||||||
|             'invoice_date'       => $this->date('invoice_date'), |             'invoice_date'       => $this->date('invoice_date'), | ||||||
|             'internal_reference' => $this->string('internal_reference'), |             'internal_reference' => $this->string('internal_reference'), | ||||||
|             'notes'              => $this->string('notes'), |             'notes'              => $this->string('notes'), | ||||||
|  |             'transactions'       => $this->getTransactionData(), | ||||||
|             // then, transactions (see below). |  | ||||||
|             'transactions'       => [], |  | ||||||
|  |  | ||||||
|         ]; |         ]; | ||||||
|         foreach ($this->get('transactions') as $index => $transaction) { |  | ||||||
|             $array                  = [ |  | ||||||
|                 'description'           => $transaction['description'] ?? null, |  | ||||||
|                 '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, |  | ||||||
|                 'reconciled'            => $transaction['reconciled'] ?? false, |  | ||||||
|                 'identifier'            => $index, |  | ||||||
|             ]; |  | ||||||
|             $data['transactions'][] = $array; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return $data; |         return $data; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * The rules that the incoming request must be matched against. | ||||||
|  |      * | ||||||
|      * @return array |      * @return array | ||||||
|  |      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||||
|      */ |      */ | ||||||
|     public function rules(): array |     public function rules(): array | ||||||
|     { |     { | ||||||
| @@ -148,13 +128,8 @@ class TransactionRequest extends Request | |||||||
|             'transactions.*.destination_name'      => 'between:1,255|nullable', |             'transactions.*.destination_name'      => 'between:1,255|nullable', | ||||||
|         ]; |         ]; | ||||||
|  |  | ||||||
|         switch ($this->method()) { |         if ('PUT' === $this->method()) { | ||||||
|             default: |             unset($rules['type'], $rules['piggy_bank_id'], $rules['piggy_bank_name']); | ||||||
|                 break; |  | ||||||
|             case 'PUT': |  | ||||||
|             case 'PATCH': |  | ||||||
|                 unset($rules['type'], $rules['piggy_bank_id'], $rules['piggy_bank_name']); |  | ||||||
|                 break; |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return $rules; |         return $rules; | ||||||
| @@ -173,11 +148,11 @@ class TransactionRequest extends Request | |||||||
|     { |     { | ||||||
|         $validator->after( |         $validator->after( | ||||||
|             function (Validator $validator) { |             function (Validator $validator) { | ||||||
|                 $this->atLeastOneTransaction($validator); |                 $this->validateOneTransaction($validator); | ||||||
|                 $this->checkValidDescriptions($validator); |                 $this->validateDescriptions($validator); | ||||||
|                 $this->equalToJournalDescription($validator); |                 $this->validateJournalDescription($validator); | ||||||
|                 $this->emptySplitDescriptions($validator); |                 $this->validateSplitDescriptions($validator); | ||||||
|                 $this->foreignCurrencyInformation($validator); |                 $this->validateForeignCurrencyInformation($validator); | ||||||
|                 $this->validateAccountInformation($validator); |                 $this->validateAccountInformation($validator); | ||||||
|                 $this->validateSplitAccounts($validator); |                 $this->validateSplitAccounts($validator); | ||||||
|             } |             } | ||||||
| @@ -185,329 +160,37 @@ class TransactionRequest extends Request | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Throws an error when this asset account is invalid. |      * Get transaction data. | ||||||
|      * |      * | ||||||
|      * @param Validator   $validator |      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||||
|      * @param int|null    $accountId |      * @SuppressWarnings(PHPMD.NPathComplexity) | ||||||
|      * @param null|string $accountName |      * @return array | ||||||
|      * @param string      $idField |  | ||||||
|      * @param string      $nameField |  | ||||||
|      * |  | ||||||
|      * @return null|Account |  | ||||||
|      */ |      */ | ||||||
|     protected function assetAccountExists(Validator $validator, ?int $accountId, ?string $accountName, string $idField, string $nameField): ?Account |     private function getTransactionData(): array | ||||||
|     { |     { | ||||||
|  |         $return = []; | ||||||
|         $accountId   = (int)$accountId; |         foreach ($this->get('transactions') as $index => $transaction) { | ||||||
|         $accountName = (string)$accountName; |             $return[] = [ | ||||||
|         // both empty? hard exit. |                 'description'           => $transaction['description'] ?? null, | ||||||
|         if ($accountId < 1 && \strlen($accountName) === 0) { |                 'amount'                => $transaction['amount'], | ||||||
|             $validator->errors()->add($idField, trans('validation.filled', ['attribute' => $idField])); |                 'currency_id'           => isset($transaction['currency_id']) ? (int)$transaction['currency_id'] : null, | ||||||
|  |                 'currency_code'         => $transaction['currency_code'] ?? null, | ||||||
|             return null; |                 'foreign_amount'        => $transaction['foreign_amount'] ?? null, | ||||||
|         } |                 'foreign_currency_id'   => isset($transaction['foreign_currency_id']) ? (int)$transaction['foreign_currency_id'] : null, | ||||||
|         // ID belongs to user and is asset account: |                 'foreign_currency_code' => $transaction['foreign_currency_code'] ?? null, | ||||||
|         /** @var AccountRepositoryInterface $repository */ |                 'budget_id'             => isset($transaction['budget_id']) ? (int)$transaction['budget_id'] : null, | ||||||
|         $repository = app(AccountRepositoryInterface::class); |                 'budget_name'           => $transaction['budget_name'] ?? null, | ||||||
|         $repository->setUser(auth()->user()); |                 'category_id'           => isset($transaction['category_id']) ? (int)$transaction['category_id'] : null, | ||||||
|         $set = $repository->getAccountsById([$accountId]); |                 'category_name'         => $transaction['category_name'] ?? null, | ||||||
|         if ($set->count() === 1) { |                 'source_id'             => isset($transaction['source_id']) ? (int)$transaction['source_id'] : null, | ||||||
|             /** @var Account $first */ |                 'source_name'           => isset($transaction['source_name']) ? (string)$transaction['source_name'] : null, | ||||||
|             $first = $set->first(); |                 'destination_id'        => isset($transaction['destination_id']) ? (int)$transaction['destination_id'] : null, | ||||||
|             if ($first->accountType->type !== AccountType::ASSET) { |                 'destination_name'      => isset($transaction['destination_name']) ? (string)$transaction['destination_name'] : null, | ||||||
|                 $validator->errors()->add($idField, trans('validation.belongs_user')); |                 'reconciled'            => $transaction['reconciled'] ?? false, | ||||||
|  |                 'identifier'            => $index, | ||||||
|                 return null; |             ]; | ||||||
|             } |  | ||||||
|  |  | ||||||
|             // we ignore the account name at this point. |  | ||||||
|             return $first; |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         $account = $repository->findByName($accountName, [AccountType::ASSET]); |         return $return; | ||||||
|         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 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')); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Adds an error to the "description" field when the user has submitted no descriptions and no |  | ||||||
|      * journal description. |  | ||||||
|      * |  | ||||||
|      * @param Validator $validator |  | ||||||
|      */ |  | ||||||
|     protected function checkValidDescriptions(Validator $validator) |  | ||||||
|     { |  | ||||||
|         $data               = $validator->getData(); |  | ||||||
|         $transactions       = $data['transactions'] ?? []; |  | ||||||
|         $journalDescription = (string)($data['description'] ?? ''); |  | ||||||
|         $validDescriptions  = 0; |  | ||||||
|         foreach ($transactions as $index => $transaction) { |  | ||||||
|             if (\strlen((string)($transaction['description'] ?? '')) > 0) { |  | ||||||
|                 $validDescriptions++; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // no valid descriptions and empty journal description? error. |  | ||||||
|         if ($validDescriptions === 0 && \strlen($journalDescription) === 0) { |  | ||||||
|             $validator->errors()->add('description', trans('validation.filled', ['attribute' => trans('validation.attributes.description')])); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Adds an error to the validator when the user submits a split transaction (more than 1 transactions) |  | ||||||
|      * but does not give them a description. |  | ||||||
|      * |  | ||||||
|      * @param Validator $validator |  | ||||||
|      */ |  | ||||||
|     protected function emptySplitDescriptions(Validator $validator): void |  | ||||||
|     { |  | ||||||
|         $data         = $validator->getData(); |  | ||||||
|         $transactions = $data['transactions'] ?? []; |  | ||||||
|         foreach ($transactions as $index => $transaction) { |  | ||||||
|             $description = (string)($transaction['description'] ?? ''); |  | ||||||
|             // filled description is mandatory for split transactions. |  | ||||||
|             if (\count($transactions) > 1 && \strlen($description) === 0) { |  | ||||||
|                 $validator->errors()->add( |  | ||||||
|                     'transactions.' . $index . '.description', |  | ||||||
|                     trans('validation.filled', ['attribute' => trans('validation.attributes.transaction_description')]) |  | ||||||
|                 ); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Adds an error to the validator when any transaction descriptions are equal to the journal description. |  | ||||||
|      * |  | ||||||
|      * @param Validator $validator |  | ||||||
|      */ |  | ||||||
|     protected function equalToJournalDescription(Validator $validator): void |  | ||||||
|     { |  | ||||||
|         $data               = $validator->getData(); |  | ||||||
|         $transactions       = $data['transactions'] ?? []; |  | ||||||
|         $journalDescription = (string)($data['description'] ?? ''); |  | ||||||
|         foreach ($transactions as $index => $transaction) { |  | ||||||
|             $description = (string)($transaction['description'] ?? ''); |  | ||||||
|             // description cannot be equal to journal description. |  | ||||||
|             if ($description === $journalDescription) { |  | ||||||
|                 $validator->errors()->add('transactions.' . $index . '.description', trans('validation.equal_description')); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 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. |  | ||||||
|      * |  | ||||||
|      * @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; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Validates the given account information. Switches on given transaction type. |  | ||||||
|      * |  | ||||||
|      * @param Validator $validator |  | ||||||
|      * |  | ||||||
|      * @throws FireflyException |  | ||||||
|      */ |  | ||||||
|     protected function validateAccountInformation(Validator $validator): void |  | ||||||
|     { |  | ||||||
|         $data         = $validator->getData(); |  | ||||||
|         $transactions = $data['transactions'] ?? []; |  | ||||||
|         if (!isset($data['type'])) { |  | ||||||
|             // the journal may exist in the request: |  | ||||||
|             /** @var Transaction $transaction */ |  | ||||||
|             $transaction = $this->route()->parameter('transaction'); |  | ||||||
|             if (null === $transaction) { |  | ||||||
|                 return; // @codeCoverageIgnore |  | ||||||
|             } |  | ||||||
|             $data['type'] = strtolower($transaction->transactionJournal->transactionType->type); |  | ||||||
|         } |  | ||||||
|         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 ($data['type']) { |  | ||||||
|                 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: |  | ||||||
|                     // @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')); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * @param Validator $validator |  | ||||||
|      * |  | ||||||
|      * @throws FireflyException |  | ||||||
|      */ |  | ||||||
|     protected function validateSplitAccounts(Validator $validator) |  | ||||||
|     { |  | ||||||
|         $data  = $validator->getData(); |  | ||||||
|         $count = isset($data['transactions']) ? \count($data['transactions']) : 0; |  | ||||||
|         if ($count < 2) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|         // this is pretty much impossible: |  | ||||||
|         // @codeCoverageIgnoreStart |  | ||||||
|         if (!isset($data['type'])) { |  | ||||||
|             // the journal may exist in the request: |  | ||||||
|             /** @var Transaction $transaction */ |  | ||||||
|             $transaction = $this->route()->parameter('transaction'); |  | ||||||
|             if (null === $transaction) { |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|             $data['type'] = strtolower($transaction->transactionJournal->transactionType->type); |  | ||||||
|         } |  | ||||||
|         // @codeCoverageIgnoreEnd |  | ||||||
|  |  | ||||||
|         // collect all source ID's and destination ID's, if present: |  | ||||||
|         $sources      = []; |  | ||||||
|         $destinations = []; |  | ||||||
|  |  | ||||||
|         foreach ($data['transactions'] as $transaction) { |  | ||||||
|             $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) { |  | ||||||
|                     $validator->errors()->add('transactions.0.source_id', trans('validation.all_accounts_equal')); |  | ||||||
|                 } |  | ||||||
|                 break; |  | ||||||
|             case 'deposit': |  | ||||||
|                 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) { |  | ||||||
|                     $validator->errors()->add('transactions.0.source_id', trans('validation.all_accounts_equal')); |  | ||||||
|                     $validator->errors()->add('transactions.0.destination_id', trans('validation.all_accounts_equal')); |  | ||||||
|                 } |  | ||||||
|                 break; |  | ||||||
|             default: |  | ||||||
|                 // @codeCoverageIgnoreStart |  | ||||||
|                 throw new FireflyException( |  | ||||||
|                     sprintf('The validator cannot handle transaction type "%s" in validateSplitAccounts().', $data['type']) |  | ||||||
|                 ); |  | ||||||
|             // @codeCoverageIgnoreEnd |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * UserRequest.php |  * UserRequest.php | ||||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
| @@ -20,9 +20,11 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Api\V1\Requests; | namespace FireflyIII\Api\V1\Requests; | ||||||
|  |  | ||||||
|  | use FireflyIII\Repositories\User\UserRepositoryInterface; | ||||||
| use FireflyIII\User; | use FireflyIII\User; | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -32,24 +34,32 @@ use FireflyIII\User; | |||||||
| class UserRequest extends Request | class UserRequest extends Request | ||||||
| { | { | ||||||
|     /** |     /** | ||||||
|  |      * Authorize logged in users. | ||||||
|  |      * | ||||||
|      * @return bool |      * @return bool | ||||||
|      */ |      */ | ||||||
|     public function authorize(): bool |     public function authorize(): bool | ||||||
|     { |     { | ||||||
|  |         $result = false; | ||||||
|         // Only allow authenticated users |         // Only allow authenticated users | ||||||
|         if (!auth()->check()) { |         if (auth()->check()) { | ||||||
|             return false; // @codeCoverageIgnore |             /** @var User $user */ | ||||||
|         } |             $user = auth()->user(); | ||||||
|         /** @var User $user */ |  | ||||||
|         $user = auth()->user(); |             /** @var UserRepositoryInterface $repository */ | ||||||
|         if (!$user->hasRole('owner')) { |             $repository = app(UserRepositoryInterface::class); | ||||||
|             return false; // @codeCoverageIgnore |  | ||||||
|  |             if ($repository->hasRole($user, 'owner')) { | ||||||
|  |                 $result = true; // @codeCoverageIgnore | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return true; |         return $result; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Get all data from the request. | ||||||
|  |      * | ||||||
|      * @return array |      * @return array | ||||||
|      */ |      */ | ||||||
|     public function getAll(): array |     public function getAll(): array | ||||||
| @@ -64,6 +74,8 @@ class UserRequest extends Request | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * The rules that the incoming request must be matched against. | ||||||
|  |      * | ||||||
|      * @return array |      * @return array | ||||||
|      */ |      */ | ||||||
|     public function rules(): array |     public function rules(): array | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * CreateExport.php |  * CreateExport.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +19,10 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | /** @noinspection MultipleReturnStatementsInspection */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Console\Commands; | namespace FireflyIII\Console\Commands; | ||||||
|  |  | ||||||
| use Carbon\Carbon; | use Carbon\Carbon; | ||||||
| @@ -36,10 +39,13 @@ use Storage; | |||||||
|  * Class CreateExport. |  * Class CreateExport. | ||||||
|  * |  * | ||||||
|  * Generates export from the command line. |  * Generates export from the command line. | ||||||
|  |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  */ |  */ | ||||||
| class CreateExport extends Command | class CreateExport extends Command | ||||||
| { | { | ||||||
|     use VerifiesAccessToken; |     use VerifiesAccessToken; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * The console command description. |      * The console command description. | ||||||
|      * |      * | ||||||
| @@ -62,9 +68,11 @@ class CreateExport extends Command | |||||||
|     /** |     /** | ||||||
|      * Execute the console command. |      * Execute the console command. | ||||||
|      * |      * | ||||||
|      * @return mixed |      * @return int | ||||||
|  |      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||||
|  |      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||||
|      */ |      */ | ||||||
|     public function handle() |     public function handle(): int | ||||||
|     { |     { | ||||||
|         if (!$this->verifyAccessToken()) { |         if (!$this->verifyAccessToken()) { | ||||||
|             $this->error('Invalid access token.'); |             $this->error('Invalid access token.'); | ||||||
| @@ -84,6 +92,9 @@ class CreateExport extends Command | |||||||
|  |  | ||||||
|         // set user |         // set user | ||||||
|         $user = $userRepository->findNull((int)$this->option('user')); |         $user = $userRepository->findNull((int)$this->option('user')); | ||||||
|  |         if (null === $user) { | ||||||
|  |             return 1; | ||||||
|  |         } | ||||||
|         $jobRepository->setUser($user); |         $jobRepository->setUser($user); | ||||||
|         $journalRepository->setUser($user); |         $journalRepository->setUser($user); | ||||||
|         $accountRepository->setUser($user); |         $accountRepository->setUser($user); | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * CreateImport.php |  * CreateImport.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,20 +19,26 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | /** @noinspection MultipleReturnStatementsInspection */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Console\Commands; | namespace FireflyIII\Console\Commands; | ||||||
|  |  | ||||||
|  | use Exception; | ||||||
| use FireflyIII\Exceptions\FireflyException; | use FireflyIII\Exceptions\FireflyException; | ||||||
|  | use FireflyIII\Import\Prerequisites\PrerequisitesInterface; | ||||||
| use FireflyIII\Import\Routine\RoutineInterface; | use FireflyIII\Import\Routine\RoutineInterface; | ||||||
|  | use FireflyIII\Import\Storage\ImportArrayStorage; | ||||||
| use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; | use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; | ||||||
| use FireflyIII\Repositories\User\UserRepositoryInterface; | use FireflyIII\Repositories\User\UserRepositoryInterface; | ||||||
| use FireflyIII\Services\Internal\File\EncryptService; |  | ||||||
| use Illuminate\Console\Command; | use Illuminate\Console\Command; | ||||||
| use Illuminate\Support\MessageBag; |  | ||||||
| use Log; | use Log; | ||||||
| use Preferences; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class CreateImport. |  * Class CreateImport. | ||||||
|  |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  */ |  */ | ||||||
| class CreateImport extends Command | class CreateImport extends Command | ||||||
| { | { | ||||||
| @@ -52,18 +57,17 @@ class CreateImport extends Command | |||||||
|      */ |      */ | ||||||
|     protected $signature |     protected $signature | ||||||
|         = 'firefly:create-import |         = 'firefly:create-import | ||||||
|                             {file : The file to import.} |                             {file? : The file to import.} | ||||||
|                             {configuration : The configuration file to use for the import.} |                             {configuration? : The configuration file to use for the import.} | ||||||
|                             {--type=csv : The file type of 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.} |                             {--token= : The user\'s access token.} | ||||||
|                             {--start : Starts the job immediately.}'; |                             {--start : Starts the job immediately.}'; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Run the command. |      * Run the command. | ||||||
|      * |      * | ||||||
|      * @noinspection MultipleReturnStatementsInspection |  | ||||||
|      * |  | ||||||
|      * @throws FireflyException |      * @throws FireflyException | ||||||
|      */ |      */ | ||||||
|     public function handle(): int |     public function handle(): int | ||||||
| @@ -74,79 +78,162 @@ class CreateImport extends Command | |||||||
|             return 1; |             return 1; | ||||||
|         } |         } | ||||||
|         /** @var UserRepositoryInterface $userRepository */ |         /** @var UserRepositoryInterface $userRepository */ | ||||||
|         $userRepository = app(UserRepositoryInterface::class); |         $userRepository    = app(UserRepositoryInterface::class); | ||||||
|         $file           = $this->argument('file'); |         $file              = (string)$this->argument('file'); | ||||||
|         $configuration  = $this->argument('configuration'); |         $configuration     = (string)$this->argument('configuration'); | ||||||
|         $user           = $userRepository->findNull((int)$this->option('user')); |         $user              = $userRepository->findNull((int)$this->option('user')); | ||||||
|         $cwd            = getcwd(); |         $cwd               = getcwd(); | ||||||
|         $type           = strtolower($this->option('type')); |         $provider          = strtolower((string)$this->option('provider')); | ||||||
|  |         $configurationData = []; | ||||||
|  |  | ||||||
|  |         if (null === $user) { | ||||||
|  |             $this->errorLine('User is NULL.'); | ||||||
|  |  | ||||||
|  |             return 1; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         if (!$this->validArguments()) { |         if (!$this->validArguments()) { | ||||||
|             $this->errorLine('Invalid arguments.'); |             $this->errorLine('Invalid arguments.'); | ||||||
|  |  | ||||||
|             return 1; |             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)); | ||||||
|  |  | ||||||
|         $configurationData = json_decode(file_get_contents($configuration), true); |                 return 1; | ||||||
|         if (null === $configurationData) { |             } | ||||||
|             $this->errorLine(sprintf('Firefly III cannot read the contents of configuration file "%s" (working directory: "%s").', $configuration, $cwd)); |  | ||||||
|  |  | ||||||
|             return 1; |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|         $this->infoLine(sprintf('Going to create a job to import file: %s', $file)); |         $this->infoLine(sprintf('Going to create a job to import file: %s', $file)); | ||||||
|         $this->infoLine(sprintf('Using configuration file: %s', $configuration)); |         $this->infoLine(sprintf('Using configuration file: %s', $configuration)); | ||||||
|         $this->infoLine(sprintf('Import into user: #%d (%s)', $user->id, $user->email)); |         $this->infoLine(sprintf('Import into user: #%d (%s)', $user->id, $user->email)); | ||||||
|         $this->infoLine(sprintf('Type of import: %s', $type)); |         $this->infoLine(sprintf('Type of import: %s', $provider)); | ||||||
|  |  | ||||||
|         /** @var ImportJobRepositoryInterface $jobRepository */ |         /** @var ImportJobRepositoryInterface $jobRepository */ | ||||||
|         $jobRepository = app(ImportJobRepositoryInterface::class); |         $jobRepository = app(ImportJobRepositoryInterface::class); | ||||||
|         $jobRepository->setUser($user); |         $jobRepository->setUser($user); | ||||||
|         $job = $jobRepository->create($type); |         $importJob = $jobRepository->create($provider); | ||||||
|         $this->infoLine(sprintf('Created job "%s"', $job->key)); |         $this->infoLine(sprintf('Created job "%s"', $importJob->key)); | ||||||
|  |  | ||||||
|         /** @var EncryptService $service */ |         // make sure that job has no prerequisites. | ||||||
|         $service = app(EncryptService::class); |         if ((bool)config(sprintf('import.has_prereq.%s', $provider))) { | ||||||
|         $service->encrypt($file, $job->key); |             // make prerequisites thing. | ||||||
|  |             $class = (string)config(sprintf('import.prerequisites.%s', $provider)); | ||||||
|         $this->infoLine('Stored import data...'); |             if (!class_exists($class)) { | ||||||
|  |                 throw new FireflyException(sprintf('No class to handle prerequisites for "%s".', $provider)); // @codeCoverageIgnore | ||||||
|         $jobRepository->setConfiguration($job, $configurationData); |  | ||||||
|         $jobRepository->updateStatus($job, 'configured'); |  | ||||||
|         $this->infoLine('Stored configuration...'); |  | ||||||
|  |  | ||||||
|         if (true === $this->option('start')) { |  | ||||||
|             $this->infoLine('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... |  | ||||||
|  |  | ||||||
|             // 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 |  | ||||||
|             } |             } | ||||||
|             /** @var RoutineInterface $routine */ |             /** @var PrerequisitesInterface $object */ | ||||||
|             $routine = app($className); |             $object = app($class); | ||||||
|             $routine->setJob($job); |             $object->setUser($user); | ||||||
|             $routine->run(); |             if (!$object->isComplete()) { | ||||||
|  |                 $this->errorLine(sprintf('Import provider "%s" has prerequisites that can only be filled in using the browser.', $provider)); | ||||||
|  |  | ||||||
|             // give feedback. |                 return 1; | ||||||
|             /** @var MessageBag $error */ |  | ||||||
|             foreach ($routine->getErrors() as $index => $error) { |  | ||||||
|                 $this->errorLine(sprintf('Error importing line #%d: %s', $index, $error)); |  | ||||||
|             } |             } | ||||||
|             $this->infoLine( |  | ||||||
|                 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 import routine 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 ('provider_finished' === $importJob->status) { | ||||||
|  |                 $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: |         // clear cache for user: | ||||||
|         Preferences::setForUser($user, 'lastActivity', microtime()); |         app('preferences')->setForUser($user, 'lastActivity', microtime()); | ||||||
|  |  | ||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
| @@ -180,25 +267,33 @@ class CreateImport extends Command | |||||||
|      */ |      */ | ||||||
|     private function validArguments(): bool |     private function validArguments(): bool | ||||||
|     { |     { | ||||||
|         $file          = $this->argument('file'); |         $file          = (string)$this->argument('file'); | ||||||
|         $configuration = $this->argument('configuration'); |         $configuration = (string)$this->argument('configuration'); | ||||||
|         $cwd           = getcwd(); |         $cwd           = getcwd(); | ||||||
|         $validTypes    = config('import.options.file.import_formats'); |         $validTypes    = config('import.options.file.import_formats'); | ||||||
|         $type          = strtolower($this->option('type')); |         $type          = strtolower($this->option('type')); | ||||||
|  |         $provider      = strtolower($this->option('provider')); | ||||||
|  |         $enabled       = (bool)config(sprintf('import.enabled.%s', $provider)); | ||||||
|  |  | ||||||
|         if (!\in_array($type, $validTypes, true)) { |         if (false === $enabled) { | ||||||
|  |             $this->errorLine(sprintf('Provider "%s" is not enabled.', $provider)); | ||||||
|  |  | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if ('file' === $provider && !\in_array($type, $validTypes, true)) { | ||||||
|             $this->errorLine(sprintf('Cannot import file of type "%s"', $type)); |             $this->errorLine(sprintf('Cannot import file of type "%s"', $type)); | ||||||
|  |  | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (!file_exists($file)) { |         if ('file' === $provider && !file_exists($file)) { | ||||||
|             $this->errorLine(sprintf('Firefly III cannot find file "%s" (working directory: "%s").', $file, $cwd)); |             $this->errorLine(sprintf('Firefly III cannot find file "%s" (working directory: "%s").', $file, $cwd)); | ||||||
|  |  | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (!file_exists($configuration)) { |         if ('file' === $provider && !file_exists($configuration)) { | ||||||
|             $this->errorLine(sprintf('Firefly III cannot find configuration file "%s" (working directory: "%s").', $configuration, $cwd)); |             $this->errorLine(sprintf('Firefly III cannot find configuration file "%s" (working directory: "%s").', $configuration, $cwd)); | ||||||
|  |  | ||||||
|             return false; |             return false; | ||||||
|   | |||||||
							
								
								
									
										67
									
								
								app/Console/Commands/Cron.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								app/Console/Commands/Cron.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace FireflyIII\Console\Commands; | ||||||
|  |  | ||||||
|  | use FireflyIII\Exceptions\FireflyException; | ||||||
|  | use FireflyIII\Support\Cronjobs\RecurringCronjob; | ||||||
|  | use Illuminate\Console\Command; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Class Cron | ||||||
|  |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  |  */ | ||||||
|  | class Cron extends Command | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * The console command description. | ||||||
|  |      * | ||||||
|  |      * @var string | ||||||
|  |      */ | ||||||
|  |     protected $description = 'Runs all Firefly III cron-job related commands. Configure a cron job according to the official Firefly III documentation.'; | ||||||
|  |     /** | ||||||
|  |      * The name and signature of the console command. | ||||||
|  |      * | ||||||
|  |      * @var string | ||||||
|  |      */ | ||||||
|  |     protected $signature = 'firefly:cron'; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Create a new command instance. | ||||||
|  |      * | ||||||
|  |      * @return void | ||||||
|  |      */ | ||||||
|  |     public function __construct() | ||||||
|  |     { | ||||||
|  |         parent::__construct(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Execute the console command. | ||||||
|  |      * | ||||||
|  |      * @return mixed | ||||||
|  |      */ | ||||||
|  |     public function handle(): int | ||||||
|  |     { | ||||||
|  |         $recurring = new RecurringCronjob; | ||||||
|  |         try { | ||||||
|  |             $result = $recurring->fire(); | ||||||
|  |         } catch (FireflyException $e) { | ||||||
|  |             $this->error($e->getMessage()); | ||||||
|  |  | ||||||
|  |             return 0; | ||||||
|  |         } | ||||||
|  |         if (false === $result) { | ||||||
|  |             $this->line('The recurring transaction cron job did not fire.'); | ||||||
|  |         } | ||||||
|  |         if (true === $result) { | ||||||
|  |             $this->line('The recurring transaction cron job fired successfully.'); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         $this->info('More feedback on the cron jobs can be found in the log files.'); | ||||||
|  |  | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -1,8 +1,7 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * DecryptAttachment.php |  * DecryptAttachment.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +19,10 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | /** @noinspection MultipleReturnStatementsInspection */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Console\Commands; | namespace FireflyIII\Console\Commands; | ||||||
|  |  | ||||||
| use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; | use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; | ||||||
| @@ -28,6 +31,8 @@ use Log; | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class DecryptAttachment. |  * Class DecryptAttachment. | ||||||
|  |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  */ |  */ | ||||||
| class DecryptAttachment extends Command | class DecryptAttachment extends Command | ||||||
| { | { | ||||||
| @@ -49,44 +54,45 @@ class DecryptAttachment extends Command | |||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Execute the console command. |      * Execute the console command. | ||||||
|      * |      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's five its fine. |  | ||||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) |      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||||
|  |      * | ||||||
|  |      * @return int | ||||||
|      */ |      */ | ||||||
|     public function handle() |     public function handle(): int | ||||||
|     { |     { | ||||||
|         /** @var AttachmentRepositoryInterface $repository */ |         /** @var AttachmentRepositoryInterface $repository */ | ||||||
|         $repository     = app(AttachmentRepositoryInterface::class); |         $repository     = app(AttachmentRepositoryInterface::class); | ||||||
|         $attachmentId   = (int)$this->argument('id'); |         $attachmentId   = (int)$this->argument('id'); | ||||||
|         $attachment     = $repository->findWithoutUser($attachmentId); |         $attachment     = $repository->findWithoutUser($attachmentId); | ||||||
|         $attachmentName = trim($this->argument('name')); |         $attachmentName = trim((string)$this->argument('name')); | ||||||
|         $storagePath    = realpath(trim($this->argument('directory'))); |         $storagePath    = realpath(trim((string)$this->argument('directory'))); | ||||||
|         if (null === $attachment->id) { |         if (null === $attachment) { | ||||||
|             $this->error(sprintf('No attachment with id #%d', $attachmentId)); |             $this->error(sprintf('No attachment with id #%d', $attachmentId)); | ||||||
|             Log::error(sprintf('DecryptAttachment: No attachment with id #%d', $attachmentId)); |             Log::error(sprintf('DecryptAttachment: No attachment with id #%d', $attachmentId)); | ||||||
|  |  | ||||||
|             return; |             return 1; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if ($attachmentName !== $attachment->filename) { |         if ($attachmentName !== $attachment->filename) { | ||||||
|             $this->error('File name does not match.'); |             $this->error('File name does not match.'); | ||||||
|             Log::error('DecryptAttachment: File name does not match.'); |             Log::error('DecryptAttachment: File name does not match.'); | ||||||
|  |  | ||||||
|             return; |             return 1; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (!is_dir($storagePath)) { |         if (!is_dir($storagePath)) { | ||||||
|             $this->error(sprintf('Path "%s" is not a directory.', $storagePath)); |             $this->error(sprintf('Path "%s" is not a directory.', $storagePath)); | ||||||
|             Log::error(sprintf('DecryptAttachment: Path "%s" is not a directory.', $storagePath)); |             Log::error(sprintf('DecryptAttachment: Path "%s" is not a directory.', $storagePath)); | ||||||
|  |  | ||||||
|             return; |             return 1; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (!is_writable($storagePath)) { |         if (!is_writable($storagePath)) { | ||||||
|             $this->error(sprintf('Path "%s" is not writable.', $storagePath)); |             $this->error(sprintf('Path "%s" is not writable.', $storagePath)); | ||||||
|             Log::error(sprintf('DecryptAttachment: Path "%s" is not writable.', $storagePath)); |             Log::error(sprintf('DecryptAttachment: Path "%s" is not writable.', $storagePath)); | ||||||
|  |  | ||||||
|             return; |             return 1; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         $fullPath = $storagePath . DIRECTORY_SEPARATOR . $attachment->filename; |         $fullPath = $storagePath . DIRECTORY_SEPARATOR . $attachment->filename; | ||||||
| @@ -96,9 +102,10 @@ class DecryptAttachment extends Command | |||||||
|         if (false === $result) { |         if (false === $result) { | ||||||
|             $this->error('Could not write to file.'); |             $this->error('Could not write to file.'); | ||||||
|  |  | ||||||
|             return; |             return 1; | ||||||
|         } |         } | ||||||
|         $this->info(sprintf('%d bytes written. Exiting now..', $result)); |         $this->info(sprintf('%d bytes written. Exiting now..', $result)); | ||||||
|  |  | ||||||
|  |         return 0; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * EncryptFile.php |  * EncryptFile.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +19,8 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Console\Commands; | namespace FireflyIII\Console\Commands; | ||||||
|  |  | ||||||
| use FireflyIII\Exceptions\FireflyException; | use FireflyIII\Exceptions\FireflyException; | ||||||
| @@ -28,6 +29,8 @@ use Illuminate\Console\Command; | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class EncryptFile. |  * Class EncryptFile. | ||||||
|  |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  */ |  */ | ||||||
| class EncryptFile extends Command | class EncryptFile extends Command | ||||||
| { | { | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * Import.php |  * Import.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,17 +19,24 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | /** @noinspection MultipleReturnStatementsInspection */ | ||||||
|  | /** @noinspection PhpDynamicAsStaticMethodCallInspection */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Console\Commands; | namespace FireflyIII\Console\Commands; | ||||||
|  |  | ||||||
| use FireflyIII\Exceptions\FireflyException; | use FireflyIII\Exceptions\FireflyException; | ||||||
| use FireflyIII\Import\Routine\RoutineInterface; | use FireflyIII\Import\Routine\RoutineInterface; | ||||||
| use FireflyIII\Models\ImportJob; | use FireflyIII\Models\ImportJob; | ||||||
|  | use FireflyIII\Models\Tag; | ||||||
| use Illuminate\Console\Command; | use Illuminate\Console\Command; | ||||||
| use Illuminate\Support\MessageBag; |  | ||||||
| use Log; | use Log; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class Import. |  * Class Import. | ||||||
|  |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  */ |  */ | ||||||
| class Import extends Command | class Import extends Command | ||||||
| { | { | ||||||
| @@ -50,23 +56,26 @@ class Import extends Command | |||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Run the import routine. |      * Run the import routine. | ||||||
|  |      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||||
|  |      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||||
|      * |      * | ||||||
|      * @throws FireflyException |      * @throws FireflyException | ||||||
|      */ |      */ | ||||||
|     public function handle() |     public function handle(): int | ||||||
|     { |     { | ||||||
|         Log::debug('Start start-import command'); |         Log::debug('Start start-import command'); | ||||||
|         $jobKey = $this->argument('key'); |         $jobKey = (string)$this->argument('key'); | ||||||
|         $job    = ImportJob::where('key', $jobKey)->first(); |         /** @var ImportJob $job */ | ||||||
|  |         $job = ImportJob::where('key', $jobKey)->first(); | ||||||
|         if (null === $job) { |         if (null === $job) { | ||||||
|             $this->errorLine(sprintf('No job found with key "%s"', $jobKey)); |             $this->errorLine(sprintf('No job found with key "%s"', $jobKey)); | ||||||
|  |  | ||||||
|             return; |             return 1; | ||||||
|         } |         } | ||||||
|         if (!$this->isValid($job)) { |         if (!$this->isValid($job)) { | ||||||
|             $this->errorLine('Job is not valid for some reason. Exit.'); |             $this->errorLine('Job is not valid for some reason. Exit.'); | ||||||
|  |  | ||||||
|             return; |             return 1; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         $this->infoLine(sprintf('Going to import job with key "%s" of type "%s"', $job->key, $job->file_type)); |         $this->infoLine(sprintf('Going to import job with key "%s" of type "%s"', $job->key, $job->file_type)); | ||||||
| @@ -81,21 +90,32 @@ class Import extends Command | |||||||
|  |  | ||||||
|         /** @var RoutineInterface $routine */ |         /** @var RoutineInterface $routine */ | ||||||
|         $routine = app($className); |         $routine = app($className); | ||||||
|         $routine->setJob($job); |         $routine->setImportJob($job); | ||||||
|         $routine->run(); |         $routine->run(); | ||||||
|  |  | ||||||
|         /** @var MessageBag $error */ |         /** | ||||||
|         foreach ($routine->getErrors() as $index => $error) { |          * @var int    $index | ||||||
|  |          * @var string $error | ||||||
|  |          */ | ||||||
|  |         foreach ($job->errors as $index => $error) { | ||||||
|             $this->errorLine(sprintf('Error importing line #%d: %s', $index, $error)); |             $this->errorLine(sprintf('Error importing line #%d: %s', $index, $error)); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         $this->infoLine( |         /** @var Tag $tag */ | ||||||
|             sprintf('The import has finished. %d transactions have been imported out of %d records.', $routine->getJournals()->count(), $routine->getLines()) |         $tag   = $job->tag()->first(); | ||||||
|         ); |         $count = 0; | ||||||
|  |         if (null === $tag) { | ||||||
|  |             $count = $tag->transactionJournals()->count(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         $this->infoLine(sprintf('The import has finished. %d transactions have been imported.', $count)); | ||||||
|  |  | ||||||
|  |         return 0; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Displays an error. | ||||||
|  |      * | ||||||
|      * @param string     $message |      * @param string     $message | ||||||
|      * @param array|null $data |      * @param array|null $data | ||||||
|      */ |      */ | ||||||
| @@ -107,6 +127,8 @@ class Import extends Command | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Displays an informational message. | ||||||
|  |      * | ||||||
|      * @param string $message |      * @param string $message | ||||||
|      * @param array  $data |      * @param array  $data | ||||||
|      */ |      */ | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * ScanAttachments.php |  * ScanAttachments.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +19,10 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | /** @noinspection PhpDynamicAsStaticMethodCallInspection */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Console\Commands; | namespace FireflyIII\Console\Commands; | ||||||
|  |  | ||||||
| use Crypt; | use Crypt; | ||||||
| @@ -31,6 +34,8 @@ use Storage; | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class ScanAttachments. |  * Class ScanAttachments. | ||||||
|  |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  */ |  */ | ||||||
| class ScanAttachments extends Command | class ScanAttachments extends Command | ||||||
| { | { | ||||||
| @@ -51,7 +56,7 @@ class ScanAttachments extends Command | |||||||
|     /** |     /** | ||||||
|      * Execute the console command. |      * Execute the console command. | ||||||
|      */ |      */ | ||||||
|     public function handle() |     public function handle(): int | ||||||
|     { |     { | ||||||
|         $attachments = Attachment::get(); |         $attachments = Attachment::get(); | ||||||
|         $disk        = Storage::disk('upload'); |         $disk        = Storage::disk('upload'); | ||||||
| @@ -61,13 +66,13 @@ class ScanAttachments extends Command | |||||||
|             try { |             try { | ||||||
|                 $content = $disk->get($fileName); |                 $content = $disk->get($fileName); | ||||||
|             } catch (FileNotFoundException $e) { |             } catch (FileNotFoundException $e) { | ||||||
|                 $this->error(sprintf('Could not find data for attachment #%d', $attachment->id)); |                 $this->error(sprintf('Could not find data for attachment #%d: %s', $attachment->id, $e->getMessage())); | ||||||
|                 continue; |                 continue; | ||||||
|             } |             } | ||||||
|             try { |             try { | ||||||
|                 $decrypted = Crypt::decrypt($content); |                 $decrypted = Crypt::decrypt($content); | ||||||
|             } catch (DecryptException $e) { |             } catch (DecryptException $e) { | ||||||
|                 $this->error(sprintf('Could not decrypt data of attachment #%d', $attachment->id)); |                 $this->error(sprintf('Could not decrypt data of attachment #%d: %s', $attachment->id, $e->getMessage())); | ||||||
|                 continue; |                 continue; | ||||||
|             } |             } | ||||||
|             $tmpfname = tempnam(sys_get_temp_dir(), 'FireflyIII'); |             $tmpfname = tempnam(sys_get_temp_dir(), 'FireflyIII'); | ||||||
| @@ -79,5 +84,7 @@ class ScanAttachments extends Command | |||||||
|             $attachment->save(); |             $attachment->save(); | ||||||
|             $this->line(sprintf('Fixed attachment #%d', $attachment->id)); |             $this->line(sprintf('Fixed attachment #%d', $attachment->id)); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         return 0; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * UpgradeDatabase.php |  * UpgradeDatabase.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +20,12 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | /** @noinspection MultipleReturnStatementsInspection */ | ||||||
|  | /** @noinspection PhpStaticAsDynamicMethodCallInspection */ | ||||||
|  | /** @noinspection PhpDynamicAsStaticMethodCallInspection */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Console\Commands; | namespace FireflyIII\Console\Commands; | ||||||
|  |  | ||||||
| use DB; | use DB; | ||||||
| @@ -40,22 +46,24 @@ use FireflyIII\Models\TransactionCurrency; | |||||||
| use FireflyIII\Models\TransactionJournal; | use FireflyIII\Models\TransactionJournal; | ||||||
| use FireflyIII\Models\TransactionJournalMeta; | use FireflyIII\Models\TransactionJournalMeta; | ||||||
| use FireflyIII\Models\TransactionType; | use FireflyIII\Models\TransactionType; | ||||||
|  | use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||||
| use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | ||||||
|  | use FireflyIII\Repositories\Journal\JournalRepositoryInterface; | ||||||
| use FireflyIII\User; | use FireflyIII\User; | ||||||
| use Illuminate\Console\Command; | use Illuminate\Console\Command; | ||||||
| use Illuminate\Database\QueryException; | use Illuminate\Database\QueryException; | ||||||
| use Illuminate\Support\Collection; | use Illuminate\Support\Collection; | ||||||
| use Log; | use Log; | ||||||
| use Preferences; |  | ||||||
| use Schema; | use Schema; | ||||||
|  | use UnexpectedValueException; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class UpgradeDatabase. |  * Class UpgradeDatabase. | ||||||
|  * |  * | ||||||
|  * Upgrade user database. |  * Upgrade user database. | ||||||
|  * |  * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) | ||||||
|  * |  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) // it just touches a lot of things. |  * @codeCoverageIgnore | ||||||
|  */ |  */ | ||||||
| class UpgradeDatabase extends Command | class UpgradeDatabase extends Command | ||||||
| { | { | ||||||
| @@ -75,7 +83,7 @@ class UpgradeDatabase extends Command | |||||||
|     /** |     /** | ||||||
|      * Execute the console command. |      * Execute the console command. | ||||||
|      */ |      */ | ||||||
|     public function handle() |     public function handle(): int | ||||||
|     { |     { | ||||||
|         $this->setTransactionIdentifier(); |         $this->setTransactionIdentifier(); | ||||||
|         $this->updateAccountCurrencies(); |         $this->updateAccountCurrencies(); | ||||||
| @@ -89,22 +97,39 @@ class UpgradeDatabase extends Command | |||||||
|         $this->migrateBillsToRules(); |         $this->migrateBillsToRules(); | ||||||
|  |  | ||||||
|         $this->info('Firefly III database is up to date.'); |         $this->info('Firefly III database is up to date.'); | ||||||
|  |  | ||||||
|  |         return 0; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public function migrateBillsToRules() |     /** | ||||||
|  |      * Since it is one routine these warnings make sense and should be supressed. | ||||||
|  |      * | ||||||
|  |      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||||
|  |      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||||
|  |      * @SuppressWarnings(PHPMD.NPathComplexity) | ||||||
|  |      */ | ||||||
|  |     public function migrateBillsToRules(): void | ||||||
|     { |     { | ||||||
|         foreach (User::get() as $user) { |         foreach (User::get() as $user) { | ||||||
|             /** @var Preference $lang */ |             /** @var Preference $lang */ | ||||||
|             $lang               = Preferences::getForUser($user, 'language', 'en_US'); |             $lang               = app('preferences')->getForUser($user, 'language', 'en_US'); | ||||||
|             $groupName          = (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data); |             $groupName          = (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data); | ||||||
|             $ruleGroup          = $user->ruleGroups()->where('title', $groupName)->first(); |             $ruleGroup          = $user->ruleGroups()->where('title', $groupName)->first(); | ||||||
|             $currencyPreference = Preferences::getForUser($user, 'currencyPreference', config('firefly.default_currency', 'EUR')); |             $currencyPreference = app('preferences')->getForUser($user, 'currencyPreference', config('firefly.default_currency', 'EUR')); | ||||||
|             $currency           = TransactionCurrency::where('code', $currencyPreference->data)->first(); |  | ||||||
|  |             if (null === $currencyPreference) { | ||||||
|  |                 $this->error('User has no currency preference. Impossible.'); | ||||||
|  |  | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             $currency = TransactionCurrency::where('code', $currencyPreference->data)->first(); | ||||||
|             if (null === $currency) { |             if (null === $currency) { | ||||||
|  |                 $this->line('Fall back to default currency in migrateBillsToRules().'); | ||||||
|                 $currency = app('amount')->getDefaultCurrency(); |                 $currency = app('amount')->getDefaultCurrency(); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if ($ruleGroup === null) { |             if (null === $ruleGroup) { | ||||||
|                 $array     = RuleGroup::get(['order'])->pluck('order')->toArray(); |                 $array     = RuleGroup::get(['order'])->pluck('order')->toArray(); | ||||||
|                 $order     = \count($array) > 0 ? max($array) + 1 : 1; |                 $order     = \count($array) > 0 ? max($array) + 1 : 1; | ||||||
|                 $ruleGroup = RuleGroup::create( |                 $ruleGroup = RuleGroup::create( | ||||||
| @@ -124,7 +149,7 @@ class UpgradeDatabase extends Command | |||||||
|             $collection = $user->bills()->get(); |             $collection = $user->bills()->get(); | ||||||
|             /** @var Bill $bill */ |             /** @var Bill $bill */ | ||||||
|             foreach ($collection as $bill) { |             foreach ($collection as $bill) { | ||||||
|                 if ($bill->match !== 'MIGRATED_TO_RULES') { |                 if ('MIGRATED_TO_RULES' !== $bill->match) { | ||||||
|                     $rule = Rule::create( |                     $rule = Rule::create( | ||||||
|                         [ |                         [ | ||||||
|                             'user_id'         => $user->id, |                             'user_id'         => $user->id, | ||||||
| @@ -159,28 +184,41 @@ class UpgradeDatabase extends Command | |||||||
|                             'order'           => 2, |                             'order'           => 2, | ||||||
|                         ] |                         ] | ||||||
|                     ); |                     ); | ||||||
|  |                     if ($bill->amount_max !== $bill->amount_min) { | ||||||
|                     // add triggers for amounts: |                         // add triggers for amounts: | ||||||
|                     RuleTrigger::create( |                         RuleTrigger::create( | ||||||
|                         [ |                             [ | ||||||
|                             'rule_id'         => $rule->id, |                                 'rule_id'         => $rule->id, | ||||||
|                             'trigger_type'    => 'amount_less', |                                 'trigger_type'    => 'amount_less', | ||||||
|                             'trigger_value'   => round($bill->amount_max, $currency->decimal_places), |                                 'trigger_value'   => round($bill->amount_max, $currency->decimal_places), | ||||||
|                             'active'          => 1, |                                 'active'          => 1, | ||||||
|                             'stop_processing' => 0, |                                 'stop_processing' => 0, | ||||||
|                             'order'           => 3, |                                 'order'           => 3, | ||||||
|                         ] |                             ] | ||||||
|                     ); |                         ); | ||||||
|                     RuleTrigger::create( |                         RuleTrigger::create( | ||||||
|                         [ |                             [ | ||||||
|                             'rule_id'         => $rule->id, |                                 'rule_id'         => $rule->id, | ||||||
|                             'trigger_type'    => 'amount_more', |                                 'trigger_type'    => 'amount_more', | ||||||
|                             'trigger_value'   => round($bill->amount_min, $currency->decimal_places), |                                 'trigger_value'   => round((float)$bill->amount_min, $currency->decimal_places), | ||||||
|                             'active'          => 1, |                                 'active'          => 1, | ||||||
|                             'stop_processing' => 0, |                                 'stop_processing' => 0, | ||||||
|                             'order'           => 4, |                                 'order'           => 4, | ||||||
|                         ] |                             ] | ||||||
|                     ); |                         ); | ||||||
|  |                     } | ||||||
|  |                     if ($bill->amount_max === $bill->amount_min) { | ||||||
|  |                         RuleTrigger::create( | ||||||
|  |                             [ | ||||||
|  |                                 'rule_id'         => $rule->id, | ||||||
|  |                                 'trigger_type'    => 'amount_exactly', | ||||||
|  |                                 'trigger_value'   => round((float)$bill->amount_min, $currency->decimal_places), | ||||||
|  |                                 'active'          => 1, | ||||||
|  |                                 'stop_processing' => 0, | ||||||
|  |                                 'order'           => 3, | ||||||
|  |                             ] | ||||||
|  |                         ); | ||||||
|  |                     } | ||||||
|  |  | ||||||
|                     // create action |                     // create action | ||||||
|                     RuleAction::create( |                     RuleAction::create( | ||||||
| @@ -245,23 +283,29 @@ class UpgradeDatabase extends Command | |||||||
|     /** |     /** | ||||||
|      * Each (asset) account must have a reference to a preferred currency. If the account does not have one, it's forced upon the account. |      * Each (asset) account must have a reference to a preferred currency. If the account does not have one, it's forced upon the account. | ||||||
|      * |      * | ||||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's seven but it can't really be helped. |      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) |      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||||
|      */ |      */ | ||||||
|     public function updateAccountCurrencies(): void |     public function updateAccountCurrencies(): void | ||||||
|     { |     { | ||||||
|         $accounts = Account::leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') |         $accounts = Account::leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') | ||||||
|                            ->whereIn('account_types.type', [AccountType::DEFAULT, AccountType::ASSET])->get(['accounts.*']); |                            ->whereIn('account_types.type', [AccountType::DEFAULT, AccountType::ASSET])->get(['accounts.*']); | ||||||
|  |         /** @var AccountRepositoryInterface $repository */ | ||||||
|  |         $repository = app(AccountRepositoryInterface::class); | ||||||
|         $accounts->each( |         $accounts->each( | ||||||
|             function (Account $account) { |             function (Account $account) use ($repository) { | ||||||
|  |                 $repository->setUser($account->user); | ||||||
|                 // get users preference, fall back to system pref. |                 // get users preference, fall back to system pref. | ||||||
|                 $defaultCurrencyCode = Preferences::getForUser($account->user, 'currencyPreference', config('firefly.default_currency', 'EUR'))->data; |                 $defaultCurrencyCode = app('preferences')->getForUser($account->user, 'currencyPreference', config('firefly.default_currency', 'EUR'))->data; | ||||||
|                 $defaultCurrency     = TransactionCurrency::where('code', $defaultCurrencyCode)->first(); |                 $defaultCurrency     = TransactionCurrency::where('code', $defaultCurrencyCode)->first(); | ||||||
|                 $accountCurrency     = (int)$account->getMeta('currency_id'); |                 $accountCurrency     = (int)$repository->getMetaValue($account, 'currency_id'); | ||||||
|                 $openingBalance      = $account->getOpeningBalance(); |                 $openingBalance      = $account->getOpeningBalance(); | ||||||
|                 $obCurrency          = (int)$openingBalance->transaction_currency_id; |                 $obCurrency          = (int)$openingBalance->transaction_currency_id; | ||||||
|  |  | ||||||
|  |                 if (null === $defaultCurrency) { | ||||||
|  |                     throw new UnexpectedValueException('The default currency is NULL, and this is more or less impossible.'); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|                 // both 0? set to default currency: |                 // both 0? set to default currency: | ||||||
|                 if (0 === $accountCurrency && 0 === $obCurrency) { |                 if (0 === $accountCurrency && 0 === $obCurrency) { | ||||||
|                     AccountMeta::where('account_id', $account->id)->where('name', 'currency_id')->forceDelete(); |                     AccountMeta::where('account_id', $account->id)->where('name', 'currency_id')->forceDelete(); | ||||||
| @@ -302,19 +346,22 @@ class UpgradeDatabase extends Command | |||||||
|      * Both source and destination must match the respective currency preference of the related asset account. |      * Both source and destination must match the respective currency preference of the related asset account. | ||||||
|      * So FF3 must verify all transactions. |      * So FF3 must verify all transactions. | ||||||
|      * |      * | ||||||
|  |      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) |      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||||
|      */ |      */ | ||||||
|     public function updateOtherCurrencies(): void |     public function updateOtherCurrencies(): void | ||||||
|     { |     { | ||||||
|         /** @var CurrencyRepositoryInterface $repository */ |         /** @var CurrencyRepositoryInterface $repository */ | ||||||
|         $repository = app(CurrencyRepositoryInterface::class); |         $repository = app(CurrencyRepositoryInterface::class); | ||||||
|         $set        = TransactionJournal |         /** @var AccountRepositoryInterface $accountRepos */ | ||||||
|  |         $accountRepos = app(AccountRepositoryInterface::class); | ||||||
|  |         $set          = TransactionJournal | ||||||
|             ::leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') |             ::leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') | ||||||
|             ->whereIn('transaction_types.type', [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::OPENING_BALANCE]) |             ->whereIn('transaction_types.type', [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::OPENING_BALANCE]) | ||||||
|             ->get(['transaction_journals.*']); |             ->get(['transaction_journals.*']); | ||||||
|  |  | ||||||
|         $set->each( |         $set->each( | ||||||
|             function (TransactionJournal $journal) use ($repository) { |             function (TransactionJournal $journal) use ($repository, $accountRepos) { | ||||||
|                 // get the transaction with the asset account in it: |                 // get the transaction with the asset account in it: | ||||||
|                 /** @var Transaction $transaction */ |                 /** @var Transaction $transaction */ | ||||||
|                 $transaction = $journal->transactions() |                 $transaction = $journal->transactions() | ||||||
| @@ -324,9 +371,13 @@ class UpgradeDatabase extends Command | |||||||
|                 if (null === $transaction) { |                 if (null === $transaction) { | ||||||
|                     return; |                     return; | ||||||
|                 } |                 } | ||||||
|  |                 $accountRepos->setUser($journal->user); | ||||||
|                 /** @var Account $account */ |                 /** @var Account $account */ | ||||||
|                 $account      = $transaction->account; |                 $account  = $transaction->account; | ||||||
|                 $currency     = $repository->find((int)$account->getMeta('currency_id')); |                 $currency = $repository->findNull((int)$accountRepos->getMetaValue($account, 'currency_id')); | ||||||
|  |                 if (null === $currency) { | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|                 $transactions = $journal->transactions()->get(); |                 $transactions = $journal->transactions()->get(); | ||||||
|                 $transactions->each( |                 $transactions->each( | ||||||
|                     function (Transaction $transaction) use ($currency) { |                     function (Transaction $transaction) use ($currency) { | ||||||
| @@ -362,7 +413,7 @@ class UpgradeDatabase extends Command | |||||||
|      * Both source and destination must match the respective currency preference. So FF3 must verify ALL |      * Both source and destination must match the respective currency preference. So FF3 must verify ALL | ||||||
|      * transactions. |      * transactions. | ||||||
|      */ |      */ | ||||||
|     public function updateTransferCurrencies() |     public function updateTransferCurrencies(): void | ||||||
|     { |     { | ||||||
|         $set = TransactionJournal |         $set = TransactionJournal | ||||||
|             ::leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') |             ::leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') | ||||||
| @@ -434,6 +485,7 @@ class UpgradeDatabase extends Command | |||||||
|      */ |      */ | ||||||
|     private function migrateNotes(): void |     private function migrateNotes(): void | ||||||
|     { |     { | ||||||
|  |         /** @noinspection PhpUndefinedMethodInspection */ | ||||||
|         $set = TransactionJournalMeta::whereName('notes')->get(); |         $set = TransactionJournalMeta::whereName('notes')->get(); | ||||||
|         /** @var TransactionJournalMeta $meta */ |         /** @var TransactionJournalMeta $meta */ | ||||||
|         foreach ($set as $meta) { |         foreach ($set as $meta) { | ||||||
| @@ -464,8 +516,15 @@ class UpgradeDatabase extends Command | |||||||
|     { |     { | ||||||
|         /** @var CurrencyRepositoryInterface $repository */ |         /** @var CurrencyRepositoryInterface $repository */ | ||||||
|         $repository = app(CurrencyRepositoryInterface::class); |         $repository = app(CurrencyRepositoryInterface::class); | ||||||
|         $currency   = $repository->find((int)$transaction->account->getMeta('currency_id')); |         /** @var AccountRepositoryInterface $accountRepos */ | ||||||
|         $journal    = $transaction->transactionJournal; |         $accountRepos = app(AccountRepositoryInterface::class); | ||||||
|  |         $accountRepos->setUser($transaction->account->user); | ||||||
|  |         $currency = $repository->findNull((int)$accountRepos->getMetaValue($transaction->account, 'currency_id')); | ||||||
|  |         $journal  = $transaction->transactionJournal; | ||||||
|  |  | ||||||
|  |         if (null === $currency) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         if (!((int)$currency->id === (int)$journal->transaction_currency_id)) { |         if (!((int)$currency->id === (int)$journal->transaction_currency_id)) { | ||||||
|             $this->line( |             $this->line( | ||||||
| @@ -534,11 +593,11 @@ class UpgradeDatabase extends Command | |||||||
|      * |      * | ||||||
|      * The transaction that is sent to this function MUST be the source transaction (amount negative). |      * The transaction that is sent to this function MUST be the source transaction (amount negative). | ||||||
|      * |      * | ||||||
|      * Method is long and complex bit I'm taking it for granted. |      * Method is long and complex but I'll allow it. https://imgur.com/gallery/dVDJiez | ||||||
|      * |      * | ||||||
|  |      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) |      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||||
|      * @SuppressWarnings(PHPMD.NPathComplexity) |      * @SuppressWarnings(PHPMD.NPathComplexity) | ||||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) |  | ||||||
|      * |      * | ||||||
|      * @param Transaction $transaction |      * @param Transaction $transaction | ||||||
|      */ |      */ | ||||||
| @@ -546,7 +605,14 @@ class UpgradeDatabase extends Command | |||||||
|     { |     { | ||||||
|         /** @var CurrencyRepositoryInterface $repository */ |         /** @var CurrencyRepositoryInterface $repository */ | ||||||
|         $repository = app(CurrencyRepositoryInterface::class); |         $repository = app(CurrencyRepositoryInterface::class); | ||||||
|         $currency   = $repository->findNull((int)$transaction->account->getMeta('currency_id')); |         /** @var AccountRepositoryInterface $accountRepos */ | ||||||
|  |         $accountRepos = app(AccountRepositoryInterface::class); | ||||||
|  |         /** @var JournalRepositoryInterface $journalRepos */ | ||||||
|  |         $journalRepos = app(JournalRepositoryInterface::class); | ||||||
|  |  | ||||||
|  |         $accountRepos->setUser($transaction->account->user); | ||||||
|  |         $journalRepos->setUser($transaction->account->user); | ||||||
|  |         $currency = $repository->findNull((int)$accountRepos->getMetaValue($transaction->account, 'currency_id')); | ||||||
|  |  | ||||||
|         if (null === $currency) { |         if (null === $currency) { | ||||||
|             Log::error(sprintf('Account #%d ("%s") must have currency preference but has none.', $transaction->account->id, $transaction->account->name)); |             Log::error(sprintf('Account #%d ("%s") must have currency preference but has none.', $transaction->account->id, $transaction->account->name)); | ||||||
| @@ -582,7 +648,7 @@ class UpgradeDatabase extends Command | |||||||
|         $journal = $transaction->transactionJournal; |         $journal = $transaction->transactionJournal; | ||||||
|         /** @var Transaction $opposing */ |         /** @var Transaction $opposing */ | ||||||
|         $opposing         = $journal->transactions()->where('amount', '>', 0)->where('identifier', $transaction->identifier)->first(); |         $opposing         = $journal->transactions()->where('amount', '>', 0)->where('identifier', $transaction->identifier)->first(); | ||||||
|         $opposingCurrency = $repository->findNull((int)$opposing->account->getMeta('currency_id')); |         $opposingCurrency = $repository->findNull((int)$accountRepos->getMetaValue($opposing->account, 'currency_id')); | ||||||
|  |  | ||||||
|         if (null === $opposingCurrency) { |         if (null === $opposingCurrency) { | ||||||
|             Log::error(sprintf('Account #%d ("%s") must have currency preference but has none.', $opposing->account->id, $opposing->account->name)); |             Log::error(sprintf('Account #%d ("%s") must have currency preference but has none.', $opposing->account->id, $opposing->account->name)); | ||||||
| @@ -600,12 +666,16 @@ class UpgradeDatabase extends Command | |||||||
|             $opposing->transaction_currency_id = $currency->id; |             $opposing->transaction_currency_id = $currency->id; | ||||||
|             $transaction->save(); |             $transaction->save(); | ||||||
|             $opposing->save(); |             $opposing->save(); | ||||||
|             Log::debug(sprintf('Currency for account "%s" is %s, and currency for account "%s" is also |             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.', |              %s, so %s #%d (#%d and #%d) has been verified to be to %s exclusively.', | ||||||
|                                $opposing->account->name, $opposingCurrency->code, |                     $opposing->account->name, $opposingCurrency->code, | ||||||
|                                $transaction->account->name, $transaction->transactionCurrency->code, |                     $transaction->account->name, $transaction->transactionCurrency->code, | ||||||
|                                $journal->transactionType->type, $journal->id, |                     $journal->transactionType->type, $journal->id, | ||||||
|                                $transaction->id, $opposing->id, $currency->code)); |                     $transaction->id, $opposing->id, $currency->code | ||||||
|  |                 ) | ||||||
|  |             ); | ||||||
|  |  | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| @@ -634,7 +704,7 @@ class UpgradeDatabase extends Command | |||||||
|  |  | ||||||
|         // when both are zero, try to grab it from journal: |         // when both are zero, try to grab it from journal: | ||||||
|         if (null === $opposing->foreign_amount && null === $transaction->foreign_amount) { |         if (null === $opposing->foreign_amount && null === $transaction->foreign_amount) { | ||||||
|             $foreignAmount = $journal->getMeta('foreign_amount'); |             $foreignAmount = $journalRepos->getMetaField($journal, 'foreign_amount'); | ||||||
|             if (null === $foreignAmount) { |             if (null === $foreignAmount) { | ||||||
|                 Log::debug(sprintf('Journal #%d has missing foreign currency data, forced to do 1:1 conversion :(.', $transaction->transaction_journal_id)); |                 Log::debug(sprintf('Journal #%d has missing foreign currency data, forced to do 1:1 conversion :(.', $transaction->transaction_journal_id)); | ||||||
|                 $transaction->foreign_amount = bcmul((string)$transaction->amount, '-1'); |                 $transaction->foreign_amount = bcmul((string)$transaction->amount, '-1'); | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * UpgradeFireflyInstructions.php |  * UpgradeFireflyInstructions.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,12 +19,16 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Console\Commands; | namespace FireflyIII\Console\Commands; | ||||||
|  |  | ||||||
| use Illuminate\Console\Command; | use Illuminate\Console\Command; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class UpgradeFireflyInstructions. |  * Class UpgradeFireflyInstructions. | ||||||
|  |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  */ |  */ | ||||||
| class UpgradeFireflyInstructions extends Command | class UpgradeFireflyInstructions extends Command | ||||||
| { | { | ||||||
| @@ -45,14 +48,16 @@ class UpgradeFireflyInstructions extends Command | |||||||
|     /** |     /** | ||||||
|      * Execute the console command. |      * Execute the console command. | ||||||
|      */ |      */ | ||||||
|     public function handle() |     public function handle(): int | ||||||
|     { |     { | ||||||
|         if ('update' === $this->argument('task')) { |         if ('update' === (string)$this->argument('task')) { | ||||||
|             $this->updateInstructions(); |             $this->updateInstructions(); | ||||||
|         } |         } | ||||||
|         if ('install' === $this->argument('task')) { |         if ('install' === (string)$this->argument('task')) { | ||||||
|             $this->installInstructions(); |             $this->installInstructions(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         return 0; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -60,7 +65,7 @@ class UpgradeFireflyInstructions extends Command | |||||||
|      * |      * | ||||||
|      * @param string $text |      * @param string $text | ||||||
|      */ |      */ | ||||||
|     private function boxed(string $text) |     private function boxed(string $text): void | ||||||
|     { |     { | ||||||
|         $parts = explode("\n", wordwrap($text)); |         $parts = explode("\n", wordwrap($text)); | ||||||
|         foreach ($parts as $string) { |         foreach ($parts as $string) { | ||||||
| @@ -73,7 +78,7 @@ class UpgradeFireflyInstructions extends Command | |||||||
|      * |      * | ||||||
|      * @param string $text |      * @param string $text | ||||||
|      */ |      */ | ||||||
|     private function boxedInfo(string $text) |     private function boxedInfo(string $text): void | ||||||
|     { |     { | ||||||
|         $parts = explode("\n", wordwrap($text)); |         $parts = explode("\n", wordwrap($text)); | ||||||
|         foreach ($parts as $string) { |         foreach ($parts as $string) { | ||||||
| @@ -84,7 +89,7 @@ class UpgradeFireflyInstructions extends Command | |||||||
|     /** |     /** | ||||||
|      * Render instructions. |      * Render instructions. | ||||||
|      */ |      */ | ||||||
|     private function installInstructions() |     private function installInstructions(): void | ||||||
|     { |     { | ||||||
|         /** @var string $version */ |         /** @var string $version */ | ||||||
|         $version = config('firefly.version'); |         $version = config('firefly.version'); | ||||||
| @@ -92,8 +97,7 @@ class UpgradeFireflyInstructions extends Command | |||||||
|         $text    = ''; |         $text    = ''; | ||||||
|         foreach (array_keys($config) as $compare) { |         foreach (array_keys($config) as $compare) { | ||||||
|             // if string starts with: |             // if string starts with: | ||||||
|             $len = \strlen($compare); |             if (0 === strpos($version, $compare)) { | ||||||
|             if (substr($version, 0, $len) === $compare) { |  | ||||||
|                 $text = $config[$compare]; |                 $text = $config[$compare]; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @@ -118,7 +122,7 @@ class UpgradeFireflyInstructions extends Command | |||||||
|     /** |     /** | ||||||
|      * Show a line. |      * Show a line. | ||||||
|      */ |      */ | ||||||
|     private function showLine() |     private function showLine(): void | ||||||
|     { |     { | ||||||
|         $line = '+'; |         $line = '+'; | ||||||
|         for ($i = 0; $i < 78; ++$i) { |         for ($i = 0; $i < 78; ++$i) { | ||||||
| @@ -131,7 +135,7 @@ class UpgradeFireflyInstructions extends Command | |||||||
|     /** |     /** | ||||||
|      * Render upgrade instructions. |      * Render upgrade instructions. | ||||||
|      */ |      */ | ||||||
|     private function updateInstructions() |     private function updateInstructions(): void | ||||||
|     { |     { | ||||||
|         /** @var string $version */ |         /** @var string $version */ | ||||||
|         $version = config('firefly.version'); |         $version = config('firefly.version'); | ||||||
| @@ -139,8 +143,7 @@ class UpgradeFireflyInstructions extends Command | |||||||
|         $text    = ''; |         $text    = ''; | ||||||
|         foreach (array_keys($config) as $compare) { |         foreach (array_keys($config) as $compare) { | ||||||
|             // if string starts with: |             // if string starts with: | ||||||
|             $len = \strlen($compare); |             if (0 === strpos($version, $compare)) { | ||||||
|             if (substr($version, 0, $len) === $compare) { |  | ||||||
|                 $text = $config[$compare]; |                 $text = $config[$compare]; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -1,9 +1,7 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * UseEncryption.php |  * UseEncryption.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -21,6 +19,8 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Console\Commands; | namespace FireflyIII\Console\Commands; | ||||||
|  |  | ||||||
| use Illuminate\Console\Command; | use Illuminate\Console\Command; | ||||||
| @@ -28,6 +28,7 @@ use Illuminate\Support\Str; | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class UseEncryption. |  * Class UseEncryption. | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  */ |  */ | ||||||
| class UseEncryption extends Command | class UseEncryption extends Command | ||||||
| { | { | ||||||
| @@ -47,12 +48,12 @@ class UseEncryption extends Command | |||||||
|     /** |     /** | ||||||
|      * Execute the console command. |      * Execute the console command. | ||||||
|      */ |      */ | ||||||
|     public function handle() |     public function handle(): int | ||||||
|     { |     { | ||||||
|         if (config('firefly.encryption') === true) { |         if (true === config('firefly.encryption')) { | ||||||
|             $this->info('Firefly III configuration calls for encrypted data.'); |             $this->info('Firefly III configuration calls for encrypted data.'); | ||||||
|         } |         } | ||||||
|         if (config('firefly.encryption') === false) { |         if (false === config('firefly.encryption')) { | ||||||
|             $this->info('Firefly III configuration calls for unencrypted data.'); |             $this->info('Firefly III configuration calls for unencrypted data.'); | ||||||
|         } |         } | ||||||
|         $this->handleObjects('Account', 'name', 'encrypted'); |         $this->handleObjects('Account', 'name', 'encrypted'); | ||||||
| @@ -62,6 +63,8 @@ class UseEncryption extends Command | |||||||
|         $this->handleObjects('Category', 'name', 'encrypted'); |         $this->handleObjects('Category', 'name', 'encrypted'); | ||||||
|         $this->handleObjects('PiggyBank', 'name', 'encrypted'); |         $this->handleObjects('PiggyBank', 'name', 'encrypted'); | ||||||
|         $this->handleObjects('TransactionJournal', 'description', 'encrypted'); |         $this->handleObjects('TransactionJournal', 'description', 'encrypted'); | ||||||
|  |  | ||||||
|  |         return 0; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -71,18 +74,21 @@ class UseEncryption extends Command | |||||||
|      * @param string $field |      * @param string $field | ||||||
|      * @param string $indicator |      * @param string $indicator | ||||||
|      */ |      */ | ||||||
|     public function handleObjects(string $class, string $field, string $indicator) |     public function handleObjects(string $class, string $field, string $indicator): void | ||||||
|     { |     { | ||||||
|         $fqn     = sprintf('FireflyIII\Models\%s', $class); |         $fqn     = sprintf('FireflyIII\Models\%s', $class); | ||||||
|         $encrypt = config('firefly.encryption') === true ? 0 : 1; |         $encrypt = true === config('firefly.encryption') ? 0 : 1; | ||||||
|         $set     = $fqn::where($indicator, $encrypt)->get(); |         /** @noinspection PhpUndefinedMethodInspection */ | ||||||
|  |         $set = $fqn::where($indicator, $encrypt)->get(); | ||||||
|  |  | ||||||
|         foreach ($set as $entry) { |         foreach ($set as $entry) { | ||||||
|             $newName       = $entry->$field; |             $newName       = $entry->$field; | ||||||
|             $entry->$field = $newName; |             $entry->$field = $newName; | ||||||
|  |             /** @noinspection PhpUndefinedMethodInspection */ | ||||||
|             $entry->save(); |             $entry->save(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         /** @noinspection PhpUndefinedMethodInspection */ | ||||||
|         $this->line(sprintf('Updated %d %s.', $set->count(), strtolower(Str::plural($class)))); |         $this->line(sprintf('Updated %d %s.', $set->count(), strtolower(Str::plural($class)))); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * VerifiesAccessToken.php |  * VerifiesAccessToken.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,16 +19,18 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Console\Commands; | namespace FireflyIII\Console\Commands; | ||||||
|  |  | ||||||
| use FireflyIII\Repositories\User\UserRepositoryInterface; | use FireflyIII\Repositories\User\UserRepositoryInterface; | ||||||
| use Log; | use Log; | ||||||
| use Preferences; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Trait VerifiesAccessToken. |  * Trait VerifiesAccessToken. | ||||||
|  * |  * | ||||||
|  * Verifies user access token for sensitive commands. |  * Verifies user access token for sensitive commands. | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  */ |  */ | ||||||
| trait VerifiesAccessToken | trait VerifiesAccessToken | ||||||
| { | { | ||||||
| @@ -60,7 +61,7 @@ trait VerifiesAccessToken | |||||||
|  |  | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|         $accessToken = Preferences::getForUser($user, 'access_token', null); |         $accessToken = app('preferences')->getForUser($user, 'access_token', null); | ||||||
|         if (null === $accessToken) { |         if (null === $accessToken) { | ||||||
|             Log::error(sprintf('User #%d has no access token, so cannot access command line options.', $userId)); |             Log::error(sprintf('User #%d has no access token, so cannot access command line options.', $userId)); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * VerifyDatabase.php |  * VerifyDatabase.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +19,10 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | /** @noinspection PhpDynamicAsStaticMethodCallInspection */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Console\Commands; | namespace FireflyIII\Console\Commands; | ||||||
|  |  | ||||||
| use Crypt; | use Crypt; | ||||||
| @@ -27,6 +30,7 @@ use DB; | |||||||
| use FireflyIII\Models\Account; | use FireflyIII\Models\Account; | ||||||
| use FireflyIII\Models\AccountType; | use FireflyIII\Models\AccountType; | ||||||
| use FireflyIII\Models\Budget; | use FireflyIII\Models\Budget; | ||||||
|  | use FireflyIII\Models\Category; | ||||||
| use FireflyIII\Models\LinkType; | use FireflyIII\Models\LinkType; | ||||||
| use FireflyIII\Models\PiggyBankEvent; | use FireflyIII\Models\PiggyBankEvent; | ||||||
| use FireflyIII\Models\Transaction; | use FireflyIII\Models\Transaction; | ||||||
| @@ -37,14 +41,16 @@ use FireflyIII\User; | |||||||
| use Illuminate\Console\Command; | use Illuminate\Console\Command; | ||||||
| use Illuminate\Contracts\Encryption\DecryptException; | use Illuminate\Contracts\Encryption\DecryptException; | ||||||
| use Illuminate\Database\Eloquent\Builder; | use Illuminate\Database\Eloquent\Builder; | ||||||
| use Preferences; | use Log; | ||||||
| use Schema; | use Schema; | ||||||
| use stdClass; | use stdClass; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class VerifyDatabase. |  * Class VerifyDatabase. | ||||||
|  * |  * | ||||||
|  |  * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) | ||||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) |  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  */ |  */ | ||||||
| class VerifyDatabase extends Command | class VerifyDatabase extends Command | ||||||
| { | { | ||||||
| @@ -64,15 +70,15 @@ class VerifyDatabase extends Command | |||||||
|     /** |     /** | ||||||
|      * Execute the console command. |      * Execute the console command. | ||||||
|      */ |      */ | ||||||
|     public function handle() |     public function handle(): int | ||||||
|     { |     { | ||||||
|         // if table does not exist, return false |         // if table does not exist, return false | ||||||
|         if (!Schema::hasTable('users')) { |         if (!Schema::hasTable('users')) { | ||||||
|             return; |             return 1; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         $this->reportObject('budget'); |         $this->reportEmptyBudgets(); | ||||||
|         $this->reportObject('category'); |         $this->reportEmptyCategories(); | ||||||
|         $this->reportObject('tag'); |         $this->reportObject('tag'); | ||||||
|         $this->reportAccounts(); |         $this->reportAccounts(); | ||||||
|         $this->reportBudgetLimits(); |         $this->reportBudgetLimits(); | ||||||
| @@ -88,6 +94,9 @@ class VerifyDatabase extends Command | |||||||
|         $this->createAccessTokens(); |         $this->createAccessTokens(); | ||||||
|         $this->fixDoubleAmounts(); |         $this->fixDoubleAmounts(); | ||||||
|         $this->fixBadMeta(); |         $this->fixBadMeta(); | ||||||
|  |         $this->removeBills(); | ||||||
|  |  | ||||||
|  |         return 0; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -99,10 +108,10 @@ class VerifyDatabase extends Command | |||||||
|         $users = User::get(); |         $users = User::get(); | ||||||
|         /** @var User $user */ |         /** @var User $user */ | ||||||
|         foreach ($users as $user) { |         foreach ($users as $user) { | ||||||
|             $pref = Preferences::getForUser($user, 'access_token', null); |             $pref = app('preferences')->getForUser($user, 'access_token', null); | ||||||
|             if (null === $pref) { |             if (null === $pref) { | ||||||
|                 $token = $user->generateAccessToken(); |                 $token = $user->generateAccessToken(); | ||||||
|                 Preferences::setForUser($user, 'access_token', $token); |                 app('preferences')->setForUser($user, 'access_token', $token); | ||||||
|                 $this->line(sprintf('Generated access token for user %s', $user->email)); |                 $this->line(sprintf('Generated access token for user %s', $user->email)); | ||||||
|                 ++$count; |                 ++$count; | ||||||
|             } |             } | ||||||
| @@ -142,9 +151,10 @@ class VerifyDatabase extends Command | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Fix the situation where the matching transactions |      * Fix the situation where the matching transactions of a journal somehow have non-matching categories or budgets. | ||||||
|      * of a journal somehow have non-matching categories |      * | ||||||
|      * or budgets |      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||||
|  |      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||||
|      */ |      */ | ||||||
|     private function fixBadMeta(): void |     private function fixBadMeta(): void | ||||||
|     { |     { | ||||||
| @@ -162,7 +172,8 @@ class VerifyDatabase extends Command | |||||||
|             if (isset($results[$key]) && $results[$key] !== $category) { |             if (isset($results[$key]) && $results[$key] !== $category) { | ||||||
|                 $this->error( |                 $this->error( | ||||||
|                     sprintf( |                     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] |                         '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]]); |                 DB::table('category_transaction')->where('id', $obj->ct_id)->update(['category_id' => $results[$key]]); | ||||||
| @@ -182,14 +193,15 @@ class VerifyDatabase extends Command | |||||||
|             ->get(['transactions.id', 'transaction_journal_id', 'identifier', 'budget_transaction.budget_id', 'budget_transaction.id as ct_id']); |             ->get(['transactions.id', 'transaction_journal_id', 'identifier', 'budget_transaction.budget_id', 'budget_transaction.id as ct_id']); | ||||||
|         $results = []; |         $results = []; | ||||||
|         foreach ($set as $obj) { |         foreach ($set as $obj) { | ||||||
|             $key      = $obj->transaction_journal_id . '-' . $obj->identifier; |             $key    = $obj->transaction_journal_id . '-' . $obj->identifier; | ||||||
|             $budget = (int)$obj->budget_id; |             $budget = (int)$obj->budget_id; | ||||||
|  |  | ||||||
|             // value exists and is not budget: |             // value exists and is not budget: | ||||||
|             if (isset($results[$key]) && $results[$key] !== $budget) { |             if (isset($results[$key]) && $results[$key] !== $budget) { | ||||||
|                 $this->error( |                 $this->error( | ||||||
|                     sprintf( |                     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] |                         '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]]); |                 DB::table('budget_transaction')->where('id', $obj->ct_id)->update(['budget_id' => $results[$key]]); | ||||||
| @@ -203,6 +215,12 @@ class VerifyDatabase extends Command | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Makes sure amounts are stored correctly. | ||||||
|  |      * | ||||||
|  |      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||||
|  |      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||||
|  |      */ | ||||||
|     private function fixDoubleAmounts(): void |     private function fixDoubleAmounts(): void | ||||||
|     { |     { | ||||||
|         $count = 0; |         $count = 0; | ||||||
| @@ -251,6 +269,23 @@ class VerifyDatabase extends Command | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Removes bills from journals that should not have bills. | ||||||
|  |      */ | ||||||
|  |     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(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Eeport (and fix) piggy banks. Make sure there are only transfers linked to piggy bank events. |      * Eeport (and fix) piggy banks. Make sure there are only transfers linked to piggy bank events. | ||||||
|      */ |      */ | ||||||
| @@ -283,7 +318,7 @@ class VerifyDatabase extends Command | |||||||
|     /** |     /** | ||||||
|      * Reports on accounts with no transactions. |      * Reports on accounts with no transactions. | ||||||
|      */ |      */ | ||||||
|     private function reportAccounts() |     private function reportAccounts(): void | ||||||
|     { |     { | ||||||
|         $set = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id') |         $set = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id') | ||||||
|                       ->leftJoin('users', 'accounts.user_id', '=', 'users.id') |                       ->leftJoin('users', 'accounts.user_id', '=', 'users.id') | ||||||
| @@ -356,6 +391,82 @@ class VerifyDatabase extends Command | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Report on budgets with no transactions or journals. | ||||||
|  |      */ | ||||||
|  |     private function reportEmptyBudgets(): void | ||||||
|  |     { | ||||||
|  |         $set = Budget::leftJoin('budget_transaction_journal', 'budgets.id', '=', 'budget_transaction_journal.budget_id') | ||||||
|  |                      ->leftJoin('users', 'budgets.user_id', '=', 'users.id') | ||||||
|  |                      ->distinct() | ||||||
|  |                      ->whereNull('budget_transaction_journal.budget_id') | ||||||
|  |                      ->whereNull('budgets.deleted_at') | ||||||
|  |                      ->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'users.email']); | ||||||
|  |  | ||||||
|  |         /** @var stdClass $entry */ | ||||||
|  |         foreach ($set as $entry) { | ||||||
|  |             $objName = $entry->name; | ||||||
|  |             try { | ||||||
|  |                 $objName = Crypt::decrypt($objName); | ||||||
|  |             } catch (DecryptException $e) { | ||||||
|  |                 // it probably was not encrypted. | ||||||
|  |                 Log::debug(sprintf('Not a problem: %s', $e->getMessage())); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             // also count the transactions: | ||||||
|  |             $countTransactions = DB::table('budget_transaction')->where('budget_id', $entry->id)->count(); | ||||||
|  |  | ||||||
|  |             if (0 === $countTransactions) { | ||||||
|  |                 $line = sprintf( | ||||||
|  |                     'User #%d (%s) has budget #%d ("%s") which has no transactions.', | ||||||
|  |                     $entry->user_id, | ||||||
|  |                     $entry->email, | ||||||
|  |                     $entry->id, | ||||||
|  |                     $objName | ||||||
|  |                 ); | ||||||
|  |                 $this->line($line); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Report on categories with no transactions or journals. | ||||||
|  |      */ | ||||||
|  |     private function reportEmptyCategories(): void | ||||||
|  |     { | ||||||
|  |         $set = Category::leftJoin('category_transaction_journal', 'categories.id', '=', 'category_transaction_journal.category_id') | ||||||
|  |                        ->leftJoin('users', 'categories.user_id', '=', 'users.id') | ||||||
|  |                        ->distinct() | ||||||
|  |                        ->whereNull('category_transaction_journal.category_id') | ||||||
|  |                        ->whereNull('categories.deleted_at') | ||||||
|  |                        ->get(['categories.id', 'categories.name', 'categories.user_id', 'users.email']); | ||||||
|  |  | ||||||
|  |         /** @var stdClass $entry */ | ||||||
|  |         foreach ($set as $entry) { | ||||||
|  |             $objName = $entry->name; | ||||||
|  |             try { | ||||||
|  |                 $objName = Crypt::decrypt($objName); | ||||||
|  |             } catch (DecryptException $e) { | ||||||
|  |                 // it probably was not encrypted. | ||||||
|  |                 Log::debug(sprintf('Not a problem: %s', $e->getMessage())); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             // also count the transactions: | ||||||
|  |             $countTransactions = DB::table('category_transaction')->where('category_id', $entry->id)->count(); | ||||||
|  |  | ||||||
|  |             if (0 === $countTransactions) { | ||||||
|  |                 $line = sprintf( | ||||||
|  |                     'User #%d (%s) has category #%d ("%s") which has no transactions.', | ||||||
|  |                     $entry->user_id, | ||||||
|  |                     $entry->email, | ||||||
|  |                     $entry->id, | ||||||
|  |                     $objName | ||||||
|  |                 ); | ||||||
|  |                 $this->line($line); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Report on journals with bad account types linked to them. |      * Report on journals with bad account types linked to them. | ||||||
|      */ |      */ | ||||||
| @@ -461,12 +572,13 @@ class VerifyDatabase extends Command | |||||||
|         $plural = str_plural($name); |         $plural = str_plural($name); | ||||||
|         $class  = sprintf('FireflyIII\Models\%s', ucfirst($name)); |         $class  = sprintf('FireflyIII\Models\%s', ucfirst($name)); | ||||||
|         $field  = 'tag' === $name ? 'tag' : 'name'; |         $field  = 'tag' === $name ? 'tag' : 'name'; | ||||||
|         $set    = $class::leftJoin($name . '_transaction_journal', $plural . '.id', '=', $name . '_transaction_journal.' . $name . '_id') |         /** @noinspection PhpUndefinedMethodInspection */ | ||||||
|                         ->leftJoin('users', $plural . '.user_id', '=', 'users.id') |         $set = $class::leftJoin($name . '_transaction_journal', $plural . '.id', '=', $name . '_transaction_journal.' . $name . '_id') | ||||||
|                         ->distinct() |                      ->leftJoin('users', $plural . '.user_id', '=', 'users.id') | ||||||
|                         ->whereNull($name . '_transaction_journal.' . $name . '_id') |                      ->distinct() | ||||||
|                         ->whereNull($plural . '.deleted_at') |                      ->whereNull($name . '_transaction_journal.' . $name . '_id') | ||||||
|                         ->get([$plural . '.id', $plural . '.' . $field . ' as name', $plural . '.user_id', 'users.email']); |                      ->whereNull($plural . '.deleted_at') | ||||||
|  |                      ->get([$plural . '.id', $plural . '.' . $field . ' as name', $plural . '.user_id', 'users.email']); | ||||||
|  |  | ||||||
|         /** @var stdClass $entry */ |         /** @var stdClass $entry */ | ||||||
|         foreach ($set as $entry) { |         foreach ($set as $entry) { | ||||||
| @@ -475,6 +587,7 @@ class VerifyDatabase extends Command | |||||||
|                 $objName = Crypt::decrypt($objName); |                 $objName = Crypt::decrypt($objName); | ||||||
|             } catch (DecryptException $e) { |             } catch (DecryptException $e) { | ||||||
|                 // it probably was not encrypted. |                 // it probably was not encrypted. | ||||||
|  |                 Log::debug(sprintf('Not a problem: %s', $e->getMessage())); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             $line = sprintf( |             $line = sprintf( | ||||||
| @@ -502,7 +615,8 @@ class VerifyDatabase extends Command | |||||||
|             $sum = (string)$user->transactions()->sum('amount'); |             $sum = (string)$user->transactions()->sum('amount'); | ||||||
|             if (0 !== bccomp($sum, '0')) { |             if (0 !== bccomp($sum, '0')) { | ||||||
|                 $this->error('Error: Transactions for user #' . $user->id . ' (' . $user->email . ') are off by ' . $sum . '!'); |                 $this->error('Error: Transactions for user #' . $user->id . ' (' . $user->email . ') are off by ' . $sum . '!'); | ||||||
|             } else { |             } | ||||||
|  |             if (0 === bccomp($sum, '0')) { | ||||||
|                 $this->info(sprintf('Amount integrity OK for user #%d', $user->id)); |                 $this->info(sprintf('Amount integrity OK for user #%d', $user->id)); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @@ -532,7 +646,7 @@ class VerifyDatabase extends Command | |||||||
|     /** |     /** | ||||||
|      * Report on transfers that have budgets. |      * Report on transfers that have budgets. | ||||||
|      */ |      */ | ||||||
|     private function reportTransfersBudgets() |     private function reportTransfersBudgets(): void | ||||||
|     { |     { | ||||||
|         $set = TransactionJournal::distinct() |         $set = TransactionJournal::distinct() | ||||||
|                                  ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') |                                  ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * Kernel.php |  * Kernel.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,32 +20,28 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Console; | namespace FireflyIII\Console; | ||||||
|  |  | ||||||
| use Illuminate\Console\Scheduling\Schedule; | use Illuminate\Console\Scheduling\Schedule; | ||||||
| use Illuminate\Foundation\Console\Kernel as ConsoleKernel; | use Illuminate\Foundation\Console\Kernel as ConsoleKernel; | ||||||
|  | use Log; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * File to make sure commnds work. |  * File to make sure commands work. | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  */ |  */ | ||||||
| class Kernel extends ConsoleKernel | class Kernel extends ConsoleKernel | ||||||
| { | { | ||||||
|     /** |  | ||||||
|      * The Artisan commands provided by your application. |  | ||||||
|      * |  | ||||||
|      * @var array |  | ||||||
|      */ |  | ||||||
|     protected $commands |  | ||||||
|         = [ |  | ||||||
|         ]; |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Register the commands for the application. |      * Register the commands for the application. | ||||||
|      */ |      */ | ||||||
|     protected function commands() |     protected function commands(): void | ||||||
|     { |     { | ||||||
|         $this->load(__DIR__ . '/Commands'); |         $this->load(__DIR__ . '/Commands'); | ||||||
|  |  | ||||||
|  |         /** @noinspection PhpIncludeInspection */ | ||||||
|         require base_path('routes/console.php'); |         require base_path('routes/console.php'); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -53,10 +49,24 @@ class Kernel extends ConsoleKernel | |||||||
|      * Define the application's command schedule. |      * Define the application's command schedule. | ||||||
|      * |      * | ||||||
|      * @param \Illuminate\Console\Scheduling\Schedule $schedule |      * @param \Illuminate\Console\Scheduling\Schedule $schedule | ||||||
|      * |  | ||||||
|      * @SuppressWarnings(PHPMD.UnusedFormalParameter) |  | ||||||
|      */ |      */ | ||||||
|     protected function schedule(Schedule $schedule) |     protected function schedule(Schedule $schedule): void | ||||||
|     { |     { | ||||||
|  |         $schedule->call( | ||||||
|  |             function () { | ||||||
|  |                 Log::error('Firefly III no longer users the Laravel scheduler to do cron jobs! Please read the instructions at https://firefly-iii.readthedocs.io/en/latest/'); | ||||||
|  |                 echo "\n"; | ||||||
|  |                 echo '------------'; | ||||||
|  |                 echo "\n"; | ||||||
|  |                 echo wordwrap('Firefly III no longer users the Laravel scheduler to do cron jobs! Please read the instructions here:'); | ||||||
|  |                 echo "\n"; | ||||||
|  |                 echo 'https://firefly-iii.readthedocs.io/en/latest/'; | ||||||
|  |                 echo "\n\n"; | ||||||
|  |                 echo 'Disable this cron job!'; | ||||||
|  |                 echo "\n"; | ||||||
|  |                 echo '------------'; | ||||||
|  |                 echo "\n"; | ||||||
|  |             } | ||||||
|  |         )->everyMinute(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * AdminRequestedTestMessage.php |  * AdminRequestedTestMessage.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Events; | namespace FireflyIII\Events; | ||||||
|  |  | ||||||
| use FireflyIII\User; | use FireflyIII\User; | ||||||
| @@ -28,18 +30,15 @@ use Log; | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class AdminRequestedTestMessage. |  * Class AdminRequestedTestMessage. | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  */ |  */ | ||||||
| class AdminRequestedTestMessage extends Event | class AdminRequestedTestMessage extends Event | ||||||
| { | { | ||||||
|     use SerializesModels; |     use SerializesModels; | ||||||
|  |  | ||||||
|     /** |     /** @var string The users IP address */ | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $ipAddress; |     public $ipAddress; | ||||||
|     /** |     /** @var User The user */ | ||||||
|      * @var User |  | ||||||
|      */ |  | ||||||
|     public $user; |     public $user; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * Event.php |  * Event.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,10 +20,13 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Events; | namespace FireflyIII\Events; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class Event. |  * Class Event. | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  */ |  */ | ||||||
| abstract class Event | abstract class Event | ||||||
| { | { | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * RegisteredUser.php |  * RegisteredUser.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Events; | namespace FireflyIII\Events; | ||||||
|  |  | ||||||
| use FireflyIII\User; | use FireflyIII\User; | ||||||
| @@ -27,18 +29,15 @@ use Illuminate\Queue\SerializesModels; | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class RegisteredUser. |  * Class RegisteredUser. | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  */ |  */ | ||||||
| class RegisteredUser extends Event | class RegisteredUser extends Event | ||||||
| { | { | ||||||
|     use SerializesModels; |     use SerializesModels; | ||||||
|  |  | ||||||
|     /** |     /** @var string The users IP address */ | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $ipAddress; |     public $ipAddress; | ||||||
|     /** |     /** @var User The user */ | ||||||
|      * @var User |  | ||||||
|      */ |  | ||||||
|     public $user; |     public $user; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * RequestedNewPassword.php |  * RequestedNewPassword.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Events; | namespace FireflyIII\Events; | ||||||
|  |  | ||||||
| use FireflyIII\User; | use FireflyIII\User; | ||||||
| @@ -27,22 +29,17 @@ use Illuminate\Queue\SerializesModels; | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class RequestedNewPassword. |  * Class RequestedNewPassword. | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  */ |  */ | ||||||
| class RequestedNewPassword extends Event | class RequestedNewPassword extends Event | ||||||
| { | { | ||||||
|     use SerializesModels; |     use SerializesModels; | ||||||
|  |  | ||||||
|     /** |     /** @var string The users IP address */ | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $ipAddress; |     public $ipAddress; | ||||||
|     /** |     /** @var string The token */ | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $token; |     public $token; | ||||||
|     /** |     /** @var User The user */ | ||||||
|      * @var User |  | ||||||
|      */ |  | ||||||
|     public $user; |     public $user; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|   | |||||||
							
								
								
									
										68
									
								
								app/Events/RequestedReportOnJournals.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								app/Events/RequestedReportOnJournals.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | |||||||
|  | <?php | ||||||
|  | declare(strict_types=1); | ||||||
|  | /** | ||||||
|  |  * RequestedReportOnJournals.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/>. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | 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 | ||||||
|  |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  |  */ | ||||||
|  | class RequestedReportOnJournals | ||||||
|  | { | ||||||
|  |     use Dispatchable, InteractsWithSockets, SerializesModels; | ||||||
|  |  | ||||||
|  |     /** @var Collection The journals to report on. */ | ||||||
|  |     public $journals; | ||||||
|  |     /** @var int The ID of the user. */ | ||||||
|  |     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,8 +1,8 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * RequestedVersionCheckStatus.php |  * RequestedVersionCheckStatus.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +20,7 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Events; | namespace FireflyIII\Events; | ||||||
|  |  | ||||||
| @@ -29,14 +30,14 @@ use Illuminate\Queue\SerializesModels; | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class RequestedVersionCheckStatus |  * Class RequestedVersionCheckStatus | ||||||
|  |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  */ |  */ | ||||||
| class RequestedVersionCheckStatus extends Event | class RequestedVersionCheckStatus extends Event | ||||||
| { | { | ||||||
|     use SerializesModels; |     use SerializesModels; | ||||||
|  |  | ||||||
|     /** |     /** @var User The user */ | ||||||
|      * @var User |  | ||||||
|      */ |  | ||||||
|     public $user; |     public $user; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * StoredTransactionJournal.php |  * StoredTransactionJournal.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,22 +20,25 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Events; | namespace FireflyIII\Events; | ||||||
|  |  | ||||||
| use FireflyIII\Models\TransactionJournal; | use FireflyIII\Models\TransactionJournal; | ||||||
| use Illuminate\Queue\SerializesModels; | use Illuminate\Queue\SerializesModels; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @codeCoverageIgnore |  | ||||||
|  * Class StoredTransactionJournal. |  * Class StoredTransactionJournal. | ||||||
|  |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  */ |  */ | ||||||
| class StoredTransactionJournal extends Event | class StoredTransactionJournal extends Event | ||||||
| { | { | ||||||
|     use SerializesModels; |     use SerializesModels; | ||||||
|  |  | ||||||
|     /** @var TransactionJournal */ |     /** @var TransactionJournal The journal that was stored. */ | ||||||
|     public $journal; |     public $journal; | ||||||
|     /** @var int */ |     /** @var int The piggy bank ID. */ | ||||||
|     public $piggyBankId; |     public $piggyBankId; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * UpdatedTransactionJournal.php |  * UpdatedTransactionJournal.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Events; | namespace FireflyIII\Events; | ||||||
|  |  | ||||||
| use FireflyIII\Models\TransactionJournal; | use FireflyIII\Models\TransactionJournal; | ||||||
| @@ -35,7 +37,7 @@ class UpdatedTransactionJournal extends Event | |||||||
| { | { | ||||||
|     use SerializesModels; |     use SerializesModels; | ||||||
|  |  | ||||||
|     /** @var TransactionJournal */ |     /** @var TransactionJournal The journal. */ | ||||||
|     public $journal; |     public $journal; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * UserChangedEmail.php |  * UserChangedEmail.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Events; | namespace FireflyIII\Events; | ||||||
|  |  | ||||||
| use FireflyIII\User; | use FireflyIII\User; | ||||||
| @@ -27,18 +29,20 @@ use Illuminate\Queue\SerializesModels; | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class UserChangedEmail. |  * Class UserChangedEmail. | ||||||
|  |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  */ |  */ | ||||||
| class UserChangedEmail extends Event | class UserChangedEmail extends Event | ||||||
| { | { | ||||||
|     use SerializesModels; |     use SerializesModels; | ||||||
|  |  | ||||||
|     /** @var string */ |     /** @var string The user's IP address */ | ||||||
|     public $ipAddress; |     public $ipAddress; | ||||||
|     /** @var string */ |     /** @var string The user's new email address */ | ||||||
|     public $newEmail; |     public $newEmail; | ||||||
|     /** @var string */ |     /** @var string The user's old email address */ | ||||||
|     public $oldEmail; |     public $oldEmail; | ||||||
|     /** @var User */ |     /** @var User The user itself */ | ||||||
|     public $user; |     public $user; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * FireflyException.php |  * FireflyException.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Exceptions; | namespace FireflyIII\Exceptions; | ||||||
|  |  | ||||||
| use Exception; | use Exception; | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * Handler.php |  * Handler.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +20,10 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | /** @noinspection MultipleReturnStatementsInspection */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Exceptions; | namespace FireflyIII\Exceptions; | ||||||
|  |  | ||||||
| use ErrorException; | use ErrorException; | ||||||
| @@ -27,45 +31,31 @@ use Exception; | |||||||
| use FireflyIII\Jobs\MailError; | use FireflyIII\Jobs\MailError; | ||||||
| use Illuminate\Auth\AuthenticationException; | use Illuminate\Auth\AuthenticationException; | ||||||
| use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; | use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; | ||||||
| use Illuminate\Validation\ValidationException; | use Illuminate\Validation\ValidationException as LaravelValidationException; | ||||||
|  | use League\OAuth2\Server\Exception\OAuthServerException; | ||||||
| use Request; | use Request; | ||||||
| use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class Handler |  * Class Handler | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  */ |  */ | ||||||
| class Handler extends ExceptionHandler | class Handler extends ExceptionHandler | ||||||
| { | { | ||||||
|     /** |  | ||||||
|      * A list of the inputs that are never flashed for validation exceptions. |  | ||||||
|      * |  | ||||||
|      * @var array |  | ||||||
|      */ |  | ||||||
|     protected $dontFlash |  | ||||||
|         = [ |  | ||||||
|             'password', |  | ||||||
|             'password_confirmation', |  | ||||||
|         ]; |  | ||||||
|     /** |  | ||||||
|      * A list of the exception types that are not reported. |  | ||||||
|      * |  | ||||||
|      * @var array |  | ||||||
|      */ |  | ||||||
|     protected $dontReport |  | ||||||
|         = [ |  | ||||||
|         ]; |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Render an exception into an HTTP response. |      * Render an exception into an HTTP response. | ||||||
|      * |      * | ||||||
|      * @param \Illuminate\Http\Request $request |      * @param Request   $request | ||||||
|      * @param \Exception               $exception |      * @param Exception $exception | ||||||
|  |      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||||
|  |      * @SuppressWarnings(PHPMD.NPathComplexity) | ||||||
|  |      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||||
|      * |      * | ||||||
|      * @return \Illuminate\Http\Response |      * @return mixed | ||||||
|      */ |      */ | ||||||
|     public function render($request, Exception $exception) |     public function render($request, Exception $exception) | ||||||
|     { |     { | ||||||
|         if ($exception instanceof ValidationException && $request->expectsJson()) { |         if ($exception instanceof LaravelValidationException && $request->expectsJson()) { | ||||||
|             // ignore it: controller will handle it. |             // ignore it: controller will handle it. | ||||||
|             return parent::render($request, $exception); |             return parent::render($request, $exception); | ||||||
|         } |         } | ||||||
| @@ -79,6 +69,11 @@ class Handler extends ExceptionHandler | |||||||
|             return response()->json(['message' => 'Unauthenticated', 'exception' => 'AuthenticationException'], 401); |             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()) { |         if ($request->expectsJson()) { | ||||||
|             $isDebug = config('app.debug', false); |             $isDebug = config('app.debug', false); | ||||||
|             if ($isDebug) { |             if ($isDebug) { | ||||||
| @@ -96,7 +91,7 @@ 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); |             $isDebug = env('APP_DEBUG', false); | ||||||
|  |  | ||||||
|             return response()->view('errors.FireflyException', ['exception' => $exception, 'debug' => $isDebug], 500); |             return response()->view('errors.FireflyException', ['exception' => $exception, 'debug' => $isDebug], 500); | ||||||
| @@ -120,8 +115,12 @@ class Handler extends ExceptionHandler | |||||||
|      */ |      */ | ||||||
|     public function report(Exception $exception) |     public function report(Exception $exception) | ||||||
|     { |     { | ||||||
|  |  | ||||||
|         $doMailError = env('SEND_ERROR_MESSAGE', true); |         $doMailError = env('SEND_ERROR_MESSAGE', true); | ||||||
|         if (($exception instanceof FireflyException || $exception instanceof ErrorException) && $doMailError) { |         // if the user wants us to mail: | ||||||
|  |         if (true === $doMailError | ||||||
|  |             // and if is one of these error instances | ||||||
|  |             && ($exception instanceof FireflyException || $exception instanceof ErrorException || $exception instanceof OAuthServerException)) { | ||||||
|             $userData = [ |             $userData = [ | ||||||
|                 'id'    => 0, |                 'id'    => 0, | ||||||
|                 'email' => 'unknown@example.com', |                 'email' => 'unknown@example.com', | ||||||
| @@ -139,6 +138,9 @@ class Handler extends ExceptionHandler | |||||||
|                 'line'         => $exception->getLine(), |                 'line'         => $exception->getLine(), | ||||||
|                 'code'         => $exception->getCode(), |                 'code'         => $exception->getCode(), | ||||||
|                 'version'      => config('firefly.version'), |                 'version'      => config('firefly.version'), | ||||||
|  |                 'url'          => Request::fullUrl(), | ||||||
|  |                 'userAgent'    => Request::userAgent(), | ||||||
|  |                 'json'         => Request::acceptsJson(), | ||||||
|             ]; |             ]; | ||||||
|  |  | ||||||
|             // create job that will mail. |             // create job that will mail. | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * NotImplementedException.php |  * NotImplementedException.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Exceptions; | namespace FireflyIII\Exceptions; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * ValidationException.php |  * ValidationException.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Exceptions; | namespace FireflyIII\Exceptions; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * AttachmentCollector.php |  * AttachmentCollector.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +19,8 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Export\Collector; | namespace FireflyIII\Export\Collector; | ||||||
|  |  | ||||||
| use Carbon\Carbon; | use Carbon\Carbon; | ||||||
| @@ -33,18 +34,21 @@ use Storage; | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class AttachmentCollector. |  * Class AttachmentCollector. | ||||||
|  |  * | ||||||
|  |  * @deprecated | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  */ |  */ | ||||||
| class AttachmentCollector extends BasicCollector implements CollectorInterface | class AttachmentCollector extends BasicCollector implements CollectorInterface | ||||||
| { | { | ||||||
|     /** @var Carbon */ |     /** @var Carbon The end date of the range. */ | ||||||
|     private $end; |     private $end; | ||||||
|     /** @var \Illuminate\Contracts\Filesystem\Filesystem */ |     /** @var \Illuminate\Contracts\Filesystem\Filesystem File system */ | ||||||
|     private $exportDisk; |     private $exportDisk; | ||||||
|     /** @var AttachmentRepositoryInterface */ |     /** @var AttachmentRepositoryInterface Attachment repository */ | ||||||
|     private $repository; |     private $repository; | ||||||
|     /** @var Carbon */ |     /** @var Carbon Start date of range */ | ||||||
|     private $start; |     private $start; | ||||||
|     /** @var \Illuminate\Contracts\Filesystem\Filesystem */ |     /** @var \Illuminate\Contracts\Filesystem\Filesystem Disk with uploads on it */ | ||||||
|     private $uploadDisk; |     private $uploadDisk; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -62,6 +66,8 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Run the routine. | ||||||
|  |      * | ||||||
|      * @return bool |      * @return bool | ||||||
|      */ |      */ | ||||||
|     public function run(): bool |     public function run(): bool | ||||||
| @@ -78,6 +84,8 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Set the start and end date. | ||||||
|  |      * | ||||||
|      * @param Carbon $start |      * @param Carbon $start | ||||||
|      * @param Carbon $end |      * @param Carbon $end | ||||||
|      */ |      */ | ||||||
| @@ -87,14 +95,18 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface | |||||||
|         $this->end   = $end; |         $this->end   = $end; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** @noinspection MultipleReturnStatementsInspection */ | ||||||
|     /** |     /** | ||||||
|  |      * Export attachments. | ||||||
|  |      * | ||||||
|      * @param Attachment $attachment |      * @param Attachment $attachment | ||||||
|      * |      * | ||||||
|      * @return bool |      * @return bool | ||||||
|      */ |      */ | ||||||
|     private function exportAttachment(Attachment $attachment): bool |     private function exportAttachment(Attachment $attachment): bool | ||||||
|     { |     { | ||||||
|         $file = $attachment->fileName(); |         $file      = $attachment->fileName(); | ||||||
|  |         $decrypted = false; | ||||||
|         if ($this->uploadDisk->exists($file)) { |         if ($this->uploadDisk->exists($file)) { | ||||||
|             try { |             try { | ||||||
|                 $decrypted = Crypt::decrypt($this->uploadDisk->get($file)); |                 $decrypted = Crypt::decrypt($this->uploadDisk->get($file)); | ||||||
| @@ -104,6 +116,9 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface | |||||||
|                 return false; |                 return false; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |         if (false === $decrypted) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|         $exportFile = $this->exportFileName($attachment); |         $exportFile = $this->exportFileName($attachment); | ||||||
|         $this->exportDisk->put($exportFile, $decrypted); |         $this->exportDisk->put($exportFile, $decrypted); | ||||||
|         $this->getEntries()->push($exportFile); |         $this->getEntries()->push($exportFile); | ||||||
| @@ -124,6 +139,8 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Get the attachments. | ||||||
|  |      * | ||||||
|      * @return Collection |      * @return Collection | ||||||
|      */ |      */ | ||||||
|     private function getAttachments(): Collection |     private function getAttachments(): Collection | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * BasicCollector.php |  * BasicCollector.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Export\Collector; | namespace FireflyIII\Export\Collector; | ||||||
|  |  | ||||||
| use FireflyIII\Models\ExportJob; | use FireflyIII\Models\ExportJob; | ||||||
| @@ -28,14 +30,17 @@ use Illuminate\Support\Collection; | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class BasicCollector. |  * Class BasicCollector. | ||||||
|  |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  |  * @deprecated | ||||||
|  */ |  */ | ||||||
| class BasicCollector | class BasicCollector | ||||||
| { | { | ||||||
|     /** @var ExportJob */ |     /** @var ExportJob The job to export. */ | ||||||
|     protected $job; |     protected $job; | ||||||
|     /** @var User */ |     /** @var User The user */ | ||||||
|     protected $user; |     protected $user; | ||||||
|     /** @var Collection */ |     /** @var Collection All the entries. */ | ||||||
|     private $entries; |     private $entries; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -47,6 +52,8 @@ class BasicCollector | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Get all entries. | ||||||
|  |      * | ||||||
|      * @return Collection |      * @return Collection | ||||||
|      */ |      */ | ||||||
|     public function getEntries(): Collection |     public function getEntries(): Collection | ||||||
| @@ -55,26 +62,32 @@ class BasicCollector | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Set entries. | ||||||
|  |      * | ||||||
|      * @param Collection $entries |      * @param Collection $entries | ||||||
|      */ |      */ | ||||||
|     public function setEntries(Collection $entries) |     public function setEntries(Collection $entries): void | ||||||
|     { |     { | ||||||
|         $this->entries = $entries; |         $this->entries = $entries; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Set export job. | ||||||
|  |      * | ||||||
|      * @param ExportJob $job |      * @param ExportJob $job | ||||||
|      */ |      */ | ||||||
|     public function setJob(ExportJob $job) |     public function setJob(ExportJob $job): void | ||||||
|     { |     { | ||||||
|         $this->job  = $job; |         $this->job  = $job; | ||||||
|         $this->user = $job->user; |         $this->user = $job->user; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Set user. | ||||||
|  |      * | ||||||
|      * @param User $user |      * @param User $user | ||||||
|      */ |      */ | ||||||
|     public function setUser(User $user) |     public function setUser(User $user): void | ||||||
|     { |     { | ||||||
|         $this->user = $user; |         $this->user = $user; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * CollectorInterface.php |  * CollectorInterface.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Export\Collector; | namespace FireflyIII\Export\Collector; | ||||||
|  |  | ||||||
| use FireflyIII\Models\ExportJob; | use FireflyIII\Models\ExportJob; | ||||||
| @@ -27,25 +29,36 @@ use Illuminate\Support\Collection; | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Interface CollectorInterface. |  * Interface CollectorInterface. | ||||||
|  |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  |  * @deprecated | ||||||
|  */ |  */ | ||||||
| interface CollectorInterface | interface CollectorInterface | ||||||
| { | { | ||||||
|     /** |     /** | ||||||
|  |      * Get entries. | ||||||
|  |      * | ||||||
|      * @return Collection |      * @return Collection | ||||||
|      */ |      */ | ||||||
|     public function getEntries(): Collection; |     public function getEntries(): Collection; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Run the collector. | ||||||
|  |      * | ||||||
|      * @return bool |      * @return bool | ||||||
|      */ |      */ | ||||||
|     public function run(): bool; |     public function run(): bool; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Set entries. | ||||||
|  |      * | ||||||
|      * @param Collection $entries |      * @param Collection $entries | ||||||
|      */ |      */ | ||||||
|     public function setEntries(Collection $entries); |     public function setEntries(Collection $entries); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Set export job. | ||||||
|  |      * | ||||||
|      * @param ExportJob $job |      * @param ExportJob $job | ||||||
|      * |      * | ||||||
|      * @return mixed |      * @return mixed | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * UploadCollector.php |  * UploadCollector.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +19,8 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Export\Collector; | namespace FireflyIII\Export\Collector; | ||||||
|  |  | ||||||
| use Crypt; | use Crypt; | ||||||
| @@ -30,6 +31,9 @@ use Storage; | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class UploadCollector. |  * Class UploadCollector. | ||||||
|  |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  |  * @deprecated | ||||||
|  */ |  */ | ||||||
| class UploadCollector extends BasicCollector implements CollectorInterface | class UploadCollector extends BasicCollector implements CollectorInterface | ||||||
| { | { | ||||||
| @@ -82,7 +86,10 @@ class UploadCollector extends BasicCollector implements CollectorInterface | |||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** @noinspection MultipleReturnStatementsInspection */ | ||||||
|     /** |     /** | ||||||
|  |      * Process new file uploads. | ||||||
|  |      * | ||||||
|      * @param string $key |      * @param string $key | ||||||
|      * |      * | ||||||
|      * @return bool |      * @return bool | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * Entry.php |  * Entry.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Export\Entry; | namespace FireflyIII\Export\Entry; | ||||||
|  |  | ||||||
| use FireflyIII\Models\Transaction; | use FireflyIII\Models\Transaction; | ||||||
| @@ -41,140 +43,71 @@ use FireflyIII\Models\Transaction; | |||||||
|  * |  * | ||||||
|  * @SuppressWarnings(PHPMD.LongVariable) |  * @SuppressWarnings(PHPMD.LongVariable) | ||||||
|  * @SuppressWarnings(PHPMD.TooManyFields) |  * @SuppressWarnings(PHPMD.TooManyFields) | ||||||
|  |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  |  * @deprecated | ||||||
|  */ |  */ | ||||||
| final class Entry | final class Entry | ||||||
| { | { | ||||||
|     // @formatter:off |     /** @var int ID of the journal */ | ||||||
|     /** |  | ||||||
|      * @var int |  | ||||||
|      */ |  | ||||||
|     public $journal_id; |     public $journal_id; | ||||||
|     /** |     /** @var int ID of the transaction */ | ||||||
|      * @var int |  | ||||||
|      */ |  | ||||||
|     public $transaction_id = 0; |     public $transaction_id = 0; | ||||||
|  |     /** @var string The date. */ | ||||||
|     /** |  | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $date; |     public $date; | ||||||
|     /** |     /** @var string The description */ | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $description; |     public $description; | ||||||
|  |     /** @var string The currency code. */ | ||||||
|     /** |  | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $currency_code; |     public $currency_code; | ||||||
|     /** |     /** @var string The amount. */ | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $amount; |     public $amount; | ||||||
|     /** |     /** @var string The foreign currency code */ | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $foreign_currency_code = ''; |     public $foreign_currency_code = ''; | ||||||
|     /** |     /** @var string Foreign amount */ | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $foreign_amount = '0'; |     public $foreign_amount = '0'; | ||||||
|  |     /** @var string Transaction type */ | ||||||
|     /** |  | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $transaction_type; |     public $transaction_type; | ||||||
|  |     /** @var string Asset account ID */ | ||||||
|     /** |  | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $asset_account_id; |     public $asset_account_id; | ||||||
|     /** |     /** @var string Asset account name */ | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $asset_account_name; |     public $asset_account_name; | ||||||
|     /** |     /** @var string Asset account IBAN */ | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $asset_account_iban; |     public $asset_account_iban; | ||||||
|     /** |     /** @var string Asset account BIC */ | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $asset_account_bic; |     public $asset_account_bic; | ||||||
|     /** |     /** @var string Asset account number */ | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $asset_account_number; |     public $asset_account_number; | ||||||
|     /** |     /** @var string Asset account currency code */ | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $asset_currency_code; |     public $asset_currency_code; | ||||||
|  |     /** @var string Opposing account ID */ | ||||||
|     /** |  | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $opposing_account_id; |     public $opposing_account_id; | ||||||
|     /** |     /** @var string Opposing account name */ | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $opposing_account_name; |     public $opposing_account_name; | ||||||
|     /** |     /** @var string Opposing account IBAN */ | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $opposing_account_iban; |     public $opposing_account_iban; | ||||||
|     /** |     /** @var string Opposing account BIC */ | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $opposing_account_bic; |     public $opposing_account_bic; | ||||||
|     /** |     /** @var string Opposing account number */ | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $opposing_account_number; |     public $opposing_account_number; | ||||||
|     /** |     /** @var string Opposing account code */ | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $opposing_currency_code; |     public $opposing_currency_code; | ||||||
|  |     /** @var string Budget ID */ | ||||||
|     /** |  | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $budget_id; |     public $budget_id; | ||||||
|     /** |     /** @var string Budget name */ | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $budget_name; |     public $budget_name; | ||||||
|  |     /** @var string Category ID */ | ||||||
|     /** |  | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $category_id; |     public $category_id; | ||||||
|     /** |     /** @var string Category name */ | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $category_name; |     public $category_name; | ||||||
|  |     /** @var string Bill ID */ | ||||||
|     /** |  | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $bill_id; |     public $bill_id; | ||||||
|     /** |     /** @var string Bill name */ | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $bill_name; |     public $bill_name; | ||||||
|  |     /** @var string Notes */ | ||||||
|     /** |  | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $notes; |     public $notes; | ||||||
|  |     /** @var string Tags */ | ||||||
|     /** |  | ||||||
|      * @var string |  | ||||||
|      */ |  | ||||||
|     public $tags; |     public $tags; | ||||||
|  |  | ||||||
|  |  | ||||||
|     // @formatter:on |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Entry constructor. |      * Entry constructor. | ||||||
|      */ |      */ | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * ExpandedProcessor.php |  * ExpandedProcessor.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +19,10 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | /** @noinspection PhpDynamicAsStaticMethodCallInspection */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Export; | namespace FireflyIII\Export; | ||||||
|  |  | ||||||
| use Crypt; | use Crypt; | ||||||
| @@ -28,43 +31,47 @@ use FireflyIII\Exceptions\FireflyException; | |||||||
| use FireflyIII\Export\Collector\AttachmentCollector; | use FireflyIII\Export\Collector\AttachmentCollector; | ||||||
| use FireflyIII\Export\Collector\UploadCollector; | use FireflyIII\Export\Collector\UploadCollector; | ||||||
| use FireflyIII\Export\Entry\Entry; | use FireflyIII\Export\Entry\Entry; | ||||||
| use FireflyIII\Helpers\Collector\JournalCollectorInterface; | use FireflyIII\Export\Exporter\ExporterInterface; | ||||||
|  | use FireflyIII\Helpers\Collector\TransactionCollectorInterface; | ||||||
| use FireflyIII\Helpers\Filter\InternalTransferFilter; | use FireflyIII\Helpers\Filter\InternalTransferFilter; | ||||||
| use FireflyIII\Models\AccountMeta; | use FireflyIII\Models\AccountMeta; | ||||||
| use FireflyIII\Models\ExportJob; | use FireflyIII\Models\ExportJob; | ||||||
| use FireflyIII\Models\Note; | use FireflyIII\Models\Note; | ||||||
| use FireflyIII\Models\Transaction; | use FireflyIII\Models\Transaction; | ||||||
|  | use FireflyIII\Models\TransactionJournal; | ||||||
| use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | ||||||
| use Illuminate\Support\Collection; | use Illuminate\Support\Collection; | ||||||
| use Log; | use Log; | ||||||
| use Storage; | use Storage; | ||||||
| use ZipArchive; | use ZipArchive; | ||||||
| use FireflyIII\Models\TransactionJournal; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class ExpandedProcessor. |  * Class ExpandedProcessor. | ||||||
|  * |  * | ||||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) // its doing a lot. |  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) // its doing a lot. | ||||||
|  |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  |  * @deprecated | ||||||
|  */ |  */ | ||||||
| class ExpandedProcessor implements ProcessorInterface | class ExpandedProcessor implements ProcessorInterface | ||||||
| { | { | ||||||
|     /** @var Collection */ |     /** @var Collection All accounts */ | ||||||
|     public $accounts; |     public $accounts; | ||||||
|     /** @var string */ |     /** @var string The export format */ | ||||||
|     public $exportFormat; |     public $exportFormat; | ||||||
|     /** @var bool */ |     /** @var bool Should include attachments */ | ||||||
|     public $includeAttachments; |     public $includeAttachments; | ||||||
|     /** @var bool */ |     /** @var bool Should include old uploads */ | ||||||
|     public $includeOldUploads; |     public $includeOldUploads; | ||||||
|     /** @var ExportJob */ |     /** @var ExportJob The export job itself */ | ||||||
|     public $job; |     public $job; | ||||||
|     /** @var array */ |     /** @var array The settings */ | ||||||
|     public $settings; |     public $settings; | ||||||
|     /** @var Collection */ |     /** @var Collection The entries to export. */ | ||||||
|     private $exportEntries; |     private $exportEntries; | ||||||
|     /** @var Collection */ |     /** @var Collection The files to export */ | ||||||
|     private $files; |     private $files; | ||||||
|     /** @var Collection */ |     /** @var Collection The journals. */ | ||||||
|     private $journals; |     private $journals; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -78,6 +85,8 @@ class ExpandedProcessor implements ProcessorInterface | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Collect all attachments | ||||||
|  |      * | ||||||
|      * @return bool |      * @return bool | ||||||
|      */ |      */ | ||||||
|     public function collectAttachments(): bool |     public function collectAttachments(): bool | ||||||
| @@ -101,13 +110,13 @@ class ExpandedProcessor implements ProcessorInterface | |||||||
|     public function collectJournals(): bool |     public function collectJournals(): bool | ||||||
|     { |     { | ||||||
|         // use journal collector thing. |         // use journal collector thing. | ||||||
|         /** @var JournalCollectorInterface $collector */ |         /** @var TransactionCollectorInterface $collector */ | ||||||
|         $collector = app(JournalCollectorInterface::class); |         $collector = app(TransactionCollectorInterface::class); | ||||||
|         $collector->setUser($this->job->user); |         $collector->setUser($this->job->user); | ||||||
|         $collector->setAccounts($this->accounts)->setRange($this->settings['startDate'], $this->settings['endDate']) |         $collector->setAccounts($this->accounts)->setRange($this->settings['startDate'], $this->settings['endDate']) | ||||||
|                   ->withOpposingAccount()->withBudgetInformation()->withCategoryInformation() |                   ->withOpposingAccount()->withBudgetInformation()->withCategoryInformation() | ||||||
|                   ->removeFilter(InternalTransferFilter::class); |                   ->removeFilter(InternalTransferFilter::class); | ||||||
|         $transactions = $collector->getJournals(); |         $transactions = $collector->getTransactions(); | ||||||
|         // get some more meta data for each entry: |         // get some more meta data for each entry: | ||||||
|         $ids         = $transactions->pluck('journal_id')->toArray(); |         $ids         = $transactions->pluck('journal_id')->toArray(); | ||||||
|         $assetIds    = $transactions->pluck('account_id')->toArray(); |         $assetIds    = $transactions->pluck('account_id')->toArray(); | ||||||
| @@ -141,6 +150,8 @@ class ExpandedProcessor implements ProcessorInterface | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Get old oploads. | ||||||
|  |      * | ||||||
|      * @return bool |      * @return bool | ||||||
|      */ |      */ | ||||||
|     public function collectOldUploads(): bool |     public function collectOldUploads(): bool | ||||||
| @@ -156,6 +167,8 @@ class ExpandedProcessor implements ProcessorInterface | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Convert journals to export objects. | ||||||
|  |      * | ||||||
|      * @return bool |      * @return bool | ||||||
|      */ |      */ | ||||||
|     public function convertJournals(): bool |     public function convertJournals(): bool | ||||||
| @@ -171,6 +184,8 @@ class ExpandedProcessor implements ProcessorInterface | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Create a ZIP file. | ||||||
|  |      * | ||||||
|      * @return bool |      * @return bool | ||||||
|      * |      * | ||||||
|      * @throws FireflyException |      * @throws FireflyException | ||||||
| @@ -202,12 +217,15 @@ class ExpandedProcessor implements ProcessorInterface | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Export the journals. | ||||||
|  |      * | ||||||
|      * @return bool |      * @return bool | ||||||
|      */ |      */ | ||||||
|     public function exportJournals(): bool |     public function exportJournals(): bool | ||||||
|     { |     { | ||||||
|         $exporterClass = config('firefly.export_formats.' . $this->exportFormat); |         $exporterClass = config('firefly.export_formats.' . $this->exportFormat); | ||||||
|         $exporter      = app($exporterClass); |         /** @var ExporterInterface $exporter */ | ||||||
|  |         $exporter = app($exporterClass); | ||||||
|         $exporter->setJob($this->job); |         $exporter->setJob($this->job); | ||||||
|         $exporter->setEntries($this->exportEntries); |         $exporter->setEntries($this->exportEntries); | ||||||
|         $exporter->run(); |         $exporter->run(); | ||||||
| @@ -217,6 +235,8 @@ class ExpandedProcessor implements ProcessorInterface | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Get files. | ||||||
|  |      * | ||||||
|      * @return Collection |      * @return Collection | ||||||
|      */ |      */ | ||||||
|     public function getFiles(): Collection |     public function getFiles(): Collection | ||||||
| @@ -229,7 +249,7 @@ class ExpandedProcessor implements ProcessorInterface | |||||||
|      * |      * | ||||||
|      * @param array $settings |      * @param array $settings | ||||||
|      */ |      */ | ||||||
|     public function setSettings(array $settings) |     public function setSettings(array $settings): void | ||||||
|     { |     { | ||||||
|         // save settings |         // save settings | ||||||
|         $this->settings           = $settings; |         $this->settings           = $settings; | ||||||
| @@ -241,9 +261,9 @@ class ExpandedProcessor implements ProcessorInterface | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * |      * Delete files. | ||||||
|      */ |      */ | ||||||
|     private function deleteFiles() |     private function deleteFiles(): void | ||||||
|     { |     { | ||||||
|         $disk = Storage::disk('export'); |         $disk = Storage::disk('export'); | ||||||
|         foreach ($this->getFiles() as $file) { |         foreach ($this->getFiles() as $file) { | ||||||
| @@ -252,6 +272,8 @@ class ExpandedProcessor implements ProcessorInterface | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Get currencies. | ||||||
|  |      * | ||||||
|      * @param array $array |      * @param array $array | ||||||
|      * |      * | ||||||
|      * @return array |      * @return array | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * BasicExporter.php |  * BasicExporter.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Export\Exporter; | namespace FireflyIII\Export\Exporter; | ||||||
|  |  | ||||||
| use FireflyIII\Models\ExportJob; | use FireflyIII\Models\ExportJob; | ||||||
| @@ -27,12 +29,15 @@ use Illuminate\Support\Collection; | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class BasicExporter. |  * Class BasicExporter. | ||||||
|  |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  |  * @deprecated | ||||||
|  */ |  */ | ||||||
| class BasicExporter | class BasicExporter | ||||||
| { | { | ||||||
|     /** @var ExportJob */ |     /** @var ExportJob The export job */ | ||||||
|     protected $job; |     protected $job; | ||||||
|     /** @var Collection */ |     /** @var Collection The entries */ | ||||||
|     private $entries; |     private $entries; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -44,6 +49,8 @@ class BasicExporter | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Get all entries. | ||||||
|  |      * | ||||||
|      * @return Collection |      * @return Collection | ||||||
|      */ |      */ | ||||||
|     public function getEntries(): Collection |     public function getEntries(): Collection | ||||||
| @@ -52,17 +59,21 @@ class BasicExporter | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Set all entries. | ||||||
|  |      * | ||||||
|      * @param Collection $entries |      * @param Collection $entries | ||||||
|      */ |      */ | ||||||
|     public function setEntries(Collection $entries) |     public function setEntries(Collection $entries): void | ||||||
|     { |     { | ||||||
|         $this->entries = $entries; |         $this->entries = $entries; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Set the job. | ||||||
|  |      * | ||||||
|      * @param ExportJob $job |      * @param ExportJob $job | ||||||
|      */ |      */ | ||||||
|     public function setJob(ExportJob $job) |     public function setJob(ExportJob $job): void | ||||||
|     { |     { | ||||||
|         $this->job = $job; |         $this->job = $job; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| <?php | <?php | ||||||
| declare(strict_types=1); |  | ||||||
| /** | /** | ||||||
|  * CsvExporter.php |  * CsvExporter.php | ||||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com |  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||||
|  * |  * | ||||||
|  * This file is part of Firefly III. |  * This file is part of Firefly III. | ||||||
|  * |  * | ||||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | |||||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
| namespace FireflyIII\Export\Exporter; | namespace FireflyIII\Export\Exporter; | ||||||
|  |  | ||||||
| use FireflyIII\Export\Entry\Entry; | use FireflyIII\Export\Entry\Entry; | ||||||
| @@ -28,13 +30,18 @@ use Storage; | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class CsvExporter. |  * Class CsvExporter. | ||||||
|  |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  |  * @deprecated | ||||||
|  */ |  */ | ||||||
| class CsvExporter extends BasicExporter implements ExporterInterface | class CsvExporter extends BasicExporter implements ExporterInterface | ||||||
| { | { | ||||||
|     /** @var string */ |     /** @var string Filename */ | ||||||
|     private $fileName; |     private $fileName; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Get file name. | ||||||
|  |      * | ||||||
|      * @return string |      * @return string | ||||||
|      */ |      */ | ||||||
|     public function getFileName(): string |     public function getFileName(): string | ||||||
| @@ -43,6 +50,8 @@ class CsvExporter extends BasicExporter implements ExporterInterface | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * Run collector. | ||||||
|  |      * | ||||||
|      * @return bool |      * @return bool | ||||||
|      * |      * | ||||||
|      */ |      */ | ||||||
| @@ -81,6 +90,9 @@ class CsvExporter extends BasicExporter implements ExporterInterface | |||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Make a temp file. | ||||||
|  |      */ | ||||||
|     private function tempFile() |     private function tempFile() | ||||||
|     { |     { | ||||||
|         $this->fileName = $this->job->key . '-records.csv'; |         $this->fileName = $this->job->key . '-records.csv'; | ||||||
|   | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user