mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 02:36:28 +00:00 
			
		
		
		
	Compare commits
	
		
			683 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 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 | ||
|  | a826b0e0fb | ||
|  | 4aaec0e379 | ||
|  | 69019d5215 | ||
|  | 96411b17e9 | ||
|  | 5a093b58d8 | ||
|  | 470b3e0973 | ||
|  | dc251c216c | ||
|  | ae9ef61f80 | ||
|  | d9ca7b7277 | ||
|  | 0c99248deb | ||
|  | 1aae84a4d0 | ||
|  | 528da3f08e | ||
|  | 9c507f7f62 | ||
|  | 07da2fdda3 | ||
|  | ca3366544e | ||
|  | ccee7b483c | ||
|  | 5903133e3b | ||
|  | 5bf520b6ed | ||
|  | a47da92d81 | ||
|  | 63f84ae7b1 | ||
|  | 4d6bc55723 | ||
|  | 9bb4df4cc3 | ||
|  | c47a5379ae | ||
|  | cde9c4a2bc | ||
|  | 5a560b42ef | ||
|  | 50874c9cf7 | ||
|  | 6f984aa591 | ||
|  | 274162afcd | ||
|  | 6bd23d897f | ||
|  | 73f29ebf69 | ||
|  | cabcb9c6d0 | ||
|  | 116f7ed613 | ||
|  | 6ef0eb73d0 | ||
|  | 7f4feb0cfc | ||
|  | 626f7357bb | ||
|  | 690c9203c8 | ||
|  | 1209f3b39a | ||
|  | a4524b3c2c | ||
|  | a3cbdadb39 | ||
|  | 9e3c5fd984 | ||
|  | 7d80ac37a6 | ||
|  | f74b9ba7ab | ||
|  | 3ac240dc1c | ||
|  | d233b3f24f | ||
|  | 19fff681d2 | ||
|  | bc7c3bb9b3 | ||
|  | 57be7f2905 | ||
|  | 1c0da454db | ||
|  | b541f7b944 | ||
|  | 6e84326583 | ||
|  | ca14496e4e | ||
|  | 480d65fc1f | ||
|  | 6bddb63b45 | ||
|  | c5142aeba5 | ||
|  | 38d9f10672 | ||
|  | 937394af7a | ||
|  | fe10955eb9 | ||
|  | ccda71ff8e | ||
|  | cd75224cdd | ||
|  | 1c2089b8a3 | ||
|  | 3ead4d4587 | ||
|  | f2b71bc280 | ||
|  | f027d71136 | ||
|  | fa41d6df04 | ||
|  | d2bb65bf04 | ||
|  | b5be1b11d1 | ||
|  | 9fb049991f | ||
|  | fba847dd28 | ||
|  | b33883b334 | ||
|  | f74a6dffca | ||
|  | 7390e20218 | ||
|  | 9646dc439e | ||
|  | 554c63b9c7 | ||
|  | 24d8640e9b | ||
|  | ea151d069c | ||
|  | f140d2f37a | ||
|  | 4e163c4bda | ||
|  | ddcf8b892b | ||
|  | 49138eb03a | ||
|  | 71b63bd33b | ||
|  | 88348f59c2 | ||
|  | 7eb5643204 | ||
|  | 565cb6d79e | ||
|  | c0d715c78a | ||
|  | a3d0355ddd | ||
|  | bc4e06568d | ||
|  | 8acb9f4056 | ||
|  | 9cbbd581ee | ||
|  | fdc9467218 | ||
|  | 84ac3df580 | ||
|  | 7f459df9e9 | ||
|  | 3625f3293a | ||
|  | 0a2308592f | ||
|  | 8ef3f18da7 | ||
|  | e126427809 | ||
|  | 7b39828980 | ||
|  | d03de52735 | ||
|  | cabe90b2dd | ||
|  | 13b78bdc20 | ||
|  | 6f0e1c79ac | ||
|  | b66daad3d3 | ||
|  | 9c5523252d | ||
|  | bc8bcf7a1a | ||
|  | 85d655d3e2 | ||
|  | ac419e01d3 | ||
|  | 5d4467a6c0 | ||
|  | 81da7f3667 | ||
|  | 9734196eb9 | ||
|  | 7e0f9b9b8e | ||
|  | bb25132865 | ||
|  | 28bcff99f6 | ||
|  | 246cb36836 | ||
|  | 9a0c0f6d21 | ||
|  | a9dd8eb9e7 | ||
|  | 9026c9d6f1 | ||
|  | d5f7430723 | ||
|  | 5a53249fbb | ||
|  | d2848cf569 | ||
|  | 71f39f55f2 | ||
|  | 490c817fc1 | ||
|  | 2e1a777811 | ||
|  | 48357d1cc9 | ||
|  | 846df21764 | ||
|  | f78b8f9267 | ||
|  | 798d9ee876 | ||
|  | 1eea81e9dd | ||
|  | 4fcdfd41fa | ||
|  | 36a5f17af2 | ||
|  | 8032684ad0 | ||
|  | f7d3d4a010 | ||
|  | 9975e0b3f3 | ||
|  | ea484a7787 | ||
|  | c2e8a67330 | ||
|  | 8f3e4a2dee | ||
|  | 07768a43c8 | ||
|  | 01c10e320c | ||
|  | f16b2257c6 | ||
|  | e005fe7ce1 | ||
|  | c682e69ee7 | ||
|  | 49421f50ac | ||
|  | 529dd490b7 | ||
|  | 36329e596e | ||
|  | fb75e2ef02 | ||
|  | 352171e339 | ||
|  | 592901b143 | ||
|  | 769b4819b2 | ||
|  | 77fa2bcc39 | ||
|  | 1129001bc6 | ||
|  | 8dd765ee89 | ||
|  | 479648e7c1 | ||
|  | 45cd19d1e3 | ||
|  | f8718e0b7b | ||
|  | dcc45631da | ||
|  | c6d3a5bedc | ||
|  | 7cc8539298 | ||
|  | 900e8202e6 | ||
|  | eb6ac7d1d1 | ||
|  | 178f917a49 | ||
|  | 1a8293d9ef | ||
|  | ecdc00dcb7 | ||
|  | 147e04ecd2 | ||
|  | 49e48725a5 | ||
|  | b3af744041 | ||
|  | 58a6a95d90 | ||
|  | 1aa9461370 | ||
|  | 1f78b9d4bc | ||
|  | 6f974fe285 | ||
|  | f4f3c8798e | ||
|  | ce1614f4e7 | ||
|  | 91494584c2 | ||
|  | a85ebb49b2 | ||
|  | ae273f8320 | ||
|  | ef62e31b61 | ||
|  | 0c2c5d5344 | ||
|  | 11e93eac3d | ||
|  | dbe17debb4 | ||
|  | 6c12337317 | ||
|  | b2aa73b31e | ||
|  | 38b1fc7aa6 | ||
|  | f4afcb4d50 | ||
|  | 4b019fe38b | ||
|  | 191401f32b | ||
|  | 62b68c6a21 | ||
|  | 15a22f0bfc | ||
|  | 926c03986c | ||
|  | d8a00f4314 | ||
|  | 5862b832d9 | ||
|  | 67fa4a0fc7 | ||
|  | 90cf7a3bf5 | ||
|  | 0847040017 | ||
|  | 69b577048e | ||
|  | 3fbd2f93c8 | ||
|  | 8f0e36a8e4 | ||
|  | 7583698ee5 | ||
|  | b561e79a6c | ||
|  | 5850ad06b1 | ||
|  | e597f04b0d | ||
|  | 7b715925cf | ||
|  | d3701837e3 | ||
|  | 7af10aca9e | ||
|  | b54e99642b | ||
|  | b1ad0668cc | ||
|  | 6583d0f69b | ||
|  | cee6bbf134 | ||
|  | 43e49bf14a | ||
|  | 371b58a807 | ||
|  | 7812a1bb51 | ||
|  | 538e045e4c | ||
|  | 91fe1493a7 | ||
|  | 4650a2ea52 | ||
|  | 7cd51a7747 | ||
|  | b55545b959 | ||
|  | 2685256c93 | ||
|  | 3819de4e74 | ||
|  | 73fee4eb6b | ||
|  | 609c193b88 | ||
|  | 03a42976b1 | ||
|  | 6db0efdfbc | ||
|  | ebbbe1a620 | ||
|  | 5d1c77cb16 | ||
|  | d48fb3ba55 | ||
|  | 8c024a1ae9 | ||
|  | a3c34e6b3c | ||
|  | fa7ab45a40 | ||
|  | 379b104778 | ||
|  | d956c795a4 | ||
|  | 7d02d0f762 | ||
|  | f96f38b172 | ||
|  | 4cea5d65a6 | ||
|  | 40d94e7a62 | ||
|  | 66019fdbbf | ||
|  | 37b02e3d5b | ||
|  | 093bdd6090 | ||
|  | 52656b25da | ||
|  | 1386c9d915 | ||
|  | 02c9441727 | ||
|  | b1e926f2cb | ||
|  | df9dcb395b | ||
|  | ad59dad921 | ||
|  | 46e75968f5 | ||
|  | 0df5c5121d | ||
|  | 16f04b45ac | ||
|  | 5ce35a50c2 | ||
|  | 7110c1178a | ||
|  | 220f5e2913 | ||
|  | 9f8c75efc6 | ||
|  | 8f3e84df4d | ||
|  | 08ff3d8ad0 | ||
|  | 5c4d7734ac | ||
|  | 15f8cd49d3 | ||
|  | 62b3986fcd | ||
|  | 55b6d711f3 | ||
|  | 7e51d57d21 | ||
|  | 170d23d768 | ||
|  | 40266c6821 | ||
|  | 0a71077513 | ||
|  | be5c44af61 | ||
|  | 720dcb0fe5 | ||
|  | c86b207b1c | ||
|  | 413c1bc2fe | ||
|  | 5ca31ea3dd | ||
|  | dd5d2d1616 | ||
|  | 5f08790f12 | ||
|  | d5ef5ee5a7 | ||
|  | f641c70172 | ||
|  | 992657b942 | ||
|  | 41e468b507 | ||
|  | 6660306ac4 | ||
|  | dd9694890a | ||
|  | 0b8654d865 | ||
|  | f07dc7bd81 | ||
|  | 6a6482dc7f | ||
|  | 3c9b7c07af | ||
|  | 796ab4bf2c | ||
|  | 55602d632d | ||
|  | 310ed9f504 | ||
|  | dafddfa39a | ||
|  | 3e22c9860e | ||
|  | fb0a0c3fb5 | ||
|  | 3b735c7533 | ||
|  | 1645490f5c | ||
|  | aecffe10d9 | ||
|  | 4e69bc0e32 | ||
|  | 909f72e6be | ||
|  | 6a1d39d5f8 | ||
|  | c5d4ec17c3 | ||
|  | ed33a72945 | ||
|  | d8c0091680 | ||
|  | 6419d68626 | ||
|  | e2ecaf5bcf | ||
|  | 31146954d1 | ||
|  | 601ca9ec80 | ||
|  | 082b5ba895 | ||
|  | e06361d5d7 | ||
|  | 552a8e130c | ||
|  | 40787bc29a | ||
|  | 6ab03bb228 | ||
|  | 3fdb782321 | ||
|  | c8f52a1c40 | ||
|  | eb63090387 | ||
|  | 5bc8f31c31 | ||
|  | 5776de7745 | ||
|  | f45d0bb317 | ||
|  | 93aa5b7753 | ||
|  | dd6a6a565f | ||
|  | aba8025645 | ||
|  | b12872e5de | ||
|  | 5a7b1ba292 | ||
|  | 24715c72a2 | ||
|  | ed3a4e4663 | ||
|  | e97283b34b | ||
|  | c2dfbcba10 | ||
|  | a9870b35be | ||
|  | ed5cd2b9ca | ||
|  | a9356ca1e2 | ||
|  | cfba11e9ca | ||
|  | 4304a3c916 | ||
|  | 9e6194bfdc | ||
|  | 7d6c8aa9dc | ||
|  | aad0864018 | ||
|  | a55d18709c | ||
|  | dd2f3c861b | ||
|  | da1dc67e1c | ||
|  | 0c2b35e542 | ||
|  | 85dc1263ea | ||
|  | c8ecb3e0ee | ||
|  | ce10036a27 | ||
|  | 30e49846e0 | ||
|  | be97dd1c57 | ||
|  | 648a6dca42 | ||
|  | 0566d0d198 | ||
|  | dfc25722c9 | ||
|  | a436c55c50 | ||
|  | 0d58530f55 | ||
|  | 04b2eaf535 | ||
|  | ace2ed8bd0 | ||
|  | dff2d716a1 | ||
|  | ad18b9b81b | ||
|  | eabfe0769b | ||
|  | 19f7027718 | ||
|  | f537945351 | ||
|  | d02372ab90 | ||
|  | 1b020c522f | ||
|  | 79d0450c77 | ||
|  | bc32bc8831 | ||
|  | f68a307eeb | ||
|  | 82e7479cfe | ||
|  | 462fe5d89f | ||
|  | b0d8ac83ae | ||
|  | d8ac817c91 | ||
|  | 5105bc6f64 | ||
|  | 47c9f1e9b8 | ||
|  | 49d0ed0c1b | ||
|  | 99f5151aab | ||
|  | 0a056ad02d | ||
|  | c76b634d0b | ||
|  | a81698d50f | ||
|  | bae79063e1 | ||
|  | fb5323c283 | ||
|  | e2d1de94b7 | ||
|  | 7109fd8196 | ||
|  | a5fd821e0c | ||
|  | 6c63583e49 | ||
|  | dd16e1b784 | ||
|  | d52d8d7970 | ||
|  | f349aa47ce | ||
|  | ef4018934c | ||
|  | 951aa9535e | ||
|  | de1fe36226 | ||
|  | 64fd36d437 | ||
|  | 6f9ecc0ffa | ||
|  | a97bfc92e1 | ||
|  | 0d72fcdf02 | ||
|  | 0e84ca1df5 | ||
|  | b28bdda510 | ||
|  | 72314e2d9f | ||
|  | d22fb9f438 | ||
|  | 04b8552d27 | ||
|  | 5d6f44cd91 | ||
|  | afc8ad7ff5 | ||
|  | ae039bf1c7 | ||
|  | 8fa25e9d37 | ||
|  | 0daab491ec | ||
|  | 4f825bac1a | ||
|  | 39c8b79ebb | ||
|  | 7d66c90beb | ||
|  | 1b8b65582a | ||
|  | d25971cb44 | ||
|  | 89a56e661d | 
							
								
								
									
										29
									
								
								.deploy/docker/entrypoint.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										29
									
								
								.deploy/docker/entrypoint.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| # make sure the correct directories exists (suggested by @chrif): | ||||
| mkdir -p $FIREFLY_PATH/storage/app | ||||
| mkdir -p $FIREFLY_PATH/storage/app/public | ||||
| mkdir -p $FIREFLY_PATH/storage/build | ||||
| mkdir -p $FIREFLY_PATH/storage/database | ||||
| mkdir -p $FIREFLY_PATH/storage/debugbar | ||||
| mkdir -p $FIREFLY_PATH/storage/export | ||||
| mkdir -p $FIREFLY_PATH/storage/framework/cache | ||||
| mkdir -p $FIREFLY_PATH/storage/framework/sessions | ||||
| mkdir -p $FIREFLY_PATH/storage/framework/testing | ||||
| mkdir -p $FIREFLY_PATH/storage/framework/views | ||||
| mkdir -p $FIREFLY_PATH/storage/logs | ||||
| mkdir -p $FIREFLY_PATH/storage/upload | ||||
|  | ||||
|  | ||||
| # make sure we own the volumes: | ||||
| chown -R www-data:www-data -R $FIREFLY_PATH/storage | ||||
| chmod -R 775 $FIREFLY_PATH/storage | ||||
|  | ||||
| # remove any lingering files that may break upgrades: | ||||
| rm -f $FIREFLY_PATH/storage/logs/laravel.log | ||||
|  | ||||
| cat .env.docker | envsubst > .env && cat .env | ||||
| composer dump-autoload | ||||
| php artisan package:discover | ||||
| php artisan firefly:instructions install | ||||
| exec apache2-foreground | ||||
							
								
								
									
										82
									
								
								.deploy/kubernetes/firefly.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								.deploy/kubernetes/firefly.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| apiVersion: v1 | ||||
| kind: PersistentVolumeClaim | ||||
| metadata: | ||||
|   name: mysql-pv-export-claim | ||||
|   labels: | ||||
|     app: firefly-local | ||||
| spec: | ||||
|   accessModes: | ||||
|     - ReadWriteOnce | ||||
|   resources: | ||||
|     requests: | ||||
|       storage: 20Gi | ||||
| --- | ||||
| apiVersion: v1 | ||||
| kind: PersistentVolumeClaim | ||||
| metadata: | ||||
|   name: mysql-pv-upload-claim | ||||
|   labels: | ||||
|     app: firefly-local | ||||
| spec: | ||||
|   accessModes: | ||||
|     - ReadWriteOnce | ||||
|   resources: | ||||
|     requests: | ||||
|       storage: 20Gi | ||||
| ---  | ||||
| apiVersion: apps/v1beta1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   name: firefly-local | ||||
|   namespace: firefly | ||||
|   labels: | ||||
|     app: firefly-local | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: firefly-local | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: firefly-local | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: firefly-local | ||||
|         name: firefly-local | ||||
|         env: | ||||
|         - name: FF_APP_ENV | ||||
|           value: "local" | ||||
|         - name: FF_APP_KEY | ||||
|           value: "S0m3R@nd0mString0f32Ch@rsEx@ct1y" | ||||
|         - name: FF_DB_HOST | ||||
|           value: "172.17.0.9"  | ||||
|         - name: FF_DB_NAME | ||||
|           value: "firefly_db" | ||||
|         - name: FF_DB_USER | ||||
|           value: "firefly_db" | ||||
|         - name: FF_DB_PASSWORD | ||||
|           value: "password"  | ||||
|         volumeMounts: | ||||
|         - mountPath: "/var/www/firefly-iii/storage/export" | ||||
|           name: mysql-persistent-export | ||||
|         - mountPath: "/var/www/firefly-iii/storage/upload" | ||||
|           name: mysql-persistent-upload  | ||||
|         imagePullPolicy: IfNotPresent | ||||
|       volumes: | ||||
|         - name: mysql-persistent-export | ||||
|           persistentVolumeClaim: | ||||
|             claimName: mysql-pv-export-claim | ||||
|         - name: mysql-persistent-upload | ||||
|           persistentVolumeClaim: | ||||
|             claimName: mysql-pv-upload-claim | ||||
| --- | ||||
| apiVersion: v1 | ||||
| kind: Service | ||||
| metadata: | ||||
|   name: firefly-local | ||||
| spec: | ||||
|   ports: | ||||
|     - port: 80 | ||||
|   type: NodePort | ||||
|   selector: | ||||
|     app: firefly-local | ||||
							
								
								
									
										49
									
								
								.deploy/kubernetes/sql.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								.deploy/kubernetes/sql.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| apiVersion: v1 | ||||
| kind: Secret | ||||
| metadata: | ||||
|   name: sql-pass | ||||
| type: Opaque | ||||
| data: | ||||
|   password: cGFzc3dvcmQ= | ||||
| --- | ||||
| apiVersion: apps/v1beta1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   name: mysql | ||||
|   namespace: firefly | ||||
|   labels: | ||||
|     app: mysql | ||||
| spec: | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: mysql | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app: mysql | ||||
|     spec: | ||||
|       containers: | ||||
|       - image: mysql | ||||
|         imagePullPolicy: IfNotPresent | ||||
|         name: mysql | ||||
|         env: | ||||
|           - name: MYSQL_ROOT_PASSWORD | ||||
|             valueFrom: | ||||
|               secretKeyRef: | ||||
|                 name: sql-pass | ||||
|                 key: password | ||||
|         ports: | ||||
|         - containerPort: 3306 | ||||
|           name: mysql | ||||
| --- | ||||
| apiVersion: v1 | ||||
| kind: Service | ||||
| metadata: | ||||
|   name: mysql | ||||
| spec: | ||||
|   ports: | ||||
|     - port: 3306 | ||||
|   type: NodePort | ||||
|   selector: | ||||
|     app: mysql | ||||
|  | ||||
| @@ -1,4 +1,3 @@ | ||||
| # Ignore composer specific files and vendor folder | ||||
| composer.phar | ||||
| composer.lock | ||||
| vendor | ||||
|   | ||||
							
								
								
									
										22
									
								
								.env.docker
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								.env.docker
									
									
									
									
									
								
							| @@ -17,11 +17,14 @@ APP_KEY=${FF_APP_KEY} | ||||
| APP_URL=${APP_URL} | ||||
| TRUSTED_PROXIES=${TRUSTED_PROXIES} | ||||
|  | ||||
| # The log channel defines where your log entries go to. | ||||
| LOG_CHANNEL=${LOG_CHANNEL} | ||||
|  | ||||
| # Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III | ||||
| # If you use SQLite, set connection to `sqlite` and remove the database, username and password settings. | ||||
| DB_CONNECTION=mysql | ||||
| DB_CONNECTION=${FF_DB_CONNECTION} | ||||
| DB_HOST=${FF_DB_HOST} | ||||
| DB_PORT=3306 | ||||
| DB_PORT=${FF_DB_PORT} | ||||
| DB_DATABASE=${FF_DB_NAME} | ||||
| DB_USERNAME=${FF_DB_USER} | ||||
| DB_PASSWORD=${FF_DB_PASSWORD} | ||||
| @@ -47,6 +50,7 @@ COOKIE_DOMAIN= | ||||
| COOKIE_SECURE=false | ||||
|  | ||||
| # If you want Firefly III to mail you, update these settings | ||||
| # For instructions, see: https://firefly-iii.readthedocs.io/en/latest/installation/mail.html | ||||
| MAIL_DRIVER=${MAIL_DRIVER} | ||||
| MAIL_HOST=${MAIL_HOST} | ||||
| MAIL_PORT=${MAIL_PORT} | ||||
| @@ -55,6 +59,12 @@ MAIL_USERNAME=${MAIL_USERNAME} | ||||
| MAIL_PASSWORD=${MAIL_PASSWORD} | ||||
| MAIL_ENCRYPTION=${MAIL_ENCRYPTION} | ||||
|  | ||||
| # Other mail drivers: | ||||
| MAILGUN_DOMAIN=${MAILGUN_DOMAIN} | ||||
| MAILGUN_SECRET=${MAILGUN_SECRET} | ||||
| MANDRILL_SECRET=${MANDRILL_SECRET} | ||||
| SPARKPOST_SECRET=${SPARKPOST_SECRET} | ||||
|  | ||||
| # Firefly III can send you the following messages | ||||
| SEND_REGISTRATION_MAIL=true | ||||
| SEND_ERROR_MESSAGE=false | ||||
| @@ -62,6 +72,11 @@ SEND_ERROR_MESSAGE=false | ||||
| # Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places. | ||||
| MAPBOX_API_KEY=${MAPBOX_API_KEY} | ||||
|  | ||||
| # Set a Fixer IO API key here (see https://fixer.io) to enable live currency exchange rates. | ||||
| # Please note that this will only work for paid fixer.io accounts because they severly limited | ||||
| # the free API up to the point where you might as well offer nothing. | ||||
| FIXER_API_KEY=${FIXER_API_KEY} | ||||
|  | ||||
| # If you wish to track your own behavior over Firefly III, set a valid analytics tracker ID here. | ||||
| ANALYTICS_ID=${ANALYTICS_ID} | ||||
|  | ||||
| @@ -79,7 +94,6 @@ REDIS_PASSWORD=null | ||||
| REDIS_PORT=6379 | ||||
| CACHE_PREFIX=firefly | ||||
| SEARCH_RESULT_LIMIT=50 | ||||
| EXCHANGE_RATE_SERVICE=fixerio | ||||
| PUSHER_KEY= | ||||
| PUSHER_SECRET= | ||||
| PUSHER_ID= | ||||
| @@ -88,3 +102,5 @@ DEMO_PASSWORD= | ||||
| IS_DOCKER=true | ||||
| IS_SANDSTORM=false | ||||
| IS_HEROKU=false | ||||
| BUNQ_USE_SANDBOX=false | ||||
| TZ=${TZ} | ||||
|   | ||||
							
								
								
									
										27
									
								
								.env.example
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								.env.example
									
									
									
									
									
								
							| @@ -13,12 +13,19 @@ SITE_OWNER=mail@example.com | ||||
| # Change it to a string of exactly 32 chars or use command `php artisan key:generate` to generate it | ||||
| APP_KEY=SomeRandomStringOf32CharsExactly | ||||
|  | ||||
| # Change this value to your preferred time zone. | ||||
| # Example: Europe/Amsterdam | ||||
| TZ=UTC | ||||
|  | ||||
| # APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy. | ||||
| APP_URL=http://localhost | ||||
| TRUSTED_PROXIES= | ||||
|  | ||||
| # The log channel defines where your log entries go to. | ||||
| LOG_CHANNEL=daily | ||||
|  | ||||
| # Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III | ||||
| # If you use SQLite, set connection to `sqlite` and remove the database, username and password settings. | ||||
| # For other database types, please see the FAQ: http://firefly-iii.readthedocs.io/en/latest/support/faq.html | ||||
| DB_CONNECTION=mysql | ||||
| DB_HOST=127.0.0.1 | ||||
| DB_PORT=3306 | ||||
| @@ -47,7 +54,8 @@ COOKIE_DOMAIN= | ||||
| COOKIE_SECURE=false | ||||
|  | ||||
| # If you want Firefly III to mail you, update these settings | ||||
| MAIL_DRIVER=smtp | ||||
| # For instructions, see: https://firefly-iii.readthedocs.io/en/latest/installation/mail.html | ||||
| MAIL_DRIVER=log | ||||
| MAIL_HOST=smtp.mailtrap.io | ||||
| MAIL_PORT=2525 | ||||
| MAIL_FROM=changeme@example.com | ||||
| @@ -55,6 +63,12 @@ MAIL_USERNAME=null | ||||
| MAIL_PASSWORD=null | ||||
| MAIL_ENCRYPTION=null | ||||
|  | ||||
| # Other mail drivers: | ||||
| MAILGUN_DOMAIN= | ||||
| MAILGUN_SECRET= | ||||
| MANDRILL_SECRET= | ||||
| SPARKPOST_SECRET= | ||||
|  | ||||
| # Firefly III can send you the following messages | ||||
| SEND_REGISTRATION_MAIL=true | ||||
| SEND_ERROR_MESSAGE=true | ||||
| @@ -62,6 +76,11 @@ SEND_ERROR_MESSAGE=true | ||||
| # Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places. | ||||
| MAPBOX_API_KEY= | ||||
|  | ||||
| # Set a Fixer IO API key here (see https://fixer.io) to enable live currency exchange rates. | ||||
| # Please note that this will only work for paid fixer.io accounts because they severly limited | ||||
| # the free API up to the point where you might as well offer nothing. | ||||
| FIXER_API_KEY= | ||||
|  | ||||
| # If you wish to track your own behavior over Firefly III, set a valid analytics tracker ID here. | ||||
| ANALYTICS_ID= | ||||
|  | ||||
| @@ -79,7 +98,6 @@ REDIS_PASSWORD=null | ||||
| REDIS_PORT=6379 | ||||
| CACHE_PREFIX=firefly | ||||
| SEARCH_RESULT_LIMIT=50 | ||||
| EXCHANGE_RATE_SERVICE=fixerio | ||||
| PUSHER_KEY= | ||||
| PUSHER_SECRET= | ||||
| PUSHER_ID= | ||||
| @@ -87,4 +105,7 @@ DEMO_USERNAME= | ||||
| DEMO_PASSWORD= | ||||
| IS_DOCKER=false | ||||
| IS_SANDSTORM=false | ||||
| BUNQ_USE_SANDBOX=false | ||||
| IS_HEROKU=false | ||||
| MAILGUN_DOMAIN= | ||||
| MAILGUN_SECRET= | ||||
|   | ||||
							
								
								
									
										25
									
								
								.env.heroku
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								.env.heroku
									
									
									
									
									
								
							| @@ -13,10 +13,17 @@ SITE_OWNER=heroku@example.com | ||||
