mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 02:36:28 +00:00 
			
		
		
		
	Compare commits
	
		
			2241 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 8b9607f9b5 | ||
|  | af107ad5e8 | ||
|  | 8926d62165 | ||
|  | 45344ee347 | ||
|  | b7dab817f2 | ||
|  | 2c966a1234 | ||
|  | 143ea69c0d | ||
|  | 8a02ead013 | ||
|  | 930d5ab941 | ||
|  | e54a56d3a8 | ||
|  | f5216c0d85 | ||
|  | ebc77540b9 | ||
|  | 28d2583c10 | ||
|  | b0988a7b00 | ||
|  | 2c4920db2d | ||
|  | 8321663815 | ||
|  | ac0280d460 | ||
|  | ba6f4268f0 | ||
|  | 0bd18f94ac | ||
|  | 66fb63661f | ||
|  | d9b16beb0a | ||
|  | 6a01a9bdfd | ||
|  | b81b34a706 | ||
|  | 3750a00b5f | ||
|  | 05ddcc169d | ||
|  | f571a5f1bd | ||
|  | 48b786adea | ||
|  | d691fa9b4d | ||
|  | da50f9e419 | ||
|  | 103de5e18a | ||
|  | dac6efd98b | ||
|  | 46aa7f81b2 | ||
|  | 0683c7cd67 | ||
|  | 50d7aa7b6a | ||
|  | b781215d0a | ||
|  | 866bc2f3bd | ||
|  | 49d4705014 | ||
|  | 9163fcfccb | ||
|  | 7e10641461 | ||
|  | cdc0e3cfd8 | ||
|  | 466e81d56a | ||
|  | 5953f691d1 | ||
|  | e2790ca6c1 | ||
|  | 66dbd48b76 | ||
|  | 73cfbbd2ba | ||
|  | 38bc38bf26 | ||
|  | e12d13c838 | ||
|  | fcc3af6136 | ||
|  | 491298e1cb | ||
|  | 72b5895217 | ||
|  | 0a8f4017bd | ||
|  | cb985f5897 | ||
|  | 968ec0853f | ||
|  | 0bde72d3df | ||
|  | 45293fbd42 | ||
|  | 72997065f0 | ||
|  | a838dc163d | ||
|  | 3d15a4ca6d | ||
|  | 51c7d4fb1b | ||
|  | fa586dba7e | ||
|  | 8ad40389f2 | ||
|  | b3333cc2d3 | ||
|  | 3699a7ba9a | ||
|  | 204e521ba4 | ||
|  | c9bab3e5c3 | ||
|  | 3d00e20238 | ||
|  | c3958ed3c4 | ||
|  | e5b88be5fa | ||
|  | 425552988a | ||
|  | a81dd8abe5 | ||
|  | bac8154a5b | ||
|  | 737d15fa0e | ||
|  | 5f2317af7f | ||
|  | 2bd1f783e5 | ||
|  | d6c0c9f963 | ||
|  | 21b6ad7a41 | ||
|  | a65d609fdc | ||
|  | 04e676b936 | ||
|  | be8eaaffdf | ||
|  | 28c753523f | ||
|  | 7fbd0b2ffc | ||
|  | 7ffb48a87a | ||
|  | d485270e1f | ||
|  | 5fd688b266 | ||
|  | 3716668e0c | ||
|  | ae7fd18c34 | ||
|  | 4f59b1d32f | ||
|  | 90cb3279df | ||
|  | cf0c7ef6b2 | ||
|  | 47c23781d9 | ||
|  | e258c050f7 | ||
|  | 57801b2f34 | ||
|  | 710e9c9423 | ||
|  | deefef83bd | ||
|  | 51e30aed66 | ||
|  | 8d109a3cfe | ||
|  | 3424e019b5 | ||
|  | c6b4bceb67 | ||
|  | afb4155015 | ||
|  | 8d99baf38a | ||
|  | b91cb60328 | ||
|  | c0d62237fc | ||
|  | 223ea80860 | ||
|  | 5a77bef494 | ||
|  | 80c0efe821 | ||
|  | 8044d89557 | ||
|  | 4f0ed97410 | ||
|  | af7952f204 | ||
|  | d8dcae856b | ||
|  | 7296796ed9 | ||
|  | a2c2bb4948 | ||
|  | 72ebfdc20e | ||
|  | 16b95ea78a | ||
|  | c04f08dfd8 | ||
|  | a30793e818 | ||
|  | e39e1eaf21 | ||
|  | ab22d2cbaa | ||
|  | 96ddbe7227 | ||
|  | 4d09235aef | ||
|  | 136b8975e3 | ||
|  | e21b1eca17 | ||
|  | 244b90b1d4 | ||
|  | b318f3f940 | ||
|  | e211c9812e | ||
|  | eef28d96f4 | ||
|  | c8227e09ee | ||
|  | 3e05fd91d9 | ||
|  | 450baba56a | ||
|  | 17a8c4918c | ||
|  | 0e2419d61a | ||
|  | 79b1a2ca6d | ||
|  | 2213c68155 | ||
|  | 2492b1fa96 | ||
|  | 6c6598dac5 | ||
|  | a137112e66 | ||
|  | 8642ae8180 | ||
|  | 894c4dc5a7 | ||
|  | d96063ea6e | ||
|  | c3dc193f3e | ||
|  | 3c2952009e | ||
|  | f4ade470df | ||
|  | 2e33b43389 | ||
|  | 92799699bc | ||
|  | 7ab0508167 | ||
|  | 3c65c28936 | ||
|  | 43892da07e | ||
|  | 7c436920a4 | ||
|  | 89d565e63b | ||
|  | 150b6fe5b6 | ||
|  | 0e77574c26 | ||
|  | df23863443 | ||
|  | 581bf11b21 | ||
|  | d602d4b429 | ||
|  | d1d4a52934 | ||
|  | 375d113769 | ||
|  | 9b83974bff | ||
|  | 3c68c99bd5 | ||
|  | ec4b37c596 | ||
|  | ba9601d21c | ||
|  | 50c13fd469 | ||
|  | 7af072b8fc | ||
|  | faa128d41e | ||
|  | 868fe46932 | ||
|  | e9e4307ce5 | ||
|  | 774d4844a9 | ||
|  | 586c53e670 | ||
|  | 68e073fbff | ||
|  | 8101dc37b1 | ||
|  | 63f16c458d | ||
|  | 821e007e95 | ||
|  | 1656a2f11a | ||
|  | 4dbc135dce | ||
|  | fc886f6bc1 | ||
|  | f93e480466 | ||
|  | fe807e23f8 | ||
|  | ecf61c31f1 | ||
|  | 4feff18af5 | ||
|  | a07c52e0d8 | ||
|  | 7bb07d7f55 | ||
|  | f12dfc8a14 | ||
|  | be030f15c4 | ||
|  | f5fb6c063b | ||
|  | fb722f06b9 | ||
|  | c0ea19e15e | ||
|  | cdeb1ad87c | ||
|  | 0dbe4e94fa | ||
|  | b5e2e8aa1d | ||
|  | 9502010248 | ||
|  | fea0557b47 | ||
|  | ed4fcc9011 | ||
|  | ed12ea7cfb | ||
|  | 73e526645e | ||
|  | 72aeafb2b5 | ||
|  | cc1af60cb4 | ||
|  | 359fab315f | ||
|  | 6a9574bab9 | ||
|  | 83d6158483 | ||
|  | 63ef89b6cc | ||
|  | b0beab4cd3 | ||
|  | a34782575f | ||
|  | 142bdc9430 | ||
|  | 14b79cb0a4 | ||
|  | ce5beeaf2c | ||
|  | 31114a2ca5 | ||
|  | 32528094ad | ||
|  | 0a2a01c44c | ||
|  | c1888dc3ac | ||
|  | 4d76afbe01 | ||
|  | 76d7a97f93 | ||
|  | 8b1366b20a | ||
|  | e0f9685578 | ||
|  | 5235657954 | ||
|  | a15fbc8094 | ||
|  | 546f1d9c50 | ||
|  | 74231f552a | ||
|  | b250a10e3c | ||
|  | a9f1b31dd6 | ||
|  | 7fe393acaf | ||
|  | 04faba4db5 | ||
|  | 91bba40c20 | ||
|  | 79e39f7de8 | ||
|  | 9c09353559 | ||
|  | 50752a5bfe | ||
|  | d59879db7d | ||
|  | aab125da27 | ||
|  | 74fc731f96 | ||
|  | bd0050fec2 | ||
|  | aa5e313b92 | ||
|  | e89d613b7e | ||
|  | 8757929ead | ||
|  | e0a9b19802 | ||
|  | 308da6dc6e | ||
|  | b6960fb0e5 | ||
|  | 137208c3fd | ||
|  | d7a9a62a1d | ||
|  | 075315bdaa | ||
|  | 3948fcd614 | ||
|  | 8e61e129ab | ||
|  | 20cffd0502 | ||
|  | 5df09dab09 | ||
|  | 7446b911e5 | ||
|  | f15267c1ab | ||
|  | 9c9fc2b5dc | ||
|  | 28f601b54b | ||
|  | 18b8a05014 | ||
|  | 910c995ed8 | ||
|  | 498468aa2c | ||
|  | 637aebcb34 | ||
|  | 9afd5cb277 | ||
|  | bc525e7272 | ||
|  | a80180780d | ||
|  | 0d73086c37 | ||
|  | 02ae39238d | ||
|  | 43d6b51d42 | ||
|  | 84566310de | ||
|  | 6a6ec9fbe4 | ||
|  | 84a7f825d7 | ||
|  | 0372c1aaf1 | ||
|  | c9fff197f7 | ||
|  | 6900392e43 | ||
|  | c00bcd78cc | ||
|  | b2b82124e6 | ||
|  | 3de57c668f | ||
|  | 43669648ce | ||
|  | 3b73b416d5 | ||
|  | 5153591c8f | ||
|  | 3172bc90da | ||
|  | 76a1b2cd51 | ||
|  | bdf7eee72f | ||
|  | 2d4b148b2c | ||
|  | d67db74ca2 | ||
|  | 516725456f | ||
|  | 001d72a484 | ||
|  | c555e28988 | ||
|  | af13d1943f | ||
|  | 52df2edc8f | ||
|  | cd08484a13 | ||
|  | f38d38f139 | ||
|  | 93b6c68938 | ||
|  | a4cc25175a | ||
|  | 3fb14b4708 | ||
|  | 6bdb6db330 | ||
|  | d05c165ace | ||
|  | ab53cdb896 | ||
|  | c1f142af78 | ||
|  | 6e261abb73 | ||
|  | 39af9e4414 | ||
|  | 5b50abb2c7 | ||
|  | 13bda0a264 | ||
|  | 1658c666ab | ||
|  | 170aebfe54 | ||
|  | c4ef379d0e | ||
|  | 18b038d8ff | ||
|  | 12ee5da872 | ||
|  | 601f9f86bb | ||
|  | d7329a5915 | ||
|  | 9e7b730002 | ||
|  | 2d59d845bc | ||
|  | c2645894e0 | ||
|  | 3751106317 | ||
|  | 60bb639351 | ||
|  | 74c50930bd | ||
|  | 9105104303 | ||
|  | 540dde135e | ||
|  | f8936210cf | ||
|  | 1dc6d8de40 | ||
|  | 1069db3c13 | ||
|  | 65122f0144 | ||
|  | d2c018f7da | ||
|  | 46493c2af6 | ||
|  | c303e03f76 | ||
|  | d8b65f62e7 | ||
|  | 854368a8f3 | ||
|  | 7653a34aea | ||
|  | ee50b58e00 | ||
|  | 1eb60ab100 | ||
|  | 4a20eef351 | ||
|  | 26c9b2c353 | ||
|  | 16374bce9b | ||
|  | 86011d4ea2 | ||
|  | fcb8b02da9 | ||
|  | 571165c2bb | ||
|  | c842113610 | ||
|  | 974a8b3b70 | ||
|  | 2e20c99ada | ||
|  | aa88ff6f2c | ||
|  | 5e6aa63d03 | ||
|  | ad6700c114 | ||
|  | f08c6efb00 | ||
|  | cc807ec132 | ||
|  | 24e7c68243 | ||
|  | ab25edd37a | ||
|  | be47fde6c2 | ||
|  | 1ffa8c5e72 | ||
|  | d855ccb8a7 | ||
|  | d88919474b | ||
|  | e139664301 | ||
|  | 5adf5f6e3f | ||
|  | aef2075c8e | ||
|  | 922b2962a3 | ||
|  | b4a401700e | ||
|  | e9601bb9c1 | ||
|  | 58af3dc6ea | ||
|  | 074295df61 | ||
|  | ec349b31c7 | ||
|  | 5ae236e016 | ||
|  | d7c5897aba | ||
|  | 5252e7efe7 | ||
|  | fc7d65629a | ||
|  | f28fdf8252 | ||
|  | 5d07c4a949 | ||
|  | fdd9eaab4b | ||
|  | e0d863a46f | ||
|  | 3aacb6f5f3 | ||
|  | 428e331b3e | ||
|  | 847e05e9a7 | ||
|  | 087eb5dbe6 | ||
|  | f15932b2ac | ||
|  | d3a4c3795d | ||
|  | b15d55e1d9 | ||
|  | 4f5889cc5b | ||
|  | bf2a104a4e | ||
|  | 0c6dd5cd16 | ||
|  | 5efb06a7aa | ||
|  | b13acef272 | ||
|  | cfa67d6c0f | ||
|  | e70444f19a | ||
|  | 0258982e60 | ||
|  | 70eed5cb5e | ||
|  | a650fa51f7 | ||
|  | cb205580d8 | ||
|  | f9329aac00 | ||
|  | 745f4a7523 | ||
|  | 60254dafd7 | ||
|  | a8d60388ba | ||
|  | 83ec60254c | ||
|  | c15c45f765 | ||
|  | cbe52b5089 | ||
|  | e4e2921f3e | ||
|  | 4673170531 | ||
|  | 2c2ed26c38 | ||
|  | 94be5244fe | ||
|  | f137a08493 | ||
|  | 48624d0a34 | ||
|  | 4cceb3ddaa | ||
|  | f728395603 | ||
|  | 3e82d43807 | ||
|  | 2194c4e0a9 | ||
|  | c581080f3f | ||
|  | f6b1ec27e5 | ||
|  | 368b183230 | ||
|  | 9028ad36ad | ||
|  | 6cc041cd39 | ||
|  | 63ff01e78d | ||
|  | 9e5484937e | ||
|  | b8ed489b14 | ||
|  | 765152d04b | ||
|  | 14934367d8 | ||
|  | 04164500c8 | ||
|  | 5160f2c298 | ||
|  | 124c9303b9 | ||
|  | cd27f0ad69 | ||
|  | a7555bcce3 | ||
|  | 6b5c4fd3f4 | ||
|  | cc55e2acee | ||
|  | 1511f75a80 | ||
|  | f01bbefc1f | ||
|  | 1d1eb5ffa8 | ||
|  | a465cb2191 | ||
|  | 42d13e02ef | ||
|  | d00786c43f | ||
|  | 4b47f99829 | ||
|  | 35aaf40003 | ||
|  | cc5b4a1e02 | ||
|  | 7079521e8c | ||
|  | b5025560a5 | ||
|  | 3f4bdd7f0e | ||
|  | e94bb9b549 | ||
|  | 1ddaacbef5 | ||
|  | e8b40518e0 | ||
|  | 0f88cbb41b | ||
|  | 780d137b76 | ||
|  | ad8a9717d1 | ||
|  | 9d6ea6b2f6 | ||
|  | 7559383089 | ||
|  | f84381c927 | ||
|  | cb0122a43f | ||
|  | 6776b20989 | ||
|  | e98d556022 | ||
|  | 5bf18b69d7 | ||
|  | ea17f045a7 | ||
|  | 526f565ea7 | ||
|  | 4aff9d6e73 | ||
|  | bf516d4d21 | ||
|  | ae92e409d9 | ||
|  | 4d017dc8a9 | ||
|  | 707f4e2965 | ||
|  | 1c3bffdc50 | ||
|  | e54ddcb8b0 | ||
|  | ddefb0debc | ||
|  | 92d8dde90d | ||
|  | 1bb0508ddf | ||
|  | a280a326b9 | ||
|  | 683e9b7c2c | ||
|  | a44e5da421 | ||
|  | 8cd2c90ad7 | ||
|  | 5e57a390a2 | ||
|  | 620848272e | ||
|  | 1e86794416 | ||
|  | e36717259b | ||
|  | 75b9238b90 | ||
|  | ce5b20027e | ||
|  | 0de1242c83 | ||
|  | 8bd445ab19 | ||
|  | fdef0de163 | ||
|  | b1b03a4325 | ||
|  | 0587d96474 | ||
|  | c2241567e4 | ||
|  | 7ac24ba418 | ||
|  | c933ffec66 | ||
|  | e587d934b1 | ||
|  | f354e90656 | ||
|  | 1b0bc7ec6e | ||
|  | ee1acb9c00 | ||
|  | 06862a2812 | ||
|  | 5fa87e18db | ||
|  | 77989e2720 | ||
|  | 3a1102fa4e | ||
|  | 8a9974ce53 | ||
|  | 4be8f1ca03 | ||
|  | 1ec2970ee3 | ||
|  | 81b3a22606 | ||
|  | f81a475cc9 | ||
|  | d7ee03d4f9 | ||
|  | c1c06410c2 | ||
|  | 657d16bb60 | ||
|  | e65a4c1010 | ||
|  | e23d3f5661 | ||
|  | e13611f7af | ||
|  | 596cd09489 | ||
|  | 0be5b27d34 | ||
|  | a27471ae55 | ||
|  | e27e3622a8 | ||
|  | e95273b72b | ||
|  | 583d4f3249 | ||
|  | d6967c4516 | ||
|  | 40b3097374 | ||
|  | 1a1f127993 | ||
|  | a0f34a7ce1 | ||
|  | db020db34b | ||
|  | 681167bc1b | ||
|  | 40e49ffc37 | ||
|  | 834b1afb38 | ||
|  | 62d5a1da87 | ||
|  | 8d8308e557 | ||
|  | e1aa63487a | ||
|  | b7fbe110d4 | ||
|  | 58859eb35a | ||
|  | 4b7e1ae1c6 | ||
|  | 3a06a6ac07 | ||
|  | db0f269dc8 | ||
|  | 3cabe6ca5a | ||
|  | d483005219 | ||
|  | fea9bc4e7e | ||
|  | d579992c98 | ||
|  | ad1c61d959 | ||
|  | bb1da31830 | ||
|  | a50949e554 | ||
|  | 14dce8a10b | ||
|  | 1240c8f685 | ||
|  | cc7c2e952c | ||
|  | 409ec2e086 | ||
|  | a7f6848e53 | ||
|  | 4b0b79199d | ||
|  | d1d6c48d9b | ||
|  | 21631780bb | ||
|  | b935e32340 | ||
|  | 72dd064932 | ||
|  | 2e75446665 | ||
|  | be17e4481e | ||
|  | 616c849b1f | ||
|  | 71947c097f | ||
|  | 546787802d | ||
|  | 294d0e388a | ||
|  | 193a1b0325 | ||
|  | 12743217a2 | ||
|  | b252b9da66 | ||
|  | cdef9c3c7e | ||
|  | 71dcebb744 | ||
|  | 25f248c60a | ||
|  | d5cbc17831 | ||
|  | 7a10217511 | ||
|  | 7559efab77 | ||
|  | 8254efbd03 | ||
|  | 4ae24225a5 | ||
|  | 67d9154563 | ||
|  | ad0319c188 | ||
|  | eb650ea3ec | ||
|  | 7eba33e805 | ||
|  | e1cb9d387e | ||
|  | 2ace7c3ca0 | ||
|  | 58014f0592 | ||
|  | 1d4938bb09 | ||
|  | bbf4007c3e | ||
|  | 4d5124fb4c | ||
|  | 14a7cd05b1 | ||
|  | 946be80eef | ||
|  | 9ad8b1a980 | ||
|  | f733216fcb | ||
|  | ffc6139e21 | ||
|  | 571cac6644 | ||
|  | 2738ac5a5c | ||
|  | 7dfde51b84 | ||
|  | 2d2f18e538 | ||
|  | 3af0dd2e3b | ||
|  | 349e077802 | ||
|  | 812aae358f | ||
|  | c3c59d0627 | ||
|  | 89518b412d | ||
|  | f43b026162 | ||
|  | b806c70f52 | ||
|  | 10bff3c0b8 | ||
|  | 65c12fd0b2 | ||
|  | 50f71c4130 | ||
|  | 8e401a53dc | ||
|  | 64a289a47c | ||
|  | 8f2c37061b | ||
|  | 39f2de6b90 | ||
|  | 855ba8d4f3 | ||
|  | 74f098e718 | ||
|  | 56c8a84691 | ||
|  | 8bbf319032 | ||
|  | afbca4ae65 | ||
|  | 0ef6d2f91a | ||
|  | fbe4435599 | ||
|  | 34be565dd1 | ||
|  | af838e4ed1 | ||
|  | 60fe8ce011 | ||
|  | 8ece341467 | ||
|  | dfa6bdbcb8 | ||
|  | fb2481ebaa | ||
|  | 4874c116cf | ||
|  | e19c44efbd | ||
|  | 4b687b9bdc | ||
|  | 6af79ef601 | ||
|  | 352b996ad2 | ||
|  | 4a93bb35f8 | ||
|  | 8e1f493daf | ||
|  | 59ee153375 | ||
|  | 60f7f1fc16 | ||
|  | b7433683d8 | ||
|  | 42799b9273 | ||
|  | 860a0f790e | ||
|  | 8daccbfbb4 | ||
|  | 285b77dcb7 | ||
|  | 6e48827d3f | ||
|  | f0c20cc706 | ||
|  | 8916c0a3de | ||
|  | 7193a77840 | ||
|  | 61930b5b51 | ||
|  | 11a494cacf | ||
|  | 17f9bf0339 | ||
|  | 3d9755ca8c | ||
|  | b5cf2d03e6 | ||
|  | e3b35b8f35 | ||
|  | 1c1fe672bd | ||
|  | 6c71f68ed8 | ||
|  | 8f2f912cdf | ||
|  | bf6ea16acb | ||
|  | 288546c2b9 | ||
|  | 724db6c34c | ||
|  | 067c451c1d | ||
|  | 11e3696191 | ||
|  | 41e20664de | ||
|  | d8de90d6f3 | ||
|  | b01e8299d3 | ||
|  | 1ec11e3e2e | ||
|  | 422f429725 | ||
|  | 5c55fa5fbb | ||
|  | 80d845fdf2 | ||
|  | 601fe68346 | ||
|  | 9e050fb059 | ||
|  | 99d4adf5e6 | ||
|  | 85f8d1e8e9 | ||
|  | 8334d3d99f | ||
|  | cff08d19eb | ||
|  | 2d86390bc1 | ||
|  | 7a20835571 | ||
|  | ff3c9676b5 | ||
|  | 055f97dab1 | ||
|  | 8a867e71a1 | ||
|  | b8275b4734 | ||
|  | 36b951b146 | ||
|  | c5a5f17643 | ||
|  | 16b909c4df | ||
|  | 92b7648e03 | ||
|  | ca46ebe3b2 | ||
|  | 676e48254a | ||
|  | b15b55227d | ||
|  | 3c3b723913 | ||
|  | f05002c729 | ||
|  | 1c2cbd5b40 | ||
|  | 54c6ca9f45 | ||
|  | c10efbb170 | ||
|  | a496ad5814 | ||
|  | 50cf7f6a3b | ||
|  | f946f10afd | ||
|  | eecb4db34c | ||
|  | 1f865d3ea4 | ||
|  | 623bb4b350 | ||
|  | dc8ad673a6 | ||
|  | 4914ad821e | ||
|  | f099cbadc3 | ||
|  | 42cda384c8 | ||
|  | 23c91b9990 | ||
|  | ff0379182e | ||
|  | e08a23948f | ||
|  | bd56de6d36 | ||
|  | 42970aea80 | ||
|  | 003a05ee8d | ||
|  | ffb11b01a6 | ||
|  | e426f5d5da | ||
|  | 6989f61e1b | ||
|  | 0e6677ccb3 | ||
|  | 8f104d555a | ||
|  | b1d3158db1 | ||
|  | 7645005d5a | ||
|  | 411f77fd29 | ||
|  | 568ab26db1 | ||
|  | 29652108f0 | ||
|  | f07e4dc711 | ||
|  | 8a2ac457c2 | ||
|  | 9e54eecfaa | ||
|  | 95ef691077 | ||
|  | 7a0ad5a587 | ||
|  | 42b49d0e4b | ||
|  | 9217c2f003 | ||
|  | fbdf66998d | ||
|  | deda9d3c54 | ||
|  | a5d78f20ae | ||
|  | 5ed09e3f38 | ||
|  | 3e9774cd66 | ||
|  | 54387c8fdf | ||
|  | 7eec949a13 | ||
|  | 4113c4ff40 | ||
|  | 1bf0968bfe | ||
|  | 374b90fb00 | ||
|  | 064e60e9d5 | ||
|  | b637455970 | ||
|  | 68158937d1 | ||
|  | adb1356b7a | ||
|  | d880ccb8e0 | ||
|  | 050fb1d1ef | ||
|  | 6580752bde | ||
|  | c9df265c9b | ||
|  | 098e5bc162 | ||
|  | 4b2dcc74d4 | ||
|  | a9254c5c9a | ||
|  | 7ce57e6ccb | ||
|  | 0fcb32a66f | ||
|  | 9946535f01 | ||
|  | 2b17396d6b | ||
|  | b01d5bc237 | ||
|  | b123860304 | ||
|  | 033f5b67db | ||
|  | 6280448dfb | ||
|  | 01cd3333e4 | ||
|  | 63050907b9 | ||
|  | beedf7d780 | ||
|  | 6b8194261f | ||
|  | dbb1c4d534 | ||
|  | e6263f9ff5 | ||
|  | 6ca119c4db | ||
|  | c483a1ab3a | ||
|  | 2e7edd033c | ||
|  | c576902501 | ||
|  | 66c2951594 | ||
|  | b812881cdb | ||
|  | cdeac2c6db | ||
|  | bca2ddd529 | ||
|  | e7285c6499 | ||
|  | bdff275672 | ||
|  | bec58a1ee6 | ||
|  | f64616748c | ||
|  | 512ce15973 | ||
|  | ed8b301574 | ||
|  | d22a6c019c | ||
|  | a0cb1b9d9e | ||
|  | a5294c62ea | ||
|  | e155d3311c | ||
|  | 0a372b0daf | ||
|  | 69143399d1 | ||
|  | 3270d3bf96 | ||
|  | 3896a66122 | ||
|  | b94781aef1 | ||
|  | bed1adc367 | ||
|  | ae54497efa | ||
|  | 06b747c221 | ||
|  | f159beee0d | ||
|  | 49d7dea086 | ||
|  | 3e65733dc5 | ||
|  | cc375d58bb | ||
|  | 911c7c662a | ||
|  | aae003be33 | ||
|  | aede03d8b2 | ||
|  | f0f5ada7de | ||
|  | 58365121a3 | ||
|  | d5a154d2e6 | ||
|  | b20f369aef | ||
|  | abb8aa0b29 | ||
|  | 5368a0f1d7 | ||
|  | d3897eece7 | ||
|  | a82b829da9 | ||
|  | 9f5058e81a | ||
|  | 5b19263720 | ||
|  | 9d5a0db0d9 | ||
|  | 4bd8a7014f | ||
|  | 353e96d951 | ||
|  | 149a6f92b0 | ||
|  | d66426c137 | ||
|  | 4fc9966392 | ||
|  | 417766f0db | ||
|  | de9ac97887 | ||
|  | 6be42f112a | ||
|  | 3895ae63c7 | ||
|  | 607d416d54 | ||
|  | 038693dc86 | ||
|  | cc9be13544 | ||
|  | 9c1474087f | ||
|  | 831de2bcf4 | ||
|  | eb687333bb | ||
|  | 5cc7966d54 | ||
|  | d1a34e7a6f | ||
|  | d63d791717 | ||
|  | 015570c741 | ||
|  | 8400ebc9c6 | ||
|  | 9f99e7c0af | ||
|  | 392c1fc399 | ||
|  | d3cea7a89c | ||
|  | 1dcf7407e6 | ||
|  | d543c033a3 | ||
|  | aaa186be5e | ||
|  | 2054b5b3dd | ||
|  | 98ae5b0ca0 | ||
|  | 36c8171d0f | ||
|  | 3603eb94cc | ||
|  | 0e068d4ccf | ||
|  | 199f348ff4 | ||
|  | b22655fb7c | ||
|  | 06cc9618ba | ||
|  | b9019c8c7f | ||
|  | 77e133e67c | ||
|  | 571e7df807 | ||
|  | 22f4d2979a | ||
|  | e46e366694 | ||
|  | 7b4bc23815 | ||
|  | 9ca79f767c | ||
|  | 274dba7408 | ||
|  | 31708ca29e | ||
|  | 671b025588 | ||
|  | a7956e4856 | ||
|  | 355862025a | ||
|  | a2a39ee0f8 | ||
|  | ec8e39c16f | ||
|  | 88f714999e | ||
|  | c0c2aa3be0 | ||
|  | 822044820e | ||
|  | 6ffc182142 | ||
|  | 3d54a78573 | ||
|  | 8ddf7d953a | ||
|  | 8b9e9ad103 | ||
|  | 5737224c40 | ||
|  | ec9aacbcae | ||
|  | 9395454997 | ||
|  | 66198a8d98 | ||
|  | 96ed9a4256 | ||
|  | 10e54b2263 | ||
|  | cf00922ad2 | ||
|  | 84e8e007a5 | ||
|  | d07b2e773b | ||
|  | 506ef7b0b9 | ||
|  | 2cd5dae8e2 | ||
|  | a1cd49c111 | ||
|  | aca2973aef | ||
|  | 0a7a691c95 | ||
|  | 72906a7afd | ||
|  | d1a4a83570 | ||
|  | e0396b29e8 | ||
|  | 536833cfe0 | ||
|  | 317b02d1b9 | ||
|  | 75e279ea0d | ||
|  | dc2ad21f4c | ||
|  | 484d49aae1 | ||
|  | ca39438ad4 | ||
|  | 49a65ebff4 | ||
|  | befdc05084 | ||
|  | 1fbffe761b | ||
|  | 36aad379ff | ||
|  | 540cfa072e | ||
|  | 3b049c15cc | ||
|  | 3e93ed0a17 | ||
|  | d7d9358136 | ||
|  | 5cf0939ff9 | ||
|  | 8dc6f91d3c | ||
|  | a3a25db230 | ||
|  | c06f18c815 | ||
|  | 6802f04036 | ||
|  | beeccdf345 | ||
|  | 58241ed39d | ||
|  | 31128020f0 | ||
|  | 6c48afc37b | ||
|  | 7a2f169dfc | ||
|  | ed910b99a7 | ||
|  | 54195c0826 | ||
|  | cefbbcd1df | ||
|  | cc01592085 | ||
|  | 5a98a5252d | ||
|  | 184e8b1132 | ||
|  | 2b6b896c2e | ||
|  | 96d06b7a93 | ||
|  | f54f1611b5 | ||
|  | 69ad757e8b | ||
|  | e0beb796ad | ||
|  | f331e7d820 | ||
|  | cbb62d3d78 | ||
|  | c85bc59c1d | ||
|  | 8081eeb007 | ||
|  | 56f91bd10d | ||
|  | 8e20b78731 | ||
|  | 23a09b7081 | ||
|  | 67fdd27499 | ||
|  | e1941daedd | ||
|  | f28bc568a4 | ||
|  | f24cfe39aa | ||
|  | 59d2bf3f79 | ||
|  | 3176e54614 | ||
|  | eb090f7265 | ||
|  | 6d3a9bfd18 | ||
|  | 76f08b7acb | ||
|  | 1ff99346aa | ||
|  | 369695ab32 | ||
|  | 7e23dd1d66 | ||
|  | 0205d3fc5c | ||
|  | 4660cf2ad5 | ||
|  | e26d08d674 | ||
|  | 0932bf2797 | ||
|  | f560fc6d76 | ||
|  | aa6209af00 | ||
|  | 4a51176193 | ||
|  | bb84f7a434 | ||
|  | 48168b1ef0 | ||
|  | 8281c7c83e | ||
|  | a07c1e3c71 | ||
|  | 0766bb31fe | ||
|  | ff4472c1a5 | ||
|  | 17424740e5 | ||
|  | dad0b2fcd3 | ||
|  | c48dbf030f | ||
|  | 617808d603 | ||
|  | 845149deee | ||
|  | 1a9e009327 | ||
|  | ae90815708 | ||
|  | 1c460343b7 | ||
|  | 26079622f9 | ||
|  | 06c6d6096f | ||
|  | c8183aea51 | ||
|  | 7531134ad2 | ||
|  | cd0c6439c2 | ||
|  | c918c93f51 | ||
|  | 97d3bd68ed | ||
|  | 75f1e034ae | ||
|  | 8e72f218f1 | ||
|  | d643e05c5a | ||
|  | fea44834d0 | ||
|  | 195a2d7523 | ||
|  | b2fd346ef8 | ||
|  | 1ff8b62cb7 | ||
|  | c7ae15a41a | ||
|  | efe6f59f79 | ||
|  | 8e31d0491d | ||
|  | 73d4a10351 | ||
|  | 81d9d4dbc7 | ||
|  | 184ec13f99 | ||
|  | dee0422eff | ||
|  | 81a2975f1a | ||
|  | 5cd2ef4a5e | ||
|  | 466c2a68c2 | ||
|  | 0fb9fba531 | ||
|  | 356dd2c6cd | ||
|  | 32c4661233 | ||
|  | a245b504ec | ||
|  | a2f5fbdfd3 | ||
|  | 04be26adc5 | ||
|  | be0adb7cf2 | ||
|  | 84fd92bf5a | ||
|  | ee4e061739 | ||
|  | 4a2b01cd9a | ||
|  | efdd6460fb | ||
|  | 803827e05c | ||
|  | a41d5e9ab3 | ||
|  | e94333f877 | ||
|  | 6dbb80d687 | ||
|  | 31a1031624 | ||
|  | f8e9ce0d52 | ||
|  | 11baa968cd | ||
|  | 3e5e5b376f | ||
|  | bda18f296d | ||
|  | 287d110c84 | ||
|  | c98275e73a | ||
|  | aa573cc951 | ||
|  | 883d3d86e3 | ||
|  | fb047bd5f4 | ||
|  | 66a04d8365 | ||
|  | a0e501f9fd | ||
|  | 8b40d3346d | ||
|  | eddf5cd250 | ||
|  | ee5c534ca3 | ||
|  | fd4e77ae0f | ||
|  | b747c50aa3 | ||
|  | deebdd86a6 | ||
|  | b2db79cc10 | ||
|  | bbab370b1e | ||
|  | db4adf399d | ||
|  | 0683c87e52 | ||
|  | 3f62b647fc | ||
|  | 2562a5b30d | ||
|  | e232f2e223 | ||
|  | 21644ff4dd | ||
|  | be96a4fce5 | ||
|  | a1cabcbed3 | ||
|  | ce933b1f06 | ||
|  | 51ae130922 | ||
|  | da1bc18a47 | ||
|  | e7165a526b | ||
|  | 6081cc399f | ||
|  | 7c5c24e15d | ||
|  | e3e55b4347 | ||
|  | 40d8e7d1ad | ||
|  | 59e23b89f2 | ||
|  | cc33af8193 | ||
|  | 0e1e7eb2a9 | ||
|  | 52a28a7758 | ||
|  | 3f752d6832 | ||
|  | fe714e9989 | ||
|  | 0d3213a379 | ||
|  | 44056629e8 | ||
|  | 54125c05d3 | ||
|  | 7d32e50f25 | ||
|  | 4af9ff49a0 | ||
|  | 23faef845c | ||
|  | 41dad4091a | ||
|  | daf859b977 | ||
|  | f47ba6c977 | ||
|  | 4b9b207d92 | ||
|  | 875cbf66af | ||
|  | 412d6d4fd7 | ||
|  | 91c6deeb1f | ||
|  | 6d1978fd9a | ||
|  | 52d23b6ef5 | ||
|  | 0656ccbdd9 | ||
|  | e774ebd0a3 | ||
|  | edbda32a84 | ||
|  | 721fa04e3c | ||
|  | 9fd8d8915d | ||
|  | 7a9f5ebdd1 | ||
|  | a3423f0321 | ||
|  | c37e9a4467 | ||
|  | 6157d82a0b | ||
|  | 38b27fec92 | ||
|  | c43439bb68 | ||
|  | 8d9561d7a5 | ||
|  | 2a72cce3b7 | ||
|  | d3bbb6fb1f | ||
|  | 7b6723e9a2 | ||
|  | 1ee741460d | ||
|  | 967b0b493b | ||
|  | b53aaf7dde | ||
|  | 714c13bdbf | ||
|  | 651a4fd3cc | ||
|  | 505aee22bb | ||
|  | ca3d59dc33 | ||
|  | 13890e32a1 | ||
|  | df8976eabe | ||
|  | 3e01daa172 | ||
|  | f6999f355b | ||
|  | 5c06b45eb1 | ||
|  | 1802bb967a | ||
|  | d8d92f147f | ||
|  | 4a95bdd8ba | ||
|  | db5d94d956 | ||
|  | 06f2e34bb5 | ||
|  | 2ef7a01945 | ||
|  | d3f642551d | ||
|  | 490997157e | ||
|  | 2432af7883 | ||
|  | 7abeece3f0 | ||
|  | 3851652821 | ||
|  | 1d67d2250a | ||
|  | 37f40d8637 | ||
|  | 0224d1d59b | ||
|  | 587b94153d | ||
|  | 5124ce0302 | ||
|  | 950c4045b0 | ||
|  | 9c8ba66873 | ||
|  | 25d1d1be1b | ||
|  | 339c352505 | ||
|  | c587081fe4 | ||
|  | 8f9b1b866b | ||
|  | ff5ecf6182 | ||
|  | 05670cf393 | ||
|  | f10f5d30bf | ||
|  | 0d336727e8 | ||
|  | bf354275b3 | ||
|  | 1932bf277a | ||
|  | 192db4bb6e | ||
|  | 701efb943d | ||
|  | b2674971f1 | ||
|  | c907cb4cf1 | ||
|  | bb1462b4d9 | ||
|  | 1035f0e139 | ||
|  | 8475757716 | ||
|  | 20ffd8d61b | ||
|  | 8601428c4c | ||
|  | 59998573ee | ||
|  | 293cd72001 | ||
|  | 22ab9ebb2f | ||
|  | 9136e592d3 | ||
|  | ed8e392616 | ||
|  | e57ce6e644 | ||
|  | 8204e46086 | ||
|  | 9e365d9f80 | ||
|  | 6b40a933e9 | ||
|  | 8520a5002f | ||
|  | b38ed06f6e | ||
|  | 48427b1143 | ||
|  | 5d505f4ed0 | ||
|  | 0c02a08954 | ||
|  | 0221bd0f80 | ||
|  | 28216cbcb5 | ||
|  | 3e08a8cd6b | ||
|  | 67fafdeef7 | ||
|  | cc82505b66 | ||
|  | fd5f075f63 | ||
|  | a115960411 | ||
|  | e9fa4ca816 | ||
|  | 75d92bc7f0 | ||
|  | 74aa6e911e | ||
|  | 9d000c1898 | ||
|  | b2254875b2 | ||
|  | 78d04230d5 | ||
|  | 1c04477393 | ||
|  | 2a9679c94e | ||
|  | 6009f8ecde | ||
|  | 35cdbec70a | ||
|  | 0faef542c1 | ||
|  | 8b085af6a1 | ||
|  | e3b11a9eb2 | ||
|  | 72fc88f3c6 | ||
|  | a5b759f268 | ||
|  | 6a9ffae25d | ||
|  | 64c031c7fe | ||
|  | 720926c50d | ||
|  | 36ec974284 | ||
|  | cff77c39e2 | ||
|  | 056a0a1736 | ||
|  | f301da83c6 | ||
|  | 5362231efa | ||
|  | 4bb14cad73 | ||
|  | 7f5188f5a4 | ||
|  | a80b7aac6c | ||
|  | 83f32478fa | ||
|  | 7578ec6801 | ||
|  | e14a32f76f | ||
|  | 58faa189ac | ||
|  | 9b4f87d44a | ||
|  | 7830a64170 | ||
|  | 8f0fa02107 | ||
|  | e000fb5d80 | ||
|  | 566fadad15 | ||
|  | cf23858c10 | ||
|  | 216a223617 | ||
|  | 638f38d823 | ||
|  | 98ee70f04e | ||
|  | b365db5a4b | ||
|  | 02e55496df | ||
|  | e11e53913a | ||
|  | f8a5fb4225 | ||
|  | 3a49450461 | ||
|  | 3c375fb955 | ||
|  | 011fea2cc6 | ||
|  | a079eec2cb | ||
|  | 776b37f4ea | ||
|  | a4d8bbe3da | ||
|  | 72166743fa | ||
|  | c4312c0b11 | ||
|  | 38ba645415 | ||
|  | ac12a47071 | ||
|  | bea321939e | ||
|  | 210f84b6ea | ||
|  | d4c642741f | ||
|  | e6b1b58379 | ||
|  | 8d982c1a90 | ||
|  | be10e836dc | ||
|  | 9be05e7e17 | ||
|  | bd96b2819f | ||
|  | f601af3da0 | ||
|  | 70a01c082b | ||
|  | bcf066ead7 | ||
|  | 24dd3578ed | ||
|  | d5c39d54d8 | ||
|  | 6e3f6abc67 | ||
|  | 463201df2c | ||
|  | a7501c396f | ||
|  | 4c8bc49a7e | ||
|  | f254674f88 | ||
|  | a97c267378 | ||
|  | eaa947894b | ||
|  | fb3a26510b | ||
|  | bfe8b14e49 | ||
|  | afb47eb742 | ||
|  | ba97f96288 | ||
|  | ecbafb8f4b | ||
|  | 12d3800d67 | ||
|  | d586b82372 | ||
|  | ba9877c9b4 | ||
|  | 907933f3df | ||
|  | 2e91d21a88 | ||
|  | dca395a018 | ||
|  | 625070a5b9 | ||
|  | f875c7cbf5 | ||
|  | eed88fc103 | ||
|  | 6fc54d1d27 | ||
|  | 0ef52bf909 | ||
|  | 95e34af6ef | ||
|  | 650b99ead2 | ||
|  | 57941a19de | ||
|  | 6157db0b6a | ||
|  | c9358acf5d | ||
|  | ed29eb8a5d | ||
|  | bcf7452312 | ||
|  | b9000519e4 | ||
|  | 2694297466 | ||
|  | 53ff5c1490 | ||
|  | 32a036b076 | ||
|  | aae2ab2693 | ||
|  | 4ef23e28a3 | ||
|  | 38beb7f8d2 | ||
|  | 0129a66906 | ||
|  | 45bced7b34 | ||
|  | 7f5a55dffb | ||
|  | 80289df6d3 | ||
|  | 2115c3ced8 | ||
|  | 1c2d0e6618 | ||
|  | ea4f7f79ce | ||
|  | b17f8ac311 | ||
|  | 6870d13b72 | ||
|  | 81fa304fd2 | ||
|  | a663ddb0d9 | ||
|  | f7969afc22 | ||
|  | 52ce4cd313 | ||
|  | 247175881f | ||
|  | fcf5009338 | ||
|  | 12542d8f63 | ||
|  | e94194e28b | ||
|  | 115499f3b2 | ||
|  | 12af05b94f | ||
|  | 88b83d8164 | ||
|  | fcc22c692a | ||
|  | a876e8005c | ||
|  | 2288e3705a | ||
|  | e8b58154e0 | ||
|  | 4393475af3 | ||
|  | 3fc560597c | ||
|  | 9f9af0b693 | ||
|  | a83fe2caea | ||
|  | 30c5376217 | ||
|  | 6dddd6629d | ||
|  | f80de12cb5 | ||
|  | 544ffca3a5 | ||
|  | e0730c7b39 | ||
|  | 3d59d141c4 | ||
|  | ccddc2623d | ||
|  | fcc47b58b4 | ||
|  | f67ac2e25e | ||
|  | 26127c9ccf | ||
|  | d624efa799 | ||
|  | ed3d40a4e0 | ||
|  | 6e90ce5496 | ||
|  | ab851b1be4 | ||
|  | 340de53825 | ||
|  | a867b60af0 | ||
|  | 26eafb0bd2 | ||
|  | 0dbe44764b | ||
|  | 2159df6802 | ||
|  | 23389b9f17 | ||
|  | 6d3e3b894a | ||
|  | 55340aefa3 | ||
|  | 94bc751e41 | ||
|  | 89259c11e2 | ||
|  | 6bbaf1523c | ||
|  | fa3f18b60f | ||
|  | 3dc794002f | ||
|  | f50b133f2e | ||
|  | 1d6f6d28c9 | ||
|  | c913de3c8b | ||
|  | bbc7b54a38 | ||
|  | 05fa1b40d1 | ||
|  | 6a88c8634d | ||
|  | 8ae1efa230 | ||
|  | ab8df4c8ab | ||
|  | c259a46ed3 | ||
|  | 5dc0677599 | ||
|  | 7ed662ecc2 | ||
|  | 4361cc69d4 | ||
|  | 461cbcbc28 | ||
|  | 09ae6c488b | ||
|  | 271a0ade26 | ||
|  | 4b076d227a | ||
|  | 3c4e7158a1 | ||
|  | 0b16765f37 | ||
|  | 20c2ff3443 | ||
|  | 96f2e598f4 | ||
|  | 7374f0f9dd | ||
|  | ccc44a74a0 | ||
|  | 66cd63a68d | ||
|  | decf7e5485 | ||
|  | 063c8025aa | ||
|  | 2fa7d2bd56 | ||
|  | e55e7bce74 | ||
|  | f572445a65 | ||
|  | 8b4f656d90 | ||
|  | 6c1e093ebd | ||
|  | 6dd1b4537a | ||
|  | 39ca9bea72 | ||
|  | 999103277e | ||
|  | 3cc57ab89c | ||
|  | 4e830079de | ||
|  | ea7231e9fe | ||
|  | ddfaca6d0c | ||
|  | 3b11bd0593 | ||
|  | 3f89057528 | ||
|  | 2f1073712f | ||
|  | 678e504c48 | ||
|  | e69545fd95 | ||
|  | a7ed025cd6 | ||
|  | 3d8e1f2484 | ||
|  | c38c9608da | ||
|  | 2396b75e3c | ||
|  | e5c19b7562 | ||
|  | 114788567d | ||
|  | 17ae4b7d2a | ||
|  | 12d652bd0e | ||
|  | ff1bed97b8 | ||
|  | 56490f0e84 | ||
|  | 0b028a8923 | ||
|  | 43ac541cb8 | ||
|  | 5218443678 | ||
|  | d9028ed9b7 | ||
|  | 9b9bd11ebb | ||
|  | 07011ec5f7 | ||
|  | c3990ac32f | ||
|  | 081ff3ff55 | ||
|  | 93996ada96 | ||
|  | a60671d4c1 | ||
|  | 3f716cc369 | ||
|  | 9f23cffd1b | ||
|  | 07c416cfbf | ||
|  | 389fcc1c8d | ||
|  | fa07811375 | ||
|  | fc91a50979 | ||
|  | f9c518f321 | ||
|  | 015b439f0d | ||
|  | 0675622508 | ||
|  | e9969bdd5f | ||
|  | 1139f950ed | ||
|  | 284732c7a6 | ||
|  | 0cb0720d8b | ||
|  | 8ad1ede0c5 | ||
|  | a349aac8a4 | ||
|  | 83b169c6ef | ||
|  | 49c37baac5 | ||
|  | 8d62088576 | ||
|  | f5437a17f8 | ||
|  | 92af4e5c96 | ||
|  | 0619adb0cd | ||
|  | 65a5107854 | ||
|  | 0fcc1e252b | ||
|  | 4b7f817475 | ||
|  | 0439599971 | ||
|  | fa344d5308 | ||
|  | f0316f09ed | ||
|  | b1af6bab28 | ||
|  | ad2aebb54d | ||
|  | 23fc652092 | ||
|  | f0a5756f25 | ||
|  | 14c7ad201a | ||
|  | 08ca3c89d3 | ||
|  | edda470bf8 | ||
|  | 7183d72e5c | ||
|  | 5e38ebfce5 | ||
|  | 56e36847a5 | ||
|  | 6dba916d02 | ||
|  | fd57086ffd | ||
|  | d98d366eea | ||
|  | b261b0b447 | ||
|  | c6042a9053 | ||
|  | ae1245abec | ||
|  | e26d2376fc | ||
|  | bb36ad64a7 | ||
|  | 262d4f92d4 | ||
|  | 675530458c | ||
|  | 19e34b460f | ||
|  | dddb8cdbc0 | ||
|  | 0d0df5f143 | ||
|  | d1cf683f57 | ||
|  | d099c33e5b | ||
|  | 21fb41545b | ||
|  | 4c56814785 | ||
|  | cffe05e22b | ||
|  | 4237850299 | ||
|  | b5fc36a8e1 | ||
|  | 4586c1ef52 | ||
|  | 2722f0b749 | ||
|  | d6cf7c4872 | ||
|  | 3aedfed432 | ||
|  | edeaf13259 | ||
|  | c1290c4e9b | ||
|  | b2c1527b17 | ||
|  | a4a65ea56e | ||
|  | ccf0e1875e | ||
|  | 9c009aceaf | ||
|  | da4b1c7276 | ||
|  | add098d5c0 | ||
|  | aca096548c | ||
|  | 75aa3abcae | ||
|  | e685d262cc | ||
|  | d2599d6ef9 | ||
|  | cd5223d98d | ||
|  | 7b68d9047d | ||
|  | 9a7ea06d66 | ||
|  | c69ef34ac9 | ||
|  | 021999d05f | ||
|  | 6054430a5e | ||
|  | 8f578ed95a | ||
|  | fc5c339e27 | ||
|  | defad3d820 | ||
|  | c0f96aa948 | ||
|  | f2eae2fc98 | ||
|  | 0e4f786978 | ||
|  | d36b2318fd | ||
|  | d83b508bbc | ||
|  | 5b9c2cdc13 | ||
|  | 49066c282a | ||
|  | 3e28c0c00a | ||
|  | 220d689f69 | ||
|  | 5a0a28a04c | ||
|  | b44e69e09b | ||
|  | fcbe10f5ec | ||
|  | 182fe170fd | ||
|  | 184e9bdaf6 | ||
|  | 0096f50cde | ||
|  | 460f14deca | ||
|  | 910ad45bee | ||
|  | 74e319855d | ||
|  | 9af0fb4cd5 | ||
|  | 185f5cce29 | ||
|  | aca1174566 | ||
|  | e791f7fde2 | ||
|  | 7bba7fcf66 | ||
|  | 1d78f98ec8 | ||
|  | 7ed2e03654 | ||
|  | 549e0f3477 | ||
|  | 7785ec0222 | ||
|  | ca504965f9 | ||
|  | 3841259779 | ||
|  | 169d1065cc | ||
|  | e864f5507a | ||
|  | 434b4ded4a | ||
|  | 3d01669cea | ||
|  | 1499b2cd40 | ||
|  | 6b54ef8398 | ||
|  | 07ad43f7a2 | ||
|  | 72e72c60c2 | ||
|  | f9a242d33e | ||
|  | b0f43eaa07 | ||
|  | b02046b884 | ||
|  | 864c931ee9 | ||
|  | 5cd8da6d91 | ||
|  | 4a4671c2ae | ||
|  | 8de142cd9a | ||
|  | 1a42bec51c | ||
|  | 577e38759e | ||
|  | 9cdf43a2c9 | ||
|  | 62d43c2cb2 | ||
|  | 2dc67d1674 | ||
|  | fb1c78c657 | ||
|  | 37e58ac13a | ||
|  | de715c14be | ||
|  | c4d8a0da05 | ||
|  | 1b54b14671 | ||
|  | a92efbc55f | ||
|  | 1bd02529e0 | ||
|  | bc16298b6e | ||
|  | 804a97cad7 | ||
|  | ab52bdec15 | ||
|  | ddc3e82c14 | ||
|  | 57691471bb | ||
|  | c502dd445b | ||
|  | ed475b1b9c | ||
|  | df165a817c | ||
|  | d16015d625 | ||
|  | a4b3bf3ef4 | ||
|  | 6b006853e6 | ||
|  | 6001180e29 | ||
|  | 662fbed1d0 | ||
|  | 19c7e08c5d | ||
|  | 72f04aaedc | ||
|  | 2998382969 | ||
|  | 37fe79944f | ||
|  | 536735519a | ||
|  | 6b0a711395 | ||
|  | 13d3d40376 | ||
|  | 6873336aca | ||
|  | c2d2eb53e8 | ||
|  | 210d597a48 | ||
|  | e41ede0a6b | ||
|  | 4a8b17ac7c | ||
|  | 1f5f515d72 | ||
|  | 1e6242b89f | ||
|  | dde09f9f89 | ||
|  | 916d85c3fe | ||
|  | b243ed93aa | ||
|  | 70d28bbf6e | ||
|  | 3c76da7132 | ||
|  | 3254565c09 | ||
|  | cd0033791f | ||
|  | 2427ee44a5 | ||
|  | ff0e617b2a | ||
|  | e6cfe040b5 | ||
|  | 94e2f9b6dc | ||
|  | 512b81ad93 | ||
|  | fc0e76f431 | ||
|  | 9da69358e2 | ||
|  | aa246b0b2b | ||
|  | 6ed649bc8a | ||
|  | 725f5b7110 | ||
|  | 5a890c5c3a | ||
|  | 7752329b94 | ||
|  | 5f48f13890 | ||
|  | a734e04561 | ||
|  | 5aa1db293f | ||
|  | f89aee37f5 | ||
|  | 538018fed1 | ||
|  | a2327c50ec | ||
|  | c2711023e2 | ||
|  | cac30f0b4c | ||
|  | 4bb17019a4 | ||
|  | ba2a40bdf3 | ||
|  | f3460cca49 | ||
|  | 64ce53ac30 | ||
|  | a43238360c | ||
|  | b2cbadf5d8 | ||
|  | 81640ba06d | ||
|  | 9327430484 | ||
|  | a24c90eae8 | ||
|  | 1d3987ece6 | ||
|  | 83f5b5e293 | ||
|  | f231263085 | ||
|  | 4ad67a87f1 | ||
|  | b766d93d9a | ||
|  | 0905ceb1d5 | ||
|  | 2fbf837354 | ||
|  | 4bd79c880c | ||
|  | 4af041e015 | ||
|  | 8dc3e3ec93 | ||
|  | f4b68d26d6 | ||
|  | 1887977b92 | ||
|  | 8eb84acf4f | ||
|  | 1b685da3e3 | ||
|  | 406b658801 | ||
|  | bba1ee1264 | ||
|  | 02b6191d47 | ||
|  | c5a3de09cd | ||
|  | 0afe2a680e | ||
|  | 03e0510c4f | ||
|  | 1068dcb8a4 | ||
|  | 10a93df653 | ||
|  | 79ff67852f | ||
|  | a36cab969f | ||
|  | 45447646fa | ||
|  | 8a0f76ab68 | ||
|  | 037135e764 | ||
|  | 21e89c3b64 | ||
|  | bd11ec69fa | ||
|  | 9e2b34bc12 | ||
|  | 0faebc290f | ||
|  | fc0ef4b79d | ||
|  | 027b954b50 | ||
|  | 33c830a432 | ||
|  | a7887f1e25 | ||
|  | fa7a59572a | ||
|  | d9c2df5b0d | ||
|  | a854b2c17e | ||
|  | 7d4006b205 | ||
|  | 86ecca6011 | ||
|  | 0ea5cf2caa | ||
|  | a950e02e9b | ||
|  | 9eec6641dd | ||
|  | 18f46676fd | ||
|  | 9735ef6d41 | ||
|  | d3e8ceee00 | ||
|  | 144e329eca | ||
|  | 21d5420b2a | ||
|  | 3011b5074d | ||
|  | 83190572c7 | ||
|  | 9cf9e5f865 | ||
|  | 5bdef7f1c7 | ||
|  | ba285a2d2d | ||
|  | 0dff371e62 | ||
|  | ce4a2a5851 | ||
|  | 2c978dc89a | ||
|  | 4b8b819109 | ||
|  | c230b3a806 | ||
|  | df08b9c5c6 | ||
|  | eca65376a3 | ||
|  | 88e3705636 | ||
|  | 5476509ef5 | ||
|  | 0bd6636453 | ||
|  | 105894e00d | ||
|  | 230a319510 | ||
|  | ae16a2b14f | ||
|  | da0c0742bf | ||
|  | 61d60a9048 | ||
|  | 3e28e9a016 | ||
|  | 423f9fefa9 | ||
|  | 5707dc7579 | ||
|  | 3be1cdb249 | ||
|  | 426d3d948c | ||
|  | 9a3aed8038 | ||
|  | fb58bf1bf5 | ||
|  | a6dbd912c6 | ||
|  | 65ce277a20 | ||
|  | 0b2d423c87 | ||
|  | da056092fb | ||
|  | 45aa85d690 | ||
|  | 5c35fee0c2 | ||
|  | 24bdc319dd | ||
|  | f1dcc41e42 | ||
|  | 550f301ba2 | ||
|  | d9bf4d1c0d | ||
|  | c3c1a6eb22 | ||
|  | 2c4454418e | ||
|  | e44de572f5 | ||
|  | f27919f91b | ||
|  | ba9968bde0 | ||
|  | 05ea8216ff | ||
|  | fa1695672a | ||
|  | ac6f98fc47 | ||
|  | 1a1f89f555 | ||
|  | 6c3262e176 | ||
|  | b4bdb48f1e | ||
|  | 823afe877b | ||
|  | cb8e082414 | ||
|  | 98c1fcc68f | ||
|  | 8c439a2852 | ||
|  | 50c6109be7 | ||
|  | 6e362663b5 | ||
|  | 74c9feb53f | ||
|  | 402e8588cf | ||
|  | 778a42bcc0 | ||
|  | 584f7ced84 | ||
|  | 8e892e7ea5 | ||
|  | 3386c8b455 | ||
|  | 6fa73ee28d | ||
|  | 8ec8042045 | ||
|  | cddc123539 | ||
|  | 4c2938c5cd | ||
|  | 6d03ddadcc | ||
|  | 64311da4b4 | ||
|  | 0cbb50ae9d | ||
|  | 7e96054dc2 | ||
|  | 578298580e | ||
|  | ee5afaa6bc | ||
|  | 15b023d116 | ||
|  | 1ef96c0b4d | ||
|  | 8c3ae40de1 | ||
|  | 94fcfacec4 | ||
|  | ba7c01c6bc | ||
|  | 9f92e1b7bd | ||
|  | 1f0e692ee2 | ||
|  | 0acd75a24f | ||
|  | eedf27f8a5 | ||
|  | b451e207e2 | ||
|  | c0c37eec7b | ||
|  | 89363ecfa3 | ||
|  | 593e799ca1 | ||
|  | 8fc055cad9 | ||
|  | 75f86462e2 | ||
|  | 40892ccfa7 | ||
|  | 87fbf9c1a5 | ||
|  | 4944b233b6 | ||
|  | 9f23462c42 | ||
|  | 84a24f0333 | ||
|  | 7a885bfc3c | ||
|  | 3ba0cf1454 | ||
|  | 2d67a3159d | ||
|  | 290f25f1a0 | ||
|  | 1659904f81 | ||
|  | 230bd6e40a | ||
|  | ce27e97b92 | ||
|  | 18c1223c7b | ||
|  | 8ef659f5de | ||
|  | 037452e525 | ||
|  | e3482011d5 | ||
|  | 62748fa255 | ||
|  | 7a9df05f6b | ||
|  | 335279e728 | ||
|  | 0332104738 | ||
|  | 9f04854902 | ||
|  | 73008a35fe | ||
|  | eae96cd2af | ||
|  | cb670bb27d | ||
|  | fe1fb23e5b | ||
|  | c2dd61e96b | ||
|  | 80f5e61b6b | ||
|  | dbcae16b75 | ||
|  | 886dcae822 | ||
|  | ed495ec600 | ||
|  | ddb60ccdc5 | ||
|  | 335e2083af | ||
|  | 7b1d9d4962 | ||
|  | da6ff9f90a | ||
|  | 48f26c7bf1 | ||
|  | 3ce317b170 | ||
|  | b741565f57 | ||
|  | d8fea44968 | ||
|  | 778300b67e | ||
|  | cb2b44fef3 | ||
|  | cdb5875d6b | ||
|  | 01c5e15bcd | ||
|  | f0babb4be7 | ||
|  | 10b00da874 | ||
|  | e9f391b2eb | ||
|  | 50be39b054 | ||
|  | a94e0bb3da | ||
|  | 3f65d5d760 | ||
|  | 48cb528ae4 | ||
|  | e62e0345df | ||
|  | 441f011fba | ||
|  | af1349160a | ||
|  | 2072607889 | ||
|  | 073fd5aa0d | ||
|  | 7b4703e4ff | ||
|  | 1484621300 | ||
|  | 40709c8367 | ||
|  | b6ab5770a2 | ||
|  | 83b7cb4ff9 | ||
|  | 256dba66b2 | ||
|  | 6ac12f8ffa | ||
|  | 82e438d29b | ||
|  | e86547645c | ||
|  | 8b901084fe | ||
|  | 1a0cbbdb31 | ||
|  | 30ac62ffb7 | ||
|  | 8ab294e90b | ||
|  | f5edb15f43 | ||
|  | eed6107ce7 | ||
|  | d49dc599a2 | ||
|  | 3c5179f145 | ||
|  | 067d17c09c | ||
|  | 4c88c9af86 | ||
|  | 1c84afe186 | ||
|  | 9d4c4be468 | ||
|  | de7db8db78 | ||
|  | 407ba4dd6d | ||
|  | 5135be3000 | ||
|  | b8ab7d1a14 | ||
|  | 6211fd8496 | ||
|  | a4f273b48b | ||
|  | 68d820a97c | ||
|  | ebadfd6358 | ||
|  | cf93a88adc | ||
|  | bd2c4252bb | ||
|  | 84e7af04b9 | ||
|  | 37c63bc6b5 | ||
|  | e7d3716549 | ||
|  | 73bc5372c0 | ||
|  | b999a8f0fb | ||
|  | 16678aa5e1 | ||
|  | f9ab49911d | ||
|  | 3fabe2e9fb | ||
|  | 9a8a3e94d6 | ||
|  | 32ef2ef801 | ||
|  | 76cd3d35e2 | ||
|  | 900dea2c66 | ||
|  | 8e6ca0dd05 | ||
|  | 4b4ad7f1a8 | ||
|  | 21a0a5d573 | ||
|  | 3cfa3f3b27 | ||
|  | c77b43458e | ||
|  | 9ab0a83f7c | ||
|  | d3cda8811d | ||
|  | 55740c0d97 | ||
|  | c0a524c8a3 | ||
|  | e51c2d10f0 | ||
|  | 7af55b7268 | ||
|  | 7350b1da1b | ||
|  | 136adbe723 | ||
|  | cb2863eaf3 | ||
|  | d054f9b92f | ||
|  | 9c83c18137 | ||
|  | 999a7481e4 | ||
|  | a3b684b4ed | ||
|  | cb312ca025 | ||
|  | 1335a52db3 | ||
|  | 727221e2cb | ||
|  | 360f286ed3 | ||
|  | 6aecd77b77 | ||
|  | ca85cab6fb | ||
|  | 742479bb01 | ||
|  | 68e54a9297 | ||
|  | 056d83eda4 | ||
|  | 42ec55d0db | ||
|  | c89bd89d9a | ||
|  | 31a0be5bb4 | ||
|  | 07610ae8fb | ||
|  | dbc95dd878 | ||
|  | 792e8a9947 | ||
|  | d774cde109 | ||
|  | cc111d14b0 | ||
|  | bb3ba42ce2 | ||
|  | f4ecf2d1aa | ||
|  | 1997666196 | ||
|  | 3aa9057c5f | ||
|  | 834f8382e9 | ||
|  | 357638a26c | ||
|  | 919a0c01e4 | ||
|  | 6ff618e388 | ||
|  | ac765b7e4c | ||
|  | 2134e87c31 | ||
|  | 0d37288129 | ||
|  | 7cbd41137d | ||
|  | ba43d7063f | ||
|  | c9b2e29ba0 | ||
|  | 4720519aef | ||
|  | d7b0106e7d | ||
|  | 0a2cbaa047 | ||
|  | 3e5f615ffc | ||
|  | 00dc73e6d9 | ||
|  | aa5b9a1727 | ||
|  | f63a287a6c | ||
|  | b9d4c8dcd6 | ||
|  | 94433f1714 | ||
|  | a4dd4358b4 | ||
|  | 4e79b43395 | ||
|  | 6bb54bfa85 | ||
|  | 0df6c3a8dc | ||
|  | dc25086eab | ||
|  | 3299188edf | ||
|  | f6afb46f6f | ||
|  | 98993cfa9b | ||
|  | 5a920d5efd | ||
|  | 935276af88 | ||
|  | 5a505c8469 | ||
|  | 2c2abe8b8e | ||
|  | 638099d989 | ||
|  | 0f32f6be4c | ||
|  | 1f7c98bdcf | ||
|  | 72068a4b78 | ||
|  | c8038e0774 | ||
|  | 6b39beecb4 | ||
|  | b1ba64db12 | ||
|  | ad53832766 | ||
|  | d5bffc8ed7 | ||
|  | 69b36ddd1d | ||
|  | 9f926394a6 | ||
|  | 1e7ecbdf9d | ||
|  | beb8a461cf | ||
|  | e235a57e2f | ||
|  | 114b27079e | ||
|  | 6e19bc01f5 | ||
|  | f9dfdeafb3 | ||
|  | f05d626e38 | ||
|  | 918041258e | ||
|  | a5b13aa67f | ||
|  | 1383cbd4d5 | ||
|  | e9b7e82aea | ||
|  | fd6e7fc1ab | ||
|  | 743deb4227 | ||
|  | b051278d2e | ||
|  | bfda4bc199 | ||
|  | 4456ef2326 | ||
|  | 7336367eff | ||
|  | 9cb6c7697e | ||
|  | cd44f51072 | ||
|  | d8976379b1 | ||
|  | 8aa847c718 | ||
|  | 6691b238f7 | ||
|  | cca2758138 | ||
|  | 4a74e68e31 | ||
|  | 3d3842b9d6 | ||
|  | 9d889d05e4 | ||
|  | 9f920bcfe3 | ||
|  | 1bb49fa496 | ||
|  | 6b1d8d3aaa | ||
|  | c6b6ed7fa8 | ||
|  | 34454261d2 | ||
|  | ddf9f52737 | ||
|  | 10b969a074 | ||
|  | 5df0634380 | ||
|  | f0f965421c | ||
|  | 6381408fba | ||
|  | 43e738cb44 | ||
|  | 6d4303aa3f | ||
|  | 13c2db5378 | ||
|  | 36f6bda525 | ||
|  | 78886e7b1f | ||
|  | 3dce194930 | ||
|  | ec776bb6eb | ||
|  | 243d942a6e | ||
|  | ea6aba62c4 | ||
|  | 73743721b1 | ||
|  | 61eb5b341d | ||
|  | d758f72393 | ||
|  | 1b1367f4c2 | ||
|  | 07388dd58a | ||
|  | 359c71ef2f | ||
|  | 93d4d3df1d | ||
|  | d3a7596be2 | ||
|  | 114d3812cc | ||
|  | b2d4dcfbf1 | ||
|  | 0baf8f6d18 | ||
|  | 2f8e3a0707 | ||
|  | d7a4bf22c6 | ||
|  | 0c2f9d22b9 | ||
|  | e75c5aac49 | ||
|  | 77e5024f54 | ||
|  | 7329c0b200 | ||
|  | 0afe3c48a1 | ||
|  | 1ab5e923bc | ||
|  | 90b3bd77e7 | ||
|  | 9c60443f97 | ||
|  | 058e5602a3 | ||
|  | eebac2a66d | ||
|  | 7e8f5c9548 | ||
|  | d34b49bd48 | ||
|  | ccffae287d | ||
|  | ad69011ac5 | ||
|  | f8ea0f971d | ||
|  | 9918410954 | ||
|  | 4f4e6fac16 | ||
|  | 15e99bd672 | ||
|  | 696e9a6fde | ||
|  | 36cbb3d71f | ||
|  | f69598c6aa | ||
|  | 5fc31f3c1e | ||
|  | 6581ee0ee0 | ||
|  | 69e7501d47 | ||
|  | 314abbea8b | ||
|  | 82c9a75578 | ||
|  | 651101912c | ||
|  | fb0d463040 | ||
|  | 8c254554eb | ||
|  | 2d9c89375a | ||
|  | 61aba29df7 | ||
|  | 8c949e6190 | ||
|  | 6eb9188690 | ||
|  | 6832f2ebd0 | ||
|  | 3e02b50ea1 | ||
|  | 7b7743c03e | ||
|  | de20563275 | ||
|  | 9e720c3a38 | ||
|  | 54685c1f5f | ||
|  | eb8f8fa935 | ||
|  | 9adbbd872c | ||
|  | 4bd38f97a2 | ||
|  | 78ab1e200a | ||
|  | 11280e473d | ||
|  | f9750a64f8 | ||
|  | ac2ab65471 | ||
|  | 0530c0402c | ||
|  | a58a560bbb | ||
|  | 96ab112b22 | ||
|  | b388dcc7d4 | ||
|  | f511a25c94 | ||
|  | 58d8b6f95b | ||
|  | 953d68c3a2 | ||
|  | 9e2f7af59b | ||
|  | 840dfa6696 | ||
|  | 4a20c008ff | ||
|  | 981ffe4194 | ||
|  | 2597633b0e | ||
|  | 71d174d765 | ||
|  | 4aa9a04516 | ||
|  | 258d6a1688 | ||
|  | 2e2c12d6a4 | ||
|  | 44d189d7d3 | ||
|  | ab508a3d9e | ||
|  | 4e166c7d2e | ||
|  | 7f175a4870 | ||
|  | 0a627f6f9e | ||
|  | d34cc65984 | ||
|  | 78d034d366 | ||
|  | 638fa9005f | ||
|  | 5cb9907bf8 | ||
|  | f08fcc36fb | ||
|  | d231cd9f61 | ||
|  | 86a586f866 | ||
|  | 9d4cba1620 | ||
|  | e9afd55e9d | ||
|  | 9fa326f630 | ||
|  | af9473c126 | ||
|  | cb08df0770 | ||
|  | d49ca2eb11 | ||
|  | a3f8841ec3 | ||
|  | fd678c286d | ||
|  | 2a3f9b621b | ||
|  | 359e1b3943 | ||
|  | 754336b3cf | ||
|  | 4918f1c4cb | ||
|  | 5d5e308942 | ||
|  | 6a18f81cec | ||
|  | 1ff135d172 | ||
|  | e666e5e9e3 | ||
|  | 9874e77ddf | ||
|  | 27e3ec693a | ||
|  | 6bb1415ad7 | ||
|  | 83594e6f1f | ||
|  | 0f6008705c | ||
|  | c58b653bb7 | ||
|  | f69b6f9b4e | ||
|  | 7750b06476 | ||
|  | 873384a34b | ||
|  | ac299e7279 | ||
|  | 7895d7f5d0 | ||
|  | fe05d218fc | ||
|  | 8196313ac0 | ||
|  | 6d8f84654f | ||
|  | ab4f34a96b | ||
|  | 139d985904 | ||
|  | 44705f0e18 | ||
|  | ddea7d696a | ||
|  | f814f45e36 | ||
|  | f7117d47c2 | ||
|  | 01b0a1058d | ||
|  | 21f362c7b9 | ||
|  | aaab7f8e0e | ||
|  | 09e1f68c69 | ||
|  | 03729aa5ae | ||
|  | ef39f31ea1 | ||
|  | 0f1437dd6a | ||
|  | 03aac2f744 | ||
|  | 2f8b10e82c | ||
|  | 3231effd20 | ||
|  | f7722c1189 | ||
|  | 70c2450ac4 | ||
|  | 2d5b0d0f99 | ||
|  | f0c0002a6d | ||
|  | dd9f08d4fa | ||
|  | de2e384225 | ||
|  | ffcd1fde0f | ||
|  | d5e1da5948 | ||
|  | ad479a5c7f | ||
|  | 0707603b63 | ||
|  | 2f9c383004 | ||
|  | 8ad0d7af93 | ||
|  | 9b4391c0bf | ||
|  | da7802a0a4 | ||
|  | 9c69949e8c | ||
|  | b1d7a9451a | ||
|  | 004488d453 | ||
|  | fc91372dd0 | ||
|  | 5970a9dc91 | ||
|  | 264cac4f9b | ||
|  | 633328a965 | ||
|  | 4d4b62a766 | ||
|  | aeb2c7deeb | ||
|  | c323942d92 | ||
|  | a0afa25145 | ||
|  | 4533b46436 | ||
|  | e5f8db78f9 | ||
|  | 899f61671f | ||
|  | d84d88cc10 | ||
|  | 97e7ac4052 | ||
|  | ba4ffa44d2 | ||
|  | 07caeccf68 | ||
|  | d54832f61f | ||
|  | b212753633 | ||
|  | f38d80cbf5 | ||
|  | 8bea1acd8e | ||
|  | 42458ce11d | ||
|  | aceb683d07 | ||
|  | b7517b49ed | ||
|  | 849b711b79 | ||
|  | 25585b28c7 | ||
|  | 073da8fb2a | ||
|  | a787ff3f3c | ||
|  | 733b6d7eb7 | ||
|  | 36d8dee853 | ||
|  | 65a2e07d24 | ||
|  | 7c97c558ab | ||
|  | a6bb61050c | ||
|  | b184aa2315 | ||
|  | e4595333e7 | ||
|  | 41dd139bde | ||
|  | c577dd302a | ||
|  | 0ab87de78b | ||
|  | 8a22509b41 | ||
|  | b024c18441 | ||
|  | d9ac681a68 | ||
|  | 637a5579ec | ||
|  | 4794156e80 | ||
|  | 5f4db7874c | ||
|  | b4ea1839a5 | ||
|  | 6a6d889983 | ||
|  | 287c2e7af8 | ||
|  | 0fe6acc8cf | ||
|  | 7d2dab7ca0 | ||
|  | f68c1aff26 | ||
|  | 81662473a6 | ||
|  | d40645be68 | ||
|  | a53550537f | ||
|  | 223ad16616 | ||
|  | 3f060979d7 | ||
|  | 2eac9081ea | ||
|  | b3eef4f40b | ||
|  | dd70fbad3f | ||
|  | 8cb7a1aef8 | ||
|  | a687140056 | ||
|  | 3cba673a9c | ||
|  | 01de230785 | ||
|  | e405d06f23 | ||
|  | d9b70f7ad8 | ||
|  | 0ef5825d98 | ||
|  | 1e76a5fc3f | ||
|  | 1fbdb3d0ae | ||
|  | d5bcf5497f | ||
|  | 28aaea1aa3 | ||
|  | 980d9ce885 | ||
|  | ec601efa6e | ||
|  | b3209d3b4d | ||
|  | 4ce978b9f3 | ||
|  | a84064663a | ||
|  | 6798cea268 | ||
|  | 8e86196352 | ||
|  | 1b3d345fbd | ||
|  | 7d2627515f | ||
|  | aa9eb8ca64 | ||
|  | 9015d6ca16 | ||
|  | 217483639d | ||
|  | 78e80530d3 | ||
|  | 3bbecfe830 | ||
|  | 9ab3679d49 | ||
|  | fc44a52ba5 | ||
|  | bb2b71bdc0 | ||
|  | b23d2a9d95 | ||
|  | eeb773fd7b | ||
|  | 53a582f374 | ||
|  | 73110f6a51 | ||
|  | 5667663fef | ||
|  | fb664ba17d | ||
|  | 0c10190a8e | ||
|  | 183a323ef6 | ||
|  | 90bada5497 | ||
|  | 7c043e1923 | ||
|  | 2720ae3c46 | ||
|  | 401508577e | ||
|  | b0a31cebc2 | ||
|  | 95adb428fa | ||
|  | f92a0310dd | ||
|  | 84f0cb3765 | ||
|  | d49e6787d6 | ||
|  | 0884853a6f | ||
|  | 1967c63006 | ||
|  | 9461e7b70a | ||
|  | f1e5df566c | ||
|  | fb02a0d5ad | ||
|  | e438a02fa3 | ||
|  | b112452aa1 | ||
|  | 1a2fc81af3 | ||
|  | 38bbda982c | ||
|  | 41ad6e64d1 | ||
|  | efcad0b935 | ||
|  | e892b69a96 | ||
|  | 5dfc04e777 | ||
|  | c119a42d70 | ||
|  | 802541b796 | ||
|  | 0770c79777 | ||
|  | 5f4669341e | ||
|  | f15fc80233 | ||
|  | a7d75ea94a | ||
|  | ba4bddf756 | ||
|  | 6a26408552 | ||
|  | c39c59fff5 | ||
|  | c1ba8dc6a7 | ||
|  | f2825da878 | ||
|  | c61f1307d8 | ||
|  | 9e88d7a60d | ||
|  | 406ae25162 | ||
|  | dbfb342021 | ||
|  | 4632142e06 | ||
|  | 9ae036f297 | ||
|  | 497b8c48c8 | ||
|  | 5d11949313 | ||
|  | a91c9f04c5 | ||
|  | 4f3493f9ff | ||
|  | 49b8742082 | ||
|  | 69cee59e23 | ||
|  | 19402b9022 | ||
|  | 62ba40b687 | ||
|  | f9af9a4fbe | ||
|  | c2ab43d0ab | ||
|  | af28e6e7b9 | ||
|  | 114ad7f292 | ||
|  | 44eb67f94e | ||
|  | 0203fee174 | ||
|  | a1ba340ead | ||
|  | 0ae9ff4575 | ||
|  | 5b501cb942 | ||
|  | 0255b7a4a0 | ||
|  | 15ef0bab1d | ||
|  | decad6830b | ||
|  | b6e0b985c2 | ||
|  | c140f71878 | ||
|  | 87044e6b8e | ||
|  | affa9014d2 | ||
|  | 4bbc3c3bd8 | ||
|  | d296dbbc23 | ||
|  | 9bcd27b847 | ||
|  | 2a54b36db0 | ||
|  | 77fb02daa4 | ||
|  | 1963ac191f | ||
|  | 33da8aa987 | ||
|  | 0192484044 | ||
|  | 3c0863d8ea | ||
|  | 710d6dfb74 | ||
|  | 2359542d72 | ||
|  | e1a2b4b9af | ||
|  | 0eadfa1c83 | ||
|  | c8dd935460 | ||
|  | e2227271b5 | ||
|  | 7a639a1d6e | ||
|  | 9edb9b91b2 | ||
|  | b2adeb20d9 | ||
|  | fa665de847 | ||
|  | ab9e5f716d | ||
|  | 5788db9f07 | ||
|  | 3068a8d58d | ||
|  | 14aacf42b9 | ||
|  | d1b97da309 | ||
|  | 867074e7b2 | ||
|  | 18748510b1 | ||
|  | bcf71cdf85 | ||
|  | 3290ce85a9 | ||
|  | 60ef80c1a5 | ||
|  | 74e852b8bd | ||
|  | 90ae21d257 | ||
|  | fdf03cd8e2 | ||
|  | f6586be5e7 | ||
|  | f9dc627d84 | ||
|  | 309177ca9c | ||
|  | 456d2342b6 | ||
|  | 0717aa22d7 | ||
|  | b8e07ac38e | ||
|  | c7273e4b60 | ||
|  | 33d4fd4af0 | ||
|  | 71b11e26d2 | ||
|  | 77f4111b09 | ||
|  | 9965297f36 | ||
|  | 5ca466a826 | ||
|  | 90f417facc | ||
|  | eacbd038b7 | ||
|  | 5446e85424 | ||
|  | 77b4942691 | ||
|  | 824cf71e0b | ||
|  | 239bbd30c0 | ||
|  | 6f6b653d54 | ||
|  | e4155ce735 | ||
|  | 7eaf307834 | ||
|  | 7db7950415 | ||
|  | fcc184cd2a | ||
|  | 6423feff3a | ||
|  | e97da25d5a | ||
|  | f49a37a38e | ||
|  | 07e6b33095 | ||
|  | 9136b50e3c | ||
|  | c3fd5c7136 | ||
|  | 98612dd253 | ||
|  | 4d7f5238dd | ||
|  | f472a01a80 | ||
|  | 420b5790e3 | ||
|  | 2e342e47a7 | ||
|  | 58b3334f05 | ||
|  | 4cd955e5cf | ||
|  | 4dbf410cdf | ||
|  | 074e6d52b1 | ||
|  | a0a36c5137 | ||
|  | 9db4137a1b | ||
|  | 85f1e744b8 | ||
|  | 8d90061d90 | ||
|  | b20d84e4b8 | 
							
								
								
									
										25
									
								
								.codeclimate.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								.codeclimate.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| # Save as .codeclimate.yml (note leading .) in project root directory | ||||