| # Change it to a string of exactly 32 chars or use command `php artisan key:generate` to generate it | ||||
| APP_KEY=7ahyYVPVsmxjdhsweWCauGeJfwc92NP2 | ||||
|  | ||||
| # Change this value to your preferred time zone. | ||||
| # Example: Europe/Amsterdam | ||||
| TZ=UTC | ||||
|  | ||||
| # APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy. | ||||
| APP_URL=http://localhost | ||||
| TRUSTED_PROXIES= | ||||
|  | ||||
| # The log channel defines where your log entries go to. | ||||
| LOG_CHANNEL=syslog | ||||
|  | ||||
| # Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III | ||||
| # If you use SQLite, set connection to `sqlite` and remove the database, username and password settings. | ||||
| DB_CONNECTION=pgsql | ||||
| @@ -47,7 +54,8 @@ COOKIE_DOMAIN= | ||||
| COOKIE_SECURE=false | ||||
|  | ||||
| # If you want Firefly III to mail you, update these settings | ||||
| MAIL_DRIVER=smtp | ||||
| # For instructions, see: https://firefly-iii.readthedocs.io/en/latest/installation/mail.html | ||||
| MAIL_DRIVER=log | ||||
| MAIL_HOST=smtp.mailtrap.io | ||||
| MAIL_PORT=2525 | ||||
| MAIL_FROM=changeme@example.com | ||||
| @@ -55,6 +63,12 @@ MAIL_USERNAME=null | ||||
| MAIL_PASSWORD=null | ||||
| MAIL_ENCRYPTION=null | ||||
|  | ||||
| # Other mail drivers: | ||||
| MAILGUN_DOMAIN= | ||||
| MAILGUN_SECRET= | ||||
| MANDRILL_SECRET= | ||||
| SPARKPOST_SECRET= | ||||
|  | ||||
| # Firefly III can send you the following messages | ||||
| SEND_REGISTRATION_MAIL=true | ||||
| SEND_ERROR_MESSAGE=true | ||||
| @@ -62,6 +76,11 @@ SEND_ERROR_MESSAGE=true | ||||
| # Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places. | ||||
| MAPBOX_API_KEY= | ||||
|  | ||||
| # Set a Fixer IO API key here (see https://fixer.io) to enable live currency exchange rates. | ||||
| # Please note that this will only work for paid fixer.io accounts because they severly limited | ||||
| # the free API up to the point where you might as well offer nothing. | ||||
| FIXER_API_KEY= | ||||
|  | ||||
| # If you wish to track your own behavior over Firefly III, set a valid analytics tracker ID here. | ||||
| ANALYTICS_ID= | ||||
|  | ||||
| @@ -79,7 +98,6 @@ REDIS_PASSWORD=null | ||||
| REDIS_PORT=6379 | ||||
| CACHE_PREFIX=firefly | ||||
| SEARCH_RESULT_LIMIT=50 | ||||
| EXCHANGE_RATE_SERVICE=fixerio | ||||
| PUSHER_KEY= | ||||
| PUSHER_SECRET= | ||||
| PUSHER_ID= | ||||
| @@ -87,4 +105,7 @@ DEMO_USERNAME= | ||||
| DEMO_PASSWORD= | ||||
| IS_DOCKER=false | ||||
| IS_SANDSTORM=false | ||||
| BUNQ_USE_SANDBOX=false | ||||
| IS_HEROKU=true | ||||
| MAILGUN_DOMAIN= | ||||
| MAILGUN_SECRET= | ||||
|   | ||||
| @@ -13,10 +13,17 @@ SITE_OWNER=sandstorm@example.com | ||||
| # Change it to a string of exactly 32 chars or use command `php artisan key:generate` to generate it | ||||
| APP_KEY=SomeRandomStringOf32CharsExactly | ||||
|  | ||||
| # Change this value to your preferred time zone. | ||||
| # Example: Europe/Amsterdam | ||||
| TZ=UTC | ||||
|  | ||||
| # APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy. | ||||
| APP_URL=http://localhost | ||||
| TRUSTED_PROXIES= | ||||
|  | ||||
| # The log channel defines where your log entries go to. | ||||
| LOG_CHANNEL=syslog | ||||
|  | ||||
| # Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III | ||||
| # If you use SQLite, set connection to `sqlite` and remove the database, username and password settings. | ||||
| DB_CONNECTION=mysql | ||||
| @@ -47,7 +54,8 @@ COOKIE_DOMAIN= | ||||
| COOKIE_SECURE=false | ||||
|  | ||||
| # If you want Firefly III to mail you, update these settings | ||||
| MAIL_DRIVER=smtp | ||||
| # For instructions, see: https://firefly-iii.readthedocs.io/en/latest/installation/mail.html | ||||
| MAIL_DRIVER=log | ||||
| MAIL_HOST=smtp.mailtrap.io | ||||
| MAIL_PORT=2525 | ||||
| MAIL_FROM=changeme@example.com | ||||
| @@ -55,6 +63,12 @@ MAIL_USERNAME=null | ||||
| MAIL_PASSWORD=null | ||||
| MAIL_ENCRYPTION=null | ||||
|  | ||||
| # Other mail drivers: | ||||
| MAILGUN_DOMAIN= | ||||
| MAILGUN_SECRET= | ||||
| MANDRILL_SECRET= | ||||
| SPARKPOST_SECRET= | ||||
|  | ||||
| # Firefly III can send you the following messages | ||||
| SEND_REGISTRATION_MAIL=true | ||||
| SEND_ERROR_MESSAGE=true | ||||
| @@ -62,6 +76,11 @@ SEND_ERROR_MESSAGE=true | ||||
| # Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places. | ||||
| MAPBOX_API_KEY= | ||||
|  | ||||
| # Set a Fixer IO API key here (see https://fixer.io) to enable live currency exchange rates. | ||||
| # Please note that this will only work for paid fixer.io accounts because they severly limited | ||||
| # the free API up to the point where you might as well offer nothing. | ||||
| FIXER_API_KEY= | ||||
|  | ||||
| # If you wish to track your own behavior over Firefly III, set a valid analytics tracker ID here. | ||||
| ANALYTICS_ID= | ||||
|  | ||||
| @@ -79,7 +98,6 @@ REDIS_PASSWORD=null | ||||
| REDIS_PORT=6379 | ||||
| CACHE_PREFIX=firefly | ||||
| SEARCH_RESULT_LIMIT=50 | ||||
| EXCHANGE_RATE_SERVICE=fixerio | ||||
| PUSHER_KEY= | ||||
| PUSHER_SECRET= | ||||
| PUSHER_ID= | ||||
| @@ -87,4 +105,7 @@ DEMO_USERNAME= | ||||
| DEMO_PASSWORD= | ||||
| IS_DOCKER=false | ||||
| IS_SANDSTORM=true | ||||
| BUNQ_USE_SANDBOX=false | ||||
| IS_HEROKU=false | ||||
| MAILGUN_DOMAIN= | ||||
| MAILGUN_SECRET= | ||||
|   | ||||
							
								
								
									
										95
									
								
								.env.testing
									
									
									
									
									
								
							
							
						
						
									
										95
									
								
								.env.testing
									
									
									
									
									
								
							| @@ -1,32 +1,55 @@ | ||||
| # You can leave this on "local". If you change it to production most console commands will ask for extra confirmation. | ||||
| # Never set it to "testing". | ||||
| APP_ENV=testing | ||||
|  | ||||
| # Set to true if you want to see debug information in error screens. | ||||
| APP_DEBUG=true | ||||
| APP_NAME=FireflyIII | ||||
|  | ||||
| # This should be your email address | ||||
| SITE_OWNER=thegrumpydictator+testing@gmail.com | ||||
|  | ||||
| # The encryption key for your database and sessions. Keep this very secure. | ||||
| # If you generate a new one all existing data must be considered LOST. | ||||
| # Change it to a string of exactly 32 chars or use command `php artisan key:generate` to generate it | ||||
| APP_KEY=TestTestTestTestTestTestTestTest | ||||
| APP_LOG=daily | ||||
| APP_LOG_LEVEL=debug | ||||
|  | ||||
| # Change this value to your preferred time zone. | ||||
| # Example: Europe/Amsterdam | ||||
| TZ=Europe/Amsterdam | ||||
|  | ||||
| # APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy. | ||||
| APP_URL=http://localhost | ||||
| TRUSTED_PROXIES= | ||||
|  | ||||
| DB_CONNECTION=sqlite | ||||
| DB_HOST=127.0.0.1 | ||||
| DB_PORT=3306 | ||||
| #DB_DATABASE=firefly | ||||
| DB_USERNAME=homestead | ||||
| DB_PASSWORD= | ||||
| # The log channel defines where your log entries go to. | ||||
| LOG_CHANNEL=dailytest | ||||
|  | ||||
| BROADCAST_DRIVER=log | ||||
| # Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III | ||||
| # For other database types, please see the FAQ: http://firefly-iii.readthedocs.io/en/latest/support/faq.html | ||||
| DB_CONNECTION=sqlite | ||||
|  | ||||
| # 'daily' is the default logging mode giving you 5 daily rotated log files in /storage/logs/. | ||||
| # Several other options exist. You can use 'single' for one big fat error log (not recommended). | ||||
| # Also available are 'syslog' and 'errorlog' which will log to the system itself. | ||||
| APP_LOG=daily | ||||
|  | ||||
| # Log level. You can set this from least severe to most severe: | ||||
| # debug, info, notice, warning, error, critical, alert, emergency | ||||
| # If you set it to debug your logs will grow large, and fast. If you set it to emergency probably | ||||
| # nothing will get logged, ever. | ||||
| APP_LOG_LEVEL=debug | ||||
|  | ||||
| # If you're looking for performance improvements, you could install memcached. | ||||
| CACHE_DRIVER=file | ||||
| SESSION_DRIVER=file | ||||
| QUEUE_DRIVER=sync | ||||
|  | ||||
| # Cookie settings. Should not be necessary to change these. | ||||
| COOKIE_PATH="/" | ||||
| COOKIE_DOMAIN= | ||||
| COOKIE_SECURE=false | ||||
|  | ||||
| REDIS_HOST=127.0.0.1 | ||||
| REDIS_PASSWORD=null | ||||
| REDIS_PORT=6379 | ||||
|  | ||||
| # If you want Firefly III to mail you, update these settings | ||||
| # For instructions, see: https://firefly-iii.readthedocs.io/en/latest/installation/mail.html | ||||
| MAIL_DRIVER=log | ||||
| MAIL_HOST=smtp.mailtrap.io | ||||
| MAIL_PORT=2525 | ||||
| @@ -35,26 +58,46 @@ MAIL_USERNAME=null | ||||
| MAIL_PASSWORD=null | ||||
| MAIL_ENCRYPTION=null | ||||
|  | ||||
| SEND_REGISTRATION_MAIL=true | ||||
| SEND_ERROR_MESSAGE=false | ||||
| # Other mail drivers: | ||||
| MAILGUN_DOMAIN= | ||||
| MAILGUN_SECRET= | ||||
| MANDRILL_SECRET= | ||||
| SPARKPOST_SECRET= | ||||
|  | ||||
| CACHE_PREFIX=firefly | ||||
|  | ||||
| SEARCH_RESULT_LIMIT=50 | ||||
| EXCHANGE_RATE_SERVICE=fixerio | ||||
|  | ||||
| # Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places. | ||||
| MAPBOX_API_KEY= | ||||
| ANALYTICS_ID= | ||||
| SITE_OWNER=mail@example.com | ||||
| USE_ENCRYPTION=true | ||||
|  | ||||
| # Set a Fixer IO API key here (see https://fixer.io) to enable live currency exchange rates. | ||||
| # Please note that this will only work for paid fixer.io accounts because they severly limited | ||||
| # the free API up to the point where you might as well offer nothing. | ||||
| FIXER_API_KEY= | ||||
|  | ||||
| # If you wish to track your own behavior over Firefly III, set a valid analytics tracker ID here. | ||||
| ANALYTICS_ID= | ||||
|  | ||||
| # Most parts of the database are encrypted by default, but you can turn this off if you want to. | ||||
| # This makes it easier to migrate your database. Not that some fields will never be decrypted. | ||||
| USE_ENCRYPTION=false | ||||
|  | ||||
| # Leave the following configuration vars as is. | ||||
| # Unless you like to tinker and know what you're doing. | ||||
| APP_NAME=FireflyIII | ||||
| BROADCAST_DRIVER=log | ||||
| QUEUE_DRIVER=sync | ||||
| REDIS_HOST=127.0.0.1 | ||||
| REDIS_PASSWORD=null | ||||
| REDIS_PORT=6379 | ||||
| CACHE_PREFIX=firefly_tst | ||||
| SEARCH_RESULT_LIMIT=50 | ||||
| PUSHER_KEY= | ||||
| PUSHER_SECRET= | ||||
| PUSHER_ID= | ||||
|  | ||||
| DEMO_USERNAME= | ||||
| DEMO_PASSWORD= | ||||
|  | ||||
| IS_DOCKER=false | ||||
| IS_SANDSTORM=false | ||||
| BUNQ_USE_SANDBOX=true | ||||
| IS_HEROKU=false | ||||
| MAILGUN_DOMAIN= | ||||
| MAILGUN_SECRET= | ||||
|   | ||||
							
								
								
									
										22
									
								
								.github/ISSUE_TEMPLATE/Bug_report.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								.github/ISSUE_TEMPLATE/Bug_report.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| --- | ||||
| name: Bug report | ||||
| about: Create a report to help Firefly III improve | ||||
|  | ||||
| --- | ||||
|  | ||||
| **Bug description** | ||||
| I am running Firefly III version x.x.x | ||||
|  | ||||
| (please give a clear and concise description of what the bug is) | ||||
|  | ||||
| **Steps to reproduce** | ||||
| What do you need to do to trigger this bug? | ||||
|  | ||||
| **Extra info** | ||||
| Please add extra info here, such as OS, browser, and the output from the /debug page of your Firefly III installation (click the version at the bottom). | ||||
|  | ||||
| **Bonus points** | ||||
| Earn bonus points by: | ||||
|  | ||||
| - Post a stacktrace from your log files | ||||
| - Add a screenshot | ||||
							
								
								
									
										27
									
								
								.github/ISSUE_TEMPLATE/Custom.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								.github/ISSUE_TEMPLATE/Custom.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| --- | ||||
| name: I have a question or a problem | ||||
| about: Ask away! | ||||
|  | ||||
| --- | ||||
|  | ||||
| I am running Firefly III version x.x.x | ||||
|  | ||||
| **Description** | ||||
|  | ||||
|  | ||||
|  | ||||
| **Steps to reproduce**  | ||||
| (if relevant of course) | ||||
|  | ||||
|  | ||||
|  | ||||
| **Extra info** | ||||
| Please add extra info here, such as OS, browser, and the output from the `/debug`-page of your Firefly III installation (click the version at the bottom).  | ||||
|  | ||||
|  | ||||
|  | ||||
| **Bonus points** | ||||
| Earn bonus points by: | ||||
|  | ||||
| - Add a screenshot | ||||
| - Replicate the problem on the demo site https://demo.firefly-iii.org/ | ||||
							
								
								
									
										21
									
								
								.github/ISSUE_TEMPLATE/Feature_request.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								.github/ISSUE_TEMPLATE/Feature_request.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| --- | ||||
| name: Feature request | ||||
| about: Suggest an idea or feature for Firefly III | ||||
|  | ||||
| --- | ||||
|  | ||||
| **Description** | ||||
| Please describe your feature request: | ||||
|  | ||||
| - I would like Firefly III to do X. | ||||
| - What if you would add feature Y? | ||||
| - Firefly III doesn't do Z. | ||||
|  | ||||
| **Solution** | ||||
| Describe what your feature would add to Firefly III. | ||||
|  | ||||
| **What are alternatives?** | ||||
| Please describe what alternatives currently exist. | ||||
|  | ||||
| **Additional context** | ||||
| Add any other context or screenshots about the feature request here. | ||||
							
								
								
									
										11
									
								
								.github/issue_template.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								.github/issue_template.md
									
									
									
									
										vendored
									
									
								
							| @@ -1,11 +0,0 @@ | ||||
| I am running Firefly III version x.x.x  | ||||
|  | ||||
| #### Description of my issue: | ||||
|  | ||||
| #### Steps to reproduce  | ||||
|  | ||||
| (please include if this problem also exists on the demo site) | ||||
|  | ||||
| #### Other important details (log files, system info): | ||||
|  | ||||
| Please click the version number in the right corner of any Firefly III page to get debug information.  | ||||
							
								
								
									
										56
									
								
								.github/stale.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								.github/stale.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| # Configuration for probot-stale - https://github.com/probot/stale | ||||
|  | ||||
| # Number of days of inactivity before an Issue or Pull Request becomes stale | ||||
| daysUntilStale: 14 | ||||
|  | ||||
| # Number of days of inactivity before a stale Issue or Pull Request is closed. | ||||
| # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. | ||||
| daysUntilClose: 7 | ||||
|  | ||||
| # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable | ||||
| # - "[Status] Maybe Later" | ||||
| exemptLabels: | ||||
|   - enhancement | ||||
|   - feature | ||||
|   - bug | ||||
|  | ||||
| # Set to true to ignore issues in a project (defaults to false) | ||||
| exemptProjects: false | ||||
|  | ||||
| # Set to true to ignore issues in a milestone (defaults to false) | ||||
| exemptMilestones: false | ||||
|  | ||||
| # Label to use when marking as stale | ||||
| staleLabel: stale | ||||
|  | ||||
| # Comment to post when marking as stale. Set to `false` to disable | ||||
| markComment: > | ||||
|   This issue has been automatically marked as stale because it has not had | ||||
|   recent activity. It will be closed if no further activity occurs. Thank you | ||||
|   for your contributions. | ||||
|  | ||||
| # Comment to post when removing the stale label. | ||||
| # unmarkComment: > | ||||
| #   Your comment here. | ||||
|  | ||||
| # Comment to post when closing a stale Issue or Pull Request. | ||||
| # closeComment: > | ||||
| #   Your comment here. | ||||
|  | ||||
| # Limit the number of actions per hour, from 1-30. Default is 30 | ||||
| limitPerRun: 30 | ||||
|  | ||||
| # Limit to only `issues` or `pulls` | ||||
| # only: issues | ||||
|  | ||||
| # Optionally, specify configuration settings that are specific to just 'issues' or 'pulls': | ||||
| # pulls: | ||||
| #   daysUntilStale: 30 | ||||
| #   markComment: > | ||||
| #     This pull request has been automatically marked as stale because it has not had | ||||
| #     recent activity. It will be closed if no further activity occurs. Thank you | ||||
| #     for your contributions. | ||||
|  | ||||
| # issues: | ||||
| #   exemptLabels: | ||||
| #     - confirmed | ||||
| @@ -1,3 +1,145 @@ | ||||
| # 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 | ||||
| - Currency added to API | ||||
| - Firfely III will also generate a cash wallet for new users. | ||||
| - Can now reset Spectre and bunq settings | ||||
| - Docker file has a time zone | ||||
| - Allow database connection to be configured in Docker file | ||||
| - Can now view and edit attachments in edit-screen | ||||
| - User can visit hidden `/attachments` page | ||||
| - [Issue 1356](https://github.com/firefly-iii/firefly-iii/issues/1356): Budgets will show the remaining amount per day | ||||
| - [Issue 1367](https://github.com/firefly-iii/firefly-iii/issues/1367): Rules now come in strict and non-strict mode. | ||||
| - Added a security.txt | ||||
| - More support for trusted proxies | ||||
| - Improved edit routine for split transactions. | ||||
| - Upgrade routine can handle `proc_close` being disabled. | ||||
| - Bills now use rules to match transactions, making it more flexible. | ||||
| - [Issue 1328](https://github.com/firefly-iii/firefly-iii/issues/1328): piggy banks no have a more useful chart. | ||||
| - Spectre API upgraded to v4 | ||||
| - Move to MariaDB ([issue 1366](https://github.com/firefly-iii/firefly-iii/issues/1366)) | ||||
| - Piggy banks take currency from parent account ([issue 1334](https://github.com/firefly-iii/firefly-iii/issues/1334)) | ||||
| - [Issue 1341](https://github.com/firefly-iii/firefly-iii/issues/1341): Removed depricated command from dockerfile | ||||
| - Several issues with docker image ([issue 1320](https://github.com/firefly-iii/firefly-iii/issues/1320), [issue 1382](https://github.com/firefly-iii/firefly-iii/issues/1382)). | ||||
| - Fix giant tags and division by zero ([issue 1325](https://github.com/firefly-iii/firefly-iii/issues/1325) and others) | ||||
| - Several issues with bunq import ([issue 1352](https://github.com/firefly-iii/firefly-iii/issues/1352), [issue 1330](https://github.com/firefly-iii/firefly-iii/issues/1330), [issue 1378](https://github.com/firefly-iii/firefly-iii/issues/1378), [issue 1380](https://github.com/firefly-iii/firefly-iii/issues/1380)) | ||||
| - [Issue 1246](https://github.com/firefly-iii/firefly-iii/issues/1246): date picker is internationalised | ||||
| - [Issue 1327](https://github.com/firefly-iii/firefly-iii/issues/1327): fix formattting issues in piggy banks | ||||
| - [Issue 1348](https://github.com/firefly-iii/firefly-iii/issues/1348): 500 error in API | ||||
| - [Issue 1349](https://github.com/firefly-iii/firefly-iii/issues/1349): Errors in import routine | ||||
| - Several fixes for (multi-currency) reconciliation ([issue 1336](https://github.com/firefly-iii/firefly-iii/issues/1336), [issue 1363](https://github.com/firefly-iii/firefly-iii/issues/1363)) | ||||
| - [Issue 1353](https://github.com/firefly-iii/firefly-iii/issues/1353): return NULL values in range-indicator | ||||
| - Bug in split transaction edit routine | ||||
| - Piggy bank percentage was very specific. | ||||
| - Logging in Slack is easier to config. | ||||
| - [Issue 1312](https://github.com/firefly-iii/firefly-iii/issues/1312) Import broken for ING accounts | ||||
| - [Issue 1313](https://github.com/firefly-iii/firefly-iii/issues/1313) Error when creating new asset account | ||||
| - [Issue 1317](https://github.com/firefly-iii/firefly-iii/issues/1317) Forgot an include :( | ||||
| - Null pointer exception in transaction overview. | ||||
| - Installations running in subdirs were incapable of creating OAuth tokens. | ||||
| - OAuth keys were not created in all cases. | ||||
|  | ||||
| # 4.7.2 | ||||
| - [Issue 1123](https://github.com/firefly-iii/firefly-iii/issues/1123) First browser based update routine. | ||||
| - Add support for Italian. | ||||
| - [Issue 1232](https://github.com/firefly-iii/firefly-iii/issues/1232) Allow user to specify Docker database port. | ||||
| - [Issue 1197](https://github.com/firefly-iii/firefly-iii/issues/1197) Beter account list overview  | ||||
| - [Issue 1202](https://github.com/firefly-iii/firefly-iii/issues/1202) Some budgetary warnings  | ||||
| - [Issue 1284](https://github.com/firefly-iii/firefly-iii/issues/1284) Experimental support for bunq import | ||||
| - [Issue 1248](https://github.com/firefly-iii/firefly-iii/issues/1248) Ability to import BIC, ability to import SEPA fields.  | ||||
| - [Issue 1102](https://github.com/firefly-iii/firefly-iii/issues/1102) Summary line for bills  | ||||
| - More info to debug page. | ||||
| - [Issue 1186](https://github.com/firefly-iii/firefly-iii/issues/1186) You can see the latest account balance in CRUD forms  | ||||
| - Add Kubernetes YAML files, kindly created by a FF3 user. | ||||
| - [Issue 1244](https://github.com/firefly-iii/firefly-iii/issues/1244) Better line for "today" marker and add it to other chart as well ([issue 1214](https://github.com/firefly-iii/firefly-iii/issues/1214)) | ||||
| - [Issue 1219](https://github.com/firefly-iii/firefly-iii/issues/1219) Languages in dropdown  | ||||
| - [Issue 1189](https://github.com/firefly-iii/firefly-iii/issues/1189) Inactive accounts get removed from net worth  | ||||
| - [Issue 1220](https://github.com/firefly-iii/firefly-iii/issues/1220) Attachment description and notes migrated to just "notes".  | ||||
| - [Issue 1236](https://github.com/firefly-iii/firefly-iii/issues/1236) Multi currency balance box  | ||||
| - [Issue 1240](https://github.com/firefly-iii/firefly-iii/issues/1240) Better overview for accounts.  | ||||
| - [Issue 1292](https://github.com/firefly-iii/firefly-iii/issues/1292) Removed some charts from the "all"-overview of budgets and categories  | ||||
| - [Issue 1245](https://github.com/firefly-iii/firefly-iii/issues/1245) Improved recognition of IBANs  | ||||
| - Improved import routine. | ||||
| - Update notifier will wait three days before notifying users. | ||||
| - [Issue 1300](https://github.com/firefly-iii/firefly-iii/issues/1300) Virtual balance of credit cards does not count for net worth  | ||||
| - [Issue 1247](https://github.com/firefly-iii/firefly-iii/issues/1247) Can now see overspent amount  | ||||
| - [Issue 1221](https://github.com/firefly-iii/firefly-iii/issues/1221) Upgrade to Laravel 5.6  | ||||
| - [Issue 1187](https://github.com/firefly-iii/firefly-iii/issues/1187) Updated the password verifier to use Troy Hunt's new API  | ||||
| - Revenue chart is now on frontpage permanently | ||||
| - [Issue 1153](https://github.com/firefly-iii/firefly-iii/issues/1153) 2FA settings are in your profile now  | ||||
| - [Issue 1227](https://github.com/firefly-iii/firefly-iii/issues/1227) Can set the timezone in config or in Docker  | ||||
| - [Issue 1294](https://github.com/firefly-iii/firefly-iii/issues/1294) Ability to link a transaction to itself  | ||||
| - Correct reference to journal description in split form. | ||||
| - [Issue 1234](https://github.com/firefly-iii/firefly-iii/issues/1234) Fix budget page issues in SQLite  | ||||
| - [Issue 1262](https://github.com/firefly-iii/firefly-iii/issues/1262) Can now use double and epty headers in CSV files  | ||||
| - [Issue 1258](https://github.com/firefly-iii/firefly-iii/issues/1258) Fixed a possible date mismatch in piggy banks | ||||
| - [Issue 1283](https://github.com/firefly-iii/firefly-iii/issues/1283) Bulk delete was broken  | ||||
| - [Issue 1293](https://github.com/firefly-iii/firefly-iii/issues/1293) Layout problem with notes  | ||||
| - [Issue 1257](https://github.com/firefly-iii/firefly-iii/issues/1257) Improve transaction lists query count  | ||||
| - [Issue 1291](https://github.com/firefly-iii/firefly-iii/issues/1291) Fixer IO problems  | ||||
| - [Issue 1239](https://github.com/firefly-iii/firefly-iii/issues/1239) Could not edit expense or revenue accounts ([issue 1298](https://github.com/firefly-iii/firefly-iii/issues/1298))  | ||||
| - [Issue 1297](https://github.com/firefly-iii/firefly-iii/issues/1297) Could not convert to withdrawal  | ||||
| - [Issue 1226](https://github.com/firefly-iii/firefly-iii/issues/1226) Category overview in default report shows no income.  | ||||
| - Various other bugs and problems ([issue 1198](https://github.com/firefly-iii/firefly-iii/issues/1198), [issue 1213](https://github.com/firefly-iii/firefly-iii/issues/1213), [issue 1237](https://github.com/firefly-iii/firefly-iii/issues/1237), [issue 1238](https://github.com/firefly-iii/firefly-iii/issues/1238), [issue 1199](https://github.com/firefly-iii/firefly-iii/issues/1199), [issue 1200](https://github.com/firefly-iii/firefly-iii/issues/1200)) | ||||
| - Fixed an issue with token validation on the command line. | ||||
|  | ||||
| # 4.7.1 | ||||
| - A brand new API. Read about it in the [documentation](http://firefly-iii.readthedocs.io/en/latest/). | ||||
| - Add support for Spanish. [issue 1194](https://github.com/firefly-iii/firefly-iii/issues/1194) | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -15,8 +15,8 @@ const pkgdef :Spk.PackageDefinition = ( | ||||
|  | ||||
|   manifest = ( | ||||
|     appTitle = (defaultText = "Firefly III"), | ||||
|     appVersion = 9, | ||||
|     appMarketingVersion = (defaultText = "4.7.1"), | ||||
|     appVersion = 14, | ||||
|     appMarketingVersion = (defaultText = "4.7.5.1"), | ||||
|  | ||||
|     actions = [ | ||||
|       # Define your "new document" handlers here. | ||||
| @@ -65,9 +65,9 @@ const pkgdef :Spk.PackageDefinition = ( | ||||
|         # Sizes are given in device-independent pixels, so if you took these | ||||
|         # screenshots on a Retina-style high DPI screen, divide each dimension by two. | ||||
|  | ||||
|         (width = 1291, height = 800, png = embed "screenshots/screenshot-1.png"), | ||||
|         (width = 1291, height = 800, png = embed "screenshots/screenshot-2.png"), | ||||
|         (width = 1291, height = 800, png = embed "screenshots/screenshot-3.png"), | ||||
|         (width = 1290, height = 800, png = embed "screenshots/screenshot-1.png"), | ||||
|         (width = 1290, height = 800, png = embed "screenshots/screenshot-2.png"), | ||||
|         (width = 1290, height = 800, png = embed "screenshots/screenshot-3.png"), | ||||
|  | ||||
|       ], | ||||
|       changeLog = (defaultText = embed "changelog.md"), | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 173 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 171 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 163 KiB | 
| @@ -14,12 +14,17 @@ apt-get install -y python-software-properties software-properties-common | ||||
|  | ||||
| # install all languages | ||||
| sed -i 's/# de_DE.UTF-8 UTF-8/de_DE.UTF-8 UTF-8/g' /etc/locale.gen | ||||
|  | ||||
| sed -i 's/# es_ES.UTF-8 UTF-8/es_ES.UTF-8 UTF-8/g' /etc/locale.gen | ||||
| sed -i 's/# fr_FR.UTF-8 UTF-8/fr_FR.UTF-8 UTF-8/g' /etc/locale.gen | ||||
| sed -i 's/# id_ID.UTF-8 UTF-8/id_ID.UTF-8 UTF-8/g' /etc/locale.gen | ||||
| sed -i 's/# it_IT.UTF-8 UTF-8/it_IT.UTF-8 UTF-8/g' /etc/locale.gen | ||||
| sed -i 's/# nl_NL.UTF-8 UTF-8/nl_NL.UTF-8 UTF-8/g' /etc/locale.gen | ||||
| sed -i 's/# pl_PL.UTF-8 UTF-8/pl_PL.UTF-8 UTF-8/g' /etc/locale.gen | ||||
| sed -i 's/# pt_BR.UTF-8 UTF-8/pt_BR.UTF-8 UTF-8/g' /etc/locale.gen | ||||
| sed -i 's/# ru_RU.UTF-8 UTF-8/ru_RU.UTF-8 UTF-8/g' /etc/locale.gen | ||||
| sed -i 's/# tr_TR.UTF-8 UTF-8/tr_TR.UTF-8 UTF-8/g' /etc/locale.gen | ||||
|  | ||||
| dpkg-reconfigure --frontend=noninteractive locales | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| language: php | ||||
| php: | ||||
|   - 7.1 | ||||
|   - 7.1.18 | ||||
|  | ||||
| cache: | ||||
|     directories: | ||||
| @@ -12,21 +12,18 @@ install: | ||||
|   - composer update --no-scripts | ||||
|   - cp .env.testing .env | ||||
|   - php artisan clear-compiled | ||||
|   - php artisan optimize | ||||
|   - php artisan env | ||||
|   - cp .env.testing .env | ||||
|   - wget -q https://github.com/firefly-iii/test-data/raw/master/storage/database.sqlite -O storage/database/database.sqlite | ||||
|   - mkdir -p build/logs | ||||
|  | ||||
| script: | ||||
|   - phpunit -c phpunit.coverage.xml | ||||
|   - ./vendor/bin/phpunit -c phpunit.coverage.xml | ||||
|  | ||||
| after_success: | ||||
|   - travis_retry php vendor/bin/php-coveralls -x storage/build/clover-all.xml | ||||
|   - bash <(curl -s https://codecov.io/bash) -f storage/build/clover-all.xml | ||||
|  | ||||
| # safelist | ||||
| branches: | ||||
|   only: | ||||
|   - develop | ||||
|   - master | ||||
|   - master | ||||
|   | ||||
							
								
								
									
										48
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								Dockerfile
									
									
									
									
									
								
							| @@ -3,6 +3,8 @@ FROM php:7.1-apache | ||||
|  | ||||
| # set working dir | ||||
| ENV FIREFLY_PATH /var/www/firefly-iii | ||||
| ENV CURL_VERSION 7.60.0 | ||||
| ENV OPENSSL_VERSION 1.1.1-pre6 | ||||
| WORKDIR $FIREFLY_PATH | ||||
| ADD . $FIREFLY_PATH | ||||
|  | ||||
| @@ -11,7 +13,8 @@ RUN apt-get update -y && \ | ||||
|     apt-get install -y --no-install-recommends libcurl4-openssl-dev \ | ||||
|                                                zlib1g-dev \ | ||||
|                                                libjpeg62-turbo-dev \ | ||||
|                                                libpng12-dev \ | ||||
|                                                wget \ | ||||
|                                                libpng-dev \ | ||||
|                                                libicu-dev \ | ||||
|                                                libedit-dev \ | ||||
|                                                libtidy-dev \ | ||||
| @@ -20,18 +23,46 @@ RUN apt-get update -y && \ | ||||
|                                                libpq-dev \ | ||||
|                                                libbz2-dev \ | ||||
|                                                gettext-base \ | ||||
|                                                cron \ | ||||
|                                                locales && \ | ||||
|                                                apt-get clean && \ | ||||
|                                                rm -rf /var/lib/apt/lists/* | ||||
|  | ||||
| # Setup the Composer installer | ||||
| RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer | ||||
|  | ||||
| # Install latest curl | ||||
| RUN cd /tmp && \ | ||||
|     wget https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz && \ | ||||
|     tar -xvf openssl-${OPENSSL_VERSION}.tar.gz && \ | ||||
|     cd openssl-${OPENSSL_VERSION} && \ | ||||
|     ./config && \ | ||||
|     make && \ | ||||
|     make install | ||||
|  | ||||
| RUN cd /tmp && \ | ||||
|     wget https://curl.haxx.se/download/curl-${CURL_VERSION}.tar.gz && \ | ||||
|     tar -xvf curl-${CURL_VERSION}.tar.gz && \ | ||||
|     cd curl-${CURL_VERSION} && \ | ||||
|     ./configure --with-ssl && \ | ||||
|     make && \ | ||||
|     make install | ||||
|  | ||||
|  | ||||
| # Create the log file to be able to run tail | ||||
| RUN touch /var/log/cron.log | ||||
|  | ||||
| # Setup cron job | ||||
| RUN (crontab -l ; echo "* * * * * root $FIREFLY_PATH/artisan schedule:run >> /var/log/cron.log") | crontab | ||||
|  | ||||
| # Install PHP exentions. | ||||
| RUN docker-php-ext-install -j$(nproc) curl gd intl json readline tidy zip bcmath xml mbstring pdo_sqlite pdo_mysql bz2 pdo_pgsql | ||||
|  | ||||
| # Generate locales supported by Firefly III | ||||
| RUN echo "de_DE.UTF-8 UTF-8\nen_US.UTF-8 UTF-8\nfr_FR.UTF-8 UTF-8\nid_ID.UTF-8 UTF-8\nnl_NL.UTF-8 UTF-8\npl_PL.UTF-8 UTF-8" > /etc/locale.gen && locale-gen | ||||
| RUN echo "de_DE.UTF-8 UTF-8\nen_US.UTF-8 UTF-8\nes_ES.UTF-8 UTF-8\nfr_FR.UTF-8 UTF-8\nid_ID.UTF-8 UTF-8\nit_IT.UTF-8 UTF-8\nnl_NL.UTF-8 UTF-8\npl_PL.UTF-8 UTF-8pt_BR.UTF-8 UTF-8ru_RU.UTF-8 UTF-8\ntr_TR.UTF-8 UTF-8\n\n" > /etc/locale.gen && locale-gen | ||||
|  | ||||
| # copy Apache config to correct spot. | ||||
| COPY ./docker/apache2.conf /etc/apache2/apache2.conf | ||||
| COPY ./.deploy/docker/apache2.conf /etc/apache2/apache2.conf | ||||
|  | ||||
| # Enable apache mod rewrite.. | ||||
| RUN a2enmod rewrite | ||||
| @@ -42,11 +73,8 @@ RUN a2enmod ssl | ||||
| # Create volumes for several directories: | ||||
| VOLUME $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload | ||||
|  | ||||
| # Setup the Composer installer | ||||
| RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer | ||||
|  | ||||
| # Enable default site (Firefly III) | ||||
| COPY ./docker/apache-firefly.conf /etc/apache2/sites-available/000-default.conf | ||||
| COPY ./.deploy/docker/apache-firefly.conf /etc/apache2/sites-available/000-default.conf | ||||
|  | ||||
| # Make sure we own Firefly III directory | ||||
| RUN chown -R www-data:www-data /var/www && chmod -R 775 $FIREFLY_PATH/storage | ||||
| @@ -57,5 +85,9 @@ RUN composer install --prefer-dist --no-dev --no-scripts --no-suggest | ||||
| # Expose port 80 | ||||
| EXPOSE 80 | ||||
|  | ||||
| # Run the command on container startup | ||||
| CMD cron | ||||
|  | ||||
| # Run entrypoint thing | ||||
| ENTRYPOINT ["docker/entrypoint.sh"] | ||||
| ENTRYPOINT [".deploy/docker/entrypoint.sh"] | ||||
|  | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * AboutController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -25,37 +26,30 @@ namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use DB; | ||||
| use FireflyIII\Transformers\UserTransformer; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use League\Fractal\Manager; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Class AboutController | ||||
|  * Returns basic information about this installation. | ||||
|  * | ||||
|  * Class AboutController. | ||||
|  */ | ||||
| class AboutController extends Controller | ||||
| { | ||||
|     /** | ||||
|      * AccountController constructor. | ||||
|      * Returns system information. | ||||
|      * | ||||
|      * @throws \FireflyIII\Exceptions\FireflyException | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function about() | ||||
|     public function about(): JsonResponse | ||||
|     { | ||||
|         $search        = ['~', '#']; | ||||
|         $replace       = ['\~', '# ']; | ||||
|         $phpVersion    = str_replace($search, $replace, PHP_VERSION); | ||||
|         $phpOs         = str_replace($search, $replace, php_uname()); | ||||
|         $phpOs         = str_replace($search, $replace, PHP_OS); | ||||
|         $currentDriver = DB::getDriverName(); | ||||
|         $data | ||||
|                        = [ | ||||
| @@ -64,18 +58,19 @@ class AboutController extends Controller | ||||
|             'php_version' => $phpVersion, | ||||
|             'os'          => $phpOs, | ||||
|             'driver'      => $currentDriver, | ||||
|  | ||||
|         ]; | ||||
|  | ||||
|         return response()->json(['data' => $data], 200)->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns information about the user. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function user(Request $request) | ||||
|     public function user(Request $request): JsonResponse | ||||
|     { | ||||
|         $manager = new Manager(); | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
| @@ -84,5 +79,4 @@ class AboutController extends Controller | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -29,6 +29,8 @@ use FireflyIII\Models\AccountType; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | ||||
| use FireflyIII\Transformers\AccountTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use League\Fractal\Manager; | ||||
| @@ -36,35 +38,35 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
| use Preferences; | ||||
|  | ||||
| /** | ||||
|  * Class AccountController | ||||
|  * Class AccountController. | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  */ | ||||
| class AccountController extends Controller | ||||
| { | ||||
|  | ||||
|     /** @var CurrencyRepositoryInterface */ | ||||
|     /** @var CurrencyRepositoryInterface The currency repository */ | ||||
|     private $currencyRepository; | ||||
|     /** @var AccountRepositoryInterface */ | ||||
|     /** @var AccountRepositoryInterface The account repository */ | ||||
|     private $repository; | ||||
|  | ||||
|     /** | ||||
|      * AccountController constructor. | ||||
|      * | ||||
|      * @throws \FireflyIII\Exceptions\FireflyException | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 /** @var AccountRepositoryInterface repository */ | ||||
|                 /** @var User $user */ | ||||
|                 $user = auth()->user(); | ||||
|                 // @var AccountRepositoryInterface repository | ||||
|                 $this->repository = app(AccountRepositoryInterface::class); | ||||
|                 $this->repository->setUser(auth()->user()); | ||||
|                 $this->repository->setUser($user); | ||||
|  | ||||
|                 $this->currencyRepository = app(CurrencyRepositoryInterface::class); | ||||
|                 $this->currencyRepository->setUser(auth()->user()); | ||||
|                 $this->currencyRepository->setUser($user); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
| @@ -74,11 +76,11 @@ class AccountController extends Controller | ||||
|     /** | ||||
|      * Remove the specified resource from storage. | ||||
|      * | ||||
|      * @param  \FireflyIII\Models\Account $account | ||||
|      * @param \FireflyIII\Models\Account $account | ||||
|      * | ||||
|      * @return \Illuminate\Http\Response | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function delete(Account $account) | ||||
|     public function delete(Account $account): JsonResponse | ||||
|     { | ||||
|         $this->repository->destroy($account, null); | ||||
|  | ||||
| @@ -90,21 +92,21 @@ class AccountController extends Controller | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function index(Request $request) | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         // create some objects: | ||||
|         $manager   = new Manager(); | ||||
|         $baseUrl   = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|  | ||||
|         // read type from URI | ||||
|         $type = $request->get('type') ?? 'all'; | ||||
|         $this->parameters->set('type', $type); | ||||
|  | ||||
|         // types to get, page size: | ||||
|         $types      = $this->mapTypes($this->parameters->get('type')); | ||||
|         $pageSize   = intval(Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data); | ||||
|         $types    = $this->mapTypes($this->parameters->get('type')); | ||||
|         $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|  | ||||
|         // get list of accounts. Count it and split it. | ||||
|         $collection = $this->repository->getAccountsByType($types); | ||||
| @@ -124,14 +126,16 @@ class AccountController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show single instance. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param Account $account | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function show(Request $request, Account $account) | ||||
|     public function show(Request $request, Account $account): JsonResponse | ||||
|     { | ||||
|         $manager = new Manager(); | ||||
|         $manager = new Manager; | ||||
|  | ||||
|         // add include parameter: | ||||
|         $include = $request->get('include') ?? ''; | ||||
| @@ -145,27 +149,28 @@ class AccountController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Store a new instance. | ||||
|      * | ||||
|      * @param AccountRequest $request | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function store(AccountRequest $request) | ||||
|     public function store(AccountRequest $request): JsonResponse | ||||
|     { | ||||
|         $data = $request->getAll(); | ||||
|         // if currency ID is 0, find the currency by the code: | ||||
|         if ($data['currency_id'] === 0) { | ||||
|         if (0 === $data['currency_id']) { | ||||
|             $currency            = $this->currencyRepository->findByCodeNull($data['currency_code']); | ||||
|             $data['currency_id'] = is_null($currency) ? 0 : $currency->id; | ||||
|             $data['currency_id'] = null === $currency ? 0 : $currency->id; | ||||
|         } | ||||
|         $account = $this->repository->store($data); | ||||
|         $manager = new Manager(); | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($account, new AccountTransformer($this->parameters), 'accounts'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -176,18 +181,18 @@ class AccountController extends Controller | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function update(AccountRequest $request, Account $account) | ||||
|     public function update(AccountRequest $request, Account $account): JsonResponse | ||||
|     { | ||||
|         $data = $request->getAll(); | ||||
|         // if currency ID is 0, find the currency by the code: | ||||
|         if ($data['currency_id'] === 0) { | ||||
|         if (0 === $data['currency_id']) { | ||||
|             $currency            = $this->currencyRepository->findByCodeNull($data['currency_code']); | ||||
|             $data['currency_id'] = is_null($currency) ? 0 : $currency->id; | ||||
|             $data['currency_id'] = null === $currency ? 0 : $currency->id; | ||||
|         } | ||||
|         // set correct type: | ||||
|         $data['type'] = config('firefly.shortNamesByFullName.' . $account->accountType->type); | ||||
|         $this->repository->update($account, $data); | ||||
|         $manager = new Manager(); | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
| @@ -197,52 +202,25 @@ class AccountController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * All the available types. | ||||
|      * | ||||
|      * @param string $type | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     private function mapTypes(string $type): array | ||||
|     { | ||||
|         $types = [ | ||||
|             'all'                        => [ | ||||
|                 AccountType::DEFAULT, | ||||
|                 AccountType::CASH, | ||||
|                 AccountType::ASSET, | ||||
|                 AccountType::EXPENSE, | ||||
|                 AccountType::REVENUE, | ||||
|                 AccountType::INITIAL_BALANCE, | ||||
|                 AccountType::BENEFICIARY, | ||||
|                 AccountType::IMPORT, | ||||
|                 AccountType::RECONCILIATION, | ||||
|                 AccountType::LOAN, | ||||
|             ], | ||||
|             'asset'                      => [ | ||||
|                 AccountType::DEFAULT, | ||||
|                 AccountType::ASSET, | ||||
|             ], | ||||
|             '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, | ||||
|             ], | ||||
|         $types  = [ | ||||
|             'all'                        => [AccountType::DEFAULT, AccountType::CASH, AccountType::ASSET, AccountType::EXPENSE, AccountType::REVENUE, | ||||
|                                              AccountType::INITIAL_BALANCE, AccountType::BENEFICIARY, AccountType::IMPORT, AccountType::RECONCILIATION, | ||||
|                                              AccountType::LOAN,], | ||||
|             'asset'                      => [AccountType::DEFAULT, AccountType::ASSET,], | ||||
|             '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::CASH            => [AccountType::CASH], | ||||
|             AccountType::ASSET           => [AccountType::ASSET], | ||||
| @@ -254,10 +232,11 @@ class AccountController extends Controller | ||||
|             AccountType::RECONCILIATION  => [AccountType::RECONCILIATION], | ||||
|             AccountType::LOAN            => [AccountType::LOAN], | ||||
|         ]; | ||||
|         $return = $types['all']; | ||||
|         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); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										190
									
								
								app/Api/V1/Controllers/AvailableBudgetController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								app/Api/V1/Controllers/AvailableBudgetController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,190 @@ | ||||
| <?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['transaction_currency_id']); | ||||
|         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,4 +1,5 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * BillController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -18,6 +19,7 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
| @@ -27,6 +29,8 @@ use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Repositories\Bill\BillRepositoryInterface; | ||||
| use FireflyIII\Transformers\BillTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Support\Collection; | ||||
| use League\Fractal\Manager; | ||||
| @@ -34,29 +38,29 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
| use Preferences; | ||||
|  | ||||
| /** | ||||
|  * Class BillController | ||||
|  * Class BillController. | ||||
|  */ | ||||
| class BillController extends Controller | ||||
| { | ||||
|     /** @var BillRepositoryInterface */ | ||||
|     /** @var BillRepositoryInterface The bill repository */ | ||||
|     private $repository; | ||||
|  | ||||
|     /** | ||||
|      * BillController constructor. | ||||
|      * | ||||
|      * @throws \FireflyIII\Exceptions\FireflyException | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 /** @var User $admin */ | ||||
|                 $admin = auth()->user(); | ||||
|  | ||||
|                 /** @var BillRepositoryInterface repository */ | ||||
|                 $this->repository = app(BillRepositoryInterface::class); | ||||
|                 $this->repository->setUser(auth()->user()); | ||||
|                 $this->repository->setUser($admin); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
| @@ -66,11 +70,11 @@ class BillController extends Controller | ||||
|     /** | ||||
|      * Remove the specified resource from storage. | ||||
|      * | ||||
|      * @param  \FireflyIII\Models\Bill $bill | ||||
|      * @param  Bill $bill | ||||
|      * | ||||
|      * @return \Illuminate\Http\Response | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function delete(Bill $bill) | ||||
|     public function delete(Bill $bill): JsonResponse | ||||
|     { | ||||
|         $this->repository->destroy($bill); | ||||
|  | ||||
| @@ -82,11 +86,11 @@ class BillController extends Controller | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function index(Request $request) | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         $pageSize  = intval(Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data); | ||||
|         $pageSize  = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|         $paginator = $this->repository->getPaginator($pageSize); | ||||
|         /** @var Collection $bills */ | ||||
|         $bills = $paginator->getCollection(); | ||||
| @@ -103,12 +107,14 @@ class BillController extends Controller | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Show the specified bill. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param Bill    $bill | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function show(Request $request, Bill $bill) | ||||
|     public function show(Request $request, Bill $bill): JsonResponse | ||||
|     { | ||||
|         $manager = new Manager(); | ||||
|         // add include parameter: | ||||
| @@ -124,31 +130,39 @@ class BillController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Store a bill. | ||||
|      * | ||||
|      * @param BillRequest $request | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function store(BillRequest $request) | ||||
|     public function store(BillRequest $request): JsonResponse | ||||
|     { | ||||
|         $bill    = $this->repository->store($request->getAll()); | ||||
|         $manager = new Manager(); | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $bill = $this->repository->store($request->getAll()); | ||||
|         if (null !== $bill) { | ||||
|             $manager = new Manager(); | ||||
|             $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|             $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($bill, new BillTransformer($this->parameters), 'bills'); | ||||
|             $resource = new Item($bill, new BillTransformer($this->parameters), 'bills'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|             return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|         } | ||||
|         throw new FireflyException('Could not store new bill.'); // @codeCoverageIgnore | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Update a bill. | ||||
|      * | ||||
|      * @param BillRequest $request | ||||
|      * @param Bill        $bill | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function update(BillRequest $request, Bill $bill) | ||||
|     public function update(BillRequest $request, Bill $bill): JsonResponse | ||||
|     { | ||||
|         $data    = $request->getAll(); | ||||
|         $bill    = $this->repository->update($bill, $data); | ||||
|   | ||||
							
								
								
									
										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'); | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										215
									
								
								app/Api/V1/Controllers/BudgetLimitController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								app/Api/V1/Controllers/BudgetLimitController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,215 @@ | ||||
| <?php | ||||
| /** | ||||
|  * BudgetLimitController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Api\V1\Requests\BudgetLimitRequest; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\BudgetLimit; | ||||
| use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; | ||||
| use FireflyIII\Transformers\BudgetLimitTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use Illuminate\Support\Collection; | ||||
| use InvalidArgumentException; | ||||
| use League\Fractal\Manager; | ||||
| use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
| use Log; | ||||
|  | ||||
| /** | ||||
|  * 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'; | ||||
|         $start    = null; | ||||
|         $end      = null; | ||||
|         $budgetId = (int)($request->get('budget_id') ?? 0); | ||||
|         $budget   = $this->repository->findNull($budgetId); | ||||
|         $this->parameters->set('budget_id', $budgetId); | ||||
|  | ||||
|         try { | ||||
|             $start = Carbon::createFromFormat('Y-m-d', $request->get('start')); | ||||
|             $this->parameters->set('start', $start->format('Y-m-d')); | ||||
|         } catch (InvalidArgumentException $e) { | ||||
|             Log::debug(sprintf('Invalid date: %s', $e->getMessage())); | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             $end = Carbon::createFromFormat('Y-m-d', $request->get('end')); | ||||
|             $this->parameters->set('end', $end->format('Y-m-d')); | ||||
|         } catch (InvalidArgumentException $e) { | ||||
|             Log::debug(sprintf('Invalid date: %s', $e->getMessage())); | ||||
|         } | ||||
|  | ||||
|         $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|  | ||||
|         $collection = new Collection; | ||||
|         if (null === $budget) { | ||||
|             $collection = $this->repository->getAllBudgetLimits($start, $end); | ||||
|         } | ||||
|         if (null !== $budget) { | ||||
|             $collection = $this->repository->getBudgetLimits($budget, $start, $end); | ||||
|         } | ||||
|  | ||||
|         $count        = $collection->count(); | ||||
|         $budgetLimits = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
|         $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'); | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										135
									
								
								app/Api/V1/Controllers/ConfigurationController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								app/Api/V1/Controllers/ConfigurationController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,135 @@ | ||||
| <?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')) { | ||||
|                     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,4 +1,5 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Controller.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -18,84 +19,80 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use Carbon\Exceptions\InvalidDateException; | ||||
| use FireflyConfig; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use Illuminate\Foundation\Auth\Access\AuthorizesRequests; | ||||
| use Illuminate\Foundation\Bus\DispatchesJobs; | ||||
| use Illuminate\Foundation\Validation\ValidatesRequests; | ||||
| use Illuminate\Routing\Controller as BaseController; | ||||
| use Log; | ||||
| use Symfony\Component\HttpFoundation\ParameterBag; | ||||
|  | ||||
| /** | ||||
|  * Class Controller. | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @SuppressWarnings(PHPMD.NumberOfChildren) | ||||
|  */ | ||||
| class Controller extends BaseController | ||||
| { | ||||
|     use AuthorizesRequests, DispatchesJobs, ValidatesRequests; | ||||
|  | ||||
|     /** @var ParameterBag */ | ||||
|     /** @var ParameterBag Parameters from the URI are stored here. */ | ||||
|     protected $parameters; | ||||
|  | ||||
|     /** | ||||
|      * Controller constructor. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         // is site a demo site? | ||||
|         $isDemoSite = FireflyConfig::get('is_demo_site', config('firefly.configuration.is_demo_site'))->data; | ||||
|  | ||||
|         // do not expose API on demo site: | ||||
|         if (true === $isDemoSite) { | ||||
|             throw new FireflyException('The API is not available on the demo site.'); | ||||
|         } | ||||
|  | ||||
|         // get global parameters | ||||
|         $this->parameters = $this->getParameters(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to help build URI's. | ||||
|      * | ||||
|      * @return string | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      */ | ||||
|     protected function buildParams(): string | ||||
|     { | ||||
|         $return = '?'; | ||||
|         $params = []; | ||||
|         foreach ($this->parameters as $key => $value) { | ||||
|             if($key === 'page') { | ||||
|             if ('page' === $key) { | ||||
|                 continue; | ||||
|             } | ||||
|             if ($value instanceof Carbon) { | ||||
|                 $params[$key] = $value->format('Y-m-d'); | ||||
|                 continue; | ||||
|             } | ||||
|             if (!$value instanceof Carbon) { | ||||
|                 $params[$key] = $value; | ||||
|             } | ||||
|             $params[$key] = $value; | ||||
|         } | ||||
|         $return .= http_build_query($params); | ||||
|         if (strlen($return) === 1) { | ||||
|             return ''; | ||||
|         } | ||||
|  | ||||
|         return $return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to grab all parameters from the URI. | ||||
|      * | ||||
|      * @return ParameterBag | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      */ | ||||
|     private function getParameters(): ParameterBag | ||||
|     { | ||||
|         $bag  = new ParameterBag; | ||||
|         $page = (int)request()->get('page'); | ||||
|         if ($page === 0) { | ||||
|         if (0 === $page) { | ||||
|             $page = 1; | ||||
|         } | ||||
|         $bag->set('page', $page); | ||||
| @@ -105,11 +102,12 @@ class Controller extends BaseController | ||||
|         foreach ($dates as $field) { | ||||
|             $date = request()->get($field); | ||||
|             $obj  = null; | ||||
|             if (!is_null($date)) { | ||||
|             if (null !== $date) { | ||||
|                 try { | ||||
|                     $obj = new Carbon($date); | ||||
|                 } catch (InvalidDateException $e) { | ||||
|                     // don't care | ||||
|                     Log::error(sprintf('Invalid date exception in API controller: %s', $e->getMessage())); | ||||
|                 } | ||||
|             } | ||||
|             $bag->set($field, $obj); | ||||
|   | ||||
							
								
								
									
										219
									
								
								app/Api/V1/Controllers/CurrencyController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										219
									
								
								app/Api/V1/Controllers/CurrencyController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,219 @@ | ||||
| <?php | ||||
| /** | ||||
|  * CurrencyController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use FireflyIII\Api\V1\Requests\CurrencyRequest; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | ||||
| use FireflyIII\Repositories\User\UserRepositoryInterface; | ||||
| use FireflyIII\Transformers\CurrencyTransformer; | ||||
| use 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 CurrencyController. | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  */ | ||||
| class CurrencyController extends Controller | ||||
| { | ||||
|     /** @var CurrencyRepositoryInterface The currency repository */ | ||||
|     private $repository; | ||||
|     /** @var UserRepositoryInterface The user repository */ | ||||
|     private $userRepository; | ||||
|  | ||||
|     /** | ||||
|      * CurrencyRepository constructor. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 /** @var User $admin */ | ||||
|                 $admin = auth()->user(); | ||||
|  | ||||
|                 /** @var CurrencyRepositoryInterface repository */ | ||||
|                 $this->repository     = app(CurrencyRepositoryInterface::class); | ||||
|                 $this->userRepository = app(UserRepositoryInterface::class); | ||||
|                 $this->repository->setUser($admin); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Remove the specified resource from storage. | ||||
|      * | ||||
|      * @param  TransactionCurrency $currency | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function delete(TransactionCurrency $currency): JsonResponse | ||||
|     { | ||||
|         /** @var User $admin */ | ||||
|         $admin = auth()->user(); | ||||
|  | ||||
|         if (!$this->userRepository->hasRole($admin, 'owner')) { | ||||
|             // access denied: | ||||
|             throw new FireflyException('No access to method, user is not owner.'); // @codeCoverageIgnore | ||||
|         } | ||||
|         if (!$this->repository->canDeleteCurrency($currency)) { | ||||
|             throw new FireflyException('No access to method, currency is in use.'); // @codeCoverageIgnore | ||||
|         } | ||||
|         $this->repository->destroy($currency); | ||||
|  | ||||
|         return response()->json([], 204); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Display a listing of the resource. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         $pageSize   = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|         $collection = $this->repository->get(); | ||||
|         $count      = $collection->count(); | ||||
|         // slice them: | ||||
|         $currencies = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
|         $paginator  = new LengthAwarePaginator($currencies, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.currencies.index') . $this->buildParams()); | ||||
|  | ||||
|  | ||||
|         $manager = new Manager(); | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user()); | ||||
|         $this->parameters->set('defaultCurrency', $defaultCurrency); | ||||
|  | ||||
|         $resource = new FractalCollection($currencies, new CurrencyTransformer($this->parameters), 'currencies'); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Show a currency. | ||||
|      * | ||||
|      * @param Request             $request | ||||
|      * @param TransactionCurrency $currency | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function show(Request $request, TransactionCurrency $currency): JsonResponse | ||||
|     { | ||||
|         $manager = new Manager(); | ||||
|         // add include parameter: | ||||
|         $include = $request->get('include') ?? ''; | ||||
|         $manager->parseIncludes($include); | ||||
|  | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user()); | ||||
|         $this->parameters->set('defaultCurrency', $defaultCurrency); | ||||
|  | ||||
|         $resource = new Item($currency, new CurrencyTransformer($this->parameters), 'currencies'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Store new currency. | ||||
|      * | ||||
|      * @param CurrencyRequest $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function store(CurrencyRequest $request): JsonResponse | ||||
|     { | ||||
|         $currency = $this->repository->store($request->getAll()); | ||||
|  | ||||
|         if (null !== $currency) { | ||||
|             if (true === $request->boolean('default')) { | ||||
|                 app('preferences')->set('currencyPreference', $currency->code); | ||||
|                 app('preferences')->mark(); | ||||
|             } | ||||
|             $manager = new Manager(); | ||||
|             $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|             $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|             $defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user()); | ||||
|             $this->parameters->set('defaultCurrency', $defaultCurrency); | ||||
|  | ||||
|             $resource = new Item($currency, new CurrencyTransformer($this->parameters), 'currencies'); | ||||
|  | ||||
|             return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|         } | ||||
|         throw new FireflyException('Could not store new currency.'); // @codeCoverageIgnore | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Update a currency. | ||||
|      * | ||||
|      * @param CurrencyRequest     $request | ||||
|      * @param TransactionCurrency $currency | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function update(CurrencyRequest $request, TransactionCurrency $currency): JsonResponse | ||||
|     { | ||||
|         $data     = $request->getAll(); | ||||
|         $currency = $this->repository->update($currency, $data); | ||||
|  | ||||
|         if (true === $request->boolean('default')) { | ||||
|             app('preferences')->set('currencyPreference', $currency->code); | ||||
|             app('preferences')->mark(); | ||||
|         } | ||||
|  | ||||
|         $manager = new Manager(); | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user()); | ||||
|         $this->parameters->set('defaultCurrency', $defaultCurrency); | ||||
|  | ||||
|         $resource = new Item($currency, new CurrencyTransformer($this->parameters), 'currencies'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										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'); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										217
									
								
								app/Api/V1/Controllers/JournalLinkController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								app/Api/V1/Controllers/JournalLinkController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,217 @@ | ||||
| <?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.'); // @codeCoverageIgnore | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 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'); | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										146
									
								
								app/Api/V1/Controllers/PreferenceController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								app/Api/V1/Controllers/PreferenceController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,146 @@ | ||||
| <?php | ||||
| /** | ||||
|  * PreferencesController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use FireflyIII\Api\V1\Requests\PreferenceRequest; | ||||
| use FireflyIII\Models\Preference; | ||||
| use FireflyIII\Transformers\PreferenceTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Support\Collection; | ||||
| use League\Fractal\Manager; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
| use Preferences; | ||||
|  | ||||
| /** | ||||
|  * | ||||
|  * Class PreferenceController | ||||
|  */ | ||||
| class PreferenceController extends Controller | ||||
| { | ||||
|     /** | ||||
|      * List all of them. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse] | ||||
|      */ | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         /** @var User $user */ | ||||
|         $user        = auth()->user(); | ||||
|         $available   = [ | ||||
|             'language', 'customFiscalYear', 'fiscalYearStart', 'currencyPreference', | ||||
|             'transaction_journal_optional_fields', 'frontPageAccounts', 'viewRange', | ||||
|             'listPageSize, twoFactorAuthEnabled', | ||||
|         ]; | ||||
|         $preferences = new Collection; | ||||
|         foreach ($available as $name) { | ||||
|             $pref = Preferences::getForUser($user, $name); | ||||
|             if (null !== $pref) { | ||||
|                 $preferences->push($pref); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // create some objects: | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|  | ||||
|         // present to user. | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new FractalCollection($preferences, new PreferenceTransformer($this->parameters), 'preferences'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * List single resource. | ||||
|      * | ||||
|      * @param Request    $request | ||||
|      * @param Preference $preference | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function show(Request $request, Preference $preference): JsonResponse | ||||
|     { | ||||
|         // create some objects: | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|  | ||||
|         // present to user. | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new Item($preference, new PreferenceTransformer($this->parameters), 'preferences'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 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 = 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.piggy_banks.index') . $this->buildParams()); | ||||
|  | ||||
|         // present to user. | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new FractalCollection($rules, new RuleTransformer($this->parameters), 'rules'); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * List single resource. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param Rule    $rule | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function show(Request $request, Rule $rule): JsonResponse | ||||
|     { | ||||
|         $manager = new Manager(); | ||||
|         // add include parameter: | ||||
|         $include = $request->get('include') ?? ''; | ||||
|         $manager->parseIncludes($include); | ||||
|  | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($rule, new RuleTransformer($this->parameters), 'rules'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Store new object. | ||||
|      * | ||||
|      * @param 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 budgets. Count it and split it. | ||||
|         $collection = $this->ruleGroupRepository->get(); | ||||
|         $count      = $collection->count(); | ||||
|         $ruleGroups = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
|  | ||||
|         // make paginator: | ||||
|         $paginator = new LengthAwarePaginator($ruleGroups, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.rule_groups.index') . $this->buildParams()); | ||||
|  | ||||
|         // present to user. | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new FractalCollection($ruleGroups, new RuleGroupTransformer($this->parameters), 'rule_groups'); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * List single resource. | ||||
|      * | ||||
|      * @param Request   $request | ||||
|      * @param RuleGroup $ruleGroup | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function show(Request $request, RuleGroup $ruleGroup): JsonResponse | ||||
|     { | ||||
|         $manager = new Manager(); | ||||
|         // add include parameter: | ||||
|         $include = $request->get('include') ?? ''; | ||||
|         $manager->parseIncludes($include); | ||||
|  | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($ruleGroup, new RuleGroupTransformer($this->parameters), 'rule_groups'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Store new object. | ||||
|      * | ||||
|      * @param RuleGroupRequest $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function store(RuleGroupRequest $request): JsonResponse | ||||
|     { | ||||
|         $ruleGroup = $this->ruleGroupRepository->store($request->getAll()); | ||||
|         $manager   = new Manager(); | ||||
|         $baseUrl   = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($ruleGroup, new RuleGroupTransformer($this->parameters), 'rule_groups'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 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,4 +1,5 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * TransactionController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -24,6 +25,7 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use FireflyIII\Api\V1\Requests\TransactionRequest; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Helpers\Collector\JournalCollectorInterface; | ||||
| use FireflyIII\Helpers\Filter\InternalTransferFilter; | ||||
| use FireflyIII\Helpers\Filter\NegativeAmountFilter; | ||||
| @@ -32,38 +34,39 @@ use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionType; | ||||
| use FireflyIII\Repositories\Journal\JournalRepositoryInterface; | ||||
| use FireflyIII\Transformers\TransactionTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Support\Collection; | ||||
| use League\Fractal\Manager; | ||||
| use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
| use Log; | ||||
| use Preferences; | ||||
|  | ||||
| /** | ||||
|  * Class TransactionController | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  */ | ||||
| class TransactionController extends Controller | ||||
| { | ||||
|  | ||||
|     /** @var JournalRepositoryInterface */ | ||||
|     /** @var JournalRepositoryInterface The journal repository */ | ||||
|     private $repository; | ||||
|  | ||||
|     /** | ||||
|      * TransactionController constructor. | ||||
|      * | ||||
|      * @throws \FireflyIII\Exceptions\FireflyException | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 /** @var User $admin */ | ||||
|                 $admin = auth()->user(); | ||||
|  | ||||
|                 /** @var JournalRepositoryInterface repository */ | ||||
|                 $this->repository = app(JournalRepositoryInterface::class); | ||||
|                 $this->repository->setUser(auth()->user()); | ||||
|                 $this->repository->setUser($admin); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
| @@ -75,9 +78,9 @@ class TransactionController extends Controller | ||||
|      * | ||||
|      * @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; | ||||
|         $this->repository->destroy($journal); | ||||
| @@ -86,37 +89,36 @@ class TransactionController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show all transactions. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function index(Request $request) | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         $pageSize = intval(Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data); | ||||
|  | ||||
|         // read type from URI | ||||
|         $type = $request->get('type') ?? 'default'; | ||||
|         $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|         $type     = $request->get('type') ?? 'default'; | ||||
|         $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(); | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         // collect transactions using the journal collector | ||||
|         /** @var User $admin */ | ||||
|         $admin = auth()->user(); | ||||
|         /** @var JournalCollectorInterface $collector */ | ||||
|         $collector = app(JournalCollectorInterface::class); | ||||
|         $collector->setUser(auth()->user()); | ||||
|         $collector->setUser($admin); | ||||
|         $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); | ||||
|         $collector->setAllAssetAccounts(); | ||||
|  | ||||
|         // remove internal transfer filter: | ||||
|         if (in_array(TransactionType::TRANSFER, $types)) { | ||||
|         if (\in_array(TransactionType::TRANSFER, $types, true)) { | ||||
|             $collector->removeFilter(InternalTransferFilter::class); | ||||
|         } | ||||
|  | ||||
|         if (!is_null($this->parameters->get('start')) && !is_null($this->parameters->get('end'))) { | ||||
|         if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) { | ||||
|             $collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); | ||||
|         } | ||||
|         $collector->setLimit($pageSize)->setPage($this->parameters->get('page')); | ||||
| @@ -125,7 +127,6 @@ class TransactionController extends Controller | ||||
|         $paginator->setPath(route('api.v1.transactions.index') . $this->buildParams()); | ||||
|         $transactions = $paginator->getCollection(); | ||||
|  | ||||
|  | ||||
|         $resource = new FractalCollection($transactions, new TransactionTransformer($this->parameters), 'transactions'); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
|  | ||||
| @@ -134,19 +135,23 @@ class TransactionController extends Controller | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Show a single transaction. | ||||
|      * | ||||
|      * @param Request     $request | ||||
|      * @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(); | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         // add include parameter: | ||||
|         $include = $request->get('include') ?? ''; | ||||
|         $include = $include ?? ''; | ||||
|         $include = $request->get('include') ?? $include; | ||||
|         $manager->parseIncludes($include); | ||||
|  | ||||
|         // collect transactions using the journal collector | ||||
| @@ -166,17 +171,22 @@ class TransactionController extends Controller | ||||
|         } | ||||
|  | ||||
|         $transactions = $collector->getJournals(); | ||||
|         $resource     = new Item($transactions->first(), new TransactionTransformer($this->parameters), 'transactions'); | ||||
|         $resource     = new FractalCollection($transactions, new TransactionTransformer($this->parameters), 'transactions'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionRequest $request | ||||
|      * Store a new transaction. | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @param TransactionRequest         $request | ||||
|      * | ||||
|      * @param JournalRepositoryInterface $repository | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function store(TransactionRequest $request, JournalRepositoryInterface $repository) | ||||
|     public function store(TransactionRequest $request, JournalRepositoryInterface $repository): JsonResponse | ||||
|     { | ||||
|         $data         = $request->getAll(); | ||||
|         $data['user'] = auth()->user()->id; | ||||
| @@ -214,23 +224,21 @@ class TransactionController extends Controller | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Update a transaction. | ||||
|      * | ||||
|      * @param TransactionRequest         $request | ||||
|      * @param JournalRepositoryInterface $repository | ||||
|      * @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['user'] = auth()->user()->id; | ||||
|  | ||||
|         Log::debug('Inside transaction update'); | ||||
|  | ||||
|         $journal = $repository->update($transaction->transactionJournal, $data); | ||||
|  | ||||
|         $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)); | ||||
|  | ||||
|         // add include parameter: | ||||
| @@ -262,72 +270,38 @@ class TransactionController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * All the types you can request. | ||||
|      * | ||||
|      * @param string $type | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     private function mapTypes(string $type): array | ||||
|     { | ||||
|         $types = [ | ||||
|             'all'             => [ | ||||
|                 TransactionType::WITHDRAWAL, | ||||
|                 TransactionType::DEPOSIT, | ||||
|                 TransactionType::TRANSFER, | ||||
|                 TransactionType::OPENING_BALANCE, | ||||
|                 TransactionType::RECONCILIATION, | ||||
|             ], | ||||
|             'withdrawal'      => [ | ||||
|                 TransactionType::WITHDRAWAL, | ||||
|             ], | ||||
|             'withdrawals'     => [ | ||||
|                 TransactionType::WITHDRAWAL, | ||||
|             ], | ||||
|             'expense'         => [ | ||||
|                 TransactionType::WITHDRAWAL, | ||||
|             ], | ||||
|             '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, | ||||
|             ], | ||||
|         $types  = [ | ||||
|             'all'             => [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE, | ||||
|                                   TransactionType::RECONCILIATION,], | ||||
|             'withdrawal'      => [TransactionType::WITHDRAWAL,], | ||||
|             'withdrawals'     => [TransactionType::WITHDRAWAL,], | ||||
|             'expense'         => [TransactionType::WITHDRAWAL,], | ||||
|             '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])) { | ||||
|             return $types[$type]; | ||||
|             $return = $types[$type]; | ||||
|         } | ||||
|  | ||||
|         return $types['default']; // @codeCoverageIgnore | ||||
|         return $return; | ||||
|  | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * UserController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -24,9 +25,11 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use FireflyIII\Api\V1\Requests\UserRequest; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Repositories\User\UserRepositoryInterface; | ||||
| use FireflyIII\Transformers\UserTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use League\Fractal\Manager; | ||||
| @@ -34,22 +37,21 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
| use Preferences; | ||||
| use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Class UserController | ||||
|  * Class UserController. | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  */ | ||||
| class UserController extends Controller | ||||
| { | ||||
|  | ||||
|     /** @var UserRepositoryInterface */ | ||||
|     /** @var UserRepositoryInterface The user repository */ | ||||
|     private $repository; | ||||
|  | ||||
|     /** | ||||
|      * UserController constructor. | ||||
|      * | ||||
|      * @throws \FireflyIII\Exceptions\FireflyException | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -69,16 +71,19 @@ class UserController extends Controller | ||||
|      * | ||||
|      * @param  \FireflyIII\User $user | ||||
|      * | ||||
|      * @return \Illuminate\Http\Response | ||||
|      * @return JsonResponse | ||||
|      * @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); | ||||
|  | ||||
|             return response()->json([], 204); | ||||
|         } | ||||
|         throw new AccessDeniedException(''); // @codeCoverageIgnore | ||||
|         throw new FireflyException('No access to method.'); // @codeCoverageIgnore | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -86,12 +91,12 @@ class UserController extends Controller | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function index(Request $request) | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         // user preferences | ||||
|         $pageSize = intval(Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data); | ||||
|         $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|  | ||||
|         // make manager | ||||
|         $manager = new Manager(); | ||||
| @@ -115,12 +120,14 @@ class UserController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show a single user. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @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 | ||||
|         $manager = new Manager(); | ||||
| @@ -138,11 +145,13 @@ class UserController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Store a new user. | ||||
|      * | ||||
|      * @param UserRequest $request | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function store(UserRequest $request) | ||||
|     public function store(UserRequest $request): JsonResponse | ||||
|     { | ||||
|         $data = $request->getAll(); | ||||
|         $user = $this->repository->store($data); | ||||
| @@ -163,12 +172,14 @@ class UserController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Update a user. | ||||
|      * | ||||
|      * @param UserRequest $request | ||||
|      * @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(); | ||||
|         $user = $this->repository->update($user, $data); | ||||
| @@ -189,4 +200,4 @@ class UserController extends Controller | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * AccountRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -22,7 +23,6 @@ | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
|  | ||||
| /** | ||||
|  * Class AccountRequest | ||||
|  */ | ||||
| @@ -30,6 +30,8 @@ class AccountRequest extends Request | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * Authorize logged in users. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize(): bool | ||||
| @@ -39,6 +41,8 @@ class AccountRequest extends Request | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all data from the request. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getAll(): array | ||||
| @@ -66,13 +70,15 @@ class AccountRequest extends Request | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
|         $accountRoles   = join(',', config('firefly.accountRoles')); | ||||
|         $types          = join(',', array_keys(config('firefly.subTitlesByIdentifier'))); | ||||
|         $ccPaymentTypes = join(',', array_keys(config('firefly.ccTypes'))); | ||||
|         $accountRoles   = implode(',', config('firefly.accountRoles')); | ||||
|         $types          = implode(',', array_keys(config('firefly.subTitlesByIdentifier'))); | ||||
|         $ccPaymentTypes = implode(',', array_keys(config('firefly.ccTypes'))); | ||||
|         $rules          = [ | ||||
|             'name'                    => 'required|min:1|uniqueAccountForUser', | ||||
|             'opening_balance'         => 'numeric|required_with:opening_balance_date|nullable', | ||||
| @@ -104,4 +110,4 @@ class AccountRequest extends Request | ||||
|  | ||||
|         return $rules; | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
							
								
								
									
										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; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										76
									
								
								app/Api/V1/Requests/AvailableBudgetRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								app/Api/V1/Requests/AvailableBudgetRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| <?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 [ | ||||
|             'transaction_currency_id' => $this->integer('transaction_currency_id'), | ||||
|             'amount'                  => $this->string('amount'), | ||||
|             'start_date'              => $this->date('start_date'), | ||||
|             'end_date'                => $this->date('end_date'), | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * TODO must also accept currency code. | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
|         $rules = [ | ||||
|             'transaction_currency_id' => 'required|numeric|exists:transaction_currencies,id', | ||||
|             'amount'                  => 'required|numeric|more:0', | ||||
|             'start_date'              => 'required|date|before:end_date', | ||||
|             'end_date'                => 'required|date|after:start_date', | ||||
|         ]; | ||||
|  | ||||
|         return $rules; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
| @@ -1,4 +1,5 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * BillRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -32,6 +33,8 @@ class BillRequest extends Request | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * Authorize logged in users. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize(): bool | ||||
| @@ -41,55 +44,56 @@ class BillRequest extends Request | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all data from the request. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getAll(): array | ||||
|     { | ||||
|         $data = [ | ||||
|             'name'        => $this->string('name'), | ||||
|             'match'       => $this->string('match'), | ||||
|             'amount_min'  => $this->string('amount_min'), | ||||
|             'amount_max'  => $this->string('amount_max'), | ||||
|             //'currency_id'   => $this->integer('currency_id'), | ||||
|             //'currency_code' => $this->string('currency_code'), | ||||
|             'date'        => $this->date('date'), | ||||
|             'repeat_freq' => $this->string('repeat_freq'), | ||||
|             'skip'        => $this->integer('skip'), | ||||
|             'automatch'   => $this->boolean('automatch'), | ||||
|             'active'      => $this->boolean('active'), | ||||
|             'notes'       => $this->string('notes'), | ||||
|             'name'          => $this->string('name'), | ||||
|             'amount_min'    => $this->string('amount_min'), | ||||
|             'amount_max'    => $this->string('amount_max'), | ||||
|             'currency_id'   => $this->integer('currency_id'), | ||||
|             'currency_code' => $this->string('currency_code'), | ||||
|             'date'          => $this->date('date'), | ||||
|             'repeat_freq'   => $this->string('repeat_freq'), | ||||
|             'skip'          => $this->integer('skip'), | ||||
|             'automatch'     => $this->boolean('automatch'), | ||||
|             'active'        => $this->boolean('active'), | ||||
|             'notes'         => $this->string('notes'), | ||||
|         ]; | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
|         $rules = [ | ||||
|             'name'        => 'required|between:1,255|uniqueObjectForUser:bills,name', | ||||
|             'match'       => 'required|between:1,255|uniqueObjectForUser:bills,match', | ||||
|             'amount_min'  => 'required|numeric|more:0', | ||||
|             'amount_max'  => 'required|numeric|more:0', | ||||
|             //'currency_id'   => 'numeric|exists:transaction_currencies,id|required_without:currency_code', | ||||
|             //'currency_code' => 'min:3|max:3|exists:transaction_currencies,code|required_without:currency_id', | ||||
|             'date'        => 'required|date', | ||||
|             'repeat_freq' => 'required|in:weekly,monthly,quarterly,half-year,yearly', | ||||
|             'skip'        => 'required|between:0,31', | ||||
|             'automatch'   => 'required|boolean', | ||||
|             'active'      => 'required|boolean', | ||||
|             'notes'       => 'between:1,65536', | ||||
|             'name'          => 'required|between:1,255|uniqueObjectForUser:bills,name', | ||||
|             'amount_min'    => 'required|numeric|more:0', | ||||
|             'amount_max'    => 'required|numeric|more:0', | ||||
|             'currency_id'   => 'numeric|exists:transaction_currencies,id|required_without:currency_code', | ||||
|             'currency_code' => 'min:3|max:3|exists:transaction_currencies,code|required_without:currency_id', | ||||
|             'date'          => 'required|date', | ||||
|             'repeat_freq'   => 'required|in:weekly,monthly,quarterly,half-year,yearly', | ||||
|             'skip'          => 'required|between:0,31', | ||||
|             'automatch'     => 'required|boolean', | ||||
|             'active'        => 'required|boolean', | ||||
|             'notes'         => 'between:1,65536', | ||||
|         ]; | ||||
|         switch ($this->method()) { | ||||
|             default: | ||||
|                 break; | ||||
|             case 'PUT': | ||||
|             case 'PATCH': | ||||
|                 $bill           = $this->route()->parameter('bill'); | ||||
|                 $rules['name']  .= ',' . $bill->id; | ||||
|                 $rules['match'] .= ',' . $bill->id; | ||||
|                 $bill          = $this->route()->parameter('bill'); | ||||
|                 $rules['name'] .= ',' . $bill->id; | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
| @@ -108,12 +112,12 @@ class BillRequest extends Request | ||||
|         $validator->after( | ||||
|             function (Validator $validator) { | ||||
|                 $data = $validator->getData(); | ||||
|                 $min  = floatval($data['amount_min'] ?? 0); | ||||
|                 $max  = floatval($data['amount_max'] ?? 0); | ||||
|                 $min  = (float)($data['amount_min'] ?? 0); | ||||
|                 $max  = (float)($data['amount_max'] ?? 0); | ||||
|                 if ($min > $max) { | ||||
|                     $validator->errors()->add('amount_min', trans('validation.amount_min_over_max')); | ||||
|                 } | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
							
								
								
									
										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; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										89
									
								
								app/Api/V1/Requests/CurrencyRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								app/Api/V1/Requests/CurrencyRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | ||||
| <?php | ||||
| /** | ||||
|  * CurrencyRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Class CurrencyRequest | ||||
|  */ | ||||
| class CurrencyRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * 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'), | ||||
|             'code'           => $this->string('code'), | ||||
|             'symbol'         => $this->string('symbol'), | ||||
|             'decimal_places' => $this->integer('decimal_places'), | ||||
|             'default'        => $this->boolean('default'), | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
|         $rules = [ | ||||
|             'name'           => 'required|between:1,255|unique:transaction_currencies,name', | ||||
|             'code'           => 'required|between:3,3|unique:transaction_currencies,code', | ||||
|             'symbol'         => 'required|between:1,5|unique:transaction_currencies,symbol', | ||||
|             'decimal_places' => 'required|between:0,20|numeric|min:0|max:20', | ||||
|             'default'        => 'boolean', | ||||
|         ]; | ||||
|  | ||||
|         switch ($this->method()) { | ||||
|             default: | ||||
|                 break; | ||||
|             case 'PUT': | ||||
|             case 'PATCH': | ||||
|                 $currency        = $this->route()->parameter('currency'); | ||||
|                 $rules['name']   = 'required|between:1,255|unique:transaction_currencies,name,' . $currency->id; | ||||
|                 $rules['code']   = 'required|between:1,255|unique:transaction_currencies,code,' . $currency->id; | ||||
|                 $rules['symbol'] = 'required|between:1,255|unique:transaction_currencies,symbol,' . $currency->id; | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         return $rules; | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										77
									
								
								app/Api/V1/Requests/JournalLinkRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								app/Api/V1/Requests/JournalLinkRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | ||||
| <?php | ||||
| /** | ||||
|  * JournalLinkRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * | ||||
|  * Class JournalLinkRequest | ||||
|  */ | ||||
| class JournalLinkRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * 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'), | ||||
|             'inward_id'    => $this->integer('inward_id'), | ||||
|             'outward_id'   => $this->integer('outward_id'), | ||||
|             'notes'        => $this->string('notes'), | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * TODO include link-type name as optional parameter. | ||||
|      * TODO be consistent and remove notes from this object. | ||||
|      * | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
|         return [ | ||||
|             'link_type_id' => 'required|exists:link_types,id', | ||||
|             'inward_id'    => 'required|belongsToUser:transaction_journals,id', | ||||
|             'outward_id'   => 'required|belongsToUser:transaction_journals,id', | ||||
|             'notes'        => 'between:0,65000', | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										92
									
								
								app/Api/V1/Requests/LinkTypeRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								app/Api/V1/Requests/LinkTypeRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | ||||
| <?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', | ||||
|         ]; | ||||
|         //        Rule::unique('users')->ignore($user->id), | ||||
|  | ||||
|  | ||||
|         switch ($this->method()) { | ||||
|             default: | ||||
|                 break; | ||||
|             case 'PUT': | ||||
|             case 'PATCH': | ||||
|                 /** @var LinkType $linkType */ | ||||
|                 $linkType         = $this->route()->parameter('linkType'); | ||||
|                 $rules['name']    = ['required', Rule::unique('link_types', 'name')->ignore($linkType->id), 'min:1']; | ||||
|                 $rules['outward'] = ['required', 'different:inward', Rule::unique('link_types', 'outward')->ignore($linkType->id), 'min:1']; | ||||
|                 $rules['inward']  = ['required', 'different:outward', Rule::unique('link_types', 'inward')->ignore($linkType->id), 'min:1']; | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         return $rules; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										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'), | ||||
|             'note'           => $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,7 +1,7 @@ | ||||
| <?php | ||||
| /** | ||||
|  * Amount.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * PreferenceRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,46 +18,52 @@ | ||||
|  * 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\Services\Bunq\Object; | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
| 
 | ||||
| /** | ||||
|  * Class Amount. | ||||
|  * | ||||
|  * Class PreferenceRequest | ||||
|  */ | ||||
| class Amount extends BunqObject | ||||
| class PreferenceRequest extends Request | ||||
| { | ||||
|     /** @var string */ | ||||
|     private $currency = ''; | ||||
|     /** @var string */ | ||||
|     private $value = ''; | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Amount constructor. | ||||
|      * Authorize logged in users. | ||||
|      * | ||||
|      * @param array $data | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function __construct(array $data) | ||||
|     public function authorize(): bool | ||||
|     { | ||||
|         $this->currency = $data['currency']; | ||||
|         $this->value    = $data['value']; | ||||
| 
 | ||||
|         return; | ||||
|         // Only allow authenticated users
 | ||||
|         return auth()->check(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return string | ||||
|      * Get all data from the request. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getCurrency(): string | ||||
|     public function getAll(): array | ||||
|     { | ||||
|         return $this->currency; | ||||
|         return [ | ||||
|             'data' => $this->get('data'), | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return string | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getValue(): string | ||||
|     public function rules(): array | ||||
|     { | ||||
|         return $this->value; | ||||
|         return [ | ||||
|             'data' => 'required|between:1,65000', | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										204
									
								
								app/Api/V1/Requests/RecurrenceRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								app/Api/V1/Requests/RecurrenceRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,204 @@ | ||||
| <?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 = new Carbon; | ||||
|         $today->addDay(); | ||||
|  | ||||
|         return [ | ||||
|             'type'                                 => 'required|in:withdrawal,transfer,deposit', | ||||
|             'title'                                => 'required|between:1,255|uniqueObjectForUser:recurrences,title', | ||||
|             'description'                          => 'between:1,65000', | ||||
|             'first_date'                           => sprintf('required|date|after:%s', $today->format('Y-m-d')), | ||||
|             'repeat_until'                         => sprintf('date|after:%s', $today->format('Y-m-d')), | ||||
|             'nr_of_repetitions'                    => 'numeric|between:1,31', | ||||
|             'apply_rules'                          => 'required|boolean', | ||||
|             'active'                               => 'required|boolean', | ||||
|             '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,4 +1,5 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Request.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -18,13 +19,19 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
|  | ||||
| use FireflyIII\Http\Requests\Request as FireflyIIIRequest; | ||||
|  | ||||
| /** | ||||
|  * Class Request. | ||||
|  * | ||||
|  * 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 | ||||
| { | ||||
|   | ||||
							
								
								
									
										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; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										162
									
								
								app/Api/V1/Requests/RuleRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								app/Api/V1/Requests/RuleRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,162 @@ | ||||
| <?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'    => [], | ||||
|             'rule-actions'     => [], | ||||
|         ]; | ||||
|  | ||||
|         foreach ($this->get('rule-triggers') as $trigger) { | ||||
|             $data['rule-triggers'][] = [ | ||||
|                 'name'            => $trigger['name'], | ||||
|                 'value'           => $trigger['value'], | ||||
|                 'stop-processing' => 1 === (int)($trigger['stop-processing'] ?? 0), | ||||
|             ]; | ||||
|         } | ||||
|         foreach ($this->get('rule-actions') as $action) { | ||||
|             $data['rule-actions'][] = [ | ||||
|                 'name'            => $action['name'], | ||||
|                 'value'           => $action['value'], | ||||
|                 'stop-processing' => 1 === (int)($action['stop-processing'] ?? 0), | ||||
|             ]; | ||||
|         } | ||||
|  | ||||
|         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-action.*.type,' . $contextActions . '|ruleActionValue', | ||||
|             'rule-actions.*.stop-processing'  => 'boolean', | ||||
|             'strict'                          => 'required|boolean', | ||||
|             'stop_processing'                 => 'required|boolean', | ||||
|             'active'                          => 'required|boolean', | ||||
|         ]; | ||||
|  | ||||
|         return $rules; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Configure the validator instance. | ||||
|      * | ||||
|      * @param  Validator $validator | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function withValidator(Validator $validator): void | ||||
|     { | ||||
|         $validator->after( | ||||
|             function (Validator $validator) { | ||||
|                 $this->atLeastOneTrigger($validator); | ||||
|                 $this->atLeastOneAction($validator); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Adds an error to the validator when there are no repetitions in the array of data. | ||||
|      * | ||||
|      * @param Validator $validator | ||||
|      */ | ||||
|     protected function atLeastOneAction(Validator $validator): void | ||||
|     { | ||||
|         $data        = $validator->getData(); | ||||
|         $repetitions = $data['rule-actions'] ?? []; | ||||
|         // need at least one transaction | ||||
|         if (0 === \count($repetitions)) { | ||||
|             $validator->errors()->add('title', trans('validation.at_least_one_action')); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Adds an error to the validator when there are no repetitions in the array of data. | ||||
|      * | ||||
|      * @param Validator $validator | ||||
|      */ | ||||
|     protected function atLeastOneTrigger(Validator $validator): void | ||||
|     { | ||||
|         $data        = $validator->getData(); | ||||
|         $repetitions = $data['rule-triggers'] ?? []; | ||||
|         // need at least one transaction | ||||
|         if (0 === \count($repetitions)) { | ||||
|             $validator->errors()->add('title', trans('validation.at_least_one_trigger')); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,4 +1,5 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * TransactionRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -23,12 +24,8 @@ declare(strict_types=1); | ||||
|  | ||||
| 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\Validation\TransactionValidation; | ||||
| use Illuminate\Validation\Validator; | ||||
|  | ||||
|  | ||||
| @@ -37,7 +34,11 @@ use Illuminate\Validation\Validator; | ||||
|  */ | ||||
| class TransactionRequest extends Request | ||||
| { | ||||
|     use TransactionValidation; | ||||
|  | ||||
|     /** | ||||
|      * Authorize logged in users. | ||||
|      * | ||||
|      * @return 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 | ||||
|      */ | ||||
|     public function getAll(): array | ||||
|     { | ||||
|         $data = [ | ||||
|             // basic fields for journal: | ||||
|             'type'               => $this->string('type'), | ||||
|             'date'               => $this->date('date'), | ||||
|             'description'        => $this->string('description'), | ||||
| @@ -61,8 +65,6 @@ class TransactionRequest extends Request | ||||
|             'bill_id'            => $this->integer('bill_id'), | ||||
|             'bill_name'          => $this->string('bill_name'), | ||||
|             'tags'               => explode(',', $this->string('tags')), | ||||
|  | ||||
|             // then, custom fields for journal | ||||
|             'interest_date'      => $this->date('interest_date'), | ||||
|             'book_date'          => $this->date('book_date'), | ||||
|             'process_date'       => $this->date('process_date'), | ||||
| @@ -71,39 +73,17 @@ class TransactionRequest extends Request | ||||
|             'invoice_date'       => $this->date('invoice_date'), | ||||
|             'internal_reference' => $this->string('internal_reference'), | ||||
|             'notes'              => $this->string('notes'), | ||||
|  | ||||
|             // then, transactions (see below). | ||||
|             'transactions'       => [], | ||||
|  | ||||
|             'transactions'       => $this->getTransactionData(), | ||||
|         ]; | ||||
|         foreach ($this->get('transactions') as $index => $transaction) { | ||||
|             $array                  = [ | ||||
|                 'description'           => $transaction['description'] ?? null, | ||||
|                 'amount'                => $transaction['amount'], | ||||
|                 'currency_id'           => isset($transaction['currency_id']) ? intval($transaction['currency_id']) : null, | ||||
|                 'currency_code'         => isset($transaction['currency_code']) ? $transaction['currency_code'] : null, | ||||
|                 'foreign_amount'        => $transaction['foreign_amount'] ?? null, | ||||
|                 'foreign_currency_id'   => isset($transaction['foreign_currency_id']) ? intval($transaction['foreign_currency_id']) : null, | ||||
|                 'foreign_currency_code' => $transaction['foreign_currency_code'] ?? null, | ||||
|                 'budget_id'             => isset($transaction['budget_id']) ? intval($transaction['budget_id']) : null, | ||||
|                 'budget_name'           => $transaction['budget_name'] ?? null, | ||||
|                 'category_id'           => isset($transaction['category_id']) ? intval($transaction['category_id']) : null, | ||||
|                 'category_name'         => $transaction['category_name'] ?? null, | ||||
|                 'source_id'             => isset($transaction['source_id']) ? intval($transaction['source_id']) : null, | ||||
|                 'source_name'           => isset($transaction['source_name']) ? strval($transaction['source_name']) : null, | ||||
|                 'destination_id'        => isset($transaction['destination_id']) ? intval($transaction['destination_id']) : null, | ||||
|                 'destination_name'      => isset($transaction['destination_name']) ? strval($transaction['destination_name']) : null, | ||||
|                 'reconciled'            => $transaction['reconciled'] ?? false, | ||||
|                 'identifier'            => $index, | ||||
|             ]; | ||||
|             $data['transactions'][] = $array; | ||||
|         } | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
| @@ -148,13 +128,8 @@ class TransactionRequest extends Request | ||||
|             'transactions.*.destination_name'      => 'between:1,255|nullable', | ||||
|         ]; | ||||
|  | ||||
|         switch ($this->method()) { | ||||
|             default: | ||||
|                 break; | ||||
|             case 'PUT': | ||||
|             case 'PATCH': | ||||
|                 unset($rules['type'], $rules['piggy_bank_id'], $rules['piggy_bank_name']); | ||||
|                 break; | ||||
|         if ('PUT' === $this->method()) { | ||||
|             unset($rules['type'], $rules['piggy_bank_id'], $rules['piggy_bank_name']); | ||||
|         } | ||||
|  | ||||
|         return $rules; | ||||
| @@ -173,11 +148,11 @@ class TransactionRequest extends Request | ||||
|     { | ||||
|         $validator->after( | ||||
|             function (Validator $validator) { | ||||
|                 $this->atLeastOneTransaction($validator); | ||||
|                 $this->checkValidDescriptions($validator); | ||||
|                 $this->equalToJournalDescription($validator); | ||||
|                 $this->emptySplitDescriptions($validator); | ||||
|                 $this->foreignCurrencyInformation($validator); | ||||
|                 $this->validateOneTransaction($validator); | ||||
|                 $this->validateDescriptions($validator); | ||||
|                 $this->validateJournalDescription($validator); | ||||
|                 $this->validateSplitDescriptions($validator); | ||||
|                 $this->validateForeignCurrencyInformation($validator); | ||||
|                 $this->validateAccountInformation($validator); | ||||
|                 $this->validateSplitAccounts($validator); | ||||
|             } | ||||
| @@ -185,316 +160,37 @@ class TransactionRequest extends Request | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Throws an error when this asset account is invalid. | ||||
|      * Get transaction data. | ||||
|      * | ||||
|      * @param Validator   $validator | ||||
|      * @param int|null    $accountId | ||||
|      * @param null|string $accountName | ||||
|      * @param string      $idField | ||||
|      * @param string      $nameField | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * @SuppressWarnings(PHPMD.NPathComplexity) | ||||
|      * @return array | ||||
|      */ | ||||
|     protected function assetAccountExists(Validator $validator, ?int $accountId, ?string $accountName, string $idField, string $nameField): void | ||||
|     private function getTransactionData(): array | ||||
|     { | ||||
|  | ||||
|         $accountId   = intval($accountId); | ||||
|         $accountName = strval($accountName); | ||||
|         // both empty? hard exit. | ||||
|         if ($accountId < 1 && strlen($accountName) === 0) { | ||||
|             $validator->errors()->add($idField, trans('validation.filled', ['attribute' => $idField])); | ||||
|  | ||||
|             return; | ||||
|         } | ||||
|         // ID belongs to user and is asset 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 !== AccountType::ASSET) { | ||||
|                 $validator->errors()->add($idField, trans('validation.belongs_user')); | ||||
|  | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // we ignore the account name at this point. | ||||
|             return; | ||||
|         $return = []; | ||||
|         foreach ($this->get('transactions') as $index => $transaction) { | ||||
|             $return[] = [ | ||||
|                 '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, | ||||
|             ]; | ||||
|         } | ||||
|  | ||||
|         $account = $repository->findByName($accountName, [AccountType::ASSET]); | ||||
|         if (is_null($account)) { | ||||
|             $validator->errors()->add($nameField, trans('validation.belongs_user')); | ||||
|         } | ||||
|  | ||||
|         return; | ||||
|         return $return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 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 = strval($data['description'] ?? ''); | ||||
|         $validDescriptions  = 0; | ||||
|         foreach ($transactions as $index => $transaction) { | ||||
|             if (strlen(strval($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 = strval($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 = strval($data['description'] ?? ''); | ||||
|         foreach ($transactions as $index => $transaction) { | ||||
|             $description = strval($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 | ||||
|      */ | ||||
|     protected function opposingAccountExists(Validator $validator, string $type, ?int $accountId, ?string $accountName, string $idField): void { | ||||
|         $accountId   = intval($accountId); | ||||
|         $accountName = strval($accountName); | ||||
|         // both empty? done! | ||||
|         if ($accountId < 1 && strlen($accountName) === 0) { | ||||
|             return; | ||||
|         } | ||||
|         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; | ||||
|                 } | ||||
|  | ||||
|                 // we ignore the account name at this point. | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // not having an opposing account by this name is NOT a problem. | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 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 (is_null($transaction)) { | ||||
|                 return; // @codeCoverageIgnore | ||||
|             } | ||||
|             $data['type'] = strtolower($transaction->transactionJournal->transactionType->type); | ||||
|         } | ||||
|         foreach ($transactions as $index => $transaction) { | ||||
|             $sourceId        = isset($transaction['source_id']) ? intval($transaction['source_id']) : null; | ||||
|             $sourceName      = $transaction['source_name'] ?? null; | ||||
|             $destinationId   = isset($transaction['destination_id']) ? intval($transaction['destination_id']) : null; | ||||
|             $destinationName = $transaction['destination_name'] ?? null; | ||||
|  | ||||
|             switch ($data['type']) { | ||||
|                 case 'withdrawal': | ||||
|                     $idField   = 'transactions.' . $index . '.source_id'; | ||||
|                     $nameField = 'transactions.' . $index . '.source_name'; | ||||
|                     $this->assetAccountExists($validator, $sourceId, $sourceName, $idField, $nameField); | ||||
|  | ||||
|                     $idField   = 'transactions.' . $index . '.destination_id'; | ||||
|                     $this->opposingAccountExists($validator, AccountType::EXPENSE, $destinationId, $destinationName, $idField); | ||||
|                     break; | ||||
|                 case 'deposit': | ||||
|                     $idField   = 'transactions.' . $index . '.source_id'; | ||||
|                     $this->opposingAccountExists($validator, AccountType::REVENUE, $sourceId, $sourceName, $idField); | ||||
|  | ||||
|                     $idField   = 'transactions.' . $index . '.destination_id'; | ||||
|                     $nameField = 'transactions.' . $index . '.destination_name'; | ||||
|                     $this->assetAccountExists($validator, $destinationId, $destinationName, $idField, $nameField); | ||||
|                     break; | ||||
|                 case 'transfer': | ||||
|                     $idField   = 'transactions.' . $index . '.source_id'; | ||||
|                     $nameField = 'transactions.' . $index . '.source_name'; | ||||
|                     $this->assetAccountExists($validator, $sourceId, $sourceName, $idField, $nameField); | ||||
|  | ||||
|                     $idField   = 'transactions.' . $index . '.destination_id'; | ||||
|                     $nameField = 'transactions.' . $index . '.destination_name'; | ||||
|                     $this->assetAccountExists($validator, $destinationId, $destinationName, $idField, $nameField); | ||||
|                     break; | ||||
|                 default: | ||||
|                     throw new FireflyException(sprintf('The validator cannot handle transaction type "%s" in validateAccountInformation().', $data['type'])); | ||||
|  | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @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 (is_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']) ? intval($transaction['source_id']) : 0; | ||||
|             $destinations[] = isset($transaction['destination_id']) ? intval($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 | ||||
|         } | ||||
|  | ||||
|         return; | ||||
|     } | ||||
|  | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * UserRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -23,6 +24,7 @@ declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
|  | ||||
| use FireflyIII\Repositories\User\UserRepositoryInterface; | ||||
| use FireflyIII\User; | ||||
|  | ||||
|  | ||||
| @@ -32,24 +34,32 @@ use FireflyIII\User; | ||||
| class UserRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * Authorize logged in users. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize(): bool | ||||
|     { | ||||
|         $result = false; | ||||
|         // Only allow authenticated users | ||||
|         if (!auth()->check()) { | ||||
|             return false; // @codeCoverageIgnore | ||||
|         } | ||||
|         /** @var User $user */ | ||||
|         $user = auth()->user(); | ||||
|         if (!$user->hasRole('owner')) { | ||||
|             return false; // @codeCoverageIgnore | ||||
|         if (auth()->check()) { | ||||
|             /** @var User $user */ | ||||
|             $user = auth()->user(); | ||||
|  | ||||
|             /** @var UserRepositoryInterface $repository */ | ||||
|             $repository = app(UserRepositoryInterface::class); | ||||
|  | ||||
|             if ($repository->hasRole($user, 'owner')) { | ||||
|                 $result = true; // @codeCoverageIgnore | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|         return $result; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all data from the request. | ||||
|      * | ||||
|      * @return 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 | ||||
|      */ | ||||
|     public function rules(): array | ||||
| @@ -86,4 +98,4 @@ class UserRequest extends Request | ||||
|         return $rules; | ||||
|     } | ||||
|  | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <?php | ||||
| /** | ||||
|  * CreateExport.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +18,9 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /** @noinspection MultipleReturnStatementsInspection */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console\Commands; | ||||
| @@ -40,6 +43,7 @@ use Storage; | ||||
| class CreateExport extends Command | ||||
| { | ||||
|     use VerifiesAccessToken; | ||||
|  | ||||
|     /** | ||||
|      * The console command description. | ||||
|      * | ||||
| @@ -60,27 +64,18 @@ class CreateExport extends Command | ||||
|                             {--with_uploads : Include user\'s uploads?}'; | ||||
|  | ||||
|     /** | ||||
|      * Create a new command instance. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's five its fine. | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||
|      * | ||||
|      * Execute the console command. | ||||
|      * | ||||
|      * @return mixed | ||||
|      * @return int | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||
|      */ | ||||
|     public function handle() | ||||
|     public function handle(): int | ||||
|     { | ||||
|         if (!$this->verifyAccessToken()) { | ||||
|             $this->error('Invalid access token.'); | ||||
|  | ||||
|             return; | ||||
|             return 1; | ||||
|         } | ||||
|         $this->line('Full export is running...'); | ||||
|         // make repositories | ||||
| @@ -94,15 +89,18 @@ class CreateExport extends Command | ||||
|         $journalRepository = app(JournalRepositoryInterface::class); | ||||
|  | ||||
|         // set user | ||||
|         $user = $userRepository->find(intval($this->option('user'))); | ||||
|         $user = $userRepository->findNull((int)$this->option('user')); | ||||
|         if (null === $user) { | ||||
|             return 1; | ||||
|         } | ||||
|         $jobRepository->setUser($user); | ||||
|         $journalRepository->setUser($user); | ||||
|         $accountRepository->setUser($user); | ||||
|  | ||||
|         // first date | ||||
|         $firstJournal = $journalRepository->first(); | ||||
|         $firstJournal = $journalRepository->firstNull(); | ||||
|         $first        = new Carbon; | ||||
|         if (null !== $firstJournal->id) { | ||||
|         if (null !== $firstJournal) { | ||||
|             $first = $firstJournal->date; | ||||
|         } | ||||
|  | ||||
| @@ -141,6 +139,6 @@ class CreateExport extends Command | ||||
|         $this->line('The export has finished! You can find the ZIP file in this location:'); | ||||
|         $this->line(storage_path(sprintf('export/%s', $fileName))); | ||||
|  | ||||
|         return; | ||||
|         return 0; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <?php | ||||
| /** | ||||
|  * CreateImport.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,20 +18,22 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /** @noinspection MultipleReturnStatementsInspection */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console\Commands; | ||||
|  | ||||
| use Artisan; | ||||
| use Exception; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Import\Logging\CommandHandler; | ||||
| use FireflyIII\Import\Prerequisites\PrerequisitesInterface; | ||||
| use FireflyIII\Import\Routine\RoutineInterface; | ||||
| use FireflyIII\Import\Storage\ImportArrayStorage; | ||||
| use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; | ||||
| use FireflyIII\Repositories\User\UserRepositoryInterface; | ||||
| use Illuminate\Console\Command; | ||||
| use Illuminate\Support\MessageBag; | ||||
| use Log; | ||||
| use Monolog\Formatter\LineFormatter; | ||||
| use Preferences; | ||||
|  | ||||
| /** | ||||
| @@ -54,150 +56,244 @@ class CreateImport extends Command | ||||
|      */ | ||||
|     protected $signature | ||||
|         = 'firefly:create-import | ||||
|                             {file : The file to import.} | ||||
|                             {configuration : The configuration file to use for the import.} | ||||
|                             {file? : The file to import.} | ||||
|                             {configuration? : The configuration file to use for the import.} | ||||
|                             {--type=csv : The file type of the import.} | ||||
|                             {--user= : The user ID that the import should import for.} | ||||
|                             {--provider=file : The file type of the import.} | ||||
|                             {--user=1 : The user ID that the import should import for.} | ||||
|                             {--token= : The user\'s access token.} | ||||
|                             {--start : Starts the job immediately.}'; | ||||
|  | ||||
|     /** | ||||
|      * Create a new command instance. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Run the command. | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) // cannot be helped | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's five exactly. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function handle() | ||||
|     public function handle(): int | ||||
|     { | ||||
|         if (!$this->verifyAccessToken()) { | ||||
|             $this->error('Invalid access token.'); | ||||
|             $this->errorLine('Invalid access token.'); | ||||
|  | ||||
|             return; | ||||
|             return 1; | ||||
|         } | ||||
|         /** @var UserRepositoryInterface $userRepository */ | ||||
|         $userRepository = app(UserRepositoryInterface::class); | ||||
|         $file           = $this->argument('file'); | ||||
|         $configuration  = $this->argument('configuration'); | ||||
|         $user           = $userRepository->find(intval($this->option('user'))); | ||||
|         $cwd            = getcwd(); | ||||
|         $type           = strtolower($this->option('type')); | ||||
|         $userRepository    = app(UserRepositoryInterface::class); | ||||
|         $file              = (string)$this->argument('file'); | ||||
|         $configuration     = (string)$this->argument('configuration'); | ||||
|         $user              = $userRepository->findNull((int)$this->option('user')); | ||||
|         $cwd               = getcwd(); | ||||
|         $provider          = strtolower((string)$this->option('provider')); | ||||
|         $configurationData = []; | ||||
|  | ||||
|         if (null === $user) { | ||||
|             $this->errorLine('User is NULL.'); | ||||
|  | ||||
|             return 1; | ||||
|         } | ||||
|  | ||||
|         if (!$this->validArguments()) { | ||||
|             return; | ||||
|             $this->errorLine('Invalid arguments.'); | ||||
|  | ||||
|             return 1; | ||||
|         } | ||||
|         if (\strlen($configuration) > 0) { | ||||
|             $configurationData = json_decode(file_get_contents($configuration), true); | ||||
|             if (null === $configurationData) { | ||||
|                 $this->errorLine(sprintf('Firefly III cannot read the contents of configuration file "%s" (working directory: "%s").', $configuration, $cwd)); | ||||
|  | ||||
|                 return 1; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $configurationData = json_decode(file_get_contents($configuration), true); | ||||
|         if (null === $configurationData) { | ||||
|             $this->error(sprintf('Firefly III cannot read the contents of configuration file "%s" (working directory: "%s").', $configuration, $cwd)); | ||||
|  | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $this->line(sprintf('Going to create a job to import file: %s', $file)); | ||||
|         $this->line(sprintf('Using configuration file: %s', $configuration)); | ||||
|         $this->line(sprintf('Import into user: #%d (%s)', $user->id, $user->email)); | ||||
|         $this->line(sprintf('Type of import: %s', $type)); | ||||
|         $this->infoLine(sprintf('Going to create a job to import file: %s', $file)); | ||||
|         $this->infoLine(sprintf('Using configuration file: %s', $configuration)); | ||||
|         $this->infoLine(sprintf('Import into user: #%d (%s)', $user->id, $user->email)); | ||||
|         $this->infoLine(sprintf('Type of import: %s', $provider)); | ||||
|  | ||||
|         /** @var ImportJobRepositoryInterface $jobRepository */ | ||||
|         $jobRepository = app(ImportJobRepositoryInterface::class); | ||||
|         $jobRepository->setUser($user); | ||||
|         $job = $jobRepository->create($type); | ||||
|         $this->line(sprintf('Created job "%s"', $job->key)); | ||||
|         $importJob = $jobRepository->create($provider); | ||||
|         $this->infoLine(sprintf('Created job "%s"', $importJob->key)); | ||||
|  | ||||
|         Artisan::call('firefly:encrypt-file', ['file' => $file, 'key' => $job->key]); | ||||
|         $this->line('Stored import data...'); | ||||
|  | ||||
|         $jobRepository->setConfiguration($job, $configurationData); | ||||
|         $jobRepository->updateStatus($job, 'configured'); | ||||
|         $this->line('Stored configuration...'); | ||||
|  | ||||
|         if (true === $this->option('start')) { | ||||
|             $this->line('The import will start in a moment. This process is not visible...'); | ||||
|             Log::debug('Go for import!'); | ||||
|  | ||||
|             // normally would refer to other firefly:start-import but that doesn't seem to work all to well... | ||||
|             $monolog   = Log::getMonolog(); | ||||
|             $handler   = new CommandHandler($this); | ||||
|             $formatter = new LineFormatter(null, null, false, true); | ||||
|             $handler->setFormatter($formatter); | ||||
|             $monolog->pushHandler($handler); | ||||
|  | ||||
|             // start the actual routine: | ||||
|             $type      = 'csv' === $job->file_type ? 'file' : $job->file_type; | ||||
|             $key       = sprintf('import.routine.%s', $type); | ||||
|             $className = config($key); | ||||
|             if (null === $className || !class_exists($className)) { | ||||
|                 throw new FireflyException(sprintf('Cannot find import routine class for job of type "%s".', $type)); // @codeCoverageIgnore | ||||
|         // make sure that job has no prerequisites. | ||||
|         if ((bool)config(sprintf('import.has_prereq.%s', $provider))) { | ||||
|             // make prerequisites thing. | ||||
|             $class = (string)config(sprintf('import.prerequisites.%s', $provider)); | ||||
|             if (!class_exists($class)) { | ||||
|                 throw new FireflyException(sprintf('No class to handle prerequisites for "%s".', $provider)); // @codeCoverageIgnore | ||||
|             } | ||||
|             /** @var RoutineInterface $routine */ | ||||
|             $routine = app($className); | ||||
|             $routine->setJob($job); | ||||
|             $routine->run(); | ||||
|             /** @var PrerequisitesInterface $object */ | ||||
|             $object = app($class); | ||||
|             $object->setUser($user); | ||||
|             if (!$object->isComplete()) { | ||||
|                 $this->errorLine(sprintf('Import provider "%s" has prerequisites that can only be filled in using the browser.', $provider)); | ||||
|  | ||||
|             // give feedback. | ||||
|             /** @var MessageBag $error */ | ||||
|             foreach ($routine->getErrors() as $index => $error) { | ||||
|                 $this->error(sprintf('Error importing line #%d: %s', $index, $error)); | ||||
|                 return 1; | ||||
|             } | ||||
|             $this->line( | ||||
|                 sprintf( | ||||
|                     'The import has finished. %d transactions have been imported out of %d records.', $routine->getJournals()->count(), $routine->getLines() | ||||
|                 ) | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         // store file as attachment. | ||||
|         if (\strlen($file) > 0) { | ||||
|             $messages = $jobRepository->storeCLIUpload($importJob, 'import_file', $file); | ||||
|             if ($messages->count() > 0) { | ||||
|                 $this->errorLine($messages->first()); | ||||
|  | ||||
|                 return 1; | ||||
|             } | ||||
|             $this->infoLine('File content saved.'); | ||||
|         } | ||||
|  | ||||
|         $this->infoLine('Job configuration saved.'); | ||||
|         $jobRepository->setConfiguration($importJob, $configurationData); | ||||
|         $jobRepository->setStatus($importJob, 'ready_to_run'); | ||||
|  | ||||
|  | ||||
|         if (true === $this->option('start')) { | ||||
|             $this->infoLine('The has started. The process is not visible. Please wait.'); | ||||
|             Log::debug('Go for import!'); | ||||
|  | ||||
|             // run it! | ||||
|             $key       = sprintf('import.routine.%s', $provider); | ||||
|             $className = config($key); | ||||
|             if (null === $className || !class_exists($className)) { | ||||
|                 // @codeCoverageIgnoreStart | ||||
|                 $this->errorLine(sprintf('No routine for provider "%s"', $provider)); | ||||
|  | ||||
|                 return 1; | ||||
|                 // @codeCoverageIgnoreEnd | ||||
|             } | ||||
|  | ||||
|             // keep repeating this call until job lands on "provider_finished" | ||||
|             $valid = ['provider_finished']; | ||||
|             $count = 0; | ||||
|             while (!\in_array($importJob->status, $valid, true) && $count < 6) { | ||||
|                 Log::debug(sprintf('Now in loop #%d.', $count + 1)); | ||||
|                 /** @var RoutineInterface $routine */ | ||||
|                 $routine = app($className); | ||||
|                 $routine->setImportJob($importJob); | ||||
|                 try { | ||||
|                     $routine->run(); | ||||
|                 } catch (FireflyException|Exception $e) { | ||||
|                     $message = 'The import routine crashed: ' . $e->getMessage(); | ||||
|                     Log::error($message); | ||||
|                     Log::error($e->getTraceAsString()); | ||||
|  | ||||
|                     // set job errored out: | ||||
|                     $jobRepository->setStatus($importJob, 'error'); | ||||
|                     $this->errorLine($message); | ||||
|  | ||||
|                     return 1; | ||||
|                 } | ||||
|                 $count++; | ||||
|             } | ||||
|             if ('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: | ||||
|         Preferences::setForUser($user, 'lastActivity', microtime()); | ||||
|  | ||||
|         return; | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string     $message | ||||
|      * @param array|null $data | ||||
|      */ | ||||
|     private function errorLine(string $message, array $data = null): void | ||||
|     { | ||||
|         Log::error($message, $data ?? []); | ||||
|         $this->error($message); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $message | ||||
|      * @param array  $data | ||||
|      */ | ||||
|     private function infoLine(string $message, array $data = null): void | ||||
|     { | ||||
|         Log::info($message, $data ?? []); | ||||
|         $this->line($message); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Verify user inserts correct arguments. | ||||
|      * | ||||
|      * @noinspection MultipleReturnStatementsInspection | ||||
|      * @return bool | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's five exactly. | ||||
|      */ | ||||
|     private function validArguments(): bool | ||||
|     { | ||||
|         /** @var UserRepositoryInterface $userRepository */ | ||||
|         $userRepository = app(UserRepositoryInterface::class); | ||||
|         $file           = $this->argument('file'); | ||||
|         $configuration  = $this->argument('configuration'); | ||||
|         $user           = $userRepository->find(intval($this->option('user'))); | ||||
|         $cwd            = getcwd(); | ||||
|         $validTypes     = config('import.options.file.import_formats'); | ||||
|         $type           = strtolower($this->option('type')); | ||||
|         if (null === $user) { | ||||
|             $this->error(sprintf('There is no user with ID %d.', $this->option('user'))); | ||||
|         $file          = $this->argument('file'); | ||||
|         $configuration = $this->argument('configuration'); | ||||
|         $cwd           = getcwd(); | ||||
|         $validTypes    = config('import.options.file.import_formats'); | ||||
|         $type          = strtolower($this->option('type')); | ||||
|         $provider      = strtolower($this->option('provider')); | ||||
|         $enabled       = (bool)config(sprintf('import.enabled.%s', $provider)); | ||||
|  | ||||
|         if (false === $enabled) { | ||||
|             $this->errorLine(sprintf('Provider "%s" is not enabled.', $provider)); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         if (!in_array($type, $validTypes)) { | ||||
|             $this->error(sprintf('Cannot import file of type "%s"', $type)); | ||||
|         if ('file' === $provider && !\in_array($type, $validTypes, true)) { | ||||
|             $this->errorLine(sprintf('Cannot import file of type "%s"', $type)); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         if (!file_exists($file)) { | ||||
|             $this->error(sprintf('Firefly III cannot find file "%s" (working directory: "%s").', $file, $cwd)); | ||||
|         if ('file' === $provider && !file_exists($file)) { | ||||
|             $this->errorLine(sprintf('Firefly III cannot find file "%s" (working directory: "%s").', $file, $cwd)); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         if (!file_exists($configuration)) { | ||||
|             $this->error(sprintf('Firefly III cannot find configuration file "%s" (working directory: "%s").', $configuration, $cwd)); | ||||
|         if ('file' === $provider && !file_exists($configuration)) { | ||||
|             $this->errorLine(sprintf('Firefly III cannot find configuration file "%s" (working directory: "%s").', $configuration, $cwd)); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <?php | ||||
| /** | ||||
|  * DecryptAttachment.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +18,9 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /** @noinspection MultipleReturnStatementsInspection */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console\Commands; | ||||
| @@ -47,25 +50,18 @@ class DecryptAttachment extends Command | ||||
|         = 'firefly:decrypt-attachment {id:The ID of the attachment.} {name:The file name of the attachment.}  | ||||
|     {directory:Where the file must be stored.}'; | ||||
|  | ||||
|     /** | ||||
|      * Create a new command instance. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Execute the console command. | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's five its fine. | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||
|      * | ||||
|      * @return int | ||||
|      */ | ||||
|     public function handle() | ||||
|     public function handle(): int | ||||
|     { | ||||
|         /** @var AttachmentRepositoryInterface $repository */ | ||||
|         $repository     = app(AttachmentRepositoryInterface::class); | ||||
|         $attachmentId   = intval($this->argument('id')); | ||||
|         $attachmentId   = (int)$this->argument('id'); | ||||
|         $attachment     = $repository->findWithoutUser($attachmentId); | ||||
|         $attachmentName = trim($this->argument('name')); | ||||
|         $storagePath    = realpath(trim($this->argument('directory'))); | ||||
| @@ -73,28 +69,28 @@ class DecryptAttachment extends Command | ||||
|             $this->error(sprintf('No attachment with id #%d', $attachmentId)); | ||||
|             Log::error(sprintf('DecryptAttachment: No attachment with id #%d', $attachmentId)); | ||||
|  | ||||
|             return; | ||||
|             return 1; | ||||
|         } | ||||
|  | ||||
|         if ($attachmentName !== $attachment->filename) { | ||||
|             $this->error('File name does not match.'); | ||||
|             Log::error('DecryptAttachment: File name does not match.'); | ||||
|  | ||||
|             return; | ||||
|             return 1; | ||||
|         } | ||||
|  | ||||
|         if (!is_dir($storagePath)) { | ||||
|             $this->error(sprintf('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)) { | ||||
|             $this->error(sprintf('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; | ||||
| @@ -104,10 +100,10 @@ class DecryptAttachment extends Command | ||||
|         if (false === $result) { | ||||
|             $this->error('Could not write to file.'); | ||||
|  | ||||
|             return; | ||||
|             return 1; | ||||
|         } | ||||
|         $this->info(sprintf('%d bytes written. Exiting now..', $result)); | ||||
|  | ||||
|         return; | ||||
|         return 0; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <?php | ||||
| /** | ||||
|  * EncryptFile.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,11 +18,13 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console\Commands; | ||||
|  | ||||
| use Crypt; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Services\Internal\File\EncryptService; | ||||
| use Illuminate\Console\Command; | ||||
|  | ||||
| /** | ||||
| @@ -44,31 +46,26 @@ class EncryptFile extends Command | ||||
|      */ | ||||
|     protected $signature = 'firefly:encrypt-file {file} {key}'; | ||||
|  | ||||
|     /** | ||||
|      * Create a new command instance. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Execute the console command. | ||||
|      * | ||||
|      * @throws \Illuminate\Contracts\Encryption\EncryptException | ||||
|      */ | ||||
|     public function handle() | ||||
|     public function handle(): int | ||||
|     { | ||||
|         $file = e(strval($this->argument('file'))); | ||||
|         if (!file_exists($file)) { | ||||
|             $this->error(sprintf('File "%s" does not seem to exist.', $file)); | ||||
|         $code = 0; | ||||
|         $file = (string)$this->argument('file'); | ||||
|         $key  = (string)$this->argument('key'); | ||||
|         /** @var EncryptService $service */ | ||||
|         $service = app(EncryptService::class); | ||||
|  | ||||
|             return; | ||||
|         try { | ||||
|             $service->encrypt($file, $key); | ||||
|         } catch (FireflyException $e) { | ||||
|             $this->error($e->getMessage()); | ||||
|             $code = 1; | ||||
|         } | ||||
|         $content = file_get_contents($file); | ||||
|         $content = Crypt::encrypt($content); | ||||
|         $newName = e(strval($this->argument('key'))) . '.upload'; | ||||
|  | ||||
|         $path = storage_path('upload') . '/' . $newName; | ||||
|         file_put_contents($path, $content); | ||||
|         $this->line(sprintf('Encrypted "%s" and put it in "%s"', $file, $path)); | ||||
|         return $code; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <?php | ||||
| /** | ||||
|  * Import.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,16 +18,19 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /** @noinspection MultipleReturnStatementsInspection */ | ||||
| /** @noinspection PhpDynamicAsStaticMethodCallInspection */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console\Commands; | ||||
|  | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Import\Logging\CommandHandler; | ||||
| use FireflyIII\Import\Routine\RoutineInterface; | ||||
| use FireflyIII\Models\ImportJob; | ||||
| use FireflyIII\Models\Tag; | ||||
| use Illuminate\Console\Command; | ||||
| use Illuminate\Support\MessageBag; | ||||
| use Log; | ||||
|  | ||||
| /** | ||||
| @@ -49,40 +52,30 @@ class Import extends Command | ||||
|      */ | ||||
|     protected $signature = 'firefly:start-import {key}'; | ||||
|  | ||||
|     /** | ||||
|      * Create a new command instance. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Run the import routine. | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function handle() | ||||
|     public function handle(): void | ||||
|     { | ||||
|         Log::debug('Start start-import command'); | ||||
|         $jobKey = $this->argument('key'); | ||||
|         $job    = ImportJob::where('key', $jobKey)->first(); | ||||
|         if (null === $job) { | ||||
|             $this->error(sprintf('No job found with key "%s"', $jobKey)); | ||||
|             $this->errorLine(sprintf('No job found with key "%s"', $jobKey)); | ||||
|  | ||||
|             return; | ||||
|         } | ||||
|         if (!$this->isValid($job)) { | ||||
|             Log::error('Job is not valid for some reason. Exit.'); | ||||
|             $this->errorLine('Job is not valid for some reason. Exit.'); | ||||
|  | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $this->line(sprintf('Going to import job with key "%s" of type "%s"', $job->key, $job->file_type)); | ||||
|  | ||||
|         $monolog = Log::getMonolog(); | ||||
|         $handler = new CommandHandler($this); | ||||
|         $monolog->pushHandler($handler); | ||||
|         $this->infoLine(sprintf('Going to import job with key "%s" of type "%s"', $job->key, $job->file_type)); | ||||
|  | ||||
|         // actually start job: | ||||
|         $type      = 'csv' === $job->file_type ? 'file' : $job->file_type; | ||||
| @@ -94,19 +87,50 @@ class Import extends Command | ||||
|  | ||||
|         /** @var RoutineInterface $routine */ | ||||
|         $routine = app($className); | ||||
|         $routine->setJob($job); | ||||
|         $routine->setImportJob($job); | ||||
|         $routine->run(); | ||||
|  | ||||
|         /** @var MessageBag $error */ | ||||
|         foreach ($routine->getErrors() as $index => $error) { | ||||
|             $this->error(sprintf('Error importing line #%d: %s', $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->line( | ||||
|             sprintf('The import has finished. %d transactions have been imported out of %d records.', $routine->getJournals()->count(), $routine->getLines()) | ||||
|         ); | ||||
|         /** @var Tag $tag */ | ||||
|         $tag   = $job->tag()->first(); | ||||
|         $count = 0; | ||||
|         if (null === $tag) { | ||||
|             $count = $tag->transactionJournals()->count(); | ||||
|         } | ||||
|  | ||||
|         return; | ||||
|         $this->infoLine(sprintf('The import has finished. %d transactions have been imported.', $count)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Displays an error. | ||||
|      * | ||||
|      * @param string     $message | ||||
|      * @param array|null $data | ||||
|      */ | ||||
|     private function errorLine(string $message, array $data = null): void | ||||
|     { | ||||
|         Log::error($message, $data ?? []); | ||||
|         $this->error($message); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Displays an informational message. | ||||
|      * | ||||
|      * @param string $message | ||||
|      * @param array  $data | ||||
|      */ | ||||
|     private function infoLine(string $message, array $data = null): void | ||||
|     { | ||||
|         Log::info($message, $data ?? []); | ||||
|         $this->line($message); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -119,15 +143,14 @@ class Import extends Command | ||||
|     private function isValid(ImportJob $job): bool | ||||
|     { | ||||
|         if (null === $job) { | ||||
|             Log::error('This job does not seem to exist.'); | ||||
|             $this->error('This job does not seem to exist.'); | ||||
|             $this->errorLine('This job does not seem to exist.'); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         if ('configured' !== $job->status) { | ||||
|             Log::error(sprintf('This job is not ready to be imported (status is %s).', $job->status)); | ||||
|             $this->error('This job is not ready to be imported.'); | ||||
|             $this->errorLine('This job is not ready to be imported.'); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <?php | ||||
| /** | ||||
|  * ScanAttachments.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +18,9 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /** @noinspection PhpDynamicAsStaticMethodCallInspection */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console\Commands; | ||||
| @@ -48,18 +51,10 @@ class ScanAttachments extends Command | ||||
|      */ | ||||
|     protected $signature = 'firefly:scan-attachments'; | ||||
|  | ||||
|     /** | ||||
|      * Create a new command instance. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Execute the console command. | ||||
|      */ | ||||
|     public function handle() | ||||
|     public function handle(): void | ||||
|     { | ||||
|         $attachments = Attachment::get(); | ||||
|         $disk        = Storage::disk('upload'); | ||||
| @@ -69,13 +64,13 @@ class ScanAttachments extends Command | ||||
|             try { | ||||
|                 $content = $disk->get($fileName); | ||||
|             } 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; | ||||
|             } | ||||
|             try { | ||||
|                 $decrypted = Crypt::decrypt($content); | ||||
|             } 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; | ||||
|             } | ||||
|             $tmpfname = tempnam(sys_get_temp_dir(), 'FireflyIII'); | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * UpgradeDatabase.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,35 +19,51 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * 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; | ||||
|  | ||||
| use DB; | ||||
| use Exception; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\AccountMeta; | ||||
| use FireflyIII\Models\AccountType; | ||||
| use FireflyIII\Models\Attachment; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Models\Note; | ||||
| use FireflyIII\Models\Preference; | ||||
| use FireflyIII\Models\Rule; | ||||
| use FireflyIII\Models\RuleAction; | ||||
| use FireflyIII\Models\RuleGroup; | ||||
| use FireflyIII\Models\RuleTrigger; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Models\TransactionJournalMeta; | ||||
| use FireflyIII\Models\TransactionType; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | ||||
| use FireflyIII\Repositories\Journal\JournalRepositoryInterface; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Console\Command; | ||||
| use Illuminate\Database\QueryException; | ||||
| use Illuminate\Support\Collection; | ||||
| use Log; | ||||
| use Preferences; | ||||
| use Schema; | ||||
| use UnexpectedValueException; | ||||
|  | ||||
| /** | ||||
|  * Class UpgradeDatabase. | ||||
|  * | ||||
|  * Upgrade user database. | ||||
|  * | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) // it just touches a lot of things. | ||||
|  * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  */ | ||||
| class UpgradeDatabase extends Command | ||||
| { | ||||
| @@ -63,20 +80,10 @@ class UpgradeDatabase extends Command | ||||
|      */ | ||||
|     protected $signature = 'firefly:upgrade-database'; | ||||
|  | ||||
|     /** | ||||
|      * Create a new command instance. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Execute the console command. | ||||
|      * | ||||
|      * @throws \Exception | ||||
|      */ | ||||
|     public function handle() | ||||
|     public function handle(): void | ||||
|     { | ||||
|         $this->setTransactionIdentifier(); | ||||
|         $this->updateAccountCurrencies(); | ||||
| @@ -86,9 +93,157 @@ class UpgradeDatabase extends Command | ||||
|         $this->updateOtherCurrencies(); | ||||
|         $this->line('Done updating currency information..'); | ||||
|         $this->migrateNotes(); | ||||
|         $this->info('Firefly III database is up to date.'); | ||||
|         $this->migrateAttachmentData(); | ||||
|         $this->migrateBillsToRules(); | ||||
|  | ||||
|         return; | ||||
|         $this->info('Firefly III database is up to date.'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 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) { | ||||
|             /** @var Preference $lang */ | ||||
|             $lang               = Preferences::getForUser($user, 'language', 'en_US'); | ||||
|             $groupName          = (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data); | ||||
|             $ruleGroup          = $user->ruleGroups()->where('title', $groupName)->first(); | ||||
|             $currencyPreference = Preferences::getForUser($user, 'currencyPreference', config('firefly.default_currency', 'EUR')); | ||||
|  | ||||
|             if (null === $currencyPreference) { | ||||
|                 $this->error('User has no currency preference. Impossible.'); | ||||
|  | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             $currency = TransactionCurrency::where('code', $currencyPreference->data)->first(); | ||||
|             if (null === $currency) { | ||||
|                 $this->line('Fall back to default currency in migrateBillsToRules().'); | ||||
|                 $currency = app('amount')->getDefaultCurrency(); | ||||
|             } | ||||
|  | ||||
|             if (null === $ruleGroup) { | ||||
|                 $array     = RuleGroup::get(['order'])->pluck('order')->toArray(); | ||||
|                 $order     = \count($array) > 0 ? max($array) + 1 : 1; | ||||
|                 $ruleGroup = RuleGroup::create( | ||||
|                     [ | ||||
|                         'user_id'     => $user->id, | ||||
|                         'title'       => (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data), | ||||
|                         'description' => (string)trans('firefly.rulegroup_for_bills_description', [], $lang->data), | ||||
|                         'order'       => $order, | ||||
|                         'active'      => 1, | ||||
|                     ] | ||||
|                 ); | ||||
|             } | ||||
|  | ||||
|             // loop bills. | ||||
|             $order = 1; | ||||
|             /** @var Collection $collection */ | ||||
|             $collection = $user->bills()->get(); | ||||
|             /** @var Bill $bill */ | ||||
|             foreach ($collection as $bill) { | ||||
|                 if ('MIGRATED_TO_RULES' !== $bill->match) { | ||||
|                     $rule = Rule::create( | ||||
|                         [ | ||||
|                             'user_id'         => $user->id, | ||||
|                             'rule_group_id'   => $ruleGroup->id, | ||||
|                             'title'           => (string)trans('firefly.rule_for_bill_title', ['name' => $bill->name], $lang->data), | ||||
|                             'description'     => (string)trans('firefly.rule_for_bill_description', ['name' => $bill->name], $lang->data), | ||||
|                             'order'           => $order, | ||||
|                             'active'          => $bill->active, | ||||
|                             'stop_processing' => 1, | ||||
|                         ] | ||||
|                     ); | ||||
|                     // add default trigger | ||||
|                     RuleTrigger::create( | ||||
|                         [ | ||||
|                             'rule_id'         => $rule->id, | ||||
|                             'trigger_type'    => 'user_action', | ||||
|                             'trigger_value'   => 'store-journal', | ||||
|                             'active'          => 1, | ||||
|                             'stop_processing' => 0, | ||||
|                             'order'           => 1, | ||||
|                         ] | ||||
|                     ); | ||||
|                     // add trigger for description | ||||
|                     $match = implode(' ', explode(',', $bill->match)); | ||||
|                     RuleTrigger::create( | ||||
|                         [ | ||||
|                             'rule_id'         => $rule->id, | ||||
|                             'trigger_type'    => 'description_contains', | ||||
|                             'trigger_value'   => $match, | ||||
|                             'active'          => 1, | ||||
|                             'stop_processing' => 0, | ||||
|                             'order'           => 2, | ||||
|                         ] | ||||
|                     ); | ||||
|                     if ($bill->amount_max !== $bill->amount_min) { | ||||
|                         // add triggers for amounts: | ||||
|                         RuleTrigger::create( | ||||
|                             [ | ||||
|                                 'rule_id'         => $rule->id, | ||||
|                                 'trigger_type'    => 'amount_less', | ||||
|                                 'trigger_value'   => round($bill->amount_max, $currency->decimal_places), | ||||
|                                 'active'          => 1, | ||||
|                                 'stop_processing' => 0, | ||||
|                                 'order'           => 3, | ||||
|                             ] | ||||
|                         ); | ||||
|                         RuleTrigger::create( | ||||
|                             [ | ||||
|                                 'rule_id'         => $rule->id, | ||||
|                                 'trigger_type'    => 'amount_more', | ||||
|                                 'trigger_value'   => round($bill->amount_min, $currency->decimal_places), | ||||
|                                 'active'          => 1, | ||||
|                                 'stop_processing' => 0, | ||||
|                                 'order'           => 4, | ||||
|                             ] | ||||
|                         ); | ||||
|                     } | ||||
|                     if ($bill->amount_max === $bill->amount_min) { | ||||
|                         RuleTrigger::create( | ||||
|                             [ | ||||
|                                 'rule_id'         => $rule->id, | ||||
|                                 'trigger_type'    => 'amount_exactly', | ||||
|                                 'trigger_value'   => round($bill->amount_min, $currency->decimal_places), | ||||
|                                 'active'          => 1, | ||||
|                                 'stop_processing' => 0, | ||||
|                                 'order'           => 3, | ||||
|                             ] | ||||
|                         ); | ||||
|                     } | ||||
|  | ||||
|                     // create action | ||||
|                     RuleAction::create( | ||||
|                         [ | ||||
|                             'rule_id'         => $rule->id, | ||||
|                             'action_type'     => 'link_to_bill', | ||||
|                             'action_value'    => $bill->name, | ||||
|                             'order'           => 1, | ||||
|                             'active'          => 1, | ||||
|                             'stop_processing' => 0, | ||||
|                         ] | ||||
|                     ); | ||||
|  | ||||
|                     $order++; | ||||
|                     $bill->match = 'MIGRATED_TO_RULES'; | ||||
|                     $bill->save(); | ||||
|                     $this->line(sprintf('Updated bill #%d ("%s") so it will use rules.', $bill->id, $bill->name)); | ||||
|                 } | ||||
|  | ||||
|                 // give bills a currency when they dont have one. | ||||
|                 if (null === $bill->transaction_currency_id) { | ||||
|                     $this->line(sprintf('Gave bill #%d ("%s") a currency (%s).', $bill->id, $bill->name, $currency->name)); | ||||
|                     $bill->transactionCurrency()->associate($currency); | ||||
|                     $bill->save(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -118,31 +273,36 @@ class UpgradeDatabase extends Command | ||||
|         $journalIds = array_unique($result->pluck('id')->toArray()); | ||||
|  | ||||
|         foreach ($journalIds as $journalId) { | ||||
|             $this->updateJournalidentifiers(intval($journalId)); | ||||
|             $this->updateJournalidentifiers((int)$journalId); | ||||
|         } | ||||
|  | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 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) | ||||
|      */ | ||||
|     public function updateAccountCurrencies(): void | ||||
|     { | ||||
|         $accounts = Account::leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') | ||||
|                            ->whereIn('account_types.type', [AccountType::DEFAULT, AccountType::ASSET])->get(['accounts.*']); | ||||
|  | ||||
|         /** @var AccountRepositoryInterface $repository */ | ||||
|         $repository = app(AccountRepositoryInterface::class); | ||||
|         $accounts->each( | ||||
|             function (Account $account) { | ||||
|             function (Account $account) use ($repository) { | ||||
|                 $repository->setUser($account->user); | ||||
|                 // get users preference, fall back to system pref. | ||||
|                 $defaultCurrencyCode = Preferences::getForUser($account->user, 'currencyPreference', config('firefly.default_currency', 'EUR'))->data; | ||||
|                 $defaultCurrency     = TransactionCurrency::where('code', $defaultCurrencyCode)->first(); | ||||
|                 $accountCurrency     = intval($account->getMeta('currency_id')); | ||||
|                 $accountCurrency     = (int)$repository->getMetaValue($account, 'currency_id'); | ||||
|                 $openingBalance      = $account->getOpeningBalance(); | ||||
|                 $obCurrency          = intval($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: | ||||
|                 if (0 === $accountCurrency && 0 === $obCurrency) { | ||||
| @@ -175,7 +335,6 @@ class UpgradeDatabase extends Command | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -185,19 +344,22 @@ class UpgradeDatabase extends Command | ||||
|      * Both source and destination must match the respective currency preference of the related asset account. | ||||
|      * So FF3 must verify all transactions. | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||
|      */ | ||||
|     public function updateOtherCurrencies(): void | ||||
|     { | ||||
|         /** @var CurrencyRepositoryInterface $repository */ | ||||
|         $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') | ||||
|             ->whereIn('transaction_types.type', [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::OPENING_BALANCE]) | ||||
|             ->get(['transaction_journals.*']); | ||||
|  | ||||
|         $set->each( | ||||
|             function (TransactionJournal $journal) use ($repository) { | ||||
|             function (TransactionJournal $journal) use ($repository, $accountRepos) { | ||||
|                 // get the transaction with the asset account in it: | ||||
|                 /** @var Transaction $transaction */ | ||||
|                 $transaction = $journal->transactions() | ||||
| @@ -207,9 +369,13 @@ class UpgradeDatabase extends Command | ||||
|                 if (null === $transaction) { | ||||
|                     return; | ||||
|                 } | ||||
|                 $accountRepos->setUser($journal->user); | ||||
|                 /** @var Account $account */ | ||||
|                 $account      = $transaction->account; | ||||
|                 $currency     = $repository->find(intval($account->getMeta('currency_id'))); | ||||
|                 $account  = $transaction->account; | ||||
|                 $currency = $repository->findNull((int)$accountRepos->getMetaValue($account, 'currency_id')); | ||||
|                 if (null === $currency) { | ||||
|                     return; | ||||
|                 } | ||||
|                 $transactions = $journal->transactions()->get(); | ||||
|                 $transactions->each( | ||||
|                     function (Transaction $transaction) use ($currency) { | ||||
| @@ -219,8 +385,8 @@ class UpgradeDatabase extends Command | ||||
|                         } | ||||
|  | ||||
|                         // when mismatch in transaction: | ||||
|                         if (!(intval($transaction->transaction_currency_id) === intval($currency->id))) { | ||||
|                             $transaction->foreign_currency_id     = intval($transaction->transaction_currency_id); | ||||
|                         if (!((int)$transaction->transaction_currency_id === (int)$currency->id)) { | ||||
|                             $transaction->foreign_currency_id     = (int)$transaction->transaction_currency_id; | ||||
|                             $transaction->foreign_amount          = $transaction->amount; | ||||
|                             $transaction->transaction_currency_id = $currency->id; | ||||
|                             $transaction->save(); | ||||
| @@ -233,7 +399,6 @@ class UpgradeDatabase extends Command | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -246,7 +411,7 @@ class UpgradeDatabase extends Command | ||||
|      * Both source and destination must match the respective currency preference. So FF3 must verify ALL | ||||
|      * transactions. | ||||
|      */ | ||||
|     public function updateTransferCurrencies() | ||||
|     public function updateTransferCurrencies(): void | ||||
|     { | ||||
|         $set = TransactionJournal | ||||
|             ::leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') | ||||
| @@ -272,22 +437,53 @@ class UpgradeDatabase extends Command | ||||
|     { | ||||
|         // create transaction type "Reconciliation". | ||||
|         $type = TransactionType::where('type', TransactionType::RECONCILIATION)->first(); | ||||
|         if (is_null($type)) { | ||||
|         if (null === $type) { | ||||
|             TransactionType::create(['type' => TransactionType::RECONCILIATION]); | ||||
|         } | ||||
|         $account = AccountType::where('type', AccountType::RECONCILIATION)->first(); | ||||
|         if (is_null($account)) { | ||||
|         if (null === $account) { | ||||
|             AccountType::create(['type' => AccountType::RECONCILIATION]); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Move the description of each attachment (when not NULL) to the notes or to a new note object | ||||
|      * for all attachments. | ||||
|      */ | ||||
|     private function migrateAttachmentData(): void | ||||
|     { | ||||
|         $attachments = Attachment::get(); | ||||
|  | ||||
|         /** @var Attachment $att */ | ||||
|         foreach ($attachments as $att) { | ||||
|  | ||||
|             // move description: | ||||
|             $description = (string)$att->description; | ||||
|             if (\strlen($description) > 0) { | ||||
|                 // find or create note: | ||||
|                 $note = $att->notes()->first(); | ||||
|                 if (null === $note) { | ||||
|                     $note = new Note; | ||||
|                     $note->noteable()->associate($att); | ||||
|                 } | ||||
|                 $note->text = $description; | ||||
|                 $note->save(); | ||||
|  | ||||
|                 // clear description: | ||||
|                 $att->description = ''; | ||||
|                 $att->save(); | ||||
|  | ||||
|                 Log::debug(sprintf('Migrated attachment #%s description to note #%d', $att->id, $note->id)); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Move all the journal_meta notes to their note object counter parts. | ||||
|      * | ||||
|      * @throws \Exception | ||||
|      */ | ||||
|     private function migrateNotes(): void | ||||
|     { | ||||
|         /** @noinspection PhpUndefinedMethodInspection */ | ||||
|         $set = TransactionJournalMeta::whereName('notes')->get(); | ||||
|         /** @var TransactionJournalMeta $meta */ | ||||
|         foreach ($set as $meta) { | ||||
| @@ -301,7 +497,11 @@ class UpgradeDatabase extends Command | ||||
|             $note->text = $meta->data; | ||||
|             $note->save(); | ||||
|             Log::debug(sprintf('Migrated meta note #%d to Note #%d', $meta->id, $note->id)); | ||||
|             $meta->delete(); | ||||
|             try { | ||||
|                 $meta->delete(); | ||||
|             } catch (Exception $e) { | ||||
|                 Log::error(sprintf('Could not delete old meta entry #%d: %s', $meta->id, $e->getMessage())); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -314,10 +514,17 @@ class UpgradeDatabase extends Command | ||||
|     { | ||||
|         /** @var CurrencyRepositoryInterface $repository */ | ||||
|         $repository = app(CurrencyRepositoryInterface::class); | ||||
|         $currency   = $repository->find(intval($transaction->account->getMeta('currency_id'))); | ||||
|         $journal    = $transaction->transactionJournal; | ||||
|         /** @var AccountRepositoryInterface $accountRepos */ | ||||
|         $accountRepos = app(AccountRepositoryInterface::class); | ||||
|         $accountRepos->setUser($transaction->account->user); | ||||
|         $currency = $repository->findNull((int)$accountRepos->getMetaValue($transaction->account, 'currency_id')); | ||||
|         $journal  = $transaction->transactionJournal; | ||||
|  | ||||
|         if (!(intval($currency->id) === intval($journal->transaction_currency_id))) { | ||||
|         if (null === $currency) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (!((int)$currency->id === (int)$journal->transaction_currency_id)) { | ||||
|             $this->line( | ||||
|                 sprintf( | ||||
|                     'Transfer #%d ("%s") has been updated to use %s instead of %s.', | ||||
| @@ -331,7 +538,6 @@ class UpgradeDatabase extends Command | ||||
|             $journal->save(); | ||||
|         } | ||||
|  | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -348,7 +554,7 @@ class UpgradeDatabase extends Command | ||||
|         /** @var Transaction $transaction */ | ||||
|         foreach ($transactions as $transaction) { | ||||
|             // find opposing: | ||||
|             $amount = bcmul(strval($transaction->amount), '-1'); | ||||
|             $amount = bcmul((string)$transaction->amount, '-1'); | ||||
|  | ||||
|             try { | ||||
|                 /** @var Transaction $opposing */ | ||||
| @@ -377,7 +583,6 @@ class UpgradeDatabase extends Command | ||||
|             ++$identifier; | ||||
|         } | ||||
|  | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -386,11 +591,11 @@ class UpgradeDatabase extends Command | ||||
|      * | ||||
|      * 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.NPathComplexity) | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * | ||||
|      * @param Transaction $transaction | ||||
|      */ | ||||
| @@ -398,18 +603,31 @@ class UpgradeDatabase extends Command | ||||
|     { | ||||
|         /** @var CurrencyRepositoryInterface $repository */ | ||||
|         $repository = app(CurrencyRepositoryInterface::class); | ||||
|         $currency   = $repository->find(intval($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) { | ||||
|             Log::error(sprintf('Account #%d ("%s") must have currency preference but has none.', $transaction->account->id, $transaction->account->name)); | ||||
|  | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // has no currency ID? Must have, so fill in using account preference: | ||||
|         if (null === $transaction->transaction_currency_id) { | ||||
|             $transaction->transaction_currency_id = intval($currency->id); | ||||
|             $transaction->transaction_currency_id = (int)$currency->id; | ||||
|             Log::debug(sprintf('Transaction #%d has no currency setting, now set to %s', $transaction->id, $currency->code)); | ||||
|             $transaction->save(); | ||||
|         } | ||||
|  | ||||
|         // does not match the source account (see above)? Can be fixed | ||||
|         // when mismatch in transaction and NO foreign amount is set: | ||||
|         if (!(intval($transaction->transaction_currency_id) === intval($currency->id)) && null === $transaction->foreign_amount) { | ||||
|         if (!((int)$transaction->transaction_currency_id === (int)$currency->id) && null === $transaction->foreign_amount) { | ||||
|             Log::debug( | ||||
|                 sprintf( | ||||
|                     'Transaction #%d has a currency setting #%d that should be #%d. Amount remains %s, currency is changed.', | ||||
| @@ -419,7 +637,7 @@ class UpgradeDatabase extends Command | ||||
|                     $transaction->amount | ||||
|                 ) | ||||
|             ); | ||||
|             $transaction->transaction_currency_id = intval($currency->id); | ||||
|             $transaction->transaction_currency_id = (int)$currency->id; | ||||
|             $transaction->save(); | ||||
|         } | ||||
|  | ||||
| @@ -428,16 +646,16 @@ class UpgradeDatabase extends Command | ||||
|         $journal = $transaction->transactionJournal; | ||||
|         /** @var Transaction $opposing */ | ||||
|         $opposing         = $journal->transactions()->where('amount', '>', 0)->where('identifier', $transaction->identifier)->first(); | ||||
|         $opposingCurrency = $repository->find(intval($opposing->account->getMeta('currency_id'))); | ||||
|         $opposingCurrency = $repository->findNull((int)$accountRepos->getMetaValue($opposing->account, 'currency_id')); | ||||
|  | ||||
|         if (null === $opposingCurrency->id) { | ||||
|         if (null === $opposingCurrency) { | ||||
|             Log::error(sprintf('Account #%d ("%s") must have currency preference but has none.', $opposing->account->id, $opposing->account->name)); | ||||
|  | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // if the destination account currency is the same, both foreign_amount and foreign_currency_id must be NULL for both transactions: | ||||
|         if (intval($opposingCurrency->id) === intval($currency->id)) { | ||||
|         if ((int)$opposingCurrency->id === (int)$currency->id) { | ||||
|             // update both transactions to match: | ||||
|             $transaction->foreign_amount       = null; | ||||
|             $transaction->foreign_currency_id  = null; | ||||
| @@ -446,12 +664,21 @@ class UpgradeDatabase extends Command | ||||
|             $opposing->transaction_currency_id = $currency->id; | ||||
|             $transaction->save(); | ||||
|             $opposing->save(); | ||||
|             Log::debug(sprintf('Cleaned up transaction #%d and #%d', $transaction->id, $opposing->id)); | ||||
|             Log::debug( | ||||
|                 sprintf( | ||||
|                     'Currency for account "%s" is %s, and currency for account "%s" is also | ||||
|              %s, so %s #%d (#%d and #%d) has been verified to be to %s exclusively.', | ||||
|                     $opposing->account->name, $opposingCurrency->code, | ||||
|                     $transaction->account->name, $transaction->transactionCurrency->code, | ||||
|                     $journal->transactionType->type, $journal->id, | ||||
|                     $transaction->id, $opposing->id, $currency->code | ||||
|                 ) | ||||
|             ); | ||||
|  | ||||
|             return; | ||||
|         } | ||||
|         // if destination account currency is different, both transactions must have this currency as foreign currency id. | ||||
|         if (!(intval($opposingCurrency->id) === intval($currency->id))) { | ||||
|         if (!((int)$opposingCurrency->id === (int)$currency->id)) { | ||||
|             $transaction->foreign_currency_id = $opposingCurrency->id; | ||||
|             $opposing->foreign_currency_id    = $opposingCurrency->id; | ||||
|             $transaction->save(); | ||||
| @@ -461,31 +688,31 @@ class UpgradeDatabase extends Command | ||||
|  | ||||
|         // if foreign amount of one is null and the other is not, use this to restore: | ||||
|         if (null === $transaction->foreign_amount && null !== $opposing->foreign_amount) { | ||||
|             $transaction->foreign_amount = bcmul(strval($opposing->foreign_amount), '-1'); | ||||
|             $transaction->foreign_amount = bcmul((string)$opposing->foreign_amount, '-1'); | ||||
|             $transaction->save(); | ||||
|             Log::debug(sprintf('Restored foreign amount of transaction (1) #%d to %s', $transaction->id, $transaction->foreign_amount)); | ||||
|         } | ||||
|  | ||||
|         // if foreign amount of one is null and the other is not, use this to restore (other way around) | ||||
|         if (null === $opposing->foreign_amount && null !== $transaction->foreign_amount) { | ||||
|             $opposing->foreign_amount = bcmul(strval($transaction->foreign_amount), '-1'); | ||||
|             $opposing->foreign_amount = bcmul((string)$transaction->foreign_amount, '-1'); | ||||
|             $opposing->save(); | ||||
|             Log::debug(sprintf('Restored foreign amount of transaction (2) #%d to %s', $opposing->id, $opposing->foreign_amount)); | ||||
|         } | ||||
|  | ||||
|         // when both are zero, try to grab it from journal: | ||||
|         if (null === $opposing->foreign_amount && null === $transaction->foreign_amount) { | ||||
|             $foreignAmount = $journal->getMeta('foreign_amount'); | ||||
|             $foreignAmount = $journalRepos->getMetaField($journal, 'foreign_amount'); | ||||
|             if (null === $foreignAmount) { | ||||
|                 Log::debug(sprintf('Journal #%d has missing foreign currency data, forced to do 1:1 conversion :(.', $transaction->transaction_journal_id)); | ||||
|                 $transaction->foreign_amount = bcmul(strval($transaction->amount), '-1'); | ||||
|                 $opposing->foreign_amount    = bcmul(strval($opposing->amount), '-1'); | ||||
|                 $transaction->foreign_amount = bcmul((string)$transaction->amount, '-1'); | ||||
|                 $opposing->foreign_amount    = bcmul((string)$opposing->amount, '-1'); | ||||
|                 $transaction->save(); | ||||
|                 $opposing->save(); | ||||
|  | ||||
|                 return; | ||||
|             } | ||||
|             $foreignPositive = app('steam')->positive(strval($foreignAmount)); | ||||
|             $foreignPositive = app('steam')->positive((string)$foreignAmount); | ||||
|             Log::debug( | ||||
|                 sprintf( | ||||
|                     'Journal #%d has missing foreign currency info, try to restore from meta-data ("%s").', | ||||
| @@ -499,7 +726,6 @@ class UpgradeDatabase extends Command | ||||
|             $opposing->save(); | ||||
|         } | ||||
|  | ||||
|         return; | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <?php | ||||
| /** | ||||
|  * UpgradeFireflyInstructions.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +18,7 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console\Commands; | ||||
| @@ -42,18 +43,10 @@ class UpgradeFireflyInstructions extends Command | ||||
|      */ | ||||
|     protected $signature = 'firefly:instructions {task}'; | ||||
|  | ||||
|     /** | ||||
|      * Create a new command instance. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Execute the console command. | ||||
|      */ | ||||
|     public function handle() | ||||
|     public function handle(): void | ||||
|     { | ||||
|         if ('update' === $this->argument('task')) { | ||||
|             $this->updateInstructions(); | ||||
| @@ -68,7 +61,7 @@ class UpgradeFireflyInstructions extends Command | ||||
|      * | ||||
|      * @param string $text | ||||
|      */ | ||||
|     private function boxed(string $text) | ||||
|     private function boxed(string $text): void | ||||
|     { | ||||
|         $parts = explode("\n", wordwrap($text)); | ||||
|         foreach ($parts as $string) { | ||||
| @@ -81,7 +74,7 @@ class UpgradeFireflyInstructions extends Command | ||||
|      * | ||||
|      * @param string $text | ||||
|      */ | ||||
|     private function boxedInfo(string $text) | ||||
|     private function boxedInfo(string $text): void | ||||
|     { | ||||
|         $parts = explode("\n", wordwrap($text)); | ||||
|         foreach ($parts as $string) { | ||||
| @@ -92,7 +85,7 @@ class UpgradeFireflyInstructions extends Command | ||||
|     /** | ||||
|      * Render instructions. | ||||
|      */ | ||||
|     private function installInstructions() | ||||
|     private function installInstructions(): void | ||||
|     { | ||||
|         /** @var string $version */ | ||||
|         $version = config('firefly.version'); | ||||
| @@ -100,8 +93,7 @@ class UpgradeFireflyInstructions extends Command | ||||
|         $text    = ''; | ||||
|         foreach (array_keys($config) as $compare) { | ||||
|             // if string starts with: | ||||
|             $len = strlen($compare); | ||||
|             if (substr($version, 0, $len) === $compare) { | ||||
|             if (0 === strpos($version, $compare)) { | ||||
|                 $text = $config[$compare]; | ||||
|             } | ||||
|         } | ||||
| @@ -126,7 +118,7 @@ class UpgradeFireflyInstructions extends Command | ||||
|     /** | ||||
|      * Show a line. | ||||
|      */ | ||||
|     private function showLine() | ||||
|     private function showLine(): void | ||||
|     { | ||||
|         $line = '+'; | ||||
|         for ($i = 0; $i < 78; ++$i) { | ||||
| @@ -139,7 +131,7 @@ class UpgradeFireflyInstructions extends Command | ||||
|     /** | ||||
|      * Render upgrade instructions. | ||||
|      */ | ||||
|     private function updateInstructions() | ||||
|     private function updateInstructions(): void | ||||
|     { | ||||
|         /** @var string $version */ | ||||
|         $version = config('firefly.version'); | ||||
| @@ -147,8 +139,7 @@ class UpgradeFireflyInstructions extends Command | ||||
|         $text    = ''; | ||||
|         foreach (array_keys($config) as $compare) { | ||||
|             // if string starts with: | ||||
|             $len = strlen($compare); | ||||
|             if (substr($version, 0, $len) === $compare) { | ||||
|             if (0 === strpos($version, $compare)) { | ||||
|                 $text = $config[$compare]; | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * UseEncryption.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -19,6 +18,7 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console\Commands; | ||||
| @@ -44,23 +44,15 @@ class UseEncryption extends Command | ||||
|      */ | ||||
|     protected $signature = 'firefly:use-encryption'; | ||||
|  | ||||
|     /** | ||||
|      * Create a new command instance. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Execute the console command. | ||||
|      */ | ||||
|     public function handle() | ||||
|     public function handle(): void | ||||
|     { | ||||
|         if (config('firefly.encryption') === true) { | ||||
|         if (true === config('firefly.encryption')) { | ||||
|             $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->handleObjects('Account', 'name', 'encrypted'); | ||||
| @@ -79,18 +71,21 @@ class UseEncryption extends Command | ||||
|      * @param string $field | ||||
|      * @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); | ||||
|         $encrypt = config('firefly.encryption') === true ? 0 : 1; | ||||
|         $set     = $fqn::where($indicator, $encrypt)->get(); | ||||
|         $encrypt = true === config('firefly.encryption') ? 0 : 1; | ||||
|         /** @noinspection PhpUndefinedMethodInspection */ | ||||
|         $set = $fqn::where($indicator, $encrypt)->get(); | ||||
|  | ||||
|         foreach ($set as $entry) { | ||||
|             $newName       = $entry->$field; | ||||
|             $entry->$field = $newName; | ||||
|             /** @noinspection PhpUndefinedMethodInspection */ | ||||
|             $entry->save(); | ||||
|         } | ||||
|  | ||||
|         /** @noinspection PhpUndefinedMethodInspection */ | ||||
|         $this->line(sprintf('Updated %d %s.', $set->count(), strtolower(Str::plural($class)))); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <?php | ||||
| /** | ||||
|  * VerifiesAccessToken.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +18,7 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console\Commands; | ||||
| @@ -49,11 +50,11 @@ trait VerifiesAccessToken | ||||
|      */ | ||||
|     protected function verifyAccessToken(): bool | ||||
|     { | ||||
|         $userId = intval($this->option('user')); | ||||
|         $token  = strval($this->option('token')); | ||||
|         $userId = (int)$this->option('user'); | ||||
|         $token  = (string)$this->option('token'); | ||||
|         /** @var UserRepositoryInterface $repository */ | ||||
|         $repository = app(UserRepositoryInterface::class); | ||||
|         $user       = $repository->find($userId); | ||||
|         $user       = $repository->findNull($userId); | ||||
|  | ||||
|         if (null === $user) { | ||||
|             Log::error(sprintf('verifyAccessToken(): no such user for input "%d"', $userId)); | ||||
| @@ -68,7 +69,7 @@ trait VerifiesAccessToken | ||||
|         } | ||||
|         if (!($accessToken->data === $token)) { | ||||
|             Log::error(sprintf('Invalid access token for user #%d.', $userId)); | ||||
|             Log::error(sprintf('Token given is "%s", expected "%s".', $token, $accessToken->data)); | ||||
|             Log::error(sprintf('Token given is "%s", expected something else.', $token)); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <?php | ||||
| /** | ||||
|  * VerifyDatabase.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +18,9 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /** @noinspection PhpDynamicAsStaticMethodCallInspection */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console\Commands; | ||||
| @@ -27,6 +30,7 @@ use DB; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\AccountType; | ||||
| use FireflyIII\Models\Budget; | ||||
| use FireflyIII\Models\Category; | ||||
| use FireflyIII\Models\LinkType; | ||||
| use FireflyIII\Models\PiggyBankEvent; | ||||
| use FireflyIII\Models\Transaction; | ||||
| @@ -37,6 +41,7 @@ use FireflyIII\User; | ||||
| use Illuminate\Console\Command; | ||||
| use Illuminate\Contracts\Encryption\DecryptException; | ||||
| use Illuminate\Database\Eloquent\Builder; | ||||
| use Log; | ||||
| use Preferences; | ||||
| use Schema; | ||||
| use stdClass; | ||||
| @@ -44,6 +49,7 @@ use stdClass; | ||||
| /** | ||||
|  * Class VerifyDatabase. | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  */ | ||||
| class VerifyDatabase extends Command | ||||
| @@ -61,26 +67,18 @@ class VerifyDatabase extends Command | ||||
|      */ | ||||
|     protected $signature = 'firefly:verify'; | ||||
|  | ||||
|     /** | ||||
|      * Create a new command instance. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Execute the console command. | ||||
|      */ | ||||
|     public function handle() | ||||
|     public function handle(): void | ||||
|     { | ||||
|         // if table does not exist, return false | ||||
|         if (!Schema::hasTable('users')) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $this->reportObject('budget'); | ||||
|         $this->reportObject('category'); | ||||
|         $this->reportEmptyBudgets(); | ||||
|         $this->reportEmptyCategories(); | ||||
|         $this->reportObject('tag'); | ||||
|         $this->reportAccounts(); | ||||
|         $this->reportBudgetLimits(); | ||||
| @@ -95,12 +93,14 @@ class VerifyDatabase extends Command | ||||
|         $this->createLinkTypes(); | ||||
|         $this->createAccessTokens(); | ||||
|         $this->fixDoubleAmounts(); | ||||
|         $this->fixBadMeta(); | ||||
|         $this->removeBills(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Create user access tokens, if not present already. | ||||
|      */ | ||||
|     private function createAccessTokens() | ||||
|     private function createAccessTokens(): void | ||||
|     { | ||||
|         $count = 0; | ||||
|         $users = User::get(); | ||||
| @@ -122,7 +122,7 @@ class VerifyDatabase extends Command | ||||
|     /** | ||||
|      * Create default link types if necessary. | ||||
|      */ | ||||
|     private function createLinkTypes() | ||||
|     private function createLinkTypes(): void | ||||
|     { | ||||
|         $count = 0; | ||||
|         $set   = [ | ||||
| @@ -148,7 +148,78 @@ class VerifyDatabase extends Command | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private function fixDoubleAmounts() | ||||
|     /** | ||||
|      * Fix the situation where the matching transactions of a journal somehow have non-matching categories or budgets. | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||
|      */ | ||||
|     private function fixBadMeta(): void | ||||
|     { | ||||
|         // categories | ||||
|         $set     = Transaction | ||||
|             ::leftJoin('category_transaction', 'category_transaction.transaction_id', '=', 'transactions.id') | ||||
|             ->whereNull('transactions.deleted_at') | ||||
|             ->get(['transactions.id', 'transaction_journal_id', 'identifier', 'category_transaction.category_id', 'category_transaction.id as ct_id']); | ||||
|         $results = []; | ||||
|         foreach ($set as $obj) { | ||||
|             $key      = $obj->transaction_journal_id . '-' . $obj->identifier; | ||||
|             $category = (int)$obj->category_id; | ||||
|  | ||||
|             // value exists and is not category: | ||||
|             if (isset($results[$key]) && $results[$key] !== $category) { | ||||
|                 $this->error( | ||||
|                     sprintf( | ||||
|                         'Transaction #%d referred to the wrong category. Was category #%d but is fixed to be category #%d.', $obj->transaction_journal_id, | ||||
|                         $category, $results[$key] | ||||
|                     ) | ||||
|                 ); | ||||
|                 DB::table('category_transaction')->where('id', $obj->ct_id)->update(['category_id' => $results[$key]]); | ||||
|  | ||||
|             } | ||||
|  | ||||
|             // value does not exist: | ||||
|             if ($category > 0 && !isset($results[$key])) { | ||||
|                 $results[$key] = $category; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // budgets | ||||
|         $set     = Transaction | ||||
|             ::leftJoin('budget_transaction', 'budget_transaction.transaction_id', '=', 'transactions.id') | ||||
|             ->whereNull('transactions.deleted_at') | ||||
|             ->get(['transactions.id', 'transaction_journal_id', 'identifier', 'budget_transaction.budget_id', 'budget_transaction.id as ct_id']); | ||||
|         $results = []; | ||||
|         foreach ($set as $obj) { | ||||
|             $key    = $obj->transaction_journal_id . '-' . $obj->identifier; | ||||
|             $budget = (int)$obj->budget_id; | ||||
|  | ||||
|             // value exists and is not budget: | ||||
|             if (isset($results[$key]) && $results[$key] !== $budget) { | ||||
|                 $this->error( | ||||
|                     sprintf( | ||||
|                         'Transaction #%d referred to the wrong budget. Was budget #%d but is fixed to be budget #%d.', $obj->transaction_journal_id, $budget, | ||||
|                         $results[$key] | ||||
|                     ) | ||||
|                 ); | ||||
|                 DB::table('budget_transaction')->where('id', $obj->ct_id)->update(['budget_id' => $results[$key]]); | ||||
|  | ||||
|             } | ||||
|  | ||||
|             // value does not exist: | ||||
|             if ($budget > 0 && !isset($results[$key])) { | ||||
|                 $results[$key] = $budget; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Makes sure amounts are stored correctly. | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||
|      */ | ||||
|     private function fixDoubleAmounts(): void | ||||
|     { | ||||
|         $count = 0; | ||||
|         // get invalid journals | ||||
| @@ -158,7 +229,7 @@ class VerifyDatabase extends Command | ||||
|                       ->get(['transaction_journal_id', DB::raw('SUM(amount) AS the_sum')]); | ||||
|         /** @var stdClass $entry */ | ||||
|         foreach ($journals as $entry) { | ||||
|             if (0 !== bccomp(strval($entry->the_sum), '0')) { | ||||
|             if (0 !== bccomp((string)$entry->the_sum, '0')) { | ||||
|                 $errored[] = $entry->transaction_journal_id; | ||||
|             } | ||||
|         } | ||||
| @@ -171,7 +242,7 @@ class VerifyDatabase extends Command | ||||
|             // report about it | ||||
|             /** @var TransactionJournal $journal */ | ||||
|             $journal = TransactionJournal::find($journalId); | ||||
|             if (is_null($journal)) { | ||||
|             if (null === $journal) { | ||||
|                 continue; | ||||
|             } | ||||
|             if (TransactionType::OPENING_BALANCE === $journal->transactionType->type) { | ||||
| @@ -194,8 +265,23 @@ class VerifyDatabase extends Command | ||||
|         if (0 === $count) { | ||||
|             $this->info('Amount integrity OK!'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|         return; | ||||
|     /** | ||||
|      * 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(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -225,14 +311,12 @@ class VerifyDatabase extends Command | ||||
|                 return true; | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Reports on accounts with no transactions. | ||||
|      */ | ||||
|     private function reportAccounts() | ||||
|     private function reportAccounts(): void | ||||
|     { | ||||
|         $set = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id') | ||||
|                       ->leftJoin('users', 'accounts.user_id', '=', 'users.id') | ||||
| @@ -254,7 +338,7 @@ class VerifyDatabase extends Command | ||||
|     /** | ||||
|      * Reports on budgets with no budget limits (which makes them pointless). | ||||
|      */ | ||||
|     private function reportBudgetLimits() | ||||
|     private function reportBudgetLimits(): void | ||||
|     { | ||||
|         $set = Budget::leftJoin('budget_limits', 'budget_limits.budget_id', '=', 'budgets.id') | ||||
|                      ->leftJoin('users', 'budgets.user_id', '=', 'users.id') | ||||
| @@ -278,7 +362,7 @@ class VerifyDatabase extends Command | ||||
|     /** | ||||
|      * Reports on deleted accounts that still have not deleted transactions or journals attached to them. | ||||
|      */ | ||||
|     private function reportDeletedAccounts() | ||||
|     private function reportDeletedAccounts(): void | ||||
|     { | ||||
|         $set = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id') | ||||
|                       ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') | ||||
| @@ -297,7 +381,7 @@ class VerifyDatabase extends Command | ||||
|                       ); | ||||
|         /** @var stdClass $entry */ | ||||
|         foreach ($set as $entry) { | ||||
|             $date = null === $entry->transaction_deleted_at ? $entry->journal_deleted_at : $entry->transaction_deleted_at; | ||||
|             $date = $entry->transaction_deleted_at ?? $entry->journal_deleted_at; | ||||
|             $this->error( | ||||
|                 'Error: Account #' . $entry->account_id . ' should have been deleted, but has not.' . | ||||
|                 ' Find it in the table called "accounts" and change the "deleted_at" field to: "' . $date . '"' | ||||
| @@ -305,10 +389,86 @@ 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. | ||||
|      */ | ||||
|     private function reportIncorrectJournals() | ||||
|     private function reportIncorrectJournals(): void | ||||
|     { | ||||
|         $configuration = [ | ||||
|             // a withdrawal can not have revenue account: | ||||
| @@ -350,7 +510,7 @@ class VerifyDatabase extends Command | ||||
|     /** | ||||
|      * Any deleted transaction journals that have transactions that are NOT deleted:. | ||||
|      */ | ||||
|     private function reportJournals() | ||||
|     private function reportJournals(): void | ||||
|     { | ||||
|         $count = 0; | ||||
|         $set   = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') | ||||
| @@ -381,7 +541,7 @@ class VerifyDatabase extends Command | ||||
|     /** | ||||
|      * Report on journals without transactions. | ||||
|      */ | ||||
|     private function reportNoTransactions() | ||||
|     private function reportNoTransactions(): void | ||||
|     { | ||||
|         $count = 0; | ||||
|         $set   = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') | ||||
| @@ -405,17 +565,18 @@ class VerifyDatabase extends Command | ||||
|      * | ||||
|      * @param string $name | ||||
|      */ | ||||
|     private function reportObject(string $name) | ||||
|     private function reportObject(string $name): void | ||||
|     { | ||||
|         $plural = str_plural($name); | ||||
|         $class  = sprintf('FireflyIII\Models\%s', ucfirst($name)); | ||||
|         $field  = 'tag' === $name ? 'tag' : 'name'; | ||||
|         $set    = $class::leftJoin($name . '_transaction_journal', $plural . '.id', '=', $name . '_transaction_journal.' . $name . '_id') | ||||
|                         ->leftJoin('users', $plural . '.user_id', '=', 'users.id') | ||||
|                         ->distinct() | ||||
|                         ->whereNull($name . '_transaction_journal.' . $name . '_id') | ||||
|                         ->whereNull($plural . '.deleted_at') | ||||
|                         ->get([$plural . '.id', $plural . '.' . $field . ' as name', $plural . '.user_id', 'users.email']); | ||||
|         /** @noinspection PhpUndefinedMethodInspection */ | ||||
|         $set = $class::leftJoin($name . '_transaction_journal', $plural . '.id', '=', $name . '_transaction_journal.' . $name . '_id') | ||||
|                      ->leftJoin('users', $plural . '.user_id', '=', 'users.id') | ||||
|                      ->distinct() | ||||
|                      ->whereNull($name . '_transaction_journal.' . $name . '_id') | ||||
|                      ->whereNull($plural . '.deleted_at') | ||||
|                      ->get([$plural . '.id', $plural . '.' . $field . ' as name', $plural . '.user_id', 'users.email']); | ||||
|  | ||||
|         /** @var stdClass $entry */ | ||||
|         foreach ($set as $entry) { | ||||
| @@ -424,6 +585,7 @@ class VerifyDatabase extends Command | ||||
|                 $objName = Crypt::decrypt($objName); | ||||
|             } catch (DecryptException $e) { | ||||
|                 // it probably was not encrypted. | ||||
|                 Log::debug(sprintf('Not a problem: %s', $e->getMessage())); | ||||
|             } | ||||
|  | ||||
|             $line = sprintf( | ||||
| @@ -441,17 +603,18 @@ class VerifyDatabase extends Command | ||||
|     /** | ||||
|      * Reports for each user when the sum of their transactions is not zero. | ||||
|      */ | ||||
|     private function reportSum() | ||||
|     private function reportSum(): void | ||||
|     { | ||||
|         /** @var UserRepositoryInterface $userRepository */ | ||||
|         $userRepository = app(UserRepositoryInterface::class); | ||||
|  | ||||
|         /** @var User $user */ | ||||
|         foreach ($userRepository->all() as $user) { | ||||
|             $sum = strval($user->transactions()->sum('amount')); | ||||
|             $sum = (string)$user->transactions()->sum('amount'); | ||||
|             if (0 !== bccomp($sum, '0')) { | ||||
|                 $this->error('Error: Transactions for user #' . $user->id . ' (' . $user->email . ') are off by ' . $sum . '!'); | ||||
|             } else { | ||||
|             } | ||||
|             if (0 === bccomp($sum, '0')) { | ||||
|                 $this->info(sprintf('Amount integrity OK for user #%d', $user->id)); | ||||
|             } | ||||
|         } | ||||
| @@ -460,7 +623,7 @@ class VerifyDatabase extends Command | ||||
|     /** | ||||
|      * Reports on deleted transactions that are connected to a not deleted journal. | ||||
|      */ | ||||
|     private function reportTransactions() | ||||
|     private function reportTransactions(): void | ||||
|     { | ||||
|         $set = Transaction::leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') | ||||
|                           ->whereNotNull('transactions.deleted_at') | ||||
| @@ -481,7 +644,7 @@ class VerifyDatabase extends Command | ||||
|     /** | ||||
|      * Report on transfers that have budgets. | ||||
|      */ | ||||
|     private function reportTransfersBudgets() | ||||
|     private function reportTransfersBudgets(): void | ||||
|     { | ||||
|         $set = TransactionJournal::distinct() | ||||
|                                  ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Kernel.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,34 +19,29 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Jobs\CreateRecurringTransactions; | ||||
| use Illuminate\Console\Scheduling\Schedule; | ||||
| use Illuminate\Foundation\Console\Kernel as ConsoleKernel; | ||||
|  | ||||
| /** | ||||
|  * File to make sure commnds work. | ||||
|  * File to make sure commands work. | ||||
|  */ | ||||
| class Kernel extends ConsoleKernel | ||||
| { | ||||
|     /** | ||||
|      * The Artisan commands provided by your application. | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $commands | ||||
|         = [ | ||||
|         ]; | ||||
|  | ||||
|     /** | ||||
|      * Register the commands for the application. | ||||
|      */ | ||||
|     protected function commands() | ||||
|     protected function commands(): void | ||||
|     { | ||||
|         $this->load(__DIR__ . '/Commands'); | ||||
|  | ||||
|         /** @noinspection PhpIncludeInspection */ | ||||
|         require base_path('routes/console.php'); | ||||
|     } | ||||
|  | ||||
| @@ -53,10 +49,9 @@ class Kernel extends ConsoleKernel | ||||
|      * Define the application's command schedule. | ||||
|      * | ||||
|      * @param \Illuminate\Console\Scheduling\Schedule $schedule | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||
|      */ | ||||
|     protected function schedule(Schedule $schedule) | ||||
|     protected function schedule(Schedule $schedule): void | ||||
|     { | ||||
|         $schedule->job(new CreateRecurringTransactions(new Carbon))->daily(); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * AdminRequestedTestMessage.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +19,7 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Events; | ||||
| @@ -33,13 +35,9 @@ class AdminRequestedTestMessage extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string The users IP address */ | ||||
|     public $ipAddress; | ||||
|     /** | ||||
|      * @var User | ||||
|      */ | ||||
|     /** @var User The user */ | ||||
|     public $user; | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Event.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +19,7 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Events; | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * RegisteredUser.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +19,7 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Events; | ||||
| @@ -32,13 +34,9 @@ class RegisteredUser extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string The users IP address */ | ||||
|     public $ipAddress; | ||||
|     /** | ||||
|      * @var User | ||||
|      */ | ||||
|     /** @var User The user */ | ||||
|     public $user; | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * RequestedNewPassword.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +19,7 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Events; | ||||
| @@ -32,18 +34,12 @@ class RequestedNewPassword extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string The users IP address */ | ||||
|     public $ipAddress; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     public $token; | ||||
|     /** | ||||
|      * @var User | ||||
|      */ | ||||
|     /** @var User The user */ | ||||
|     public $user; | ||||
|     /** @var string The token */ | ||||
|     public $token; | ||||
|  | ||||
|     /** | ||||
|      * Create a new event instance. This event is triggered when a users tries to reset his or her password. | ||||
|   | ||||
							
								
								
									
										65
									
								
								app/Events/RequestedReportOnJournals.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								app/Events/RequestedReportOnJournals.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| <?php | ||||
| /** | ||||
|  * 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 | ||||
|  */ | ||||
| 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,7 +1,8 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * RequestedVersionCheckStatus.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -34,9 +35,7 @@ class RequestedVersionCheckStatus extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
|  | ||||
|     /** | ||||
|      * @var User | ||||
|      */ | ||||
|     /** @var User The user */ | ||||
|     public $user; | ||||
|  | ||||
|     /** | ||||
| @@ -49,4 +48,4 @@ class RequestedVersionCheckStatus extends Event | ||||
|     { | ||||
|         $this->user = $user; | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * StoredTransactionJournal.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +19,7 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Events; | ||||
| @@ -27,14 +29,16 @@ use Illuminate\Queue\SerializesModels; | ||||
|  | ||||
| /** | ||||
|  * Class StoredTransactionJournal. | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  */ | ||||
| class StoredTransactionJournal extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
|  | ||||
|     /** @var TransactionJournal */ | ||||
|     /** @var TransactionJournal The journal that was stored. */ | ||||
|     public $journal; | ||||
|     /** @var int */ | ||||
|     /** @var int The piggy bank ID. */ | ||||
|     public $piggyBankId; | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * UpdatedTransactionJournal.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +19,7 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Events; | ||||
| @@ -27,12 +29,15 @@ use Illuminate\Queue\SerializesModels; | ||||
|  | ||||
| /** | ||||
|  * Class UpdatedTransactionJournal. | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * | ||||
|  */ | ||||
| class UpdatedTransactionJournal extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
|  | ||||
|     /** @var TransactionJournal */ | ||||
|     /** @var TransactionJournal The journal. */ | ||||
|     public $journal; | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * UserChangedEmail.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +19,7 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Events; | ||||
| @@ -32,13 +34,13 @@ class UserChangedEmail extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
|  | ||||
|     /** @var string */ | ||||
|     /** @var string The user's IP address */ | ||||
|     public $ipAddress; | ||||
|     /** @var string */ | ||||
|     /** @var string The user's new email address */ | ||||
|     public $newEmail; | ||||
|     /** @var string */ | ||||
|     /** @var string The user's old email address */ | ||||
|     public $oldEmail; | ||||
|     /** @var User */ | ||||
|     /** @var User The user itself */ | ||||
|     public $user; | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * FireflyException.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,13 +19,16 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Exceptions; | ||||
|  | ||||
| use Exception; | ||||
|  | ||||
| /** | ||||
|  * Class FireflyException. | ||||
|  */ | ||||
| class FireflyException extends \Exception | ||||
| class FireflyException extends Exception | ||||
| { | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Handler.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +19,9 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /** @noinspection MultipleReturnStatementsInspection */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Exceptions; | ||||
| @@ -28,6 +32,7 @@ use FireflyIII\Jobs\MailError; | ||||
| use Illuminate\Auth\AuthenticationException; | ||||
| use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; | ||||
| use Illuminate\Validation\ValidationException; | ||||
| use League\OAuth2\Server\Exception\OAuthServerException; | ||||
| use Request; | ||||
| use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | ||||
|  | ||||
| @@ -36,32 +41,16 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | ||||
|  */ | ||||
| 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. | ||||
|      * | ||||
|      * @param \Illuminate\Http\Request $request | ||||
|      * @param \Exception               $exception | ||||
|      * @param Request   $request | ||||
|      * @param Exception $exception | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * @SuppressWarnings(PHPMD.NPathComplexity) | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||
|      * | ||||
|      * @return \Illuminate\Http\Response | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function render($request, Exception $exception) | ||||
|     { | ||||
| @@ -70,13 +59,19 @@ class Handler extends ExceptionHandler | ||||
|             return parent::render($request, $exception); | ||||
|         } | ||||
|         if ($exception instanceof NotFoundHttpException && $request->expectsJson()) { | ||||
|             // JSON error: | ||||
|             return response()->json(['message' => 'Resource not found', 'exception' => 'NotFoundHttpException'], 404); | ||||
|         } | ||||
|  | ||||
|         if ($exception instanceof AuthenticationException && $request->expectsJson()) { | ||||
|             // somehow Laravel handler does not catch this: | ||||
|             return response()->json(['message' => 'Unauthenticated', 'exception' => 'AuthenticationException'], 401); | ||||
|         } | ||||
|  | ||||
|         if ($exception instanceof OAuthServerException && $request->expectsJson()) { | ||||
|             // somehow Laravel handler does not catch this: | ||||
|             return response()->json(['message' => $exception->getMessage(), 'exception' => 'OAuthServerException'], 401); | ||||
|         } | ||||
|  | ||||
|         if ($request->expectsJson()) { | ||||
|             $isDebug = config('app.debug', false); | ||||
| @@ -84,7 +79,7 @@ class Handler extends ExceptionHandler | ||||
|                 return response()->json( | ||||
|                     [ | ||||
|                         'message'   => $exception->getMessage(), | ||||
|                         'exception' => get_class($exception), | ||||
|                         'exception' => \get_class($exception), | ||||
|                         'line'      => $exception->getLine(), | ||||
|                         'file'      => $exception->getFile(), | ||||
|                         'trace'     => $exception->getTrace(), | ||||
| @@ -92,10 +87,10 @@ class Handler extends ExceptionHandler | ||||
|                 ); | ||||
|             } | ||||
|  | ||||
|             return response()->json(['message' => 'Internal Firefly III Exception. See log files.', 'exception' => get_class($exception)], 500); | ||||
|             return response()->json(['message' => 'Internal Firefly III Exception. See log files.', 'exception' => \get_class($exception)], 500); | ||||
|         } | ||||
|  | ||||
|         if ($exception instanceof FireflyException || $exception instanceof ErrorException) { | ||||
|         if ($exception instanceof FireflyException || $exception instanceof ErrorException || $exception instanceof OAuthServerException) { | ||||
|             $isDebug = env('APP_DEBUG', false); | ||||
|  | ||||
|             return response()->view('errors.FireflyException', ['exception' => $exception, 'debug' => $isDebug], 500); | ||||
| @@ -119,8 +114,12 @@ class Handler extends ExceptionHandler | ||||
|      */ | ||||
|     public function report(Exception $exception) | ||||
|     { | ||||
|  | ||||
|         $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 = [ | ||||
|                 'id'    => 0, | ||||
|                 'email' => 'unknown@example.com', | ||||
| @@ -130,7 +129,7 @@ class Handler extends ExceptionHandler | ||||
|                 $userData['email'] = auth()->user()->email; | ||||
|             } | ||||
|             $data = [ | ||||
|                 'class'        => get_class($exception), | ||||
|                 'class'        => \get_class($exception), | ||||
|                 'errorMessage' => $exception->getMessage(), | ||||
|                 'time'         => date('r'), | ||||
|                 'stackTrace'   => $exception->getTraceAsString(), | ||||
| @@ -138,6 +137,9 @@ class Handler extends ExceptionHandler | ||||
|                 'line'         => $exception->getLine(), | ||||
|                 'code'         => $exception->getCode(), | ||||
|                 'version'      => config('firefly.version'), | ||||
|                 'url'          => Request::fullUrl(), | ||||
|                 'userAgent'    => Request::userAgent(), | ||||
|                 'json'         => Request::acceptsJson(), | ||||
|             ]; | ||||
|  | ||||
|             // create job that will mail. | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * NotImplementedException.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +19,7 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Exceptions; | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * ValidationException.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +19,7 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Exceptions; | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <?php | ||||
| /** | ||||
|  * AttachmentCollector.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +18,7 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Export\Collector; | ||||
| @@ -27,6 +28,7 @@ use Crypt; | ||||
| use FireflyIII\Models\Attachment; | ||||
| use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; | ||||
| use Illuminate\Contracts\Encryption\DecryptException; | ||||
| use Illuminate\Contracts\Filesystem\FileNotFoundException; | ||||
| use Illuminate\Support\Collection; | ||||
| use Log; | ||||
| use Storage; | ||||
| @@ -36,15 +38,15 @@ use Storage; | ||||
|  */ | ||||
| class AttachmentCollector extends BasicCollector implements CollectorInterface | ||||
| { | ||||
|     /** @var Carbon */ | ||||
|     /** @var Carbon The end date of the range. */ | ||||
|     private $end; | ||||
|     /** @var \Illuminate\Contracts\Filesystem\Filesystem */ | ||||
|     /** @var \Illuminate\Contracts\Filesystem\Filesystem File system */ | ||||
|     private $exportDisk; | ||||
|     /** @var AttachmentRepositoryInterface */ | ||||
|     /** @var AttachmentRepositoryInterface Attachment repository */ | ||||
|     private $repository; | ||||
|     /** @var Carbon */ | ||||
|     /** @var Carbon Start date of range */ | ||||
|     private $start; | ||||
|     /** @var \Illuminate\Contracts\Filesystem\Filesystem */ | ||||
|     /** @var \Illuminate\Contracts\Filesystem\Filesystem Disk with uploads on it */ | ||||
|     private $uploadDisk; | ||||
|  | ||||
|     /** | ||||
| @@ -62,6 +64,8 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Run the routine. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function run(): bool | ||||
| @@ -78,6 +82,8 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set the start and end date. | ||||
|      * | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      */ | ||||
| @@ -87,24 +93,33 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface | ||||
|         $this->end   = $end; | ||||
|     } | ||||
|  | ||||
|     /** @noinspection MultipleReturnStatementsInspection */ | ||||
|     /** | ||||
|      * Export attachments. | ||||
|      * | ||||
|      * @param Attachment $attachment | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     private function exportAttachment(Attachment $attachment): bool | ||||
|     { | ||||
|         $file = $attachment->fileName(); | ||||
|         $file      = $attachment->fileName(); | ||||
|         $decrypted = false; | ||||
|         if ($this->uploadDisk->exists($file)) { | ||||
|             try { | ||||
|                 $decrypted  = Crypt::decrypt($this->uploadDisk->get($file)); | ||||
|                 $exportFile = $this->exportFileName($attachment); | ||||
|                 $this->exportDisk->put($exportFile, $decrypted); | ||||
|                 $this->getEntries()->push($exportFile); | ||||
|             } catch (DecryptException $e) { | ||||
|                 $decrypted = Crypt::decrypt($this->uploadDisk->get($file)); | ||||
|             } catch (FileNotFoundException|DecryptException $e) { | ||||
|                 Log::error('Catchable error: could not decrypt attachment #' . $attachment->id . ' because: ' . $e->getMessage()); | ||||
|  | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|         if (false === $decrypted) { | ||||
|             return false; | ||||
|         } | ||||
|         $exportFile = $this->exportFileName($attachment); | ||||
|         $this->exportDisk->put($exportFile, $decrypted); | ||||
|         $this->getEntries()->push($exportFile); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
| @@ -118,17 +133,18 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface | ||||
|      */ | ||||
|     private function exportFileName($attachment): string | ||||
|     { | ||||
|         return sprintf('%s-Attachment nr. %s - %s', $this->job->key, strval($attachment->id), $attachment->filename); | ||||
|         return sprintf('%s-Attachment nr. %s - %s', $this->job->key, (string)$attachment->id, $attachment->filename); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the attachments. | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     private function getAttachments(): Collection | ||||
|     { | ||||
|         $this->repository->setUser($this->user); | ||||
|         $attachments = $this->repository->getBetween($this->start, $this->end); | ||||
|  | ||||
|         return $attachments; | ||||
|         return $this->repository->getBetween($this->start, $this->end); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * BasicCollector.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +19,7 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Export\Collector; | ||||
| @@ -31,11 +33,11 @@ use Illuminate\Support\Collection; | ||||
|  */ | ||||
| class BasicCollector | ||||
| { | ||||
|     /** @var ExportJob */ | ||||
|     /** @var ExportJob The job to export. */ | ||||
|     protected $job; | ||||
|     /** @var User */ | ||||
|     /** @var User The user */ | ||||
|     protected $user; | ||||
|     /** @var Collection */ | ||||
|     /** @var Collection All the entries. */ | ||||
|     private $entries; | ||||
|  | ||||
|     /** | ||||
| @@ -47,6 +49,8 @@ class BasicCollector | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all entries. | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getEntries(): Collection | ||||
| @@ -55,26 +59,32 @@ class BasicCollector | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set entries. | ||||
|      * | ||||
|      * @param Collection $entries | ||||
|      */ | ||||
|     public function setEntries(Collection $entries) | ||||
|     public function setEntries(Collection $entries): void | ||||
|     { | ||||
|         $this->entries = $entries; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set export job. | ||||
|      * | ||||
|      * @param ExportJob $job | ||||
|      */ | ||||
|     public function setJob(ExportJob $job) | ||||
|     public function setJob(ExportJob $job): void | ||||
|     { | ||||
|         $this->job  = $job; | ||||
|         $this->user = $job->user; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set user. | ||||
|      * | ||||
|      * @param User $user | ||||
|      */ | ||||
|     public function setUser(User $user) | ||||
|     public function setUser(User $user): void | ||||
|     { | ||||
|         $this->user = $user; | ||||
|     } | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * CollectorInterface.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +19,7 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Export\Collector; | ||||
| @@ -31,21 +33,29 @@ use Illuminate\Support\Collection; | ||||
| interface CollectorInterface | ||||
| { | ||||
|     /** | ||||
|      * Get entries. | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getEntries(): Collection; | ||||
|  | ||||
|     /** | ||||
|      * Run the collector. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function run(): bool; | ||||
|  | ||||
|     /** | ||||
|      * Set entries. | ||||
|      * | ||||
|      * @param Collection $entries | ||||
|      */ | ||||
|     public function setEntries(Collection $entries); | ||||
|  | ||||
|     /** | ||||
|      * Set export job. | ||||
|      * | ||||
|      * @param ExportJob $job | ||||
|      * | ||||
|      * @return mixed | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <?php | ||||
| /** | ||||
|  * UploadCollector.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,13 +18,14 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Export\Collector; | ||||
|  | ||||
| use Crypt; | ||||
| use Exception; | ||||
| use Illuminate\Contracts\Encryption\DecryptException; | ||||
| use Illuminate\Contracts\Filesystem\FileNotFoundException; | ||||
| use Log; | ||||
| use Storage; | ||||
|  | ||||
| @@ -82,7 +83,10 @@ class UploadCollector extends BasicCollector implements CollectorInterface | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** @noinspection MultipleReturnStatementsInspection */ | ||||
|     /** | ||||
|      * Process new file uploads. | ||||
|      * | ||||
|      * @param string $key | ||||
|      * | ||||
|      * @return bool | ||||
| @@ -99,11 +103,11 @@ class UploadCollector extends BasicCollector implements CollectorInterface | ||||
|         $content = ''; | ||||
|         try { | ||||
|             $content = Crypt::decrypt($this->uploadDisk->get(sprintf('%s.upload', $key))); | ||||
|         } catch (FileNotFoundException | DecryptException $e) { | ||||
|         } catch (Exception | DecryptException $e) { | ||||
|             Log::error(sprintf('Could not decrypt old import file "%s". Skipped because: %s', $key, $e->getMessage())); | ||||
|         } | ||||
|  | ||||
|         if (strlen($content) > 0) { | ||||
|         if (\strlen($content) > 0) { | ||||
|             // add to export disk. | ||||
|             $date = $job->created_at->format('Y-m-d'); | ||||
|             $file = sprintf('%s-Old %s import dated %s.%s', $this->job->key, strtoupper($job->file_type), $date, $job->file_type); | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Entry.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +19,7 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Export\Entry; | ||||
| @@ -44,137 +46,65 @@ use FireflyIII\Models\Transaction; | ||||
|  */ | ||||
| final class Entry | ||||
| { | ||||
|     // @formatter:off | ||||
|     /** | ||||
|      * @var int | ||||
|      */ | ||||
|     /** @var int ID of the journal */ | ||||
|     public $journal_id; | ||||
|     /** | ||||
|      * @var int | ||||
|      */ | ||||
|     /** @var int ID of the transaction */ | ||||
|     public $transaction_id = 0; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string The date. */ | ||||
|     public $date; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string The description */ | ||||
|     public $description; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string The currency code. */ | ||||
|     public $currency_code; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string The amount. */ | ||||
|     public $amount; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string The foreign currency code */ | ||||
|     public $foreign_currency_code = ''; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Foreign amount */ | ||||
|     public $foreign_amount = '0'; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Transaction type */ | ||||
|     public $transaction_type; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Asset account ID */ | ||||
|     public $asset_account_id; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Asset account name */ | ||||
|     public $asset_account_name; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Asset account IBAN */ | ||||
|     public $asset_account_iban; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Asset account BIC */ | ||||
|     public $asset_account_bic; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Asset account number */ | ||||
|     public $asset_account_number; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Asset account currency code */ | ||||
|     public $asset_currency_code; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Opposing account ID */ | ||||
|     public $opposing_account_id; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Opposing account name */ | ||||
|     public $opposing_account_name; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Opposing account IBAN */ | ||||
|     public $opposing_account_iban; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Opposing account BIC */ | ||||
|     public $opposing_account_bic; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Opposing account number */ | ||||
|     public $opposing_account_number; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Opposing account code */ | ||||
|     public $opposing_currency_code; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Budget ID */ | ||||
|     public $budget_id; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Budget name */ | ||||
|     public $budget_name; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Category ID */ | ||||
|     public $category_id; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Category name */ | ||||
|     public $category_name; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Bill ID */ | ||||
|     public $bill_id; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Bill name */ | ||||
|     public $bill_name; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Notes */ | ||||
|     public $notes; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Tags */ | ||||
|     public $tags; | ||||
|  | ||||
|  | ||||
|     // @formatter:on | ||||
|  | ||||
|     /** | ||||
|      * Entry constructor. | ||||
|      */ | ||||
| @@ -199,31 +129,29 @@ final class Entry | ||||
|         $entry->transaction_id = $transaction->id; | ||||
|         $entry->date           = $transaction->date->format('Ymd'); | ||||
|         $entry->description    = $transaction->description; | ||||
|         if (strlen(strval($transaction->transaction_description)) > 0) { | ||||
|         if (\strlen((string)$transaction->transaction_description) > 0) { | ||||
|             $entry->description = $transaction->transaction_description . '(' . $transaction->description . ')'; | ||||
|         } | ||||
|         $entry->currency_code = $transaction->transactionCurrency->code; | ||||
|         $entry->amount        = strval(round($transaction->transaction_amount, $transaction->transactionCurrency->decimal_places)); | ||||
|         $entry->amount        = (string)round($transaction->transaction_amount, $transaction->transactionCurrency->decimal_places); | ||||
|  | ||||
|         $entry->foreign_currency_code = null === $transaction->foreign_currency_id ? null : $transaction->foreignCurrency->code; | ||||
|         $entry->foreign_amount        = null === $transaction->foreign_currency_id | ||||
|             ? null | ||||
|             : strval( | ||||
|                 round( | ||||
|                     $transaction->transaction_foreign_amount, | ||||
|                     $transaction->foreignCurrency->decimal_places | ||||
|                 ) | ||||
|             : (string)round( | ||||
|                 $transaction->transaction_foreign_amount, | ||||
|                 $transaction->foreignCurrency->decimal_places | ||||
|             ); | ||||
|  | ||||
|         $entry->transaction_type     = $transaction->transaction_type_type; | ||||
|         $entry->asset_account_id     = strval($transaction->account_id); | ||||
|         $entry->asset_account_id     = (string)$transaction->account_id; | ||||
|         $entry->asset_account_name   = app('steam')->tryDecrypt($transaction->account_name); | ||||
|         $entry->asset_account_iban   = $transaction->account_iban; | ||||
|         $entry->asset_account_number = $transaction->account_number; | ||||
|         $entry->asset_account_bic    = $transaction->account_bic; | ||||
|         $entry->asset_currency_code  = $transaction->account_currency_code; | ||||
|  | ||||
|         $entry->opposing_account_id     = strval($transaction->opposing_account_id); | ||||
|         $entry->opposing_account_id     = (string)$transaction->opposing_account_id; | ||||
|         $entry->opposing_account_name   = app('steam')->tryDecrypt($transaction->opposing_account_name); | ||||
|         $entry->opposing_account_iban   = $transaction->opposing_account_iban; | ||||
|         $entry->opposing_account_number = $transaction->opposing_account_number; | ||||
| @@ -231,7 +159,7 @@ final class Entry | ||||
|         $entry->opposing_currency_code  = $transaction->opposing_currency_code; | ||||
|  | ||||
|         // budget | ||||
|         $entry->budget_id   = strval($transaction->transaction_budget_id); | ||||
|         $entry->budget_id   = (string)$transaction->transaction_budget_id; | ||||
|         $entry->budget_name = app('steam')->tryDecrypt($transaction->transaction_budget_name); | ||||
|         if (null === $transaction->transaction_budget_id) { | ||||
|             $entry->budget_id   = $transaction->transaction_journal_budget_id; | ||||
| @@ -239,7 +167,7 @@ final class Entry | ||||
|         } | ||||
|  | ||||
|         // category | ||||
|         $entry->category_id   = strval($transaction->transaction_category_id); | ||||
|         $entry->category_id   = (string)$transaction->transaction_category_id; | ||||
|         $entry->category_name = app('steam')->tryDecrypt($transaction->transaction_category_name); | ||||
|         if (null === $transaction->transaction_category_id) { | ||||
|             $entry->category_id   = $transaction->transaction_journal_category_id; | ||||
| @@ -247,7 +175,7 @@ final class Entry | ||||
|         } | ||||
|  | ||||
|         // budget | ||||
|         $entry->bill_id   = strval($transaction->bill_id); | ||||
|         $entry->bill_id   = (string)$transaction->bill_id; | ||||
|         $entry->bill_name = app('steam')->tryDecrypt($transaction->bill_name); | ||||
|  | ||||
|         $entry->tags  = $transaction->tags; | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <?php | ||||
| /** | ||||
|  * ExpandedProcessor.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +18,9 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /** @noinspection PhpDynamicAsStaticMethodCallInspection */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Export; | ||||
| @@ -34,6 +37,7 @@ use FireflyIII\Models\AccountMeta; | ||||
| use FireflyIII\Models\ExportJob; | ||||
| use FireflyIII\Models\Note; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | ||||
| use Illuminate\Support\Collection; | ||||
| use Log; | ||||
| @@ -47,23 +51,23 @@ use ZipArchive; | ||||
|  */ | ||||
| class ExpandedProcessor implements ProcessorInterface | ||||
| { | ||||
|     /** @var Collection */ | ||||
|     /** @var Collection All accounts */ | ||||
|     public $accounts; | ||||
|     /** @var string */ | ||||
|     /** @var string The export format*/ | ||||
|     public $exportFormat; | ||||
|     /** @var bool */ | ||||
|     /** @var bool Should include attachments */ | ||||
|     public $includeAttachments; | ||||
|     /** @var bool */ | ||||
|     /** @var bool Should include old uploads */ | ||||
|     public $includeOldUploads; | ||||
|     /** @var ExportJob */ | ||||
|     /** @var ExportJob The export job itself */ | ||||
|     public $job; | ||||
|     /** @var array */ | ||||
|     /** @var array The settings*/ | ||||
|     public $settings; | ||||
|     /** @var Collection */ | ||||
|     /** @var Collection The entries to export. */ | ||||
|     private $exportEntries; | ||||
|     /** @var Collection */ | ||||
|     /** @var Collection The files to export */ | ||||
|     private $files; | ||||
|     /** @var Collection */ | ||||
|     /** @var Collection The journals. */ | ||||
|     private $journals; | ||||
|  | ||||
|     /** | ||||
| @@ -77,6 +81,8 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Collect all attachments | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function collectAttachments(): bool | ||||
| @@ -118,13 +124,13 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|         $currencies = $this->getAccountCurrencies($ibans); | ||||
|         $transactions->each( | ||||
|             function (Transaction $transaction) use ($notes, $tags, $ibans, $currencies) { | ||||
|                 $journalId                            = intval($transaction->journal_id); | ||||
|                 $accountId                            = intval($transaction->account_id); | ||||
|                 $opposingId                           = intval($transaction->opposing_account_id); | ||||
|                 $currencyId                           = $ibans[$accountId]['currency_id'] ?? 0; | ||||
|                 $opposingCurrencyId                   = $ibans[$opposingId]['currency_id'] ?? 0; | ||||
|                 $journalId                            = (int)$transaction->journal_id; | ||||
|                 $accountId                            = (int)$transaction->account_id; | ||||
|                 $opposingId                           = (int)$transaction->opposing_account_id; | ||||
|                 $currencyId                           = (int)($ibans[$accountId]['currency_id'] ?? 0.0); | ||||
|                 $opposingCurrencyId                   = (int)($ibans[$opposingId]['currency_id'] ?? 0.0); | ||||
|                 $transaction->notes                   = $notes[$journalId] ?? ''; | ||||
|                 $transaction->tags                    = join(',', $tags[$journalId] ?? []); | ||||
|                 $transaction->tags                    = implode(',', $tags[$journalId] ?? []); | ||||
|                 $transaction->account_number          = $ibans[$accountId]['accountNumber'] ?? ''; | ||||
|                 $transaction->account_bic             = $ibans[$accountId]['BIC'] ?? ''; | ||||
|                 $transaction->account_currency_code   = $currencies[$currencyId] ?? ''; | ||||
| @@ -140,6 +146,8 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get old oploads. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function collectOldUploads(): bool | ||||
| @@ -155,6 +163,8 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Convert journals to export objects. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function convertJournals(): bool | ||||
| @@ -170,6 +180,8 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Create a ZIP file. | ||||
|      * | ||||
|      * @return bool | ||||
|      * | ||||
|      * @throws FireflyException | ||||
| @@ -201,6 +213,8 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Export the journals. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function exportJournals(): bool | ||||
| @@ -216,6 +230,8 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get files. | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getFiles(): Collection | ||||
| @@ -228,7 +244,7 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|      * | ||||
|      * @param array $settings | ||||
|      */ | ||||
|     public function setSettings(array $settings) | ||||
|     public function setSettings(array $settings): void | ||||
|     { | ||||
|         // save settings | ||||
|         $this->settings           = $settings; | ||||
| @@ -240,9 +256,9 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * Delete files. | ||||
|      */ | ||||
|     private function deleteFiles() | ||||
|     private function deleteFiles():void | ||||
|     { | ||||
|         $disk = Storage::disk('export'); | ||||
|         foreach ($this->getFiles() as $file) { | ||||
| @@ -251,6 +267,8 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get currencies. | ||||
|      * | ||||
|      * @param array $array | ||||
|      * | ||||
|      * @return array | ||||
| @@ -263,7 +281,7 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|         $ids        = []; | ||||
|         $repository->setUser($this->job->user); | ||||
|         foreach ($array as $value) { | ||||
|             $ids[] = $value['currency_id'] ?? 0; | ||||
|             $ids[] = (int)($value['currency_id'] ?? 0.0); | ||||
|         } | ||||
|         $ids    = array_unique($ids); | ||||
|         $result = $repository->getByIds($ids); | ||||
| @@ -293,7 +311,7 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|                              ->get(['account_meta.id', 'account_meta.account_id', 'account_meta.name', 'account_meta.data']); | ||||
|         /** @var AccountMeta $meta */ | ||||
|         foreach ($set as $meta) { | ||||
|             $id                       = intval($meta->account_id); | ||||
|             $id                       = (int)$meta->account_id; | ||||
|             $return[$id][$meta->name] = $meta->data; | ||||
|         } | ||||
|  | ||||
| @@ -310,14 +328,14 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|     private function getNotes(array $array): array | ||||
|     { | ||||
|         $array  = array_unique($array); | ||||
|         $notes  = Note::where('notes.noteable_type', 'FireflyIII\\Models\\TransactionJournal') | ||||
|         $notes  = Note::where('notes.noteable_type', TransactionJournal::class) | ||||
|                       ->whereIn('notes.noteable_id', $array) | ||||
|                       ->get(['notes.*']); | ||||
|         $return = []; | ||||
|         /** @var Note $note */ | ||||
|         foreach ($notes as $note) { | ||||
|             if (strlen(trim(strval($note->text))) > 0) { | ||||
|                 $id          = intval($note->noteable_id); | ||||
|             if (\strlen(trim((string)$note->text)) > 0) { | ||||
|                 $id          = (int)$note->noteable_id; | ||||
|                 $return[$id] = $note->text; | ||||
|             } | ||||
|         } | ||||
| @@ -331,6 +349,7 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|      * @param array $array | ||||
|      * | ||||
|      * @return array | ||||
|      * @throws \Illuminate\Contracts\Encryption\DecryptException | ||||
|      */ | ||||
|     private function getTags(array $array): array | ||||
|     { | ||||
| @@ -342,8 +361,8 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|                     ->get(['tag_transaction_journal.transaction_journal_id', 'tags.tag']); | ||||
|         $result = []; | ||||
|         foreach ($set as $entry) { | ||||
|             $id            = intval($entry->transaction_journal_id); | ||||
|             $result[$id]   = isset($result[$id]) ? $result[$id] : []; | ||||
|             $id            = (int)$entry->transaction_journal_id; | ||||
|             $result[$id]   = $result[$id] ?? []; | ||||
|             $result[$id][] = Crypt::decrypt($entry->tag); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * BasicExporter.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +19,7 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Export\Exporter; | ||||
| @@ -30,9 +32,9 @@ use Illuminate\Support\Collection; | ||||
|  */ | ||||
| class BasicExporter | ||||
| { | ||||
|     /** @var ExportJob */ | ||||
|     /** @var ExportJob The export job */ | ||||
|     protected $job; | ||||
|     /** @var Collection */ | ||||
|     /** @var Collection The entries */ | ||||
|     private $entries; | ||||
|  | ||||
|     /** | ||||
| @@ -44,6 +46,8 @@ class BasicExporter | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all entries. | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getEntries(): Collection | ||||
| @@ -52,17 +56,21 @@ class BasicExporter | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set all entries. | ||||
|      * | ||||
|      * @param Collection $entries | ||||
|      */ | ||||
|     public function setEntries(Collection $entries) | ||||
|     public function setEntries(Collection $entries): void | ||||
|     { | ||||
|         $this->entries = $entries; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set the job. | ||||
|      * | ||||
|      * @param ExportJob $job | ||||
|      */ | ||||
|     public function setJob(ExportJob $job) | ||||
|     public function setJob(ExportJob $job): void | ||||
|     { | ||||
|         $this->job = $job; | ||||
|     } | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * CsvExporter.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +19,7 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Export\Exporter; | ||||
| @@ -31,18 +33,12 @@ use Storage; | ||||
|  */ | ||||
| class CsvExporter extends BasicExporter implements ExporterInterface | ||||
| { | ||||
|     /** @var string */ | ||||
|     /** @var string Filename */ | ||||
|     private $fileName; | ||||
|  | ||||
|     /** | ||||
|      * CsvExporter constructor. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get file name. | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getFileName(): string | ||||
| @@ -51,9 +47,10 @@ class CsvExporter extends BasicExporter implements ExporterInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Run collector. | ||||
|      * | ||||
|      * @return bool | ||||
|      * | ||||
|      * @throws \TypeError | ||||
|      */ | ||||
|     public function run(): bool | ||||
|     { | ||||
| @@ -90,6 +87,9 @@ class CsvExporter extends BasicExporter implements ExporterInterface | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Make a temp file. | ||||
|      */ | ||||
|     private function tempFile() | ||||
|     { | ||||
|         $this->fileName = $this->job->key . '-records.csv'; | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * ExporterInterface.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +19,7 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Export\Exporter; | ||||
| @@ -31,26 +33,36 @@ use Illuminate\Support\Collection; | ||||
| interface ExporterInterface | ||||
| { | ||||
|     /** | ||||
|      * Get entries. | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getEntries(): Collection; | ||||
|  | ||||
|     /** | ||||
|      * Get file name. | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getFileName(): string; | ||||
|  | ||||
|     /** | ||||
|      * Run exporter. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function run(): bool; | ||||
|  | ||||
|     /** | ||||
|      * Set entries. | ||||
|      * | ||||
|      * @param Collection $entries | ||||
|      */ | ||||
|     public function setEntries(Collection $entries); | ||||
|  | ||||
|     /** | ||||
|      * Set job. | ||||
|      * | ||||
|      * @param ExportJob $job | ||||
|      */ | ||||
|     public function setJob(ExportJob $job); | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * ProcessorInterface.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -18,6 +19,7 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Export; | ||||
| @@ -35,41 +37,57 @@ interface ProcessorInterface | ||||
|     public function __construct(); | ||||
|  | ||||
|     /** | ||||
|      * Collect all attachments. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function collectAttachments(): bool; | ||||
|  | ||||
|     /** | ||||
|      * Collect all journals. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function collectJournals(): bool; | ||||
|  | ||||
|     /** | ||||
|      * Collect old uploads. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function collectOldUploads(): bool; | ||||
|  | ||||
|     /** | ||||
|      * Convert all journals. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function convertJournals(): bool; | ||||
|  | ||||
|     /** | ||||
|      * Create a zip file. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function createZipFile(): bool; | ||||
|  | ||||
|     /** | ||||
|      * Export journals. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function exportJournals(): bool; | ||||
|  | ||||
|     /** | ||||
|      * Get all files. | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getFiles(): Collection; | ||||
|  | ||||
|     /** | ||||
|      * Set the settings. | ||||
|      * | ||||
|      * @param array $settings | ||||
|      */ | ||||
|     public function setSettings(array $settings); | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user