| languages: | ||||
|   JavaScript: true | ||||
|   PHP: true | ||||
| exclude_paths: | ||||
| - "public/packages/maximebf/php-debugbar/debugbar.js" | ||||
| - "public/packages/maximebf/php-debugbar/widgets.js" | ||||
| - "public/packages/maximebf/php-debugbar/openhandler.js" | ||||
| - "public/packages/maximebf/php-debugbar/widgets/sqlqueries/widget.js" | ||||
| - "public/js/bootstrap3-typeahead.min.js" | ||||
| - "public/js/bootstrap-sortable.js" | ||||
| - "public/js/bootstrap-tagsinput.min.js" | ||||
| - "public/js/bootstrap-tagsinput.min.js.map" | ||||
| - "public/js/daterangepicker.js" | ||||
| - "public/js/jquery-2.1.3.min.js" | ||||
| - "public/js/jquery-2.1.3.min.js.map" | ||||
| - "public/js/jquery-ui.min.js" | ||||
| - "public/js/metisMenu.js" | ||||
| - "public/js/moment.min.js" | ||||
| - "public/js/sb-admin-2.js" | ||||
| - "public/bootstrap/*" | ||||
| - "resources/lang/*" | ||||
| - "tests/*" | ||||
| - "database/*" | ||||
| - "storage/*" | ||||
							
								
								
									
										24
									
								
								.env.example
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								.env.example
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| APP_ENV=production | ||||
| APP_DEBUG=false | ||||
| APP_KEY=SomeRandomStringOf32CharsExactly | ||||
|  | ||||
| DB_CONNECTION=mysql | ||||
| DB_HOST=localhost | ||||
| DB_DATABASE=homestead | ||||
| DB_USERNAME=homestead | ||||
| DB_PASSWORD=secret | ||||
|  | ||||
| CACHE_DRIVER=file | ||||
| SESSION_DRIVER=file | ||||
|  | ||||
| EMAIL_SMTP= | ||||
| EMAIL_DRIVER=smtp | ||||
| EMAIL_USERNAME= | ||||
| EMAIL_PASSWORD= | ||||
| ANALYTICS_ID= | ||||
| EMAIL_PRETEND=false | ||||
| RUNCLEANUP=true | ||||
| SITE_OWNER=mail@example.com | ||||
|  | ||||
| SENDGRID_USERNAME= | ||||
| SENDGRID_PASSWORD= | ||||
							
								
								
									
										18
									
								
								.env.testing
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								.env.testing
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| APP_ENV=testing | ||||
| APP_DEBUG=true | ||||
| APP_KEY=SomeRandomString | ||||
|  | ||||
| DB_CONNECTION=sqlite | ||||
| DB_HOST=localhost | ||||
| DB_DATABASE=homestead | ||||
| DB_USERNAME=homestead | ||||
| DB_PASSWORD=secret | ||||
|  | ||||
| CACHE_DRIVER=array | ||||
| SESSION_DRIVER=array | ||||
|  | ||||
| EMAIL_SMTP= | ||||
| EMAIL_USERNAME= | ||||
| EMAIL_PASSWORD= | ||||
| ANALYTICS_ID=ABC | ||||
| EMAIL_PRETEND=true | ||||
							
								
								
									
										32
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,14 +1,36 @@ | ||||
| /bootstrap/compiled.php | ||||
| /vendor | ||||
| composer.phar | ||||
| composer.lock | ||||
| .env.*.php | ||||
| .env.php | ||||
| .DS_Store | ||||
| Thumbs.db | ||||
| .idea/ | ||||
| tests/_output/* | ||||
| _ide_helper.php | ||||
| /build/logs/clover.xml | ||||
| index.html* | ||||
| app/storage/firefly-export* | ||||
| app/storage/firefly-export* | ||||
| .vagrant | ||||
| firefly-iii-import-*.json | ||||
| tests/_output/* | ||||
| testing.sqlite | ||||
| _ide_helper_models.php | ||||
| clean.sqlite | ||||
| tests/acceptance/AcceptanceTester.php | ||||
| tests/functional/FunctionalTester.php | ||||
| tests/unit/UnitTester.php | ||||
| pi.php | ||||
| tests/_data/db.sqlite | ||||
| tests/_data/dump.sql | ||||
| db.sqlite_snapshot | ||||
| c3.php | ||||
| db.sqlite-journal | ||||
| tests/_output/* | ||||
| .env | ||||
| clover.xml | ||||
| node_modules/ | ||||
| addNewLines.php | ||||
| .phpstorm.meta.php | ||||
| .env.backup | ||||
| .env.local | ||||
|  | ||||
| tests/_output/* | ||||
| tests/_output/* | ||||
|   | ||||
							
								
								
									
										22
									
								
								.jshintrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								.jshintrc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| { | ||||
|   "undef": true, | ||||
|   "unused": false, | ||||
|   "strict": true, | ||||
|   "browser": true, | ||||
|   "jquery": true, | ||||
|   "devel": true, | ||||
|   "globals": [ | ||||
|     "language", | ||||
|     "token", | ||||
|     "currencyCode", | ||||
|     "$", | ||||
|     "token", | ||||
|     "accountID", | ||||
|     "billID", | ||||
|     "currentMonthName", | ||||
|     "previousMonthName", | ||||
|     "nextMonthName", | ||||
|     "everything", | ||||
|     "moment" | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										3
									
								
								.scrutinizer.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.scrutinizer.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| # .scrutinizer.yml | ||||
| tools: | ||||
|   external_code_coverage: false | ||||
							
								
								
									
										14
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								.travis.yml
									
									
									
									
									
								
							| @@ -1,13 +1,15 @@ | ||||
| language: php | ||||
| sudo: false | ||||
|  | ||||
|  | ||||
| php: | ||||
|   - 5.5 | ||||
|   - 5.4 | ||||
|   - hhvm | ||||
|   - 5.6 | ||||
|  | ||||
| install: | ||||
|   - composer install | ||||
|  | ||||
| after_script: | ||||
|   - php vendor/bin/coveralls | ||||
|   - composer update | ||||
|   - php artisan env | ||||
|   - mv -v .env.testing .env | ||||
|  | ||||
| script: | ||||
|   - phpunit | ||||
|   | ||||
							
								
								
									
										145
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										145
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,55 +1,116 @@ | ||||
| firefly-iii | ||||
| =========== | ||||
| # Firefly III | ||||
|  | ||||
| [](https://travis-ci.org/JC5/firefly-iii) | ||||
| [](https://coveralls.io/r/JC5/firefly-iii?branch=master) | ||||
|  | ||||
| [](https://packagist.org/packages/grumpydictator/firefly-iii) | ||||
| [](https://packagist.org/packages/grumpydictator/firefly-iii) | ||||
|  | ||||
| [](https://packagist.org/packages/grumpydictator/firefly-iii) | ||||
| [](https://packagist.org/packages/grumpydictator/firefly-iii) | ||||
| [](https://packagist.org/packages/grumpydictator/firefly-iii) | ||||
| [](https://packagist.org/packages/grumpydictator/firefly-iii) | ||||
| [](https://scrutinizer-ci.com/g/JC5/firefly-iii/?branch=master) | ||||
| [](https://scrutinizer-ci.com/g/JC5/firefly-iii/build-status/master) | ||||
|  | ||||
| Firefly Mark III is a new version of Firefly built upon best practices and lessons learned | ||||
| from building [Firefly](https://github.com/JC5/Firefly). It's Mark III since the original Firefly never made it outside of my | ||||
| laptop and [Firefly II](https://github.com/JC5/Firefly) is live. | ||||
| ## About | ||||
|  | ||||
| ## Changes | ||||
|  | ||||
| Firefly III will feature: | ||||
|  | ||||
| - Double-entry bookkeeping system; | ||||
| - Better budgeting tools; | ||||
| - Better financial reporting; | ||||
| - More control over other resources outside of personal finance | ||||
|   - Accounts shared with a partner (household accounts) | ||||
|   - Debts | ||||
|   - Credit cards | ||||
| - More robust code base (mainly for my own peace of mind); | ||||
| - More test-coverage (aka: actual test coverage); | ||||
|  | ||||
| ## More features | ||||
| "Firefly III" is a financial manager. It can help you keep track of expenses, income, budgets and everything in between. It even supports credit cards, shared  | ||||
| household accounts and savings accounts! It's pretty fancy. You should use it to save and organise money. | ||||
|   | ||||
| - Firefly will be able to split transactions; a single purchase can be split in multiple entries, for more fine-grained control. | ||||
| - Firefly will be able to join transactions. | ||||
| - Transfers and transactions will be combined into one internal datatype which is more consistent with what you're actually doing: moving money from A to B. The fact that A or B or both are yours should not matter. And it will not, in the future. | ||||
| - The nesting of budgets, categories and beneficiaries will be removed. | ||||
| - Firefly will be able to automatically login a specified account. Although this is pretty unsafe, it removes the need for you to login to your own tool.  | ||||
| _Firefly is a system you'll have install yourself on webhosting of your choosing._ | ||||
|  | ||||
| ## Not changed | ||||
| Personal financial management is pretty difficult, and everybody has their own approach to it. Some people | ||||
| make budgets, other people limit their cashflow by throwing away their credit cards, others try to increase | ||||
| their current cashflow. There are tons of ways to save and earn money. | ||||
|  | ||||
| Firefly works on the principle that if you know where you're money is going, you can stop it from going there. | ||||
|  | ||||
|   | ||||
| To get to know Firefly, and to see if it fits you, check out these resources: | ||||
|  | ||||
| - The screenshots below on this very page. | ||||
| - The featurelist below, also on this very page. | ||||
| - The [full description](https://github.com/JC5/firefly-iii/wiki/full-description), which will tell you how Firefly works, | ||||
| and the philosophy behind it. | ||||
|  | ||||
|  | ||||
| #### About the name (should you care) | ||||
|  | ||||
| It's III, or 3, because [version 2](https://github.com/JC5/Firefly) and version 1 (not online) preceded it. It has been growing steadily ever since. | ||||
|  | ||||
| ## Current features | ||||
|  | ||||
| - [A double-entry bookkeeping system](https://en.wikipedia.org/wiki/Double-entry_bookkeeping_system); | ||||
| - You can store, edit and remove [withdrawals, deposits and transfers](https://en.wikipedia.org/wiki/Financial_transaction). This allows you full financial management; | ||||
| - You can manage different types of accounts; | ||||
|   - [Asset](https://en.wikipedia.org/wiki/Asset) accounts | ||||
|   - Shared [asset accounts](https://en.wikipedia.org/wiki/Asset) ([household accounts](https://en.wikipedia.org/wiki/Household)) | ||||
|   - Saving accounts | ||||
|   - Credit cards | ||||
| - It's possible to create, change and manage money using _[budgets](https://en.wikipedia.org/wiki/Envelope_system)_; | ||||
| - Organize transactions using categories; | ||||
| - Save towards a goal using [piggy banks](https://en.wikipedia.org/wiki/Piggy_bank); | ||||
| - Predict and anticipate [bills](https://en.wikipedia.org/wiki/Invoice); | ||||
| - View income / expense [reports](https://en.wikipedia.org/wiki/Financial_statement); | ||||
| - Organize expenses using tags; | ||||
| - Lots of help text in case you don't get it. | ||||
|  | ||||
| Everything is organised: | ||||
|  | ||||
| - Clear views that should show you how you're doing; | ||||
| - Easy navigation through your records; | ||||
| - Browse back and forth to see previous months or even years; | ||||
| - Lots of charts because we all love them; | ||||
| - Financial reporting showing you how well you are doing. | ||||
|  | ||||
| ## Screenshots | ||||
|  | ||||
| _Please note that everything in these screenshots is fictional and may not be realistic._ | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ## Running and installing | ||||
|  | ||||
| If you're still interested please read [the installation guide](https://github.com/JC5/firefly-iii/wiki/Installation),  | ||||
| [the upgrade guide](https://github.com/JC5/firefly-iii/wiki/Upgrade-instructions) (if applicable)  | ||||
| and the **[first use guide](https://github.com/JC5/firefly-iii/wiki/First-use)**. | ||||
|   | ||||
| If you want to try out Firefly III, you can do so on [this dedicated website](https://geld.nder.be/).  | ||||
| This site always runs the latest version of Firefly III. If you want to use it, please read the [privacy considerations](https://github.com/JC5/firefly-iii/wiki/Privacy-on-demo-site) for this demo-site. Accounts on the demo sites will stop working after one week. | ||||
|  | ||||
| ## Credits | ||||
|  | ||||
| Firefly III uses the following libraries and tools: | ||||
|  | ||||
| * The AdminLTE template by [Almsaseed Studio](https://almsaeedstudio.com/) | ||||
| * The [Google charts](https://developers.google.com/chart/) library. | ||||
| * [Chart.js](http://www.chartjs.org/) | ||||
| * [Bootstrap](http://getbootstrap.com/) | ||||
| * [Laravel](http://laravel.com/) | ||||
| * [Twig](http://twig.sensiolabs.org/) | ||||
| * For development, some of the excellent tools made by [Barry van den Heuvel](https://github.com/barryvdh) | ||||
| * [Bootstrap sortable](https://github.com/drvic10k/bootstrap-sortable) by [Matúš Brliť](https://github.com/drvic10k). | ||||
| * [Date range picker](https://github.com/dangrossman/bootstrap-daterangepicker/) by [Dan Grossman](https://github.com/dangrossman) | ||||
| * The [real favicon generator](http://realfavicongenerator.net/) | ||||
| * Various other open source components (see [composer.json](https://github.com/JC5/firefly-iii/blob/master/composer.json)) | ||||
|  | ||||
| - Firefly will not encrypt the content of the (MySQL) tables. Old versions of Firefly had this capability but it sucks when searching, sorting and organizing entries. | ||||
|  | ||||
| ## Current state | ||||
| I have the basics up and running and test coverage is doing very well. | ||||
|  | ||||
| Current issues are the consistent look-and-feel of forms and likewise, the consistent inner workings of most of Firefly. | ||||
| Example: every "create"-action tends to be slightly different from the rest. Also is the fact that not all lists | ||||
| and forms are equally well thought of; some are not looking very well or miss feedback. | ||||
| Firefly III is pretty much all grown up. Full test coverage (nerd alert!) is coming. Translations are a work in progress. | ||||
|  | ||||
| Most forms will not allow you to enter invalid data because the database cracks, not because it's actually checked. | ||||
| I'm still thinking about a way to build consistent forms. Laravel doesn't really cut it. | ||||
| Questions, ideas, bugs or other things to contribute? [Let me know](https://github.com/JC5/firefly-iii/issues/new)! | ||||
|  | ||||
| A lot of views have CSRF vulnerabilities. The general advice is NOT to use this tool in production. | ||||
| If you like this tool, feel free to [donate me some beer money](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=2ZMV952UUSCLU&lc=NL&item_name=Development%20of%20Firefly¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted). | ||||
|  | ||||
| Questions, ideas or other things to contribute? [Let me know](https://github.com/JC5/firefly-iii/issues/new)! | ||||
| [](https://insight.sensiolabs.com/projects/d44c7012-5f50-41ad-add8-8445330e4102) | ||||
| [](https://codeclimate.com/github/JC5/firefly-iii) | ||||
| [](http://stillmaintained.com/JC5/firefly-iii) | ||||
| [](https://packagist.org/packages/grumpydictator/firefly-iii) | ||||
|  | ||||
|   | ||||
							
								
								
									
										12
									
								
								app/Commands/Command.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								app/Commands/Command.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| <?php namespace FireflyIII\Commands; | ||||
| /** | ||||
|  * Class Command | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Commands | ||||
|  */ | ||||
| abstract class Command | ||||
| { | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										37
									
								
								app/Console/Kernel.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								app/Console/Kernel.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| <?php namespace FireflyIII\Console; | ||||
|  | ||||
| use Illuminate\Console\Scheduling\Schedule; | ||||
| use Illuminate\Foundation\Console\Kernel as ConsoleKernel; | ||||
|  | ||||
| /** | ||||
|  * Class Kernel | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Console | ||||
|  */ | ||||
| class Kernel extends ConsoleKernel | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * The Artisan commands provided by your application. | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $commands | ||||
|         = [ | ||||
|         ]; | ||||
|  | ||||
|     /** | ||||
|      * Define the application's command schedule. | ||||
|      * | ||||
|      * @param  \Illuminate\Console\Scheduling\Schedule $schedule | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     protected function schedule(Schedule $schedule) | ||||
|     { | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										14
									
								
								app/Events/Event.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								app/Events/Event.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| <?php namespace FireflyIII\Events; | ||||
|  | ||||
| /** | ||||
|  * Class Event | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Events | ||||
|  */ | ||||
| abstract class Event | ||||
| { | ||||
|  | ||||
|     // | ||||
|  | ||||
| } | ||||
							
								
								
									
										34
									
								
								app/Events/JournalCreated.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								app/Events/JournalCreated.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| <?php namespace FireflyIII\Events; | ||||
|  | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Illuminate\Queue\SerializesModels; | ||||
|  | ||||
| /** | ||||
|  * Class JournalCreated | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Events | ||||
|  */ | ||||
| class JournalCreated extends Event | ||||
| { | ||||
|  | ||||
|     use SerializesModels; | ||||
|  | ||||
|     public $journal; | ||||
|     public $piggyBankId; | ||||
|  | ||||
|     /** | ||||
|      * Create a new event instance. | ||||
|      * | ||||
|      * @param TransactionJournal $journal | ||||
|      * @param                    $piggyBankId | ||||
|      */ | ||||
|     public function __construct(TransactionJournal $journal, $piggyBankId) | ||||
|     { | ||||
|         // | ||||
|         $this->journal     = $journal; | ||||
|         $this->piggyBankId = $piggyBankId; | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										25
									
								
								app/Events/JournalDeleted.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								app/Events/JournalDeleted.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| <?php namespace FireflyIII\Events; | ||||
|  | ||||
| use Illuminate\Queue\SerializesModels; | ||||
|  | ||||
| /** | ||||
|  * Class JournalDeleted | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Events | ||||
|  */ | ||||
| class JournalDeleted extends Event | ||||
| { | ||||
|  | ||||
|     use SerializesModels; | ||||
|  | ||||
|     /** | ||||
|      * Create a new event instance. | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         // | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										30
									
								
								app/Events/JournalSaved.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								app/Events/JournalSaved.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| <?php namespace FireflyIII\Events; | ||||
|  | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Illuminate\Queue\SerializesModels; | ||||
|  | ||||
| /** | ||||
|  * Class JournalSaved | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Events | ||||
|  */ | ||||
| class JournalSaved extends Event | ||||
| { | ||||
|  | ||||
|     use SerializesModels; | ||||
|  | ||||
|     public $journal; | ||||
|  | ||||
|     /** | ||||
|      * Create a new event instance. | ||||
|      * | ||||
|      * @param TransactionJournal $journal | ||||
|      */ | ||||
|     public function __construct(TransactionJournal $journal) | ||||
|     { | ||||
|         // | ||||
|         $this->journal = $journal; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										15
									
								
								app/Exceptions/FireflyException.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								app/Exceptions/FireflyException.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Exceptions; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Class FireflyException | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Exceptions | ||||
|  */ | ||||
| class FireflyException extends \Exception | ||||
| { | ||||
|  | ||||
| }  | ||||
							
								
								
									
										59
									
								
								app/Exceptions/Handler.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								app/Exceptions/Handler.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| <?php namespace FireflyIII\Exceptions; | ||||
|  | ||||
| use Exception; | ||||
| use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; | ||||
| use Symfony\Component\HttpKernel\Exception\HttpException; | ||||
|  | ||||
| /** | ||||
|  * Class Handler | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Exceptions | ||||
|  */ | ||||
| class Handler extends ExceptionHandler | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * A list of the exception types that should not be reported. | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $dontReport | ||||
|         = [ | ||||
|             'Symfony\Component\HttpKernel\Exception\HttpException' | ||||
|         ]; | ||||
|  | ||||
|     /** | ||||
|      * Render an exception into an HTTP response. | ||||
|      * | ||||
|      * @param  \Illuminate\Http\Request $request | ||||
|      * @param  \Exception               $e | ||||
|      * @SuppressWarnings(PHPMD.ShortVariable) | ||||
|      * | ||||
|      * @return \Illuminate\Http\Response | ||||
|      */ | ||||
|     public function render($request, Exception $e) | ||||
|     { | ||||
|         if ($e instanceof HttpException) { | ||||
|             return $this->renderHttpException($e); | ||||
|         } else { | ||||
|             return parent::render($request, $e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Report or log an exception. | ||||
|      * | ||||
|      * This is a great spot to send exceptions to Sentry, Bugsnag, etc. | ||||
|      * @SuppressWarnings(PHPMD.ShortVariable) | ||||
|      * | ||||
|      * @param  \Exception $e | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function report(Exception $e) | ||||
|     { | ||||
|         parent::report($e); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										14
									
								
								app/Exceptions/NotImplementedException.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								app/Exceptions/NotImplementedException.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| <?php | ||||
| namespace FireflyIII\Exceptions; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Class NotImplementedException | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Exceptions | ||||
|  */ | ||||
| class NotImplementedException extends \Exception | ||||
| { | ||||
|  | ||||
| }  | ||||
							
								
								
									
										13
									
								
								app/Exceptions/ValidationException.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								app/Exceptions/ValidationException.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| <?php | ||||
| namespace FireflyIII\Exceptions; | ||||
|  | ||||
| /** | ||||
|  * Class ValidationExceptions | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Exception | ||||
|  */ | ||||
| class ValidationException extends \Exception | ||||
| { | ||||
|  | ||||
| }  | ||||
							
								
								
									
										52
									
								
								app/Generator/Chart/Account/AccountChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								app/Generator/Chart/Account/AccountChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Generator\Chart\Account; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Models\Account; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * Interface AccountChartGenerator | ||||
|  * | ||||
|  * @package FireflyIII\Generator\Chart\Account | ||||
|  */ | ||||
| interface AccountChartGenerator | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function all(Collection $accounts, Carbon $start, Carbon $end); | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function frontpage(Collection $accounts, Carbon $start, Carbon $end); | ||||
|  | ||||
|     /** | ||||
|      * @param Account $account | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function single(Account $account, Carbon $start, Carbon $end); | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function expenseAccounts(Collection $accounts, Carbon $start, Carbon $end); | ||||
| } | ||||
							
								
								
									
										194
									
								
								app/Generator/Chart/Account/ChartJsAccountChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								app/Generator/Chart/Account/ChartJsAccountChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,194 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Generator\Chart\Account; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use Config; | ||||
| use FireflyIII\Models\Account; | ||||
| use Illuminate\Support\Collection; | ||||
| use Preferences; | ||||
| use Steam; | ||||
|  | ||||
| /** | ||||
|  * Class ChartJsAccountChartGenerator | ||||
|  * | ||||
|  * @package FireflyIII\Generator\Chart\Account | ||||
|  */ | ||||
| class ChartJsAccountChartGenerator implements AccountChartGenerator | ||||
| { | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function all(Collection $accounts, Carbon $start, Carbon $end) | ||||
|     { | ||||
|         return $this->frontpage($accounts, $start, $end); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function expenseAccounts(Collection $accounts, Carbon $start, Carbon $end) | ||||
|     { | ||||
|         $data = [ | ||||
|             'count'    => 1, | ||||
|             'labels'   => [], 'datasets' => [[ | ||||
|                                'label' => trans('firefly.spent'), | ||||
|                                'data'  => []]]]; | ||||
|  | ||||
|         bcscale(2); | ||||
|         $start->subDay(); | ||||
|         $ids           = $this->getIdsFromCollection($accounts); | ||||
|         $startBalances = Steam::balancesById($ids, $start); | ||||
|         $endBalances   = Steam::balancesById($ids, $end); | ||||
|  | ||||
|         $accounts->each( | ||||
|             function (Account $account) use ($startBalances, $endBalances) { | ||||
|                 $id                  = $account->id; | ||||
|                 $startBalance        = $this->isInArray($startBalances, $id); | ||||
|                 $endBalance          = $this->isInArray($endBalances, $id); | ||||
|                 $diff                = bcsub($endBalance, $startBalance); | ||||
|                 $account->difference = round($diff, 2); | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         $accounts = $accounts->sortByDesc( | ||||
|             function (Account $account) { | ||||
|                 return $account->difference; | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         foreach ($accounts as $account) { | ||||
|             if ($account->difference > 0) { | ||||
|                 $data['labels'][]              = $account->name; | ||||
|                 $data['datasets'][0]['data'][] = $account->difference; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $array | ||||
|      * @param $entryId | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     protected function isInArray($array, $entryId) | ||||
|     { | ||||
|         if (isset($array[$entryId])) { | ||||
|             return $array[$entryId]; | ||||
|         } | ||||
|  | ||||
|         return '0'; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function frontpage(Collection $accounts, Carbon $start, Carbon $end) | ||||
|     { | ||||
|         // language: | ||||
|         $language = Preferences::get('language', 'en')->data; | ||||
|         $format   = Config::get('firefly.monthAndDay.' . $language); | ||||
|         $data     = [ | ||||
|             'count'    => 0, | ||||
|             'labels'   => [], | ||||
|             'datasets' => [], | ||||
|         ]; | ||||
|         $current  = clone $start; | ||||
|         while ($current <= $end) { | ||||
|             $data['labels'][] = $current->formatLocalized($format); | ||||
|             $current->addDay(); | ||||
|         } | ||||
|  | ||||
|         foreach ($accounts as $account) { | ||||
|             $set     = [ | ||||
|                 'label'                => $account->name, | ||||
|                 'fillColor'            => 'rgba(220,220,220,0.2)', | ||||
|                 'strokeColor'          => 'rgba(220,220,220,1)', | ||||
|                 'pointColor'           => 'rgba(220,220,220,1)', | ||||
|                 'pointStrokeColor'     => '#fff', | ||||
|                 'pointHighlightFill'   => '#fff', | ||||
|                 'pointHighlightStroke' => 'rgba(220,220,220,1)', | ||||
|                 'data'                 => [], | ||||
|             ]; | ||||
|             $current = clone $start; | ||||
|             while ($current <= $end) { | ||||
|                 $set['data'][] = Steam::balance($account, $current); | ||||
|                 $current->addDay(); | ||||
|             } | ||||
|             $data['datasets'][] = $set; | ||||
|         } | ||||
|         $data['count'] = count($data['datasets']); | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Account $account | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function single(Account $account, Carbon $start, Carbon $end) | ||||
|     { | ||||
|         // language: | ||||
|         $language = Preferences::get('language', 'en')->data; | ||||
|         $format   = Config::get('firefly.monthAndDay.' . $language); | ||||
|  | ||||
|         $data = [ | ||||
|             'count'    => 1, | ||||
|             'labels'   => [], | ||||
|             'datasets' => [ | ||||
|                 [ | ||||
|                     'label' => $account->name, | ||||
|                     'data'  => [] | ||||
|                 ] | ||||
|             ], | ||||
|         ]; | ||||
|  | ||||
|         $current = clone $start; | ||||
|  | ||||
|         while ($end >= $current) { | ||||
|             $data['labels'][]              = $current->formatLocalized($format); | ||||
|             $data['datasets'][0]['data'][] = Steam::balance($account, $current); | ||||
|             $current->addDay(); | ||||
|         } | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $collection | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     protected function getIdsFromCollection(Collection $collection) | ||||
|     { | ||||
|         $ids = []; | ||||
|         foreach ($collection as $entry) { | ||||
|             $ids[] = $entry->id; | ||||
|         } | ||||
|  | ||||
|         return array_unique($ids); | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										32
									
								
								app/Generator/Chart/Bill/BillChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								app/Generator/Chart/Bill/BillChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| <?php | ||||
| namespace FireflyIII\Generator\Chart\Bill; | ||||
|  | ||||
|  | ||||
| use FireflyIII\Models\Bill; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * Interface BillChartGenerator | ||||
|  * | ||||
|  * @package FireflyIII\Generator\Chart\Bill | ||||
|  */ | ||||
| interface BillChartGenerator | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $paid | ||||
|      * @param Collection $unpaid | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function frontpage(Collection $paid, Collection $unpaid); | ||||
|  | ||||
|     /** | ||||
|      * @param Bill       $bill | ||||
|      * @param Collection $entries | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function single(Bill $bill, Collection $entries); | ||||
|  | ||||
| } | ||||
							
								
								
									
										114
									
								
								app/Generator/Chart/Bill/ChartJsBillChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								app/Generator/Chart/Bill/ChartJsBillChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,114 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Generator\Chart\Bill; | ||||
|  | ||||
| use Config; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Illuminate\Support\Collection; | ||||
| use Preferences; | ||||
|  | ||||
| /** | ||||
|  * Class ChartJsBillChartGenerator | ||||
|  * | ||||
|  * @package FireflyIII\Generator\Chart\Bill | ||||
|  */ | ||||
| class ChartJsBillChartGenerator implements BillChartGenerator | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $paid | ||||
|      * @param Collection $unpaid | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function frontpage(Collection $paid, Collection $unpaid) | ||||
|     { | ||||
|         $paidDescriptions   = []; | ||||
|         $paidAmount         = 0; | ||||
|         $unpaidDescriptions = []; | ||||
|         $unpaidAmount       = 0; | ||||
|         bcscale(2); | ||||
|  | ||||
|         /** @var TransactionJournal $entry */ | ||||
|         foreach ($paid as $entry) { // loop paid and create single entry: | ||||
|             $paidDescriptions[] = $entry->description; | ||||
|             $paidAmount         = bcadd($paidAmount, $entry->amount_positive); | ||||
|         } | ||||
|         /** @var Bill $entry */ | ||||
|         foreach ($unpaid as $entry) { // loop unpaid: | ||||
|             $description          = $entry[0]->name . ' (' . $entry[1]->format('jS M Y') . ')'; | ||||
|             $amount               = bcdiv(bcadd($entry[0]->amount_max, $entry[0]->amount_min), 2); | ||||
|             $unpaidDescriptions[] = $description; | ||||
|             $unpaidAmount         = bcadd($unpaidAmount, $amount); | ||||
|             unset($amount, $description); | ||||
|         } | ||||
|  | ||||
|         $data = [ | ||||
|             [ | ||||
|                 'value'     => $unpaidAmount, | ||||
|                 'color'     => 'rgba(53, 124, 165,0.7)', | ||||
|                 'highlight' => 'rgba(53, 124, 165,0.9)', | ||||
|                 'label'     => trans('firefly.unpaid'), | ||||
|             ], | ||||
|             [ | ||||
|                 'value'     => $paidAmount, | ||||
|                 'color'     => 'rgba(0, 141, 76, 0.7)', | ||||
|                 'highlight' => 'rgba(0, 141, 76, 0.9)', | ||||
|                 'label'     => trans('firefly.paid'), | ||||
|             ] | ||||
|         ]; | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Bill       $bill | ||||
|      * @param Collection $entries | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function single(Bill $bill, Collection $entries) | ||||
|     { | ||||
|         // language: | ||||
|         $language = Preferences::get('language', 'en')->data; | ||||
|         $format   = Config::get('firefly.month.' . $language); | ||||
|  | ||||
|         $data = [ | ||||
|             'count'    => 3, | ||||
|             'labels'   => [], | ||||
|             'datasets' => [], | ||||
|         ]; | ||||
|  | ||||
|         // dataset: max amount | ||||
|         // dataset: min amount | ||||
|         // dataset: actual amount | ||||
|  | ||||
|         $minAmount    = []; | ||||
|         $maxAmount    = []; | ||||
|         $actualAmount = []; | ||||
|         foreach ($entries as $entry) { | ||||
|             $data['labels'][] = $entry->date->formatLocalized($format); | ||||
|             $minAmount[]      = round($bill->amount_min, 2); | ||||
|             $maxAmount[]      = round($bill->amount_max, 2); | ||||
|             $actualAmount[]   = round(($entry->amount * -1), 2); | ||||
|         } | ||||
|  | ||||
|         $data['datasets'][] = [ | ||||
|             'label' => trans('firefly.minAmount'), | ||||
|             'data'  => $minAmount, | ||||
|         ]; | ||||
|         $data['datasets'][] = [ | ||||
|             'label' => trans('firefly.billEntry'), | ||||
|             'data'  => $actualAmount, | ||||
|         ]; | ||||
|         $data['datasets'][] = [ | ||||
|             'label' => trans('firefly.maxAmount'), | ||||
|             'data'  => $maxAmount, | ||||
|         ]; | ||||
|  | ||||
|         $data['count'] = count($data['datasets']); | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										43
									
								
								app/Generator/Chart/Budget/BudgetChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								app/Generator/Chart/Budget/BudgetChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Generator\Chart\Budget; | ||||
|  | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * Interface BudgetChartGenerator | ||||
|  * | ||||
|  * @package FireflyIII\Generator\Chart\Budget | ||||
|  */ | ||||
| interface BudgetChartGenerator | ||||
| { | ||||
|     /** | ||||
|      * @param Collection $entries | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function budget(Collection $entries); | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $entries | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function budgetLimit(Collection $entries); | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $entries | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function frontpage(Collection $entries); | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $budgets | ||||
|      * @param Collection $entries | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function year(Collection $budgets, Collection $entries); | ||||
|  | ||||
| } | ||||
							
								
								
									
										144
									
								
								app/Generator/Chart/Budget/ChartJsBudgetChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								app/Generator/Chart/Budget/ChartJsBudgetChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,144 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Generator\Chart\Budget; | ||||
|  | ||||
|  | ||||
| use Config; | ||||
| use Illuminate\Support\Collection; | ||||
| use Preferences; | ||||
|  | ||||
| /** | ||||
|  * Class ChartJsBudgetChartGenerator | ||||
|  * | ||||
|  * @package FireflyIII\Generator\Chart\Budget | ||||
|  */ | ||||
| class ChartJsBudgetChartGenerator implements BudgetChartGenerator | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $entries | ||||
|      * @param string     $dateFormat | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function budget(Collection $entries, $dateFormat = 'month') | ||||
|     { | ||||
|         // language: | ||||
|         $language = Preferences::get('language', 'en')->data; | ||||
|         $format   = Config::get('firefly.' . $dateFormat . '.' . $language); | ||||
|  | ||||
|         $data = [ | ||||
|             'labels'   => [], | ||||
|             'datasets' => [ | ||||
|                 [ | ||||
|                     'label' => 'Amount', | ||||
|                     'data'  => [], | ||||
|                 ] | ||||
|             ], | ||||
|         ]; | ||||
|  | ||||
|         /** @var array $entry */ | ||||
|         foreach ($entries as $entry) { | ||||
|             $data['labels'][]              = $entry[0]->formatLocalized($format); | ||||
|             $data['datasets'][0]['data'][] = $entry[1]; | ||||
|  | ||||
|         } | ||||
|  | ||||
|         $data['count'] = count($data['datasets']); | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @param Collection $entries | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function budgetLimit(Collection $entries) | ||||
|     { | ||||
|         return $this->budget($entries, 'monthAndDay'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $entries | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function frontpage(Collection $entries) | ||||
|     { | ||||
|         $data = [ | ||||
|             'count'    => 0, | ||||
|             'labels'   => [], | ||||
|             'datasets' => [], | ||||
|         ]; | ||||
|         // dataset: left | ||||
|         // dataset: spent | ||||
|         // dataset: overspent | ||||
|         $left      = []; | ||||
|         $spent     = []; | ||||
|         $overspent = []; | ||||
|         foreach ($entries as $entry) { | ||||
|             if ($entry[1] != 0 || $entry[2] != 0 || $entry[3] != 0) { | ||||
|                 $data['labels'][] = $entry[0]; | ||||
|                 $left[]           = round($entry[1], 2); | ||||
|                 $spent[]          = round($entry[2], 2); | ||||
|                 $overspent[]      = round($entry[3], 2); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $data['datasets'][] = [ | ||||
|             'label' => trans('firefly.left'), | ||||
|             'data'  => $left, | ||||
|         ]; | ||||
|         $data['datasets'][] = [ | ||||
|             'label' => trans('firefly.spent'), | ||||
|             'data'  => $spent, | ||||
|         ]; | ||||
|         $data['datasets'][] = [ | ||||
|             'label' => trans('firefly.overspent'), | ||||
|             'data'  => $overspent, | ||||
|         ]; | ||||
|  | ||||
|         $data['count'] = count($data['datasets']); | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $budgets | ||||
|      * @param Collection $entries | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function year(Collection $budgets, Collection $entries) | ||||
|     { | ||||
|         // language: | ||||
|         $language = Preferences::get('language', 'en')->data; | ||||
|         $format   = Config::get('firefly.month.' . $language); | ||||
|  | ||||
|         $data = [ | ||||
|             'labels'   => [], | ||||
|             'datasets' => [], | ||||
|         ]; | ||||
|  | ||||
|         foreach ($budgets as $budget) { | ||||
|             $data['labels'][] = $budget->name; | ||||
|         } | ||||
|         /** @var array $entry */ | ||||
|         foreach ($entries as $entry) { | ||||
|             $array = [ | ||||
|                 'label' => $entry[0]->formatLocalized($format), | ||||
|                 'data'  => [], | ||||
|             ]; | ||||
|             array_shift($entry); | ||||
|             $array['data']      = $entry; | ||||
|             $data['datasets'][] = $array; | ||||
|  | ||||
|         } | ||||
|         $data['count'] = count($data['datasets']); | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										52
									
								
								app/Generator/Chart/Category/CategoryChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								app/Generator/Chart/Category/CategoryChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Generator\Chart\Category; | ||||
|  | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * Interface CategoryChartGenerator | ||||
|  * | ||||
|  * @package FireflyIII\Generator\Chart\Category | ||||
|  */ | ||||
| interface CategoryChartGenerator | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $entries | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function all(Collection $entries); | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $entries | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function frontpage(Collection $entries); | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $entries | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function period(Collection $entries); | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $categories | ||||
|      * @param Collection $entries | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function spentInYear(Collection $categories, Collection $entries); | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $categories | ||||
|      * @param Collection $entries | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function earnedInYear(Collection $categories, Collection $entries); | ||||
| } | ||||
							
								
								
									
										161
									
								
								app/Generator/Chart/Category/ChartJsCategoryChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								app/Generator/Chart/Category/ChartJsCategoryChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,161 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Generator\Chart\Category; | ||||
|  | ||||
| use Config; | ||||
| use Illuminate\Support\Collection; | ||||
| use Preferences; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Class ChartJsCategoryChartGenerator | ||||
|  * | ||||
|  * @package FireflyIII\Generator\Chart\Category | ||||
|  */ | ||||
| class ChartJsCategoryChartGenerator implements CategoryChartGenerator | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $entries | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function all(Collection $entries) | ||||
|     { | ||||
|  | ||||
|  | ||||
|         $data = [ | ||||
|             'count'    => 2, | ||||
|             'labels'   => [], | ||||
|             'datasets' => [ | ||||
|                 [ | ||||
|                     'label' => trans('firefly.spent'), | ||||
|                     'data'  => [] | ||||
|                 ], | ||||
|                 [ | ||||
|                     'label' => trans('firefly.earned'), | ||||
|                     'data'  => [] | ||||
|                 ] | ||||
|             ], | ||||
|         ]; | ||||
|  | ||||
|         foreach ($entries as $entry) { | ||||
|             $data['labels'][] = $entry[1]; | ||||
|             $spent            = round($entry[2], 2); | ||||
|             $earned           = round($entry[3], 2); | ||||
|  | ||||
|             $data['datasets'][0]['data'][] = $spent == 0 ? null : $spent * -1; | ||||
|             $data['datasets'][1]['data'][] = $earned == 0 ? null : $earned; | ||||
|         } | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $entries | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function frontpage(Collection $entries) | ||||
|     { | ||||
|         $data = [ | ||||
|             'count'    => 1, | ||||
|             'labels'   => [], | ||||
|             'datasets' => [ | ||||
|                 [ | ||||
|                     'label' => trans('firefly.spent'), | ||||
|                     'data'  => [] | ||||
|                 ] | ||||
|             ], | ||||
|         ]; | ||||
|         foreach ($entries as $entry) { | ||||
|             if ($entry['sum'] != 0) { | ||||
|                 $data['labels'][]              = $entry['name']; | ||||
|                 $data['datasets'][0]['data'][] = round(($entry['sum'] * -1), 2); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @param Collection $entries | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function period(Collection $entries) | ||||
|     { | ||||
|         return $this->all($entries); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $categories | ||||
|      * @param Collection $entries | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function spentInYear(Collection $categories, Collection $entries) | ||||
|     { | ||||
|  | ||||
|         // language: | ||||
|         $language = Preferences::get('language', 'en')->data; | ||||
|         $format   = Config::get('firefly.month.' . $language); | ||||
|  | ||||
|         $data = [ | ||||
|             'count'    => 0, | ||||
|             'labels'   => [], | ||||
|             'datasets' => [], | ||||
|         ]; | ||||
|  | ||||
|         foreach ($categories as $category) { | ||||
|             $data['labels'][] = $category->name; | ||||
|         } | ||||
|  | ||||
|         foreach ($entries as $entry) { | ||||
|             $date = $entry[0]->formatLocalized($format); | ||||
|             array_shift($entry); | ||||
|             $data['count']++; | ||||
|             $data['datasets'][] = ['label' => $date, 'data' => $entry]; | ||||
|         } | ||||
|  | ||||
|         return $data; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $categories | ||||
|      * @param Collection $entries | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function earnedInYear(Collection $categories, Collection $entries) | ||||
|     { | ||||
|  | ||||
|         // language: | ||||
|         $language = Preferences::get('language', 'en')->data; | ||||
|         $format   = Config::get('firefly.month.' . $language); | ||||
|  | ||||
|         $data = [ | ||||
|             'count'    => 0, | ||||
|             'labels'   => [], | ||||
|             'datasets' => [], | ||||
|         ]; | ||||
|  | ||||
|         foreach ($categories as $category) { | ||||
|             $data['labels'][] = $category->name; | ||||
|         } | ||||
|  | ||||
|         foreach ($entries as $entry) { | ||||
|             $date = $entry[0]->formatLocalized($format); | ||||
|             array_shift($entry); | ||||
|             $data['count']++; | ||||
|             $data['datasets'][] = ['label' => $date, 'data' => $entry]; | ||||
|         } | ||||
|  | ||||
|         return $data; | ||||
|  | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,52 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Generator\Chart\PiggyBank; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use Config; | ||||
| use Illuminate\Support\Collection; | ||||
| use Preferences; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Class ChartJsPiggyBankChartGenerator | ||||
|  * | ||||
|  * @package FireflyIII\Generator\Chart\PiggyBank | ||||
|  */ | ||||
| class ChartJsPiggyBankChartGenerator implements PiggyBankChartGenerator | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $set | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function history(Collection $set) | ||||
|     { | ||||
|  | ||||
|         // language: | ||||
|         $language = Preferences::get('language', 'en')->data; | ||||
|         $format   = Config::get('firefly.monthAndDay.' . $language); | ||||
|  | ||||
|         $data = [ | ||||
|             'count'    => 1, | ||||
|             'labels'   => [], | ||||
|             'datasets' => [ | ||||
|                 [ | ||||
|                     'label' => 'Diff', | ||||
|                     'data'  => [] | ||||
|                 ] | ||||
|             ], | ||||
|         ]; | ||||
|         $sum  = '0'; | ||||
|         bcscale(2); | ||||
|         foreach ($set as $entry) { | ||||
|             $date                          = new Carbon($entry->date); | ||||
|             $sum                           = bcadd($sum, $entry->sum); | ||||
|             $data['labels'][]              = $date->formatLocalized($format); | ||||
|             $data['datasets'][0]['data'][] = round($sum, 2); | ||||
|         } | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										20
									
								
								app/Generator/Chart/PiggyBank/PiggyBankChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								app/Generator/Chart/PiggyBank/PiggyBankChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Generator\Chart\PiggyBank; | ||||
|  | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * Interface PiggyBankChartGenerator | ||||
|  * | ||||
|  * @package FireflyIII\Generator\Chart\PiggyBank | ||||
|  */ | ||||
| interface PiggyBankChartGenerator | ||||
| { | ||||
|     /** | ||||
|      * @param Collection $set | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function history(Collection $set); | ||||
| } | ||||
							
								
								
									
										83
									
								
								app/Generator/Chart/Report/ChartJsReportChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								app/Generator/Chart/Report/ChartJsReportChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Generator\Chart\Report; | ||||
|  | ||||
| use Config; | ||||
| use Illuminate\Support\Collection; | ||||
| use Preferences; | ||||
|  | ||||
| /** | ||||
|  * Class ChartJsReportChartGenerator | ||||
|  * | ||||
|  * @package FireflyIII\Generator\Chart\Report | ||||
|  */ | ||||
| class ChartJsReportChartGenerator implements ReportChartGenerator | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $entries | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function yearInOut(Collection $entries) | ||||
|     { | ||||
|         // language: | ||||
|         $language = Preferences::get('language', 'en')->data; | ||||
|         $format   = Config::get('firefly.month.' . $language); | ||||
|  | ||||
|         $data = [ | ||||
|             'count'    => 2, | ||||
|             'labels'   => [], | ||||
|             'datasets' => [ | ||||
|                 [ | ||||
|                     'label' => trans('firefly.income'), | ||||
|                     'data'  => [] | ||||
|                 ], | ||||
|                 [ | ||||
|                     'label' => trans('firefly.expenses'), | ||||
|                     'data'  => [] | ||||
|                 ] | ||||
|             ], | ||||
|         ]; | ||||
|  | ||||
|         foreach ($entries as $entry) { | ||||
|             $data['labels'][]              = $entry[0]->formatLocalized($format); | ||||
|             $data['datasets'][0]['data'][] = round($entry[1], 2); | ||||
|             $data['datasets'][1]['data'][] = round($entry[2], 2); | ||||
|         } | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $income | ||||
|      * @param string $expense | ||||
|      * @param int    $count | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function yearInOutSummarized($income, $expense, $count) | ||||
|     { | ||||
|  | ||||
|         $data                          = [ | ||||
|             'count'    => 2, | ||||
|             'labels'   => [trans('firefly.sum_of_year'), trans('firefly.average_of_year')], | ||||
|             'datasets' => [ | ||||
|                 [ | ||||
|                     'label' => trans('firefly.income'), | ||||
|                     'data'  => [] | ||||
|                 ], | ||||
|                 [ | ||||
|                     'label' => trans('firefly.expenses'), | ||||
|                     'data'  => [] | ||||
|                 ] | ||||
|             ], | ||||
|         ]; | ||||
|         $data['datasets'][0]['data'][] = round($income, 2); | ||||
|         $data['datasets'][1]['data'][] = round( $expense, 2); | ||||
|         $data['datasets'][0]['data'][] = round(($income / $count), 2); | ||||
|         $data['datasets'][1]['data'][] = round(( $expense / $count), 2); | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										31
									
								
								app/Generator/Chart/Report/ReportChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								app/Generator/Chart/Report/ReportChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Generator\Chart\Report; | ||||
|  | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * Interface ReportChartGenerator | ||||
|  * | ||||
|  * @package FireflyIII\Generator\Chart\Report | ||||
|  */ | ||||
| interface ReportChartGenerator | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $entries | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function yearInOut(Collection $entries); | ||||
|  | ||||
|     /** | ||||
|      * @param string $income | ||||
|      * @param string $expense | ||||
|      * @param int    $count | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function yearInOutSummarized($income, $expense, $count); | ||||
|  | ||||
| } | ||||
							
								
								
									
										73
									
								
								app/Handlers/Events/ConnectJournalToPiggyBank.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								app/Handlers/Events/ConnectJournalToPiggyBank.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| <?php namespace FireflyIII\Handlers\Events; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Events\JournalCreated; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Models\PiggyBankEvent; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
|  | ||||
| /** | ||||
|  * Class ConnectJournalToPiggyBank | ||||
|  * | ||||
|  * @package FireflyIII\Handlers\Events | ||||
|  */ | ||||
| class ConnectJournalToPiggyBank | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * Create the event handler. | ||||
|      * | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         // | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Handle the event when journal is saved. | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * | ||||
|      * @param  JournalCreated $event | ||||
|      * | ||||
|      * @return boolean | ||||
|      */ | ||||
|     public function handle(JournalCreated $event) | ||||
|     { | ||||
|         /** @var TransactionJournal $journal */ | ||||
|         $journal     = $event->journal; | ||||
|         $piggyBankId = $event->piggyBankId; | ||||
|  | ||||
|         /** @var PiggyBank $piggyBank */ | ||||
|         $piggyBank = Auth::user()->piggybanks()->where('piggy_banks.id', $piggyBankId)->first(['piggy_banks.*']); | ||||
|  | ||||
|         if (is_null($piggyBank)) { | ||||
|             return false; | ||||
|         } | ||||
|         // update piggy bank rep for date of transaction journal. | ||||
|         $repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first(); | ||||
|         if (is_null($repetition)) { | ||||
|             return false; | ||||
|         } | ||||
|         bcscale(2); | ||||
|  | ||||
|         $amount = $journal->amount_positive; | ||||
|         // if piggy account matches source account, the amount is positive | ||||
|         if ($piggyBank->account_id == $journal->source_account->id) { | ||||
|             $amount = $amount * -1; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         $repetition->currentamount = bcadd($repetition->currentamount, $amount); | ||||
|         $repetition->save(); | ||||
|  | ||||
|         PiggyBankEvent::create(['piggy_bank_id' => $piggyBank->id, 'transaction_journal_id' => $journal->id, 'date' => $journal->date, 'amount' => $amount]); | ||||
|  | ||||
|         return true; | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										52
									
								
								app/Handlers/Events/RescanJournal.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								app/Handlers/Events/RescanJournal.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| <?php namespace FireflyIII\Handlers\Events; | ||||
|  | ||||
| use FireflyIII\Events\JournalSaved; | ||||
| use Log; | ||||
|  | ||||
| /** | ||||
|  * Class RescanJournal | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Handlers\Events | ||||
|  */ | ||||
| class RescanJournal | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * Create the event handler. | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         // | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Handle the event. | ||||
|      * | ||||
|      * @param  JournalSaved $event | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function handle(JournalSaved $event) | ||||
|     { | ||||
|         $journal = $event->journal; | ||||
|  | ||||
|         Log::debug('Triggered saved event for journal #' . $journal->id . ' (' . $journal->description . ')'); | ||||
|  | ||||
|         /** @var \FireflyIII\Repositories\Bill\BillRepositoryInterface $repository */ | ||||
|         $repository = app('FireflyIII\Repositories\Bill\BillRepositoryInterface'); | ||||
|         $list       = $journal->user->bills()->where('active', 1)->where('automatch', 1)->get(); | ||||
|  | ||||
|         Log::debug('Found ' . $list->count() . ' bills to check.'); | ||||
|  | ||||
|         /** @var \FireflyIII\Models\Bill $bill */ | ||||
|         foreach ($list as $bill) { | ||||
|             Log::debug('Now calling bill #' . $bill->id . ' (' . $bill->name . ')'); | ||||
|             $repository->scan($bill, $journal); | ||||
|         } | ||||
|  | ||||
|         Log::debug('Done!'); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										65
									
								
								app/Handlers/Events/UpdateJournalConnection.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								app/Handlers/Events/UpdateJournalConnection.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| <?php namespace FireflyIII\Handlers\Events; | ||||
|  | ||||
| use FireflyIII\Events\JournalSaved; | ||||
| use FireflyIII\Models\PiggyBankEvent; | ||||
| use FireflyIII\Models\PiggyBankRepetition; | ||||
|  | ||||
| /** | ||||
|  * Class UpdateJournalConnection | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Handlers\Events | ||||
|  */ | ||||
| class UpdateJournalConnection | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * Create the event handler. | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         // | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Handle the event. | ||||
|      * | ||||
|      * @param  JournalSaved $event | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function handle(JournalSaved $event) | ||||
|     { | ||||
|         $journal = $event->journal; | ||||
|  | ||||
|         // get the event connected to this journal: | ||||
|         /** @var PiggyBankEvent $event */ | ||||
|         $event = PiggyBankEvent::where('transaction_journal_id', $journal->id)->first(); | ||||
|         if (is_null($event)) { | ||||
|             return; | ||||
|         } | ||||
|         $piggyBank  = $event->piggyBank()->first(); | ||||
|         $repetition = null; | ||||
|         if ($piggyBank) { | ||||
|             /** @var PiggyBankRepetition $repetition */ | ||||
|             $repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first(); | ||||
|         } | ||||
|  | ||||
|         if (is_null($repetition)) { | ||||
|             return; | ||||
|         } | ||||
|         bcscale(2); | ||||
|  | ||||
|         $amount = $journal->amount; | ||||
|         $diff   = bcsub($amount, $event->amount); // update current repetition | ||||
|  | ||||
|         $repetition->currentamount = bcadd($repetition->currentamount, $diff); | ||||
|         $repetition->save(); | ||||
|  | ||||
|  | ||||
|         $event->amount = $amount; | ||||
|         $event->save(); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										222
									
								
								app/Helpers/Attachments/AttachmentHelper.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										222
									
								
								app/Helpers/Attachments/AttachmentHelper.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,222 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Attachments; | ||||
|  | ||||
| use Auth; | ||||
| use Config; | ||||
| use Crypt; | ||||
| use FireflyIII\Models\Attachment; | ||||
| use Illuminate\Database\Eloquent\Model; | ||||
| use Illuminate\Support\MessageBag; | ||||
| use Input; | ||||
| use Symfony\Component\HttpFoundation\File\UploadedFile; | ||||
|  | ||||
| /** | ||||
|  * Class AttachmentHelper | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Attachments | ||||
|  */ | ||||
| class AttachmentHelper implements AttachmentHelperInterface | ||||
| { | ||||
|  | ||||
|     /** @var int */ | ||||
|     protected $maxUploadSize; | ||||
|     /** @var array */ | ||||
|     protected $allowedMimes; | ||||
|     /** @var MessageBag */ | ||||
|     public $errors; | ||||
|     /** @var MessageBag */ | ||||
|     public $messages; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->maxUploadSize = Config::get('firefly.maxUploadSize'); | ||||
|         $this->allowedMimes  = Config::get('firefly.allowedMimes'); | ||||
|         $this->errors        = new MessageBag; | ||||
|         $this->messages      = new MessageBag; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Attachment $attachment | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getAttachmentLocation(Attachment $attachment) | ||||
|     { | ||||
|         $path = storage_path('upload') . DIRECTORY_SEPARATOR . 'at-' . $attachment->id . '.data'; | ||||
|  | ||||
|         return $path; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Model $model | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function saveAttachmentsForModel(Model $model) | ||||
|     { | ||||
|         $files = Input::file('attachments'); | ||||
|  | ||||
|         if (is_array($files)) { | ||||
|             foreach ($files as $entry) { | ||||
|                 if (!is_null($entry)) { | ||||
|                     $this->processFile($entry, $model); | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             $this->processFile($files, $model); | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param UploadedFile $file | ||||
|      * @param Model        $model | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     protected function hasFile(UploadedFile $file, Model $model) | ||||
|     { | ||||
|         $md5   = md5_file($file->getRealPath()); | ||||
|         $name  = $file->getClientOriginalName(); | ||||
|         $class = get_class($model); | ||||
|         $count = Auth::user()->attachments()->where('md5', $md5)->where('attachable_id', $model->id)->where('attachable_type', $class)->count(); | ||||
|  | ||||
|         if ($count > 0) { | ||||
|             $msg = trans('validation.file_already_attached', ['name' => $name]); | ||||
|             $this->errors->add('attachments', $msg); | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param UploadedFile $file | ||||
|      * @param Model        $model | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     protected function validateUpload(UploadedFile $file, Model $model) | ||||
|     { | ||||
|         if (!$this->validMime($file)) { | ||||
|             return false; | ||||
|         } | ||||
|         if (!$this->validSize($file)) { | ||||
|             return false; | ||||
|         } | ||||
|         if ($this->hasFile($file, $model)) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param UploadedFile $file | ||||
|      * @param Model        $model | ||||
|      * | ||||
|      * @return bool|Attachment | ||||
|      */ | ||||
|     protected function processFile(UploadedFile $file, Model $model) | ||||
|     { | ||||
|         $validation = $this->validateUpload($file, $model); | ||||
|         if ($validation === false) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $attachment = new Attachment; // create Attachment object. | ||||
|         $attachment->user()->associate(Auth::user()); | ||||
|         $attachment->attachable()->associate($model); | ||||
|         $attachment->md5      = md5_file($file->getRealPath()); | ||||
|         $attachment->filename = $file->getClientOriginalName(); | ||||
|         $attachment->mime     = $file->getMimeType(); | ||||
|         $attachment->size     = $file->getSize(); | ||||
|         $attachment->uploaded = 0; | ||||
|         $attachment->save(); | ||||
|  | ||||
|         $path      = $file->getRealPath(); // encrypt and move file to storage. | ||||
|         $content   = file_get_contents($path); | ||||
|         $encrypted = Crypt::encrypt($content); | ||||
|  | ||||
|         // store it: | ||||
|         $upload = $this->getAttachmentLocation($attachment); | ||||
|         if (is_writable(dirname($upload))) { | ||||
|             file_put_contents($upload, $encrypted); | ||||
|         } | ||||
|  | ||||
|         $attachment->uploaded = 1; // update attachment | ||||
|         $attachment->save(); | ||||
|  | ||||
|         $name = e($file->getClientOriginalName()); // add message: | ||||
|         $msg  = trans('validation.file_attached', ['name' => $name]); | ||||
|         $this->messages->add('attachments', $msg); | ||||
|  | ||||
|         // return it. | ||||
|         return $attachment; | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param UploadedFile $file | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     protected function validMime(UploadedFile $file) | ||||
|     { | ||||
|         $mime = e($file->getMimeType()); | ||||
|         $name = e($file->getClientOriginalName()); | ||||
|  | ||||
|         if (!in_array($mime, $this->allowedMimes)) { | ||||
|             $msg = trans('validation.file_invalid_mime', ['name' => $name, 'mime' => $mime]); | ||||
|             $this->errors->add('attachments', $msg); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param UploadedFile $file | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     protected function validSize(UploadedFile $file) | ||||
|     { | ||||
|         $size = $file->getSize(); | ||||
|         $name = e($file->getClientOriginalName()); | ||||
|         if ($size > $this->maxUploadSize) { | ||||
|             $msg = trans('validation.file_too_large', ['name' => $name]); | ||||
|             $this->errors->add('attachments', $msg); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return MessageBag | ||||
|      */ | ||||
|     public function getErrors() | ||||
|     { | ||||
|         return $this->errors; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return MessageBag | ||||
|      */ | ||||
|     public function getMessages() | ||||
|     { | ||||
|         return $this->messages; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										41
									
								
								app/Helpers/Attachments/AttachmentHelperInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								app/Helpers/Attachments/AttachmentHelperInterface.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Attachments; | ||||
|  | ||||
| use FireflyIII\Models\Attachment; | ||||
| use Illuminate\Database\Eloquent\Model; | ||||
| use Illuminate\Support\MessageBag; | ||||
|  | ||||
| /** | ||||
|  * Interface AttachmentHelperInterface | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Attachments | ||||
|  */ | ||||
| interface AttachmentHelperInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param Model $model | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function saveAttachmentsForModel(Model $model); | ||||
|  | ||||
|     /** | ||||
|      * @return MessageBag | ||||
|      */ | ||||
|     public function getErrors(); | ||||
|  | ||||
|     /** | ||||
|      * @return MessageBag | ||||
|      */ | ||||
|     public function getMessages(); | ||||
|  | ||||
|     /** | ||||
|      * @param Attachment $attachment | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function getAttachmentLocation(Attachment $attachment); | ||||
|  | ||||
| } | ||||
							
								
								
									
										90
									
								
								app/Helpers/Collection/Account.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								app/Helpers/Collection/Account.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,90 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * Class Account | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class Account | ||||
| { | ||||
|  | ||||
|     /** @var Collection */ | ||||
|     protected $accounts; | ||||
|     /** @var float */ | ||||
|     protected $difference; | ||||
|     /** @var float */ | ||||
|     protected $end; | ||||
|     /** @var float */ | ||||
|     protected $start; | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Support\Collection | ||||
|      */ | ||||
|     public function getAccounts() | ||||
|     { | ||||
|         return $this->accounts; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param \Illuminate\Support\Collection $accounts | ||||
|      */ | ||||
|     public function setAccounts($accounts) | ||||
|     { | ||||
|         $this->accounts = $accounts; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return float | ||||
|      */ | ||||
|     public function getDifference() | ||||
|     { | ||||
|         return $this->difference; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $difference | ||||
|      */ | ||||
|     public function setDifference($difference) | ||||
|     { | ||||
|         $this->difference = $difference; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return float | ||||
|      */ | ||||
|     public function getEnd() | ||||
|     { | ||||
|         return $this->end; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $end | ||||
|      */ | ||||
|     public function setEnd($end) | ||||
|     { | ||||
|         $this->end = $end; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return float | ||||
|      */ | ||||
|     public function getStart() | ||||
|     { | ||||
|         return $this->start; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $start | ||||
|      */ | ||||
|     public function setStart($start) | ||||
|     { | ||||
|         $this->start = $start; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										64
									
								
								app/Helpers/Collection/Balance.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								app/Helpers/Collection/Balance.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * | ||||
|  * Class Balance | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class Balance | ||||
| { | ||||
|  | ||||
|     /** @var  BalanceHeader */ | ||||
|     protected $balanceHeader; | ||||
|  | ||||
|     /** @var  Collection */ | ||||
|     protected $balanceLines; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->balanceLines = new Collection; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BalanceLine $line | ||||
|      */ | ||||
|     public function addBalanceLine(BalanceLine $line) | ||||
|     { | ||||
|         $this->balanceLines->push($line); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return BalanceHeader | ||||
|      */ | ||||
|     public function getBalanceHeader() | ||||
|     { | ||||
|         return $this->balanceHeader; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BalanceHeader $balanceHeader | ||||
|      */ | ||||
|     public function setBalanceHeader($balanceHeader) | ||||
|     { | ||||
|         $this->balanceHeader = $balanceHeader; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Support\Collection | ||||
|      */ | ||||
|     public function getBalanceLines() | ||||
|     { | ||||
|         return $this->balanceLines; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										74
									
								
								app/Helpers/Collection/BalanceEntry.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								app/Helpers/Collection/BalanceEntry.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use FireflyIII\Models\Account as AccountModel; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * | ||||
|  * Class BalanceEntry | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class BalanceEntry | ||||
| { | ||||
|  | ||||
|  | ||||
|     /** @var  AccountModel */ | ||||
|     protected $account; | ||||
|     /** @var float */ | ||||
|     protected $left = 0.0; | ||||
|     /** @var float */ | ||||
|     protected $spent = 0.0; | ||||
|  | ||||
|     /** | ||||
|      * @return AccountModel | ||||
|      */ | ||||
|     public function getAccount() | ||||
|     { | ||||
|         return $this->account; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param AccountModel $account | ||||
|      */ | ||||
|     public function setAccount($account) | ||||
|     { | ||||
|         $this->account = $account; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return float | ||||
|      */ | ||||
|     public function getLeft() | ||||
|     { | ||||
|         return $this->left; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $left | ||||
|      */ | ||||
|     public function setLeft($left) | ||||
|     { | ||||
|         $this->left = $left; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return float | ||||
|      */ | ||||
|     public function getSpent() | ||||
|     { | ||||
|         return $this->spent; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $spent | ||||
|      */ | ||||
|     public function setSpent($spent) | ||||
|     { | ||||
|         $this->spent = $spent; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										46
									
								
								app/Helpers/Collection/BalanceHeader.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								app/Helpers/Collection/BalanceHeader.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use FireflyIII\Models\Account as AccountModel; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * | ||||
|  * Class BalanceHeader | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class BalanceHeader | ||||
| { | ||||
|  | ||||
|     /** @var  Collection */ | ||||
|     protected $accounts; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->accounts = new Collection; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param AccountModel $account | ||||
|      */ | ||||
|     public function addAccount(AccountModel $account) | ||||
|     { | ||||
|         $this->accounts->push($account); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getAccounts() | ||||
|     { | ||||
|         return $this->accounts; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										173
									
								
								app/Helpers/Collection/BalanceLine.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								app/Helpers/Collection/BalanceLine.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,173 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use FireflyIII\Models\Budget as BudgetModel; | ||||
| use FireflyIII\Models\LimitRepetition; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * | ||||
|  * Class BalanceLine | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class BalanceLine | ||||
| { | ||||
|  | ||||
|     const ROLE_DEFAULTROLE = 1; | ||||
|     const ROLE_TAGROLE     = 2; | ||||
|     const ROLE_DIFFROLE    = 3; | ||||
|  | ||||
|     /** @var  Collection */ | ||||
|     protected $balanceEntries; | ||||
|  | ||||
|     /** @var BudgetModel */ | ||||
|     protected $budget; | ||||
|  | ||||
|     /** @var  LimitRepetition */ | ||||
|     protected $repetition; | ||||
|  | ||||
|     protected $role = self::ROLE_DEFAULTROLE; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->balanceEntries = new Collection; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BalanceEntry $balanceEntry | ||||
|      */ | ||||
|     public function addBalanceEntry(BalanceEntry $balanceEntry) | ||||
|     { | ||||
|         $this->balanceEntries->push($balanceEntry); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getTitle() | ||||
|     { | ||||
|         if ($this->getBudget() instanceof BudgetModel) { | ||||
|             return $this->getBudget()->name; | ||||
|         } | ||||
|         if ($this->getRole() == self::ROLE_DEFAULTROLE) { | ||||
|             return trans('firefly.noBudget'); | ||||
|         } | ||||
|         if ($this->getRole() == self::ROLE_TAGROLE) { | ||||
|             return trans('firefly.coveredWithTags'); | ||||
|         } | ||||
|         if ($this->getRole() == self::ROLE_DIFFROLE) { | ||||
|             return trans('firefly.leftUnbalanced'); | ||||
|         } | ||||
|  | ||||
|         return ''; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return BudgetModel | ||||
|      */ | ||||
|     public function getBudget() | ||||
|     { | ||||
|         return $this->budget; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BudgetModel $budget | ||||
|      */ | ||||
|     public function setBudget($budget) | ||||
|     { | ||||
|         $this->budget = $budget; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return int | ||||
|      */ | ||||
|     public function getRole() | ||||
|     { | ||||
|         return $this->role; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param int $role | ||||
|      */ | ||||
|     public function setRole($role) | ||||
|     { | ||||
|         $this->role = $role; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * If a BalanceLine has a budget/repetition, each BalanceEntry in this BalanceLine | ||||
|      * should have a "spent" value, which is the amount of money that has been spent | ||||
|      * on the given budget/repetition. If you subtract all those amounts from the budget/repetition's | ||||
|      * total amount, this is returned: | ||||
|      * | ||||
|      * @return float | ||||
|      */ | ||||
|     public function leftOfRepetition() | ||||
|     { | ||||
|         $start = $this->getRepetition() ? $this->getRepetition()->amount : 0; | ||||
|         /** @var BalanceEntry $balanceEntry */ | ||||
|         foreach ($this->getBalanceEntries() as $balanceEntry) { | ||||
|             $start += $balanceEntry->getSpent(); | ||||
|         } | ||||
|  | ||||
|         return $start; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return LimitRepetition | ||||
|      */ | ||||
|     public function getRepetition() | ||||
|     { | ||||
|         return $this->repetition; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param LimitRepetition $repetition | ||||
|      */ | ||||
|     public function setRepetition($repetition) | ||||
|     { | ||||
|         $this->repetition = $repetition; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getBalanceEntries() | ||||
|     { | ||||
|         return $this->balanceEntries; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $balanceEntries | ||||
|      */ | ||||
|     public function setBalanceEntries($balanceEntries) | ||||
|     { | ||||
|         $this->balanceEntries = $balanceEntries; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * If the BalanceEntries for a BalanceLine have a "left" value, the amount | ||||
|      * of money left in the entire BalanceLine is returned here: | ||||
|      * | ||||
|      * @return float | ||||
|      */ | ||||
|     public function sumOfLeft() | ||||
|     { | ||||
|         $sum = '0'; | ||||
|         bcscale(2); | ||||
|         /** @var BalanceEntry $balanceEntry */ | ||||
|         foreach ($this->getBalanceEntries() as $balanceEntry) { | ||||
|             $sum = bcadd($sum, $balanceEntry->getLeft()); | ||||
|         } | ||||
|  | ||||
|         return $sum; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										56
									
								
								app/Helpers/Collection/Bill.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								app/Helpers/Collection/Bill.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
|  | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * Class Bill | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class Bill | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @var Collection | ||||
|      */ | ||||
|     protected $bills; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->bills = new Collection; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BillLine $bill | ||||
|      */ | ||||
|     public function addBill(BillLine $bill) | ||||
|     { | ||||
|         $this->bills->push($bill); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getBills() | ||||
|     { | ||||
|         $set = $this->bills->sortBy( | ||||
|             function (BillLine $bill) { | ||||
|                 $active = intval($bill->getBill()->active) == 0 ? 1 : 0; | ||||
|                 $name   = $bill->getBill()->name; | ||||
|  | ||||
|                 return $active . $name; | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|  | ||||
|         return $set; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										127
									
								
								app/Helpers/Collection/BillLine.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								app/Helpers/Collection/BillLine.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,127 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use FireflyIII\Models\Bill as BillModel; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * | ||||
|  * Class BillLine | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class BillLine | ||||
| { | ||||
|  | ||||
|     /** @var  bool */ | ||||
|     protected $active; | ||||
|     /** @var  string */ | ||||
|     protected $amount; | ||||
|     /** @var  BillModel */ | ||||
|     protected $bill; | ||||
|     /** @var  bool */ | ||||
|     protected $hit; | ||||
|     /** @var  string */ | ||||
|     protected $max; | ||||
|     /** @var  string */ | ||||
|     protected $min; | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getAmount() | ||||
|     { | ||||
|         return $this->amount; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $amount | ||||
|      */ | ||||
|     public function setAmount($amount) | ||||
|     { | ||||
|         $this->amount = $amount; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return BillModel | ||||
|      */ | ||||
|     public function getBill() | ||||
|     { | ||||
|         return $this->bill; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BillModel $bill | ||||
|      */ | ||||
|     public function setBill($bill) | ||||
|     { | ||||
|         $this->bill = $bill; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getMax() | ||||
|     { | ||||
|         return $this->max; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $max | ||||
|      */ | ||||
|     public function setMax($max) | ||||
|     { | ||||
|         $this->max = $max; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getMin() | ||||
|     { | ||||
|         return $this->min; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $min | ||||
|      */ | ||||
|     public function setMin($min) | ||||
|     { | ||||
|         $this->min = $min; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return boolean | ||||
|      */ | ||||
|     public function isActive() | ||||
|     { | ||||
|         return $this->active; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param boolean $active | ||||
|      */ | ||||
|     public function setActive($active) | ||||
|     { | ||||
|         $this->active = $active; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return boolean | ||||
|      */ | ||||
|     public function isHit() | ||||
|     { | ||||
|         return $this->hit; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param boolean $hit | ||||
|      */ | ||||
|     public function setHit($hit) | ||||
|     { | ||||
|         $this->hit = $hit; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										156
									
								
								app/Helpers/Collection/Budget.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								app/Helpers/Collection/Budget.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,156 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * | ||||
|  * Class Budget | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class Budget | ||||
| { | ||||
|     /** @var  Collection */ | ||||
|     protected $budgetLines; | ||||
|     /** @var string */ | ||||
|     protected $budgeted = '0'; | ||||
|     /** @var string */ | ||||
|     protected $left = '0'; | ||||
|     /** @var string */ | ||||
|     protected $overspent = '0'; | ||||
|     /** @var string */ | ||||
|     protected $spent = '0'; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->budgetLines = new Collection; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BudgetLine $budgetLine | ||||
|      */ | ||||
|     public function addBudgetLine(BudgetLine $budgetLine) | ||||
|     { | ||||
|         $this->budgetLines->push($budgetLine); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $add | ||||
|      */ | ||||
|     public function addBudgeted($add) | ||||
|     { | ||||
|         $add = strval(round($add, 2)); | ||||
|         bcscale(2); | ||||
|         $this->budgeted = bcadd($this->budgeted, $add); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $add | ||||
|      */ | ||||
|     public function addLeft($add) | ||||
|     { | ||||
|         $add = strval(round($add, 2)); | ||||
|         bcscale(2); | ||||
|         $this->left = bcadd($this->left, $add); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $add | ||||
|      */ | ||||
|     public function addOverspent($add) | ||||
|     { | ||||
|         $add = strval(round($add, 2)); | ||||
|         bcscale(2); | ||||
|         $this->overspent = bcadd($this->overspent, $add); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $add | ||||
|      */ | ||||
|     public function addSpent($add) | ||||
|     { | ||||
|         $add = strval(round($add, 2)); | ||||
|         bcscale(2); | ||||
|         $this->spent = bcadd($this->spent, $add); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Support\Collection | ||||
|      */ | ||||
|     public function getBudgetLines() | ||||
|     { | ||||
|         return $this->budgetLines; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getBudgeted() | ||||
|     { | ||||
|         return $this->budgeted; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $budgeted | ||||
|      */ | ||||
|     public function setBudgeted($budgeted) | ||||
|     { | ||||
|         $this->budgeted = $budgeted; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getLeft() | ||||
|     { | ||||
|         return $this->left; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $left | ||||
|      */ | ||||
|     public function setLeft($left) | ||||
|     { | ||||
|         $this->left = $left; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getOverspent() | ||||
|     { | ||||
|         return $this->overspent; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $overspent | ||||
|      */ | ||||
|     public function setOverspent($overspent) | ||||
|     { | ||||
|         $this->overspent = strval(round($overspent, 2)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getSpent() | ||||
|     { | ||||
|         return $this->spent; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $spent | ||||
|      */ | ||||
|     public function setSpent($spent) | ||||
|     { | ||||
|         $this->spent = strval(round($spent, 2)); | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										128
									
								
								app/Helpers/Collection/BudgetLine.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								app/Helpers/Collection/BudgetLine.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use FireflyIII\Models\Budget as BudgetModel; | ||||
| use FireflyIII\Models\LimitRepetition; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * | ||||
|  * Class BudgetLine | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class BudgetLine | ||||
| { | ||||
|  | ||||
|     /** @var  BudgetModel */ | ||||
|     protected $budget; | ||||
|     /** @var float */ | ||||
|     protected $budgeted = 0; | ||||
|     /** @var float */ | ||||
|     protected $left = 0; | ||||
|     /** @var float */ | ||||
|     protected $overspent = 0; | ||||
|     /** @var  LimitRepetition */ | ||||
|     protected $repetition; | ||||
|     /** @var float */ | ||||
|     protected $spent = 0; | ||||
|  | ||||
|     /** | ||||
|      * @return BudgetModel | ||||
|      */ | ||||
|     public function getBudget() | ||||
|     { | ||||
|         return $this->budget; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BudgetModel $budget | ||||
|      */ | ||||
|     public function setBudget($budget) | ||||
|     { | ||||
|         $this->budget = $budget; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return float | ||||
|      */ | ||||
|     public function getBudgeted() | ||||
|     { | ||||
|         return $this->budgeted; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $budgeted | ||||
|      */ | ||||
|     public function setBudgeted($budgeted) | ||||
|     { | ||||
|         $this->budgeted = $budgeted; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return float | ||||
|      */ | ||||
|     public function getLeft() | ||||
|     { | ||||
|         return $this->left; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $left | ||||
|      */ | ||||
|     public function setLeft($left) | ||||
|     { | ||||
|         $this->left = $left; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return float | ||||
|      */ | ||||
|     public function getOverspent() | ||||
|     { | ||||
|         return $this->overspent; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $overspent | ||||
|      */ | ||||
|     public function setOverspent($overspent) | ||||
|     { | ||||
|         $this->overspent = $overspent; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return LimitRepetition | ||||
|      */ | ||||
|     public function getRepetition() | ||||
|     { | ||||
|         return $this->repetition; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param LimitRepetition $repetition | ||||
|      */ | ||||
|     public function setRepetition($repetition) | ||||
|     { | ||||
|         $this->repetition = $repetition; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return float | ||||
|      */ | ||||
|     public function getSpent() | ||||
|     { | ||||
|         return $this->spent; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $spent | ||||
|      */ | ||||
|     public function setSpent($spent) | ||||
|     { | ||||
|         $this->spent = $spent; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										77
									
								
								app/Helpers/Collection/Category.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								app/Helpers/Collection/Category.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use FireflyIII\Models\Category as CategoryModel; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * | ||||
|  * Class Category | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class Category | ||||
| { | ||||
|  | ||||
|     /** @var  Collection */ | ||||
|     protected $categories; | ||||
|     /** @var string */ | ||||
|     protected $total = '0'; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->categories = new Collection; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param CategoryModel $category | ||||
|      */ | ||||
|     public function addCategory(CategoryModel $category) | ||||
|     { | ||||
|         // spent is minus zero for an expense report: | ||||
|         if ($category->spent < 0) { | ||||
|             $this->categories->push($category); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $add | ||||
|      */ | ||||
|     public function addTotal($add) | ||||
|     { | ||||
|         $add = strval(round($add, 2)); | ||||
|         bcscale(2); | ||||
|         $this->total = bcadd($this->total, $add); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getCategories() | ||||
|     { | ||||
|         $set = $this->categories->sortByDesc( | ||||
|             function (CategoryModel $category) { | ||||
|                 return $category->spent; | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|  | ||||
|         return $set; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getTotal() | ||||
|     { | ||||
|         return strval(round($this->total, 2)); | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										84
									
								
								app/Helpers/Collection/Expense.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								app/Helpers/Collection/Expense.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Illuminate\Support\Collection; | ||||
| use stdClass; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * | ||||
|  * Class Expense | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class Expense | ||||
| { | ||||
|     /** @var Collection */ | ||||
|     protected $expenses; | ||||
|     /** @var string */ | ||||
|     protected $total = '0'; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->expenses = new Collection; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionJournal $entry | ||||
|      */ | ||||
|     public function addOrCreateExpense(TransactionJournal $entry) | ||||
|     { | ||||
|         $accountId = $entry->account_id; | ||||
|         if (!$this->expenses->has($accountId)) { | ||||
|             $newObject         = new stdClass; | ||||
|             $newObject->amount = strval(round($entry->amount_positive, 2)); | ||||
|             $newObject->name   = $entry->name; | ||||
|             $newObject->count  = 1; | ||||
|             $newObject->id     = $accountId; | ||||
|             $this->expenses->put($accountId, $newObject); | ||||
|         } else { | ||||
|             bcscale(2); | ||||
|             $existing         = $this->expenses->get($accountId); | ||||
|             $existing->amount = bcadd($existing->amount, $entry->amount_positive); | ||||
|             $existing->count++; | ||||
|             $this->expenses->put($accountId, $existing); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $add | ||||
|      */ | ||||
|     public function addToTotal($add) | ||||
|     { | ||||
|         $add = strval(round($add, 2)); | ||||
|         bcscale(2); | ||||
|         $this->total = bcadd($this->total, $add); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getExpenses() | ||||
|     { | ||||
|         $set = $this->expenses->sortByDesc( | ||||
|             function (stdClass $object) { | ||||
|                 return $object->amount; | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         return $set; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getTotal() | ||||
|     { | ||||
|         return strval(round($this->total, 2)); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										88
									
								
								app/Helpers/Collection/Income.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								app/Helpers/Collection/Income.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Illuminate\Support\Collection; | ||||
| use stdClass; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * | ||||
|  * Class Income | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class Income | ||||
| { | ||||
|  | ||||
|     /** @var Collection */ | ||||
|     protected $incomes; | ||||
|     /** @var string */ | ||||
|     protected $total; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->incomes = new Collection; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionJournal $entry | ||||
|      */ | ||||
|     public function addOrCreateIncome(TransactionJournal $entry) | ||||
|     { | ||||
|  | ||||
|         $accountId = $entry->account_id; | ||||
|         if (!$this->incomes->has($accountId)) { | ||||
|             $newObject         = new stdClass; | ||||
|             $newObject->amount = strval(round($entry->amount_positive, 2)); | ||||
|             $newObject->name   = $entry->name; | ||||
|             $newObject->count  = 1; | ||||
|             $newObject->id     = $accountId; | ||||
|             $this->incomes->put($accountId, $newObject); | ||||
|         } else { | ||||
|             bcscale(2); | ||||
|             $existing         = $this->incomes->get($accountId); | ||||
|             $existing->amount = bcadd($existing->amount, $entry->amount_positive); | ||||
|             $existing->count++; | ||||
|             $this->incomes->put($accountId, $existing); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $add | ||||
|      */ | ||||
|     public function addToTotal($add) | ||||
|     { | ||||
|         $add = strval(round($add, 2)); | ||||
|         bcscale(2); | ||||
|         $this->total = bcadd($this->total, $add); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getIncomes() | ||||
|     { | ||||
|         $set = $this->incomes->sortByDesc( | ||||
|             function (stdClass $object) { | ||||
|                 return $object->amount; | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         return $set; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getTotal() | ||||
|     { | ||||
|         return strval(round($this->total, 2)); | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										38
									
								
								app/Helpers/Csv/Converter/AccountId.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								app/Helpers/Csv/Converter/AccountId.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| <?php | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Account; | ||||
| use Log; | ||||
|  | ||||
| /** | ||||
|  * Class AccountId | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class AccountId extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return Account | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         // is mapped? Then it's easy! | ||||
|         if (isset($this->mapped[$this->index][$this->value])) { | ||||
|  | ||||
|             /** @var Account $account */ | ||||
|             $account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]); | ||||
|         } else { | ||||
|  | ||||
|             /** @var Account $account */ | ||||
|             $account = Auth::user()->accounts()->find($this->value); | ||||
|  | ||||
|             if (!is_null($account)) { | ||||
|                 Log::debug('Found ' . $account->accountType->type . ' named "******" with ID: ' . $this->value . ' (not mapped) '); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $account; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										26
									
								
								app/Helpers/Csv/Converter/Amount.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								app/Helpers/Csv/Converter/Amount.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| use FireflyIII\Models\Account; | ||||
|  | ||||
| /** | ||||
|  * Class Amount | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class Amount extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return Account|null | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         if (is_numeric($this->value)) { | ||||
|             return $this->value; | ||||
|         } | ||||
|  | ||||
|         return 0; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										68
									
								
								app/Helpers/Csv/Converter/AssetAccountIban.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								app/Helpers/Csv/Converter/AssetAccountIban.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\AccountType; | ||||
|  | ||||
| /** | ||||
|  * Class AssetAccountIban | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class AssetAccountIban extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return Account|null | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         // is mapped? Then it's easy! | ||||
|         if (isset($this->mapped[$this->index][$this->value])) { | ||||
|             $account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]); | ||||
|  | ||||
|             return $account; | ||||
|         } | ||||
|         if (strlen($this->value) > 0) { | ||||
|             // find or create new account: | ||||
|             $account     = $this->findAccount(); | ||||
|             $accountType = AccountType::where('type', 'Asset account')->first(); | ||||
|  | ||||
|             if (is_null($account)) { | ||||
|                 // create it if doesn't exist. | ||||
|                 $account = Account::firstOrCreateEncrypted( | ||||
|                     [ | ||||
|                         'name'            => $this->value, | ||||
|                         'iban'            => $this->value, | ||||
|                         'user_id'         => Auth::user()->id, | ||||
|                         'account_type_id' => $accountType->id, | ||||
|                         'active'          => 1, | ||||
|                     ] | ||||
|                 ); | ||||
|             } | ||||
|  | ||||
|             return $account; | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Account|null | ||||
|      */ | ||||
|     protected function findAccount() | ||||
|     { | ||||
|         $set = Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->get(['accounts.*']); | ||||
|         /** @var Account $entry */ | ||||
|         foreach ($set as $entry) { | ||||
|             if ($entry->iban == $this->value) { | ||||
|  | ||||
|                 return $entry; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										51
									
								
								app/Helpers/Csv/Converter/AssetAccountName.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								app/Helpers/Csv/Converter/AssetAccountName.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\AccountType; | ||||
|  | ||||
| /** | ||||
|  * Class AssetAccountName | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class AssetAccountName extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return Account|null | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         // is mapped? Then it's easy! | ||||
|         if (isset($this->mapped[$this->index][$this->value])) { | ||||
|             $account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]); | ||||
|  | ||||
|             return $account; | ||||
|         } | ||||
|         // find or create new account: | ||||
|         $accountType = AccountType::where('type', 'Asset account')->first(); | ||||
|         $set         = Auth::user()->accounts()->accountTypeIn(['Asset account', 'Default account'])->get(); | ||||
|         /** @var Account $entry */ | ||||
|         foreach ($set as $entry) { | ||||
|             if ($entry->name == $this->value) { | ||||
|                 return $entry; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // create it if doesnt exist. | ||||
|         $account = Account::firstOrCreateEncrypted( | ||||
|             [ | ||||
|                 'name'            => $this->value, | ||||
|                 'iban'            => '', | ||||
|                 'user_id'         => Auth::user()->id, | ||||
|                 'account_type_id' => $accountType->id, | ||||
|                 'active'          => 1, | ||||
|             ] | ||||
|         ); | ||||
|  | ||||
|         return $account; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										122
									
								
								app/Helpers/Csv/Converter/BasicConverter.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								app/Helpers/Csv/Converter/BasicConverter.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,122 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| /** | ||||
|  * Class BasicConverter | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class BasicConverter | ||||
| { | ||||
|     /** @var  array */ | ||||
|     protected $data; | ||||
|     /** @var string */ | ||||
|     protected $field; | ||||
|     /** @var int */ | ||||
|     protected $index; | ||||
|     /** @var  array */ | ||||
|     protected $mapped; | ||||
|     /** @var string */ | ||||
|     protected $role; | ||||
|     /** @var string */ | ||||
|     protected $value; | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getData() | ||||
|     { | ||||
|         return $this->data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      */ | ||||
|     public function setData(array $data) | ||||
|     { | ||||
|         $this->data = $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getField() | ||||
|     { | ||||
|         return $this->field; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $field | ||||
|      */ | ||||
|     public function setField($field) | ||||
|     { | ||||
|         $this->field = $field; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return int | ||||
|      */ | ||||
|     public function getIndex() | ||||
|     { | ||||
|         return $this->index; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param int $index | ||||
|      */ | ||||
|     public function setIndex($index) | ||||
|     { | ||||
|         $this->index = $index; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getMapped() | ||||
|     { | ||||
|         return $this->mapped; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $mapped | ||||
|      */ | ||||
|     public function setMapped($mapped) | ||||
|     { | ||||
|         $this->mapped = $mapped; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getRole() | ||||
|     { | ||||
|         return $this->role; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $role | ||||
|      */ | ||||
|     public function setRole($role) | ||||
|     { | ||||
|         $this->role = $role; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getValue() | ||||
|     { | ||||
|         return $this->value; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $value | ||||
|      */ | ||||
|     public function setValue($value) | ||||
|     { | ||||
|         $this->value = $value; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										30
									
								
								app/Helpers/Csv/Converter/BillId.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								app/Helpers/Csv/Converter/BillId.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Bill; | ||||
|  | ||||
| /** | ||||
|  * Class BillId | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class BillId extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return Bill | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         // is mapped? Then it's easy! | ||||
|         if (isset($this->mapped[$this->index][$this->value])) { | ||||
|             $bill = Auth::user()->bills()->find($this->mapped[$this->index][$this->value]); | ||||
|         } else { | ||||
|             $bill = Auth::user()->bills()->find($this->value); | ||||
|         } | ||||
|  | ||||
|         return $bill; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										38
									
								
								app/Helpers/Csv/Converter/BillName.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								app/Helpers/Csv/Converter/BillName.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Bill; | ||||
|  | ||||
| /** | ||||
|  * Class BillName | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class BillName extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return Bill | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         $bill = null; | ||||
|         // is mapped? Then it's easy! | ||||
|         if (isset($this->mapped[$this->index][$this->value])) { | ||||
|             $bill = Auth::user()->bills()->find($this->mapped[$this->index][$this->value]); | ||||
|         } else { | ||||
|  | ||||
|             $bills = Auth::user()->bills()->get(); | ||||
|             /** @var Bill $bill */ | ||||
|             foreach ($bills as $bill) { | ||||
|                 if ($bill->name == $this->value) { | ||||
|                     return $bill; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $bill; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										29
									
								
								app/Helpers/Csv/Converter/BudgetId.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								app/Helpers/Csv/Converter/BudgetId.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| <?php | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Budget; | ||||
|  | ||||
| /** | ||||
|  * Class AccountId | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class BudgetId extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return Budget | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         // is mapped? Then it's easy! | ||||
|         if (isset($this->mapped[$this->index][$this->value])) { | ||||
|             $budget = Auth::user()->budgets()->find($this->mapped[$this->index][$this->value]); | ||||
|         } else { | ||||
|             $budget = Auth::user()->budgets()->find($this->value); | ||||
|         } | ||||
|  | ||||
|         return $budget; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										35
									
								
								app/Helpers/Csv/Converter/BudgetName.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								app/Helpers/Csv/Converter/BudgetName.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| <?php | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Budget; | ||||
|  | ||||
| /** | ||||
|  * Class BudgetName | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class BudgetName extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return Budget | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         // is mapped? Then it's easy! | ||||
|         if (isset($this->mapped[$this->index][$this->value])) { | ||||
|             $budget = Auth::user()->budgets()->find($this->mapped[$this->index][$this->value]); | ||||
|         } else { | ||||
|             $budget = Budget::firstOrCreateEncrypted( | ||||
|                 [ | ||||
|                     'name'    => $this->value, | ||||
|                     'user_id' => Auth::user()->id, | ||||
|                     'active'  => true, | ||||
|                 ] | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         return $budget; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										29
									
								
								app/Helpers/Csv/Converter/CategoryId.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								app/Helpers/Csv/Converter/CategoryId.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| <?php | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Category; | ||||
|  | ||||
| /** | ||||
|  * Class CategoryId | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class CategoryId extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return Category | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         // is mapped? Then it's easy! | ||||
|         if (isset($this->mapped[$this->index][$this->value])) { | ||||
|             $category = Auth::user()->categories()->find($this->mapped[$this->index][$this->value]); | ||||
|         } else { | ||||
|             $category = Auth::user()->categories()->find($this->value); | ||||
|         } | ||||
|  | ||||
|         return $category; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										34
									
								
								app/Helpers/Csv/Converter/CategoryName.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								app/Helpers/Csv/Converter/CategoryName.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| <?php | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Category; | ||||
|  | ||||
| /** | ||||
|  * Class CategoryName | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class CategoryName extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return Category | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         // is mapped? Then it's easy! | ||||
|         if (isset($this->mapped[$this->index][$this->value])) { | ||||
|             $category = Auth::user()->categories()->find($this->mapped[$this->index][$this->value]); | ||||
|         } else { | ||||
|             $category = Category::firstOrCreateEncrypted( | ||||
|                 [ | ||||
|                     'name'    => $this->value, | ||||
|                     'user_id' => Auth::user()->id | ||||
|                 ] | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         return $category; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										49
									
								
								app/Helpers/Csv/Converter/ConverterInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								app/Helpers/Csv/Converter/ConverterInterface.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| /** | ||||
|  * Interface ConverterInterface | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| interface ConverterInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function convert(); | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      */ | ||||
|     public function setData(array $data); | ||||
|  | ||||
|     /** | ||||
|      * @param string $field | ||||
|      * | ||||
|      */ | ||||
|     public function setField($field); | ||||
|  | ||||
|     /** | ||||
|      * @param int $index | ||||
|      */ | ||||
|     public function setIndex($index); | ||||
|  | ||||
|     /** | ||||
|      * @param array $mapped | ||||
|      */ | ||||
|     public function setMapped($mapped); | ||||
|  | ||||
|     /** | ||||
|      * @param string $role | ||||
|      */ | ||||
|     public function setRole($role); | ||||
|  | ||||
|     /** | ||||
|      * @param string $value | ||||
|      */ | ||||
|     public function setValue($value); | ||||
|  | ||||
| } | ||||
							
								
								
									
										28
									
								
								app/Helpers/Csv/Converter/CurrencyCode.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								app/Helpers/Csv/Converter/CurrencyCode.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
|  | ||||
| /** | ||||
|  * Class CurrencyCode | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class CurrencyCode extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return mixed|static | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         if (isset($this->mapped[$this->index][$this->value])) { | ||||
|             $currency = TransactionCurrency::find($this->mapped[$this->index][$this->value]); | ||||
|         } else { | ||||
|             $currency = TransactionCurrency::whereCode($this->value)->first(); | ||||
|         } | ||||
|  | ||||
|         return $currency; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										28
									
								
								app/Helpers/Csv/Converter/CurrencyId.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								app/Helpers/Csv/Converter/CurrencyId.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
|  | ||||
| /** | ||||
|  * Class CurrencyId | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class CurrencyId extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return mixed|static | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         if (isset($this->mapped[$this->index][$this->value])) { | ||||
|             $currency = TransactionCurrency::find($this->mapped[$this->index][$this->value]); | ||||
|         } else { | ||||
|             $currency = TransactionCurrency::find($this->value); | ||||
|         } | ||||
|  | ||||
|         return $currency; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										28
									
								
								app/Helpers/Csv/Converter/CurrencyName.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								app/Helpers/Csv/Converter/CurrencyName.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
|  | ||||
| /** | ||||
|  * Class CurrencyName | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class CurrencyName extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return mixed|static | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         if (isset($this->mapped[$this->index][$this->value])) { | ||||
|             $currency = TransactionCurrency::find($this->mapped[$this->index][$this->value]); | ||||
|         } else { | ||||
|             $currency = TransactionCurrency::whereName($this->value)->first(); | ||||
|         } | ||||
|  | ||||
|         return $currency; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										28
									
								
								app/Helpers/Csv/Converter/CurrencySymbol.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								app/Helpers/Csv/Converter/CurrencySymbol.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
|  | ||||
| /** | ||||
|  * Class CurrencySymbol | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class CurrencySymbol extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return mixed|static | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         if (isset($this->mapped[$this->index][$this->value])) { | ||||
|             $currency = TransactionCurrency::find($this->mapped[$this->index][$this->value]); | ||||
|         } else { | ||||
|             $currency = TransactionCurrency::whereSymbol($this->value)->first(); | ||||
|         } | ||||
|  | ||||
|         return $currency; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										38
									
								
								app/Helpers/Csv/Converter/Date.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								app/Helpers/Csv/Converter/Date.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use InvalidArgumentException; | ||||
| use Log; | ||||
| use Session; | ||||
|  | ||||
| /** | ||||
|  * Class Date | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class Date extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return Carbon | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         $format = Session::get('csv-date-format'); | ||||
|         try { | ||||
|             $date = Carbon::createFromFormat($format, $this->value); | ||||
|         } catch (InvalidArgumentException $e) { | ||||
|             Log::error('Date conversion error: ' . $e->getMessage() . '. Value was "' . $this->value . '", format was "' . $format . '".'); | ||||
|  | ||||
|             $message = trans('firefly.csv_date_parse_error', ['format' => $format, 'value' => $this->value]); | ||||
|  | ||||
|             throw new FireflyException($message); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         return $date; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										21
									
								
								app/Helpers/Csv/Converter/Description.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								app/Helpers/Csv/Converter/Description.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| /** | ||||
|  * Class Description | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class Description extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         return trim($this->data['description'] . ' ' . $this->value); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										22
									
								
								app/Helpers/Csv/Converter/Ignore.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								app/Helpers/Csv/Converter/Ignore.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| use FireflyIII\Models\Account; | ||||
|  | ||||
| /** | ||||
|  * Class Amount | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class Ignore extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return Account|null | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										57
									
								
								app/Helpers/Csv/Converter/OpposingAccountIban.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								app/Helpers/Csv/Converter/OpposingAccountIban.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Account; | ||||
| use Log; | ||||
|  | ||||
| /** | ||||
|  * Class OpposingAccountIban | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class OpposingAccountIban extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * If mapped, return account. Otherwise, only return the name itself. | ||||
|      * | ||||
|      * @return Account|string | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         if (isset($this->mapped[$this->index][$this->value])) { | ||||
|             $account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]); | ||||
|  | ||||
|             return $account; | ||||
|         } else { | ||||
|             if (strlen($this->value) > 0) { | ||||
|                 $account = $this->findAccount(); | ||||
|                 if (!is_null($account)) { | ||||
|                     return $account; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return $this->value; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Account|null | ||||
|      */ | ||||
|     protected function findAccount() | ||||
|     { | ||||
|         $set = Auth::user()->accounts()->get(); | ||||
|         /** @var Account $account */ | ||||
|         foreach ($set as $account) { | ||||
|             if ($account->iban == $this->value) { | ||||
|                 Log::debug('OpposingAccountIban::convert found an Account (#' . $account->id . ': ******) with IBAN ******'); | ||||
|  | ||||
|                 return $account; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										32
									
								
								app/Helpers/Csv/Converter/OpposingAccountId.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								app/Helpers/Csv/Converter/OpposingAccountId.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Account; | ||||
|  | ||||
| /** | ||||
|  * Class OpposingName | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class OpposingAccountId extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @return Account | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         if (isset($this->mapped[$this->index][$this->value])) { | ||||
|             $account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]); | ||||
|  | ||||
|         } else { | ||||
|             $account = Auth::user()->accounts()->find($this->value); | ||||
|         } | ||||
|  | ||||
|         return $account; | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										31
									
								
								app/Helpers/Csv/Converter/OpposingAccountName.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								app/Helpers/Csv/Converter/OpposingAccountName.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Account; | ||||
|  | ||||
| /** | ||||
|  * Class OpposingName | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class OpposingAccountName extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * If mapped, return account. Otherwise, only return the name itself. | ||||
|      * | ||||
|      * @return Account|string | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         if (isset($this->mapped[$this->index][$this->value])) { | ||||
|             $account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]); | ||||
|  | ||||
|             return $account; | ||||
|         } else { | ||||
|             return $this->value; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										26
									
								
								app/Helpers/Csv/Converter/RabobankDebetCredit.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								app/Helpers/Csv/Converter/RabobankDebetCredit.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Class RabobankDebetCredit | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class RabobankDebetCredit extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         if ($this->value == 'D') { | ||||
|             return -1; | ||||
|         } | ||||
|  | ||||
|         return 1; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										40
									
								
								app/Helpers/Csv/Converter/TagsComma.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								app/Helpers/Csv/Converter/TagsComma.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Models\Tag; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * Class TagsComma | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class TagsComma extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return Bill | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         $tags = new Collection; | ||||
|  | ||||
|         $strings = explode(',', $this->value); | ||||
|         foreach ($strings as $string) { | ||||
|             $tag = Tag::firstOrCreateEncrypted( | ||||
|                 [ | ||||
|                     'tag'     => $string, | ||||
|                     'tagMode' => 'nothing', | ||||
|                     'user_id' => Auth::user()->id, | ||||
|                 ] | ||||
|             ); | ||||
|             $tags->push($tag); | ||||
|         } | ||||
|         $tags = $tags->merge($this->data['tags']); | ||||
|  | ||||
|         return $tags; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										40
									
								
								app/Helpers/Csv/Converter/TagsSpace.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								app/Helpers/Csv/Converter/TagsSpace.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Converter; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Models\Tag; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * Class TagsSpace | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Converter | ||||
|  */ | ||||
| class TagsSpace extends BasicConverter implements ConverterInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return Bill | ||||
|      */ | ||||
|     public function convert() | ||||
|     { | ||||
|         $tags = new Collection; | ||||
|  | ||||
|         $strings = explode(' ', $this->value); | ||||
|         foreach ($strings as $string) { | ||||
|             $tag = Tag::firstOrCreateEncrypted( | ||||
|                 [ | ||||
|                     'tag'     => $string, | ||||
|                     'tagMode' => 'nothing', | ||||
|                     'user_id' => Auth::user()->id, | ||||
|                 ] | ||||
|             ); | ||||
|             $tags->push($tag); | ||||
|         } | ||||
|         $tags = $tags->merge($this->data['tags']); | ||||
|  | ||||
|         return $tags; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										283
									
								
								app/Helpers/Csv/Data.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										283
									
								
								app/Helpers/Csv/Data.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,283 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv; | ||||
|  | ||||
| use Crypt; | ||||
| use League\Csv\Reader; | ||||
| use Session; | ||||
|  | ||||
| /** | ||||
|  * Class Data | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv | ||||
|  */ | ||||
| class Data | ||||
| { | ||||
|  | ||||
|     /** @var string */ | ||||
|     protected $csvFileContent; | ||||
|  | ||||
|     /** @var string */ | ||||
|     protected $csvFileLocation; | ||||
|     /** @var  string */ | ||||
|     protected $dateFormat; | ||||
|     /** @var  bool */ | ||||
|     protected $hasHeaders; | ||||
|  | ||||
|     /** @var  array */ | ||||
|     protected $map = []; | ||||
|     /** @var  array */ | ||||
|     protected $mapped = []; | ||||
|     /** @var  Reader */ | ||||
|     protected $reader; | ||||
|     /** @var  array */ | ||||
|     protected $roles = []; | ||||
|  | ||||
|     /** @var  array */ | ||||
|     protected $specifix = []; | ||||
|  | ||||
|     /** @var int */ | ||||
|     protected $importAccount = 0; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->sessionHasHeaders(); | ||||
|         $this->sessionDateFormat(); | ||||
|         $this->sessionCsvFileLocation(); | ||||
|         $this->sessionMap(); | ||||
|         $this->sessionRoles(); | ||||
|         $this->sessionMapped(); | ||||
|         $this->sessionSpecifix(); | ||||
|         $this->sessionImportAccount(); | ||||
|     } | ||||
|  | ||||
|     protected function sessionHasHeaders() | ||||
|     { | ||||
|         if (Session::has('csv-has-headers')) { | ||||
|             $this->hasHeaders = (bool)Session::get('csv-has-headers'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     protected function sessionImportAccount() | ||||
|     { | ||||
|         if (Session::has('csv-import-account')) { | ||||
|             $this->importAccount = intval(Session::get('csv-import-account')); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     protected function sessionDateFormat() | ||||
|     { | ||||
|         if (Session::has('csv-date-format')) { | ||||
|             $this->dateFormat = (string)Session::get('csv-date-format'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     protected function sessionCsvFileLocation() | ||||
|     { | ||||
|         if (Session::has('csv-file')) { | ||||
|             $this->csvFileLocation = (string)Session::get('csv-file'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     protected function sessionMap() | ||||
|     { | ||||
|         if (Session::has('csv-map')) { | ||||
|             $this->map = (array)Session::get('csv-map'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     protected function sessionRoles() | ||||
|     { | ||||
|         if (Session::has('csv-roles')) { | ||||
|             $this->roles = (array)Session::get('csv-roles'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     protected function sessionMapped() | ||||
|     { | ||||
|         if (Session::has('csv-mapped')) { | ||||
|             $this->mapped = (array)Session::get('csv-mapped'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     protected function sessionSpecifix() | ||||
|     { | ||||
|         if (Session::has('csv-specifix')) { | ||||
|             $this->specifix = (array)Session::get('csv-specifix'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getDateFormat() | ||||
|     { | ||||
|         return $this->dateFormat; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param mixed $dateFormat | ||||
|      */ | ||||
|     public function setDateFormat($dateFormat) | ||||
|     { | ||||
|         Session::put('csv-date-format', $dateFormat); | ||||
|         $this->dateFormat = $dateFormat; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param int $importAccount | ||||
|      */ | ||||
|     public function setImportAccount($importAccount) | ||||
|     { | ||||
|         Session::put('csv-import-account', $importAccount); | ||||
|         $this->importAccount = $importAccount; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function hasHeaders() | ||||
|     { | ||||
|         return $this->hasHeaders; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param bool $hasHeaders | ||||
|      */ | ||||
|     public function setHasHeaders($hasHeaders) | ||||
|     { | ||||
|         Session::put('csv-has-headers', $hasHeaders); | ||||
|         $this->hasHeaders = $hasHeaders; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getMap() | ||||
|     { | ||||
|         return $this->map; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $map | ||||
|      */ | ||||
|     public function setMap(array $map) | ||||
|     { | ||||
|         Session::put('csv-map', $map); | ||||
|         $this->map = $map; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getMapped() | ||||
|     { | ||||
|         return $this->mapped; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $mapped | ||||
|      */ | ||||
|     public function setMapped(array $mapped) | ||||
|     { | ||||
|         Session::put('csv-mapped', $mapped); | ||||
|         $this->mapped = $mapped; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Reader | ||||
|      */ | ||||
|     public function getReader() | ||||
|     { | ||||
|  | ||||
|         if (strlen($this->csvFileContent) === 0) { | ||||
|             $this->loadCsvFile(); | ||||
|         } | ||||
|  | ||||
|         if (is_null($this->reader)) { | ||||
|             $this->reader = Reader::createFromString($this->getCsvFileContent()); | ||||
|         } | ||||
|  | ||||
|         return $this->reader; | ||||
|     } | ||||
|  | ||||
|     protected function loadCsvFile() | ||||
|     { | ||||
|         $file             = $this->getCsvFileLocation(); | ||||
|         $content          = file_get_contents($file); | ||||
|         $contentDecrypted = Crypt::decrypt($content); | ||||
|         $this->setCsvFileContent($contentDecrypted); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getCsvFileLocation() | ||||
|     { | ||||
|         return $this->csvFileLocation; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $csvFileLocation | ||||
|      */ | ||||
|     public function setCsvFileLocation($csvFileLocation) | ||||
|     { | ||||
|         Session::put('csv-file', $csvFileLocation); | ||||
|         $this->csvFileLocation = $csvFileLocation; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getCsvFileContent() | ||||
|     { | ||||
|         return $this->csvFileContent; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $csvFileContent | ||||
|      */ | ||||
|     public function setCsvFileContent($csvFileContent) | ||||
|     { | ||||
|         $this->csvFileContent = $csvFileContent; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getRoles() | ||||
|     { | ||||
|         return $this->roles; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $roles | ||||
|      */ | ||||
|     public function setRoles(array $roles) | ||||
|     { | ||||
|         Session::put('csv-roles', $roles); | ||||
|         $this->roles = $roles; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getSpecifix() | ||||
|     { | ||||
|         return is_array($this->specifix) ? $this->specifix : []; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $specifix | ||||
|      */ | ||||
|     public function setSpecifix($specifix) | ||||
|     { | ||||
|         Session::put('csv-specifix', $specifix); | ||||
|         $this->specifix = $specifix; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										371
									
								
								app/Helpers/Csv/Importer.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										371
									
								
								app/Helpers/Csv/Importer.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,371 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv; | ||||
|  | ||||
| use Auth; | ||||
| use Config; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Helpers\Csv\Converter\ConverterInterface; | ||||
| use FireflyIII\Helpers\Csv\PostProcessing\PostProcessorInterface; | ||||
| use FireflyIII\Helpers\Csv\Specifix\SpecifixInterface; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Models\TransactionType; | ||||
| use Illuminate\Support\Collection; | ||||
| use Illuminate\Support\MessageBag; | ||||
| use Log; | ||||
|  | ||||
| /** | ||||
|  * Class Importer | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv | ||||
|  */ | ||||
| class Importer | ||||
| { | ||||
|  | ||||
|     /** @var Data */ | ||||
|     protected $data; | ||||
|     /** @var array */ | ||||
|     protected $errors; | ||||
|     /** @var  array */ | ||||
|     protected $importData; | ||||
|     /** @var  array */ | ||||
|     protected $importRow; | ||||
|     /** @var int */ | ||||
|     protected $imported = 0; | ||||
|     /** @var array */ | ||||
|     protected $map; | ||||
|     /** @var  array */ | ||||
|     protected $mapped; | ||||
|     /** @var  array */ | ||||
|     protected $roles; | ||||
|     /** @var  int */ | ||||
|     protected $rows = 0; | ||||
|     /** @var array */ | ||||
|     protected $specifix = []; | ||||
|  | ||||
|     /** @var  Collection */ | ||||
|     protected $journals; | ||||
|  | ||||
|     /** | ||||
|      * Used by CsvController. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getErrors() | ||||
|     { | ||||
|         return $this->errors; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Used by CsvController | ||||
|      * | ||||
|      * @return int | ||||
|      */ | ||||
|     public function getImported() | ||||
|     { | ||||
|         return $this->imported; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Used by CsvController | ||||
|      * | ||||
|      * @return int | ||||
|      */ | ||||
|     public function getRows() | ||||
|     { | ||||
|         return $this->rows; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getJournals() | ||||
|     { | ||||
|         return $this->journals; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function run() | ||||
|     { | ||||
|         set_time_limit(0); | ||||
|  | ||||
|         $this->journals = new Collection; | ||||
|         $this->map      = $this->data->getMap(); | ||||
|         $this->roles    = $this->data->getRoles(); | ||||
|         $this->mapped   = $this->data->getMapped(); | ||||
|         $this->specifix = $this->data->getSpecifix(); | ||||
|  | ||||
|         foreach ($this->data->getReader() as $index => $row) { | ||||
|             if ($this->parseRow($index)) { | ||||
|                 Log::debug('--- Importing row ' . $index); | ||||
|                 $this->rows++; | ||||
|                 $result = $this->importRow($row); | ||||
|                 if (!($result instanceof TransactionJournal)) { | ||||
|                     Log::error('Caught error at row #' . $index . ': ' . $result); | ||||
|                     $this->errors[$index] = $result; | ||||
|                 } else { | ||||
|                     $this->imported++; | ||||
|                     $this->journals->push($result); | ||||
|                 } | ||||
|                 Log::debug('---'); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param int $index | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     protected function parseRow($index) | ||||
|     { | ||||
|         return (($this->data->hasHeaders() && $index >= 1) || !$this->data->hasHeaders()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $row | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * @return string|bool | ||||
|      */ | ||||
|     protected function importRow($row) | ||||
|     { | ||||
|  | ||||
|         $data = $this->getFiller(); // These fields are necessary to create a new transaction journal. Some are optional | ||||
|         foreach ($row as $index => $value) { | ||||
|             $role  = isset($this->roles[$index]) ? $this->roles[$index] : '_ignore'; | ||||
|             $class = Config::get('csv.roles.' . $role . '.converter'); | ||||
|             $field = Config::get('csv.roles.' . $role . '.field'); | ||||
|  | ||||
|             Log::debug('Column #' . $index . ' (role: ' . $role . ') : converter ' . $class . ' stores its data into field ' . $field . ':'); | ||||
|  | ||||
|             /** @var ConverterInterface $converter */ | ||||
|             $converter = app('FireflyIII\Helpers\Csv\Converter\\' . $class); | ||||
|             $converter->setData($data); // the complete array so far. | ||||
|             $converter->setField($field); | ||||
|             $converter->setIndex($index); | ||||
|             $converter->setMapped($this->mapped); | ||||
|             $converter->setValue($value); | ||||
|             $converter->setRole($role); | ||||
|             $data[$field] = $converter->convert(); | ||||
|         } | ||||
|         // move to class vars. | ||||
|         $this->importData = $data; | ||||
|         $this->importRow  = $row; | ||||
|         unset($data, $row); | ||||
|         // post processing and validating. | ||||
|         $this->postProcess(); | ||||
|         $result = $this->validateData(); | ||||
|  | ||||
|         if (!($result === true)) { | ||||
|             return $result; // return error. | ||||
|         } | ||||
|         $journal = $this->createTransactionJournal(); | ||||
|  | ||||
|         return $journal; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     protected function getFiller() | ||||
|     { | ||||
|         $filler = []; | ||||
|         foreach (Config::get('csv.roles') as $role) { | ||||
|             if (isset($role['field'])) { | ||||
|                 $fieldName          = $role['field']; | ||||
|                 $filler[$fieldName] = null; | ||||
|             } | ||||
|         } | ||||
|         // some extra's: | ||||
|         $filler['bill-id']                 = null; | ||||
|         $filler['opposing-account-object'] = null; | ||||
|         $filler['asset-account-object']    = null; | ||||
|         $filler['amount-modifier']         = '1'; | ||||
|  | ||||
|         return $filler; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Row denotes the original data. | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     protected function postProcess() | ||||
|     { | ||||
|         // do bank specific fixes (must be enabled but now all of them. | ||||
|  | ||||
|         foreach ($this->getSpecifix() as $className) { | ||||
|             /** @var SpecifixInterface $specifix */ | ||||
|             $specifix = app('FireflyIII\Helpers\Csv\Specifix\\' . $className); | ||||
|             $specifix->setData($this->importData); | ||||
|             $specifix->setRow($this->importRow); | ||||
|             Log::debug('Now post-process specifix named ' . $className . ':'); | ||||
|             $this->importData = $specifix->fix(); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         $set = Config::get('csv.post_processors'); | ||||
|         foreach ($set as $className) { | ||||
|             /** @var PostProcessorInterface $postProcessor */ | ||||
|             $postProcessor = app('FireflyIII\Helpers\Csv\PostProcessing\\' . $className); | ||||
|             $postProcessor->setData($this->importData); | ||||
|             Log::debug('Now post-process processor named ' . $className . ':'); | ||||
|             $this->importData = $postProcessor->process(); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getSpecifix() | ||||
|     { | ||||
|         return is_array($this->specifix) ? $this->specifix : []; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * @return bool|string | ||||
|      */ | ||||
|     protected function validateData() | ||||
|     { | ||||
|         if (is_null($this->importData['date']) && is_null($this->importData['date-rent'])) { | ||||
|             return 'No date value for this row.'; | ||||
|         } | ||||
|         if (is_null($this->importData['opposing-account-object'])) { | ||||
|             return 'Opposing account is null'; | ||||
|         } | ||||
|  | ||||
|         if (!($this->importData['asset-account-object'] instanceof Account)) { | ||||
|             return 'No asset account to import into.'; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * @return TransactionJournal|string | ||||
|      */ | ||||
|     protected function createTransactionJournal() | ||||
|     { | ||||
|         bcscale(2); | ||||
|         $date = $this->importData['date']; | ||||
|         if (is_null($this->importData['date'])) { | ||||
|             $date = $this->importData['date-rent']; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         $transactionType = $this->getTransactionType(); // defaults to deposit | ||||
|         $errors          = new MessageBag; | ||||
|         $journal         = TransactionJournal::create( | ||||
|             ['user_id'     => Auth::user()->id, 'transaction_type_id' => $transactionType->id, 'transaction_currency_id' => $this->importData['currency']->id, | ||||
|              'description' => $this->importData['description'], 'completed' => 0, 'date' => $date, 'bill_id' => $this->importData['bill-id'],] | ||||
|         ); | ||||
|         if ($journal->getErrors()->count() == 0) { | ||||
|             // first transaction | ||||
|             $accountId   = $this->importData['asset-account-object']->id; // create first transaction: | ||||
|             $amount      = $this->importData['amount']; | ||||
|             $transaction = Transaction::create(['transaction_journal_id' => $journal->id, 'account_id' => $accountId, 'amount' => $amount]); | ||||
|             $errors      = $transaction->getErrors(); | ||||
|  | ||||
|             // second transaction | ||||
|             $accountId   = $this->importData['opposing-account-object']->id; // create second transaction: | ||||
|             $amount      = bcmul($this->importData['amount'], -1); | ||||
|             $transaction = Transaction::create(['transaction_journal_id' => $journal->id, 'account_id' => $accountId, 'amount' => $amount]); | ||||
|             $errors      = $transaction->getErrors()->merge($errors); | ||||
|         } | ||||
|         if ($errors->count() == 0) { | ||||
|             $journal->completed = 1; | ||||
|             $journal->save(); | ||||
|         } else { | ||||
|             $text = join(',', $errors->all()); | ||||
|  | ||||
|             return $text; | ||||
|         } | ||||
|         $this->saveBudget($journal); | ||||
|         $this->saveCategory($journal); | ||||
|         $this->saveTags($journal); | ||||
|  | ||||
|         // some debug info: | ||||
|         $journalId = $journal->id; | ||||
|         $type      = $journal->transactionType->type; | ||||
|         /** @var Account $asset */ | ||||
|         $asset = $this->importData['asset-account-object']; | ||||
|         /** @var Account $opposing */ | ||||
|         $opposing = $this->importData['opposing-account-object']; | ||||
|  | ||||
|         Log::info('Created journal #' . $journalId . ' of type ' . $type . '!'); | ||||
|         Log::info('Asset account ****** (#' . $asset->id . ') lost/gained: ' . $this->importData['amount']); | ||||
|         Log::info($opposing->accountType->type . ' ****** (#' . $opposing->id . ') lost/gained: ' . bcmul($this->importData['amount'], -1)); | ||||
|  | ||||
|         return $journal; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return TransactionType | ||||
|      */ | ||||
|     protected function getTransactionType() | ||||
|     { | ||||
|         $transactionType = TransactionType::where('type', 'Deposit')->first(); | ||||
|         if ($this->importData['amount'] < 0) { | ||||
|             $transactionType = TransactionType::where('type', 'Withdrawal')->first(); | ||||
|         } | ||||
|  | ||||
|         if (in_array($this->importData['opposing-account-object']->accountType->type, ['Asset account', 'Default account'])) { | ||||
|             $transactionType = TransactionType::where('type', 'Transfer')->first(); | ||||
|         } | ||||
|  | ||||
|         return $transactionType; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionJournal $journal | ||||
|      */ | ||||
|     protected function saveBudget(TransactionJournal $journal) | ||||
|     { | ||||
|         // add budget: | ||||
|         if (!is_null($this->importData['budget'])) { | ||||
|             $journal->budgets()->save($this->importData['budget']); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionJournal $journal | ||||
|      */ | ||||
|     protected function saveCategory(TransactionJournal $journal) | ||||
|     { | ||||
|         // add category: | ||||
|         if (!is_null($this->importData['category'])) { | ||||
|             $journal->categories()->save($this->importData['category']); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionJournal $journal | ||||
|      */ | ||||
|     protected function saveTags(TransactionJournal $journal) | ||||
|     { | ||||
|         if (!is_null($this->importData['tags'])) { | ||||
|             foreach ($this->importData['tags'] as $tag) { | ||||
|                 $journal->tags()->save($tag); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Data $data | ||||
|      */ | ||||
|     public function setData($data) | ||||
|     { | ||||
|         $this->data = $data; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										34
									
								
								app/Helpers/Csv/Mapper/AnyAccount.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								app/Helpers/Csv/Mapper/AnyAccount.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Mapper; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Account; | ||||
|  | ||||
| /** | ||||
|  * Class AnyAccount | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Mapper | ||||
|  */ | ||||
| class AnyAccount implements MapperInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getMap() | ||||
|     { | ||||
|         $result = Auth::user()->accounts()->with('accountType')->orderBy('accounts.name', 'ASC')->get(['accounts.*']); | ||||
|  | ||||
|         $list = []; | ||||
|         /** @var Account $account */ | ||||
|         foreach ($result as $account) { | ||||
|             $list[$account->id] = $account->name . ' (' . $account->accountType->type . ')'; | ||||
|         } | ||||
|         asort($list); | ||||
|  | ||||
|         $list = [0 => trans('firefly.csv_do_not_map')] + $list; | ||||
|  | ||||
|         return $list; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										45
									
								
								app/Helpers/Csv/Mapper/AssetAccount.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								app/Helpers/Csv/Mapper/AssetAccount.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Mapper; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Account; | ||||
| use Illuminate\Database\Eloquent\Relations\HasMany; | ||||
|  | ||||
| /** | ||||
|  * Class AssetAccount | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Mapper | ||||
|  */ | ||||
| class AssetAccount implements MapperInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getMap() | ||||
|     { | ||||
|         $result = Auth::user()->accounts()->with( | ||||
|             ['accountmeta' => function (HasMany $query) { | ||||
|                 $query->where('name', 'accountRole'); | ||||
|             }] | ||||
|         )->accountTypeIn(['Default account', 'Asset account'])->orderBy('accounts.name', 'ASC')->get(['accounts.*']); | ||||
|  | ||||
|         $list = []; | ||||
|  | ||||
|         /** @var Account $account */ | ||||
|         foreach ($result as $account) { | ||||
|             $name = $account->name; | ||||
|             if (strlen($account->iban) > 0) { | ||||
|                 $name .= ' (' . $account->iban . ')'; | ||||
|             } | ||||
|             $list[$account->id] = $name; | ||||
|         } | ||||
|  | ||||
|         asort($list); | ||||
|  | ||||
|         $list = [0 => trans('firefly.csv_do_not_map')] + $list; | ||||
|  | ||||
|         return $list; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										34
									
								
								app/Helpers/Csv/Mapper/Bill.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								app/Helpers/Csv/Mapper/Bill.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Mapper; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Bill as BillModel; | ||||
|  | ||||
| /** | ||||
|  * Class Bill | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Mapper | ||||
|  */ | ||||
| class Bill implements MapperInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getMap() | ||||
|     { | ||||
|         $result = Auth::user()->bills()->get(['bills.*']); | ||||
|         $list   = []; | ||||
|  | ||||
|         /** @var BillModel $bill */ | ||||
|         foreach ($result as $bill) { | ||||
|             $list[$bill->id] = $bill->name . ' [' . $bill->match . ']'; | ||||
|         } | ||||
|         asort($list); | ||||
|  | ||||
|         $list = [0 => trans('firefly.csv_do_not_map')] + $list; | ||||
|  | ||||
|         return $list; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										34
									
								
								app/Helpers/Csv/Mapper/Budget.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								app/Helpers/Csv/Mapper/Budget.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Mapper; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Budget as BudgetModel; | ||||
|  | ||||
| /** | ||||
|  * Class Budget | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Mapper | ||||
|  */ | ||||
| class Budget implements MapperInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getMap() | ||||
|     { | ||||
|         $result = Auth::user()->budgets()->get(['budgets.*']); | ||||
|         $list   = []; | ||||
|  | ||||
|         /** @var BudgetModel $budget */ | ||||
|         foreach ($result as $budget) { | ||||
|             $list[$budget->id] = $budget->name; | ||||
|         } | ||||
|         asort($list); | ||||
|  | ||||
|         $list = [0 => trans('firefly.csv_do_not_map')] + $list; | ||||
|  | ||||
|         return $list; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										34
									
								
								app/Helpers/Csv/Mapper/Category.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								app/Helpers/Csv/Mapper/Category.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Mapper; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Category as CategoryModel; | ||||
|  | ||||
| /** | ||||
|  * Class Category | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Mapper | ||||
|  */ | ||||
| class Category implements MapperInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getMap() | ||||
|     { | ||||
|         $result = Auth::user()->categories()->get(['categories.*']); | ||||
|         $list   = []; | ||||
|  | ||||
|         /** @var CategoryModel $category */ | ||||
|         foreach ($result as $category) { | ||||
|             $list[$category->id] = $category->name; | ||||
|         } | ||||
|         asort($list); | ||||
|  | ||||
|         $list = [0 => trans('firefly.csv_do_not_map')] + $list; | ||||
|  | ||||
|         return $list; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										16
									
								
								app/Helpers/Csv/Mapper/MapperInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								app/Helpers/Csv/Mapper/MapperInterface.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Mapper; | ||||
|  | ||||
| /** | ||||
|  * Interface MapperInterface | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Mapper | ||||
|  */ | ||||
| interface MapperInterface | ||||
| { | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getMap(); | ||||
| } | ||||
							
								
								
									
										34
									
								
								app/Helpers/Csv/Mapper/Tag.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								app/Helpers/Csv/Mapper/Tag.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Mapper; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Tag as TagModel; | ||||
|  | ||||
| /** | ||||
|  * Class Tag | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Mapper | ||||
|  */ | ||||
| class Tag implements MapperInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getMap() | ||||
|     { | ||||
|         $result = Auth::user()->budgets()->get(['tags.*']); | ||||
|         $list   = []; | ||||
|  | ||||
|         /** @var TagModel $tag */ | ||||
|         foreach ($result as $tag) { | ||||
|             $list[$tag->id] = $tag->tag; | ||||
|         } | ||||
|         asort($list); | ||||
|  | ||||
|         $list = [0 => trans('firefly.csv_do_not_map')] + $list; | ||||
|  | ||||
|         return $list; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										32
									
								
								app/Helpers/Csv/Mapper/TransactionCurrency.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								app/Helpers/Csv/Mapper/TransactionCurrency.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Mapper; | ||||
|  | ||||
| use FireflyIII\Models\TransactionCurrency as TC; | ||||
|  | ||||
| /** | ||||
|  * Class TransactionCurrency | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Mapper | ||||
|  */ | ||||
| class TransactionCurrency implements MapperInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getMap() | ||||
|     { | ||||
|         $currencies = TC::get(); | ||||
|         $list       = []; | ||||
|         foreach ($currencies as $currency) { | ||||
|             $list[$currency->id] = $currency->name . ' (' . $currency->code . ')'; | ||||
|         } | ||||
|  | ||||
|         asort($list); | ||||
|  | ||||
|         $list = [0 => trans('firefly.csv_do_not_map')] + $list; | ||||
|  | ||||
|         return $list; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										35
									
								
								app/Helpers/Csv/PostProcessing/Amount.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								app/Helpers/Csv/PostProcessing/Amount.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| <?php | ||||
|  | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\PostProcessing; | ||||
|  | ||||
| /** | ||||
|  * Class Amount | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\PostProcessing | ||||
|  */ | ||||
| class Amount implements PostProcessorInterface | ||||
| { | ||||
|  | ||||
|     /** @var  array */ | ||||
|     protected $data; | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function process() | ||||
|     { | ||||
|         bcscale(2); | ||||
|         $this->data['amount'] = bcmul($this->data['amount'], $this->data['amount-modifier']); | ||||
|  | ||||
|         return $this->data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      */ | ||||
|     public function setData(array $data) | ||||
|     { | ||||
|         $this->data = $data; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										185
									
								
								app/Helpers/Csv/PostProcessing/AssetAccount.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								app/Helpers/Csv/PostProcessing/AssetAccount.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,185 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\PostProcessing; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\AccountType; | ||||
| use Log; | ||||
| use Validator; | ||||
|  | ||||
| /** | ||||
|  * Class AssetAccount | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\PostProcessing | ||||
|  */ | ||||
| class AssetAccount implements PostProcessorInterface | ||||
| { | ||||
|  | ||||
|     /** @var  array */ | ||||
|     protected $data; | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function process() | ||||
|     { | ||||
|         $result = $this->checkIdNameObject(); // has object in ID or Name? | ||||
|         if (!is_null($result)) { | ||||
|             return $result; | ||||
|         } | ||||
|  | ||||
|         $result = $this->checkIbanString(); | ||||
|         if (!is_null($result)) { | ||||
|             return $result; | ||||
|         } | ||||
|  | ||||
|         $result = $this->checkNameString(); | ||||
|         if (!is_null($result)) { | ||||
|             return $result; | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      */ | ||||
|     public function setData(array $data) | ||||
|     { | ||||
|         $this->data = $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     protected function checkIdNameObject() | ||||
|     { | ||||
|         if ($this->data['asset-account-id'] instanceof Account) { // first priority. try to find the account based on ID, if any | ||||
|             $this->data['asset-account-object'] = $this->data['asset-account-id']; | ||||
|  | ||||
|             return $this->data; | ||||
|         } | ||||
|         if ($this->data['asset-account-iban'] instanceof Account) { // second: try to find the account based on IBAN, if any. | ||||
|             $this->data['asset-account-object'] = $this->data['asset-account-iban']; | ||||
|  | ||||
|             return $this->data; | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array|null | ||||
|      */ | ||||
|     protected function checkIbanString() | ||||
|     { | ||||
|         $rules     = ['iban' => 'iban']; | ||||
|         $check     = ['iban' => $this->data['asset-account-iban']]; | ||||
|         $validator = Validator::make($check, $rules); | ||||
|         if (!$validator->fails()) { | ||||
|             $this->data['asset-account-object'] = $this->parseIbanString(); | ||||
|  | ||||
|             return $this->data; | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Account|null | ||||
|      */ | ||||
|     protected function parseIbanString() | ||||
|     { | ||||
|         // create by name and/or iban. | ||||
|         $accounts = Auth::user()->accounts()->get(); | ||||
|         foreach ($accounts as $entry) { | ||||
|             if ($entry->iban == $this->data['asset-account-iban']) { | ||||
|  | ||||
|                 return $entry; | ||||
|             } | ||||
|         } | ||||
|         $account = $this->createAccount(); | ||||
|  | ||||
|         return $account; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Account|null | ||||
|      */ | ||||
|     protected function createAccount() | ||||
|     { | ||||
|         $accountType = $this->getAccountType(); | ||||
|  | ||||
|         // create if not exists: | ||||
|         $name    = is_string($this->data['asset-account-name']) && strlen($this->data['asset-account-name']) > 0 ? $this->data['asset-account-name'] | ||||
|             : $this->data['asset-account-iban']; | ||||
|         $account = Account::firstOrCreateEncrypted( | ||||
|             [ | ||||
|                 'user_id'         => Auth::user()->id, | ||||
|                 'account_type_id' => $accountType->id, | ||||
|                 'name'            => $name, | ||||
|                 'iban'            => $this->data['asset-account-iban'], | ||||
|                 'active'          => true, | ||||
|             ] | ||||
|         ); | ||||
|  | ||||
|         return $account; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * @return AccountType | ||||
|      */ | ||||
|     protected function getAccountType() | ||||
|     { | ||||
|         return AccountType::where('type', 'Asset account')->first(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array|null | ||||
|      */ | ||||
|     protected function checkNameString() | ||||
|     { | ||||
|         if ($this->data['asset-account-name'] instanceof Account) { // third: try to find account based on name, if any. | ||||
|             $this->data['asset-account-object'] = $this->data['asset-account-name']; | ||||
|  | ||||
|             return $this->data; | ||||
|         } | ||||
|         if (is_string($this->data['asset-account-name'])) { | ||||
|             $this->data['asset-account-object'] = $this->parseNameString(); | ||||
|  | ||||
|             return $this->data; | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Account|null | ||||
|      */ | ||||
|     protected function parseNameString() | ||||
|     { | ||||
|         $accountType = $this->getAccountType(); | ||||
|         $accounts    = Auth::user()->accounts()->where('account_type_id', $accountType->id)->get(); | ||||
|         foreach ($accounts as $entry) { | ||||
|             if ($entry->name == $this->data['asset-account-name']) { | ||||
|                 Log::debug('Found an asset account with this name (#' . $entry->id . ': ******)'); | ||||
|  | ||||
|                 return $entry; | ||||
|             } | ||||
|         } | ||||
|         // create if not exists: | ||||
|         $account = Account::firstOrCreateEncrypted( | ||||
|             [ | ||||
|                 'user_id'         => Auth::user()->id, | ||||
|                 'account_type_id' => $accountType->id, | ||||
|                 'name'            => $this->data['asset-account-name'], | ||||
|                 'iban'            => '', | ||||
|                 'active'          => true, | ||||
|             ] | ||||
|         ); | ||||
|  | ||||
|         return $account; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										37
									
								
								app/Helpers/Csv/PostProcessing/Bill.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								app/Helpers/Csv/PostProcessing/Bill.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\PostProcessing; | ||||
|  | ||||
| /** | ||||
|  * Class Bill | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\PostProcessing | ||||
|  */ | ||||
| class Bill implements PostProcessorInterface | ||||
| { | ||||
|  | ||||
|     /** @var  array */ | ||||
|     protected $data; | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function process() | ||||
|     { | ||||
|  | ||||
|         // get bill id. | ||||
|         if (!is_null($this->data['bill'])) { | ||||
|             $this->data['bill-id'] = $this->data['bill']->id; | ||||
|         } | ||||
|  | ||||
|         return $this->data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      */ | ||||
|     public function setData(array $data) | ||||
|     { | ||||
|         $this->data = $data; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										41
									
								
								app/Helpers/Csv/PostProcessing/Currency.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								app/Helpers/Csv/PostProcessing/Currency.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\PostProcessing; | ||||
|  | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use Preferences; | ||||
|  | ||||
| /** | ||||
|  * Class Currency | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\PostProcessing | ||||
|  */ | ||||
| class Currency implements PostProcessorInterface | ||||
| { | ||||
|  | ||||
|     /** @var  array */ | ||||
|     protected $data; | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function process() | ||||
|     { | ||||
|  | ||||
|         // fix currency | ||||
|         if (is_null($this->data['currency'])) { | ||||
|             $currencyPreference     = Preferences::get('currencyPreference', 'EUR'); | ||||
|             $this->data['currency'] = TransactionCurrency::whereCode($currencyPreference->data)->first(); | ||||
|         } | ||||
|  | ||||
|         return $this->data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      */ | ||||
|     public function setData(array $data) | ||||
|     { | ||||
|         $this->data = $data; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										38
									
								
								app/Helpers/Csv/PostProcessing/Description.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								app/Helpers/Csv/PostProcessing/Description.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\PostProcessing; | ||||
|  | ||||
| /** | ||||
|  * Class Description | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\PostProcessing | ||||
|  */ | ||||
| class Description implements PostProcessorInterface | ||||
| { | ||||
|  | ||||
|     /** @var  array */ | ||||
|     protected $data; | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function process() | ||||
|     { | ||||
|         $this->data['description'] = trim($this->data['description']); | ||||
|         if (strlen($this->data['description']) == 0) { | ||||
|             $this->data['description'] = trans('firefly.csv_empty_description'); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         return $this->data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      */ | ||||
|     public function setData(array $data) | ||||
|     { | ||||
|  | ||||
|         $this->data = $data; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										210
									
								
								app/Helpers/Csv/PostProcessing/OpposingAccount.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								app/Helpers/Csv/PostProcessing/OpposingAccount.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,210 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\PostProcessing; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\AccountType; | ||||
| use Log; | ||||
| use Validator; | ||||
|  | ||||
| /** | ||||
|  * Class OpposingAccount | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\PostProcessing | ||||
|  */ | ||||
| class OpposingAccount implements PostProcessorInterface | ||||
| { | ||||
|  | ||||
|     /** @var  array */ | ||||
|     protected $data; | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function process() | ||||
|     { | ||||
|         // three values: | ||||
|         // opposing-account-id, opposing-account-iban, opposing-account-name | ||||
|  | ||||
|  | ||||
|         $result = $this->checkIdNameObject(); | ||||
|         if (!is_null($result)) { | ||||
|             return $result; | ||||
|         } | ||||
|  | ||||
|         $result = $this->checkIbanString(); | ||||
|         if (!is_null($result)) { | ||||
|             return $result; | ||||
|         } | ||||
|  | ||||
|         $result = $this->checkNameString(); | ||||
|         if (!is_null($result)) { | ||||
|             return $result; | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      */ | ||||
|     public function setData(array $data) | ||||
|     { | ||||
|         $this->data = $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     protected function checkIdNameObject() | ||||
|     { | ||||
|         if ($this->data['opposing-account-id'] instanceof Account) { // first priority. try to find the account based on ID, if any | ||||
|             Log::debug('OpposingAccountPostProcession: opposing-account-id is an Account.'); | ||||
|             $this->data['opposing-account-object'] = $this->data['opposing-account-id']; | ||||
|  | ||||
|             return $this->data; | ||||
|         } | ||||
|         if ($this->data['opposing-account-iban'] instanceof Account) { // second: try to find the account based on IBAN, if any. | ||||
|             Log::debug('OpposingAccountPostProcession: opposing-account-iban is an Account.'); | ||||
|             $this->data['opposing-account-object'] = $this->data['opposing-account-iban']; | ||||
|  | ||||
|             return $this->data; | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array|null | ||||
|      */ | ||||
|     protected function checkIbanString() | ||||
|     { | ||||
|         $rules     = ['iban' => 'iban']; | ||||
|         $iban      = $this->data['opposing-account-iban']; | ||||
|         $check     = ['iban' => $iban]; | ||||
|         $validator = Validator::make($check, $rules); | ||||
|         if (is_string($iban) && strlen($iban) > 0 && !$validator->fails()) { | ||||
|  | ||||
|             Log::debug('OpposingAccountPostProcession: opposing-account-iban is a string (******).'); | ||||
|             $this->data['opposing-account-object'] = $this->parseIbanString(); | ||||
|  | ||||
|             return $this->data; | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Account|null | ||||
|      */ | ||||
|     protected function parseIbanString() | ||||
|     { | ||||
|         // create by name and/or iban. | ||||
|         $accounts = Auth::user()->accounts()->get(); | ||||
|         foreach ($accounts as $entry) { | ||||
|             if ($entry->iban == $this->data['opposing-account-iban']) { | ||||
|                 Log::debug('OpposingAccountPostProcession: opposing-account-iban matches an Account.'); | ||||
|  | ||||
|                 return $entry; | ||||
|             } | ||||
|         } | ||||
|         $account = $this->createAccount(); | ||||
|  | ||||
|  | ||||
|         return $account; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Account|null | ||||
|      */ | ||||
|     protected function createAccount() | ||||
|     { | ||||
|         $accountType = $this->getAccountType(); | ||||
|  | ||||
|         // create if not exists: | ||||
|         $name    = is_string($this->data['opposing-account-name']) && strlen($this->data['opposing-account-name']) > 0 ? $this->data['opposing-account-name'] | ||||
|             : $this->data['opposing-account-iban']; | ||||
|         $account = Account::firstOrCreateEncrypted( | ||||
|             [ | ||||
|                 'user_id'         => Auth::user()->id, | ||||
|                 'account_type_id' => $accountType->id, | ||||
|                 'name'            => $name, | ||||
|                 'iban'            => $this->data['opposing-account-iban'], | ||||
|                 'active'          => true, | ||||
|             ] | ||||
|         ); | ||||
|         Log::debug('OpposingAccountPostProcession: created a new account.'); | ||||
|  | ||||
|         return $account; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * @return AccountType | ||||
|      */ | ||||
|     protected function getAccountType() | ||||
|     { | ||||
|         // opposing account type: | ||||
|         if ($this->data['amount'] < 0) { | ||||
|             // create expense account: | ||||
|  | ||||
|             return AccountType::where('type', 'Expense account')->first(); | ||||
|         } else { | ||||
|             // create revenue account: | ||||
|  | ||||
|             return AccountType::where('type', 'Revenue account')->first(); | ||||
|  | ||||
|  | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array|null | ||||
|      */ | ||||
|     protected function checkNameString() | ||||
|     { | ||||
|         if ($this->data['opposing-account-name'] instanceof Account) { // third: try to find account based on name, if any. | ||||
|             Log::debug('OpposingAccountPostProcession: opposing-account-name is an Account.'); | ||||
|             $this->data['opposing-account-object'] = $this->data['opposing-account-name']; | ||||
|  | ||||
|             return $this->data; | ||||
|         } | ||||
|         if (is_string($this->data['opposing-account-name'])) { | ||||
|  | ||||
|             $this->data['opposing-account-object'] = $this->parseNameString(); | ||||
|  | ||||
|             return $this->data; | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Account|null | ||||
|      */ | ||||
|     protected function parseNameString() | ||||
|     { | ||||
|         $accountType = $this->getAccountType(); | ||||
|         $accounts    = Auth::user()->accounts()->where('account_type_id', $accountType->id)->get(); | ||||
|         foreach ($accounts as $entry) { | ||||
|             if ($entry->name == $this->data['opposing-account-name']) { | ||||
|                 Log::debug('Found an account with this name (#' . $entry->id . ': ******)'); | ||||
|  | ||||
|                 return $entry; | ||||
|             } | ||||
|         } | ||||
|         // create if not exists: | ||||
|         $account = Account::firstOrCreateEncrypted( | ||||
|             [ | ||||
|                 'user_id'         => Auth::user()->id, | ||||
|                 'account_type_id' => $accountType->id, | ||||
|                 'name'            => $this->data['opposing-account-name'], | ||||
|                 'iban'            => '', | ||||
|                 'active'          => true, | ||||
|             ] | ||||
|         ); | ||||
|  | ||||
|         return $account; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										29
									
								
								app/Helpers/Csv/PostProcessing/PostProcessorInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								app/Helpers/Csv/PostProcessing/PostProcessorInterface.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| <?php | ||||
| /** | ||||
|  * Created by PhpStorm. | ||||
|  * User: sander | ||||
|  * Date: 05/07/15 | ||||
|  * Time: 19:20 | ||||
|  */ | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\PostProcessing; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Interface PostProcessorInterface | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\PostProcessing | ||||
|  */ | ||||
| interface PostProcessorInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function process(); | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      */ | ||||
|     public function setData(array $data); | ||||
| } | ||||
							
								
								
									
										45
									
								
								app/Helpers/Csv/Specifix/Dummy.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								app/Helpers/Csv/Specifix/Dummy.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Specifix; | ||||
|  | ||||
| /** | ||||
|  * Class Dummy | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Specifix | ||||
|  */ | ||||
| class Dummy | ||||
| { | ||||
|     /** @var array */ | ||||
|     protected $data; | ||||
|  | ||||
|     /** @var array */ | ||||
|     protected $row; | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function fix() | ||||
|     { | ||||
|         return $this->data; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      */ | ||||
|     public function setData($data) | ||||
|     { | ||||
|         $this->data = $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $row | ||||
|      */ | ||||
|     public function setRow($row) | ||||
|     { | ||||
|         $this->row = $row; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										66
									
								
								app/Helpers/Csv/Specifix/RabobankDescription.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								app/Helpers/Csv/Specifix/RabobankDescription.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv\Specifix; | ||||
|  | ||||
| use Log; | ||||
|  | ||||
| /** | ||||
|  * Class RabobankDescription | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Specifix | ||||
|  */ | ||||
| class RabobankDescription | ||||
| { | ||||
|     /** @var array */ | ||||
|     protected $data; | ||||
|  | ||||
|     /** @var array */ | ||||
|     protected $row; | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function fix() | ||||
|     { | ||||
|         $this->rabobankFixEmptyOpposing(); | ||||
|  | ||||
|         return $this->data; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Fixes Rabobank specific thing. | ||||
|      */ | ||||
|     protected function rabobankFixEmptyOpposing() | ||||
|     { | ||||
|         Log::debug('RaboSpecifix: Opposing account name is "******".'); | ||||
|         if (is_string($this->data['opposing-account-name']) && strlen($this->data['opposing-account-name']) == 0) { | ||||
|             Log::debug('RaboSpecifix: opp-name is zero length, changed to: "******"'); | ||||
|             $this->data['opposing-account-name'] = $this->row[10]; | ||||
|  | ||||
|             Log::debug('Description was: "******".'); | ||||
|             $this->data['description'] = trim(str_replace($this->row[10], '', $this->data['description'])); | ||||
|             Log::debug('Description is now: "******".'); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      */ | ||||
|     public function setData($data) | ||||
|     { | ||||
|         $this->data = $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $row | ||||
|      */ | ||||
|     public function setRow($row) | ||||
|     { | ||||
|         $this->row = $row; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										25
									
								
								app/Helpers/Csv/Specifix/SpecifixInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								app/Helpers/Csv/Specifix/SpecifixInterface.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| <?php | ||||
| namespace FireflyIII\Helpers\Csv\Specifix; | ||||
|  | ||||
| /** | ||||
|  * Interface SpecifixInterface | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv\Specifix | ||||
|  */ | ||||
| interface SpecifixInterface | ||||
| { | ||||
|     /** | ||||
|      * Implement bank and locale related fixes. | ||||
|      */ | ||||
|     public function fix(); | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      */ | ||||
|     public function setData($data); | ||||
|  | ||||
|     /** | ||||
|      * @param array $row | ||||
|      */ | ||||
|     public function setRow($row); | ||||
| } | ||||
							
								
								
									
										194
									
								
								app/Helpers/Csv/Wizard.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								app/Helpers/Csv/Wizard.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,194 @@ | ||||
| <?php | ||||
| namespace FireflyIII\Helpers\Csv; | ||||
|  | ||||
| use Auth; | ||||
| use Config; | ||||
| use Crypt; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Helpers\Csv\Mapper\MapperInterface; | ||||
| use League\Csv\Reader; | ||||
| use Log; | ||||
| use ReflectionException; | ||||
| use Session; | ||||
|  | ||||
| /** | ||||
|  * Class Wizard | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv | ||||
|  */ | ||||
| class Wizard implements WizardInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param Reader $reader | ||||
|      * @param array  $map | ||||
|      * @param bool   $hasHeaders | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getMappableValues($reader, array $map, $hasHeaders) | ||||
|     { | ||||
|         $values = []; | ||||
|         /* | ||||
|          * Loop over the CSV and collect mappable data: | ||||
|          */ | ||||
|         $keys = array_keys($map); | ||||
|         foreach ($reader as $index => $row) { | ||||
|             if ($this->useRow($hasHeaders, $index)) { | ||||
|                 // collect all map values | ||||
|  | ||||
|                 foreach ($keys as $column) { | ||||
|                     $values[$column][] = $row[$column]; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         /* | ||||
|          * Make each one unique. | ||||
|          */ | ||||
|         $values = $this->uniqueRecursive($values); | ||||
|  | ||||
|         return $values; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $roles | ||||
|      * @param mixed $map | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function processSelectedMapping(array $roles, $map) | ||||
|     { | ||||
|         $configRoles = Config::get('csv.roles'); | ||||
|         $maps        = []; | ||||
|  | ||||
|  | ||||
|         if (is_array($map)) { | ||||
|             foreach ($map as $index => $field) { | ||||
|                 if (isset($roles[$index])) { | ||||
|                     $name = $roles[$index]; | ||||
|                     if ($configRoles[$name]['mappable']) { | ||||
|                         $maps[$index] = $name; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $maps; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param mixed $input | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function processSelectedRoles($input) | ||||
|     { | ||||
|         $roles = []; | ||||
|  | ||||
|  | ||||
|         /* | ||||
|          * Store all rows for each column: | ||||
|          */ | ||||
|         if (is_array($input)) { | ||||
|             foreach ($input as $index => $role) { | ||||
|                 if ($role != '_ignore') { | ||||
|                     $roles[$index] = $role; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $roles; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $fields | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function sessionHasValues(array $fields) | ||||
|     { | ||||
|         foreach ($fields as $field) { | ||||
|             if (!Session::has($field)) { | ||||
|                 Log::error('Session is missing field: ' . $field); | ||||
|  | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $map | ||||
|      * | ||||
|      * @return array | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function showOptions(array $map) | ||||
|     { | ||||
|         $options = []; | ||||
|         foreach ($map as $index => $columnRole) { | ||||
|  | ||||
|             $mapper = Config::get('csv.roles.' . $columnRole . '.mapper'); | ||||
|             if (is_null($mapper)) { | ||||
|                 throw new FireflyException('Cannot map field of type "' . $columnRole . '".'); | ||||
|             } | ||||
|             $class = 'FireflyIII\Helpers\Csv\Mapper\\' . $mapper; | ||||
|             try { | ||||
|                 /** @var MapperInterface $mapObject */ | ||||
|                 $mapObject = app($class); | ||||
|             } catch (ReflectionException $e) { | ||||
|                 throw new FireflyException('Column "' . $columnRole . '" cannot be mapped because class ' . $mapper . ' does not exist.'); | ||||
|             } | ||||
|             $set             = $mapObject->getMap(); | ||||
|             $options[$index] = $set; | ||||
|         } | ||||
|  | ||||
|         return $options; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $path | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function storeCsvFile($path) | ||||
|     { | ||||
|         $time             = str_replace(' ', '-', microtime()); | ||||
|         $fileName         = 'csv-upload-' . Auth::user()->id . '-' . $time . '.csv.encrypted'; | ||||
|         $fullPath         = storage_path('upload') . DIRECTORY_SEPARATOR . $fileName; | ||||
|         $content          = file_get_contents($path); | ||||
|         $contentEncrypted = Crypt::encrypt($content); | ||||
|         file_put_contents($fullPath, $contentEncrypted); | ||||
|  | ||||
|         return $fullPath; | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param bool $hasHeaders | ||||
|      * @param int  $index | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     protected function useRow($hasHeaders, $index) | ||||
|     { | ||||
|         return ($hasHeaders && $index > 1) || !$hasHeaders; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $array | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     protected function uniqueRecursive(array $array) | ||||
|     { | ||||
|         foreach ($array as $column => $found) { | ||||
|             $array[$column] = array_unique($found); | ||||
|         } | ||||
|  | ||||
|         return $array; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										59
									
								
								app/Helpers/Csv/WizardInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								app/Helpers/Csv/WizardInterface.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Csv; | ||||
|  | ||||
| use League\Csv\Reader; | ||||
|  | ||||
| /** | ||||
|  * Interface WizardInterface | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Csv | ||||
|  */ | ||||
| interface WizardInterface | ||||
| { | ||||
|     /** | ||||
|      * @param Reader $reader | ||||
|      * @param array  $map | ||||
|      * @param bool   $hasHeaders | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getMappableValues($reader, array $map, $hasHeaders); | ||||
|  | ||||
|     /** | ||||
|      * @param array $roles | ||||
|      * @param mixed $map | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function processSelectedMapping(array $roles, $map); | ||||
|  | ||||
|     /** | ||||
|      * @param mixed $input | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function processSelectedRoles($input); | ||||
|  | ||||
|     /** | ||||
|      * @param array $fields | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function sessionHasValues(array $fields); | ||||
|  | ||||
|     /** | ||||
|      * @param array $map | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function showOptions(array $map); | ||||
|  | ||||
|     /** | ||||
|      * @param $path | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function storeCsvFile($path); | ||||
|  | ||||
| } | ||||
							
								
								
									
										99
									
								
								app/Helpers/Help/Help.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								app/Helpers/Help/Help.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,99 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Help; | ||||
|  | ||||
| use Cache; | ||||
| use ErrorException; | ||||
| use League\CommonMark\CommonMarkConverter; | ||||
| use Log; | ||||
| use Route; | ||||
|  | ||||
| /** | ||||
|  * Class Help | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Help | ||||
|  */ | ||||
| class Help implements HelpInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @param $key | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getFromCache($key) | ||||
|     { | ||||
|         return Cache::get($key); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @param $route | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getFromGithub($route) | ||||
|     { | ||||
|         $uri        = 'https://raw.githubusercontent.com/JC5/firefly-iii-help/master/en/' . e($route) . '.md'; | ||||
|         $routeIndex = str_replace('.', '-', $route); | ||||
|         $title      = trans('help.' . $routeIndex); | ||||
|         $content    = [ | ||||
|             'text'  => '<p>There is no help for this route!</p>', | ||||
|             'title' => $title, | ||||
|         ]; | ||||
|         try { | ||||
|             $content['text'] = file_get_contents($uri); | ||||
|         } catch (ErrorException $e) { | ||||
|             Log::error(trim($e->getMessage())); | ||||
|         } | ||||
|         if (strlen(trim($content['text'])) == 0) { | ||||
|             $content['text'] = '<p>There is no help for this route.</p>'; | ||||
|         } | ||||
|         $converter       = new CommonMarkConverter(); | ||||
|         $content['text'] = $converter->convertToHtml($content['text']); | ||||
|  | ||||
|         return $content; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @param $route | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function hasRoute($route) | ||||
|     { | ||||
|         return Route::has($route); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @param $route | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function inCache($route) | ||||
|     { | ||||
|         return Cache::has('help.' . $route . '.title') && Cache::has('help.' . $route . '.text'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @param       $route | ||||
|      * @param array $content | ||||
|      * | ||||
|      * @internal param $title | ||||
|      */ | ||||
|     public function putInCache($route, array $content) | ||||
|     { | ||||
|         Cache::put('help.' . $route . '.text', $content['text'], 10080); // a week. | ||||
|         Cache::put('help.' . $route . '.title', $content['title'], 10080); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										48
									
								
								app/Helpers/Help/HelpInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								app/Helpers/Help/HelpInterface.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Help; | ||||
|  | ||||
| /** | ||||
|  * Interface HelpInterface | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Help | ||||
|  */ | ||||
| interface HelpInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param $key | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getFromCache($key); | ||||
|  | ||||
|     /** | ||||
|      * @param $route | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getFromGithub($route); | ||||
|  | ||||
|     /** | ||||
|      * @param $route | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function hasRoute($route); | ||||
|  | ||||
|     /** | ||||
|      * @param $route | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function inCache($route); | ||||
|  | ||||
|     /** | ||||
|      * @param       $route | ||||
|      * @param array $content | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function putInCache($route, array $content); | ||||
| } | ||||
							
								
								
									
										405
									
								
								app/Helpers/Report/ReportHelper.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										405
									
								
								app/Helpers/Report/ReportHelper.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,405 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Report; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Helpers\Collection\Account as AccountCollection; | ||||
| use FireflyIII\Helpers\Collection\Balance; | ||||
| use FireflyIII\Helpers\Collection\BalanceEntry; | ||||
| use FireflyIII\Helpers\Collection\BalanceHeader; | ||||
| use FireflyIII\Helpers\Collection\BalanceLine; | ||||
| use FireflyIII\Helpers\Collection\Bill as BillCollection; | ||||
| use FireflyIII\Helpers\Collection\BillLine; | ||||
| use FireflyIII\Helpers\Collection\Budget as BudgetCollection; | ||||
| use FireflyIII\Helpers\Collection\BudgetLine; | ||||
| use FireflyIII\Helpers\Collection\Category as CategoryCollection; | ||||
| use FireflyIII\Helpers\Collection\Expense; | ||||
| use FireflyIII\Helpers\Collection\Income; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Models\Budget as BudgetModel; | ||||
| use FireflyIII\Models\LimitRepetition; | ||||
|  | ||||
| /** | ||||
|  * Class ReportHelper | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Report | ||||
|  */ | ||||
| class ReportHelper implements ReportHelperInterface | ||||
| { | ||||
|  | ||||
|     /** @var ReportQueryInterface */ | ||||
|     protected $query; | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @param ReportQueryInterface $query | ||||
|      * | ||||
|      */ | ||||
|     public function __construct(ReportQueryInterface $query) | ||||
|     { | ||||
|         $this->query = $query; | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * This method generates a full report for the given period on all | ||||
|      * the users asset and cash accounts. | ||||
|      * | ||||
|      * @param Carbon $date | ||||
|      * @param Carbon $end | ||||
|      * @param        $shared | ||||
|      * | ||||
|      * @return AccountCollection | ||||
|      */ | ||||
|     public function getAccountReport(Carbon $date, Carbon $end, $shared) | ||||
|     { | ||||
|  | ||||
|  | ||||
|         $accounts = $this->query->getAllAccounts($date, $end, $shared); | ||||
|         $start    = '0'; | ||||
|         $end      = '0'; | ||||
|         $diff     = '0'; | ||||
|         bcscale(2); | ||||
|  | ||||
|         // remove cash account, if any: | ||||
|         $accounts = $accounts->filter( | ||||
|             function (Account $account) { | ||||
|                 if ($account->accountType->type != 'Cash account') { | ||||
|                     return $account; | ||||
|                 } | ||||
|  | ||||
|                 return null; | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         // summarize: | ||||
|         foreach ($accounts as $account) { | ||||
|             $start = bcadd($start, $account->startBalance); | ||||
|             $end   = bcadd($end, $account->endBalance); | ||||
|             $diff  = bcadd($diff, bcsub($account->endBalance, $account->startBalance)); | ||||
|         } | ||||
|  | ||||
|         $object = new AccountCollection; | ||||
|         $object->setStart($start); | ||||
|         $object->setEnd($end); | ||||
|         $object->setDifference($diff); | ||||
|         $object->setAccounts($accounts); | ||||
|  | ||||
|         return $object; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * The balance report contains a Balance object which in turn contains: | ||||
|      * | ||||
|      * A BalanceHeader object which contains all relevant user asset accounts for the report. | ||||
|      * | ||||
|      * A number of BalanceLine objects, which hold: | ||||
|      * - A budget | ||||
|      * - A number of BalanceEntry objects. | ||||
|      * | ||||
|      * The BalanceEntry object holds: | ||||
|      *   - The same budget (again) | ||||
|      *   - A user asset account as mentioned in the BalanceHeader | ||||
|      *   - The amount of money spent on the budget by the user asset account | ||||
|      * | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return Balance | ||||
|      */ | ||||
|     public function getBalanceReport(Carbon $start, Carbon $end, $shared) | ||||
|     { | ||||
|         $repository    = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface'); | ||||
|         $tagRepository = app('FireflyIII\Repositories\Tag\TagRepositoryInterface'); | ||||
|         $balance       = new Balance; | ||||
|  | ||||
|         // build a balance header: | ||||
|         $header = new BalanceHeader; | ||||
|  | ||||
|         $accounts = $this->query->getAllAccounts($start, $end, $shared); | ||||
|         $budgets  = $repository->getBudgets(); | ||||
|         foreach ($accounts as $account) { | ||||
|             $header->addAccount($account); | ||||
|         } | ||||
|  | ||||
|         /** @var BudgetModel $budget */ | ||||
|         foreach ($budgets as $budget) { | ||||
|             $line = new BalanceLine; | ||||
|             $line->setBudget($budget); | ||||
|  | ||||
|             // get budget amount for current period: | ||||
|             $rep = $repository->getCurrentRepetition($budget, $start, $end); | ||||
|             $line->setRepetition($rep); | ||||
|  | ||||
|             // loop accounts: | ||||
|             foreach ($accounts as $account) { | ||||
|                 $balanceEntry = new BalanceEntry; | ||||
|                 $balanceEntry->setAccount($account); | ||||
|  | ||||
|                 // get spent: | ||||
|                 $spent = $this->query->spentInBudgetCorrected($account, $budget, $start, $end); // I think shared is irrelevant. | ||||
|  | ||||
|                 $balanceEntry->setSpent($spent); | ||||
|                 $line->addBalanceEntry($balanceEntry); | ||||
|             } | ||||
|             // add line to balance: | ||||
|             $balance->addBalanceLine($line); | ||||
|         } | ||||
|  | ||||
|         // then a new line for without budget. | ||||
|         // and one for the tags: | ||||
|         $empty    = new BalanceLine; | ||||
|         $tags     = new BalanceLine; | ||||
|         $diffLine = new BalanceLine; | ||||
|  | ||||
|         $tags->setRole(BalanceLine::ROLE_TAGROLE); | ||||
|         $diffLine->setRole(BalanceLine::ROLE_DIFFROLE); | ||||
|  | ||||
|         foreach ($accounts as $account) { | ||||
|             $spent = $this->query->spentNoBudget($account, $start, $end); | ||||
|             $left  = $tagRepository->coveredByBalancingActs($account, $start, $end); | ||||
|             bcscale(2); | ||||
|             $diff = bcsub($spent, $left); | ||||
|  | ||||
|             // budget | ||||
|             $budgetEntry = new BalanceEntry; | ||||
|             $budgetEntry->setAccount($account); | ||||
|             $budgetEntry->setSpent($spent); | ||||
|             $empty->addBalanceEntry($budgetEntry); | ||||
|  | ||||
|             // balanced by tags | ||||
|             $tagEntry = new BalanceEntry; | ||||
|             $tagEntry->setAccount($account); | ||||
|             $tagEntry->setLeft($left); | ||||
|             $tags->addBalanceEntry($tagEntry); | ||||
|  | ||||
|             // difference: | ||||
|             $diffEntry = new BalanceEntry; | ||||
|             $diffEntry->setAccount($account); | ||||
|             $diffEntry->setSpent($diff); | ||||
|             $diffLine->addBalanceEntry($diffEntry); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         $balance->addBalanceLine($empty); | ||||
|         $balance->addBalanceLine($tags); | ||||
|         $balance->addBalanceLine($diffLine); | ||||
|  | ||||
|         $balance->setBalanceHeader($header); | ||||
|  | ||||
|         return $balance; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * This method generates a full report for the given period on all | ||||
|      * the users bills and their payments. | ||||
|      * | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return BillCollection | ||||
|      */ | ||||
|     public function getBillReport(Carbon $start, Carbon $end) | ||||
|     { | ||||
|         /** @var \FireflyIII\Repositories\Bill\BillRepositoryInterface $repository */ | ||||
|         $repository = app('FireflyIII\Repositories\Bill\BillRepositoryInterface'); | ||||
|         $bills      = $repository->getBills(); | ||||
|         $collection = new BillCollection; | ||||
|  | ||||
|         /** @var Bill $bill */ | ||||
|         foreach ($bills as $bill) { | ||||
|             $billLine = new BillLine; | ||||
|             $billLine->setBill($bill); | ||||
|             $billLine->setActive(intval($bill->active) == 1); | ||||
|             $billLine->setMin($bill->amount_min); | ||||
|             $billLine->setMax($bill->amount_max); | ||||
|  | ||||
|             // is hit in period? | ||||
|             bcscale(2); | ||||
|             $set = $repository->getJournalsInRange($bill, $start, $end); | ||||
|             if ($set->count() == 0) { | ||||
|                 $billLine->setHit(false); | ||||
|             } else { | ||||
|                 $billLine->setHit(true); | ||||
|                 $amount = '0'; | ||||
|                 foreach ($set as $entry) { | ||||
|                     $amount = bcadd($amount, $entry->amount); | ||||
|                 } | ||||
|                 $billLine->setAmount($amount); | ||||
|             } | ||||
|  | ||||
|             $collection->addBill($billLine); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         return $collection; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return BudgetCollection | ||||
|      */ | ||||
|     public function getBudgetReport(Carbon $start, Carbon $end, $shared) | ||||
|     { | ||||
|         $object = new BudgetCollection; | ||||
|         /** @var \FireflyIII\Repositories\Budget\BudgetRepositoryInterface $repository */ | ||||
|         $repository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface'); | ||||
|         $set        = $repository->getBudgets(); | ||||
|  | ||||
|         bcscale(2); | ||||
|  | ||||
|         foreach ($set as $budget) { | ||||
|  | ||||
|             $repetitions = $repository->getBudgetLimitRepetitions($budget, $start, $end); | ||||
|  | ||||
|             // no repetition(s) for this budget: | ||||
|             if ($repetitions->count() == 0) { | ||||
|                 $spent      = $repository->balanceInPeriod($budget, $start, $end, $shared); | ||||
|                 $budgetLine = new BudgetLine; | ||||
|                 $budgetLine->setBudget($budget); | ||||
|                 $budgetLine->setOverspent($spent); | ||||
|                 $object->addOverspent($spent); | ||||
|                 $object->addBudgetLine($budgetLine); | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             // one or more repetitions for budget: | ||||
|             /** @var LimitRepetition $repetition */ | ||||
|             foreach ($repetitions as $repetition) { | ||||
|                 $budgetLine = new BudgetLine; | ||||
|                 $budgetLine->setBudget($budget); | ||||
|                 $budgetLine->setRepetition($repetition); | ||||
|                 $expenses  = $repository->balanceInPeriod($budget, $repetition->startdate, $repetition->enddate, $shared); | ||||
|                 $expenses = $expenses * -1; | ||||
|                 $left      = $expenses < $repetition->amount ? bcsub($repetition->amount, $expenses) : 0; | ||||
|                 $spent     = $expenses > $repetition->amount ? 0 : $expenses; | ||||
|                 $overspent = $expenses > $repetition->amount ? bcsub($expenses, $repetition->amount) : 0; | ||||
|  | ||||
|                 $budgetLine->setLeft($left); | ||||
|                 $budgetLine->setSpent($spent); | ||||
|                 $budgetLine->setOverspent($overspent); | ||||
|                 $budgetLine->setBudgeted($repetition->amount); | ||||
|  | ||||
|                 $object->addBudgeted($repetition->amount); | ||||
|                 $object->addSpent($spent); | ||||
|                 $object->addLeft($left); | ||||
|                 $object->addOverspent($overspent); | ||||
|                 $object->addBudgetLine($budgetLine); | ||||
|  | ||||
|             } | ||||
|  | ||||
|         } | ||||
|  | ||||
|         // stuff outside of budgets: | ||||
|         $noBudget   = $repository->getWithoutBudgetSum($start, $end); | ||||
|         $budgetLine = new BudgetLine; | ||||
|         $budgetLine->setOverspent($noBudget); | ||||
|         $object->addOverspent($noBudget); | ||||
|         $object->addBudgetLine($budgetLine); | ||||
|  | ||||
|         return $object; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return CategoryCollection | ||||
|      */ | ||||
|     public function getCategoryReport(Carbon $start, Carbon $end, $shared) | ||||
|     { | ||||
|         $object = new CategoryCollection; | ||||
|  | ||||
|  | ||||
|         /** | ||||
|          * GET CATEGORIES: | ||||
|          */ | ||||
|         /** @var \FireflyIII\Repositories\Category\CategoryRepositoryInterface $repository */ | ||||
|         $repository = app('FireflyIII\Repositories\Category\CategoryRepositoryInterface'); | ||||
|         $set        = $repository->getCategories(); | ||||
|         foreach ($set as $category) { | ||||
|             $spent = $repository->balanceInPeriod($category, $start, $end, $shared); | ||||
|             $category->spent = $spent; | ||||
|             $object->addCategory($category); | ||||
|             $object->addTotal($spent); | ||||
|         } | ||||
|  | ||||
|         return $object; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get a full report on the users expenses during the period. | ||||
|      * | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return Expense | ||||
|      */ | ||||
|     public function getExpenseReport($start, $end, $shared) | ||||
|     { | ||||
|         $object = new Expense; | ||||
|         $set    = $this->query->expenseInPeriodCorrected($start, $end, $shared); | ||||
|         foreach ($set as $entry) { | ||||
|             $object->addToTotal($entry->amount_positive); | ||||
|             $object->addOrCreateExpense($entry); | ||||
|         } | ||||
|  | ||||
|         return $object; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get a full report on the users incomes during the period. | ||||
|      * | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return Income | ||||
|      */ | ||||
|     public function getIncomeReport($start, $end, $shared) | ||||
|     { | ||||
|         $object = new Income; | ||||
|         $set    = $this->query->incomeInPeriodCorrected($start, $end, $shared); | ||||
|         foreach ($set as $entry) { | ||||
|             $object->addToTotal($entry->amount_positive); | ||||
|             $object->addOrCreateIncome($entry); | ||||
|         } | ||||
|  | ||||
|         return $object; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon $date | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function listOfMonths(Carbon $date) | ||||
|     { | ||||
|  | ||||
|         $start  = clone $date; | ||||
|         $end    = Carbon::now(); | ||||
|         $months = []; | ||||
|         while ($start <= $end) { | ||||
|             $year            = $start->year; | ||||
|             $months[$year][] = [ | ||||
|                 'formatted' => $start->formatLocalized('%B %Y'), | ||||
|                 'month'     => $start->month, | ||||
|                 'year'      => $year, | ||||
|             ]; | ||||
|             $start->addMonth(); | ||||
|         } | ||||
|  | ||||
|         return $months; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										101
									
								
								app/Helpers/Report/ReportHelperInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								app/Helpers/Report/ReportHelperInterface.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Report; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Helpers\Collection\Account as AccountCollection; | ||||
| use FireflyIII\Helpers\Collection\Balance; | ||||
| use FireflyIII\Helpers\Collection\Bill as BillCollection; | ||||
| use FireflyIII\Helpers\Collection\Budget as BudgetCollection; | ||||
| use FireflyIII\Helpers\Collection\Category as CategoryCollection; | ||||
| use FireflyIII\Helpers\Collection\Expense; | ||||
| use FireflyIII\Helpers\Collection\Income; | ||||
|  | ||||
| /** | ||||
|  * Interface ReportHelperInterface | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Report | ||||
|  */ | ||||
| interface ReportHelperInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * This method generates a full report for the given period on all | ||||
|      * the users asset and cash accounts. | ||||
|      * | ||||
|      * @param Carbon  $date | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return AccountCollection | ||||
|      */ | ||||
|     public function getAccountReport(Carbon $date, Carbon $end, $shared); | ||||
|  | ||||
|     /** | ||||
|      * This method generates a full report for the given period on all | ||||
|      * the users bills and their payments. | ||||
|      * | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return BillCollection | ||||
|      */ | ||||
|     public function getBillReport(Carbon $start, Carbon $end); | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return Balance | ||||
|      */ | ||||
|     public function getBalanceReport(Carbon $start, Carbon $end, $shared); | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return BudgetCollection | ||||
|      */ | ||||
|     public function getBudgetReport(Carbon $start, Carbon $end, $shared); | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return CategoryCollection | ||||
|      */ | ||||
|     public function getCategoryReport(Carbon $start, Carbon $end, $shared); | ||||
|  | ||||
|     /** | ||||
|      * Get a full report on the users expenses during the period. | ||||
|      * | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return Expense | ||||
|      */ | ||||
|     public function getExpenseReport($start, $end, $shared); | ||||
|  | ||||
|     /** | ||||
|      * Get a full report on the users incomes during the period. | ||||
|      * | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return Income | ||||
|      */ | ||||
|     public function getIncomeReport($start, $end, $shared); | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon $date | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function listOfMonths(Carbon $date); | ||||
|  | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user