mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 18:54:58 +00:00 
			
		
		
		
	Compare commits
	
		
			1154 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 5f299b895b | ||
|  | 4e1bb5fbac | ||
|  | 47ccc513ad | ||
|  | cce1a01936 | ||
|  | 6f2b1a6a76 | ||
|  | 8526907f50 | ||
|  | bc192a8e54 | ||
|  | 9ff6f8fc52 | ||
|  | 6573bd6b4b | ||
|  | 9dc3f614af | ||
|  | 3888b8cceb | ||
|  | 294df4a2b3 | ||
|  | 265dd37212 | ||
|  | eb7c79ad27 | ||
|  | de111c7100 | ||
|  | e892c9a824 | ||
|  | 5eb0e18cae | ||
|  | 27cabb398e | ||
|  | 64dbb14241 | ||
|  | bb4e2be9eb | ||
|  | 7d1de0da17 | ||
|  | bf16c9a42b | ||
|  | 1a7b1ce499 | ||
|  | efc9bc71a7 | ||
|  | fc5b315af0 | ||
|  | 7a4a78628d | ||
|  | d16fb30a62 | ||
|  | 2d177e660e | ||
|  | 2f131dc170 | ||
|  | 94810e371a | ||
|  | 59731878f6 | ||
|  | 54ede8aa18 | ||
|  | b415b6b043 | ||
|  | 70c922cdc5 | ||
|  | 068fc32cb2 | ||
|  | 3dcdacc3b8 | ||
|  | a6594358d8 | ||
|  | f98921da46 | ||
|  | 25747fbcf2 | ||
|  | aac5c2b13c | ||
|  | cc810a5b6f | ||
|  | 1b3592d959 | ||
|  | d75614e9a7 | ||
|  | 08703e282f | ||
|  | 2904baf44e | ||
|  | f99e46bf75 | ||
|  | 9f87890ead | ||
|  | 638184cf66 | ||
|  | 03babfe75c | ||
|  | 238ed3c788 | ||
|  | 6a9d931ba3 | ||
|  | a3d2a9e00b | ||
|  | 39b88e8207 | ||
|  | 449c6dfde5 | ||
|  | 7cc47ca0b1 | ||
|  | 95f4a83f41 | ||
|  | 35154dc7a3 | ||
|  | 0fd0d7d080 | ||
|  | 658265c938 | ||
|  | 38fe9e7e1c | ||
|  | 77056dcf8d | ||
|  | 026683a8e1 | ||
|  | 6ab6dd6ac3 | ||
|  | 83de3482ce | ||
|  | 919a35aed3 | ||
|  | ad3defb071 | ||
|  | 9c929ecd1b | ||
|  | f79c9f7cf1 | ||
|  | 8e75c345d9 | ||
|  | 44886d9aad | ||
|  | c2d444347d | ||
|  | 5cb497596d | ||
|  | 1857469d2f | ||
|  | ea71b4843d | ||
|  | 97727e2e3d | ||
|  | f81e7da8bb | ||
|  | 8e827bf83b | ||
|  | 9e1fa284ca | ||
|  | 3bf800be6e | ||
|  | 635b9f9dba | ||
|  | 52a0d7cf7b | ||
|  | a34516932b | ||
|  | 929a2a30a2 | ||
|  | ffa88eeb08 | ||
|  | 51b45b4ed4 | ||
|  | f263844793 | ||
|  | 18c46df9aa | ||
|  | 15846e157b | ||
|  | bc59f2db0d | ||
|  | cd2be8c1a4 | ||
|  | f958115c50 | ||
|  | e7d677bfb6 | ||
|  | 3e80ffc52b | ||
|  | d0c7a5c076 | ||
|  | f3f4e6b354 | ||
|  | 5a45b25614 | ||
|  | 0b5ee1edfc | ||
|  | da3dc599f9 | ||
|  | f013b435ab | ||
|  | 5f6975a113 | ||
|  | c5dee29e4b | ||
|  | 633ee02f13 | ||
|  | 6b750c909a | ||
|  | 5f8b6640a9 | ||
|  | dd42d8437c | ||
|  | 67a178591d | ||
|  | f5e5659c1f | ||
|  | 8b0f0fb615 | ||
|  | 209116e766 | ||
|  | 79392ab656 | ||
|  | 3ca1207231 | ||
|  | cec1b147f2 | ||
|  | 46cfcfa3e7 | ||
|  | b833e8dfa2 | ||
|  | 77b843efd8 | ||
|  | db72ad7c60 | ||
|  | eadc630fcb | ||
|  | 170c1793cc | ||
|  | 9f7c6c2d0c | ||
|  | 72d054c55c | ||
|  | 524edfe7c2 | ||
|  | c25c5623d2 | ||
|  | 4f38b77ef6 | ||
|  | 5862803434 | ||
|  | 5b3beded39 | ||
|  | c61fb7a598 | ||
|  | 33d9148029 | ||
|  | 63969f5a33 | ||
|  | edde18aeef | ||
|  | 657116d361 | ||
|  | e16269daa8 | ||
|  | c07591ff5c | ||
|  | 75a478ad54 | ||
|  | 8dae8b1a7f | ||
|  | 15fd8cf486 | ||
|  | 55333156ac | ||
|  | 8cdcba3231 | ||
|  | 8bab9e84e2 | ||
|  | 2faae83912 | ||
|  | 5a61a11a61 | ||
|  | a6d71988f2 | ||
|  | 7069e242ae | ||
|  | 56ee830558 | ||
|  | 6dd12729e6 | ||
|  | 14a48303cb | ||
|  | 72cf6c9c0f | ||
|  | 144ee6b8ca | ||
|  | 8967d86da6 | ||
|  | 18c6edbb5d | ||
|  | 53de3c4717 | ||
|  | ad577e4e81 | ||
|  | 44811a3e7c | ||
|  | 1ab3f05b3a | ||
|  | 5e76488ae7 | ||
|  | 32771fe7e1 | ||
|  | 9b40cc6881 | ||
|  | 2e35260bbb | ||
|  | a067704277 | ||
|  | de281818ac | ||
|  | c49bfad38d | ||
|  | c1ba591b26 | ||
|  | 719af38a61 | ||
|  | ac61dfae6b | ||
|  | 813fb679a7 | ||
|  | e7562781f7 | ||
|  | 56d36b7f53 | ||
|  | 53b3f7f821 | ||
|  | 08a53156bd | ||
|  | 8985cd6309 | ||
|  | 3833da7410 | ||
|  | 4210cd10db | ||
|  | a7bd1c6892 | ||
|  | 52b0111afa | ||
|  | 7921d128e4 | ||
|  | d7e838701a | ||
|  | 289bcb22aa | ||
|  | 3fe57b7983 | ||
|  | 32e92c2a16 | ||
|  | 1b3d208540 | ||
|  | 6a8bf0aa62 | ||
|  | 56715556ed | ||
|  | 838330b909 | ||
|  | 69553b138b | ||
|  | 36d7a02994 | ||
|  | 301528e2d2 | ||
|  | 0303b45707 | ||
|  | ba722e8ed5 | ||
|  | 289e5a5442 | ||
|  | fdad96e2bc | ||
|  | af994e4dae | ||
|  | 006d68e279 | ||
|  | 29dc122ad3 | ||
|  | cf4a8c6204 | ||
|  | 3c73fe92bf | ||
|  | 6637590797 | ||
|  | b8bab11acd | ||
|  | a2f600feac | ||
|  | 80dd62ef0a | ||
|  | 827b1c9cd8 | ||
|  | 2e4fcf803d | ||
|  | d00d95fc6f | ||
|  | 3e3ab9bd25 | ||
|  | 6eecc7722d | ||
|  | ada4aaf69a | ||
|  | 93244c1f78 | ||
|  | be056cea6b | ||
|  | 659ca8be14 | ||
|  | ea9af8366d | ||
|  | 80edd47d36 | ||
|  | d7746b3649 | ||
|  | c4c4fbc34c | ||
|  | 59f57c96e9 | ||
|  | a2f852fecf | ||
|  | ad114ed329 | ||
|  | c4c3d0f07f | ||
|  | 6cf8102de5 | ||
|  | e7e4aa2218 | ||
|  | 6d84f4b6c1 | ||
|  | ce3e9ffd11 | ||
|  | 3ada260e0e | ||
|  | 8fdd0cb795 | ||
|  | 913e05a2e6 | ||
|  | fa1f703ef6 | ||
|  | 4004c53e1b | ||
|  | 4838670649 | ||
|  | a985e09282 | ||
|  | 9bd1503cb4 | ||
|  | a2ccbf7844 | ||
|  | 61bbe8a905 | ||
|  | 59bc5d22d1 | ||
|  | 1423d5b314 | ||
|  | 152d0eb1d0 | ||
|  | 6426d1df06 | ||
|  | 9284eb3fe9 | ||
|  | afdae8bc1e | ||
|  | 2a7085e593 | ||
|  | 2408fb3ed4 | ||
|  | 8316afb176 | ||
|  | e59fd098a3 | ||
|  | e044199693 | ||
|  | 8f8e29fc22 | ||
|  | 8de5384158 | ||
|  | 216c659335 | ||
|  | 041ca8a5d3 | ||
|  | fe4f1b306d | ||
|  | a0972d99fb | ||
|  | e332bfef7c | ||
|  | cba5e226d8 | ||
|  | 5aff0c4943 | ||
|  | cb49c00f4d | ||
|  | e26d797d57 | ||
|  | 938581527e | ||
|  | c38ae09735 | ||
|  | 28c3cfe084 | ||
|  | 4a2823bcba | ||
|  | 18eba02026 | ||
|  | d4690ce580 | ||
|  | a785c450b1 | ||
|  | 7480dc4a19 | ||
|  | ad01891a67 | ||
|  | 67fe35d564 | ||
|  | 7f19b6957a | ||
|  | 0a54caf202 | ||
|  | 4b4c1c7f8f | ||
|  | d071f3947e | ||
|  | b3d99cd210 | ||
|  | 90e696f82c | ||
|  | 958fcd1cfa | ||
|  | 8f57c7dcb3 | ||
|  | 77262f52a4 | ||
|  | 16bfbc8a12 | ||
|  | 1fd375b875 | ||
|  | 46131ad39d | ||
|  | 0b5c5b2ae9 | ||
|  | 55be174037 | ||
|  | a17b7025f1 | ||
|  | 170cf7fd77 | ||
|  | 23cdb4d326 | ||
|  | cbbe529572 | ||
|  | 0b382426e9 | ||
|  | 1cbbf9baa4 | ||
|  | 8d41ff7b79 | ||
|  | e3b6057bf8 | ||
|  | 66a4042cad | ||
|  | 56c08d8302 | ||
|  | d4e759754d | ||
|  | a96e171cbf | ||
|  | bd4a8c8397 | ||
|  | 04f71b3b43 | ||
|  | d124de51db | ||
|  | d87d12a0f5 | ||
|  | f2b08346d0 | ||
|  | d3682a6727 | ||
|  | 371bbd9508 | ||
|  | a8a28f442f | ||
|  | 65ddd8a736 | ||
|  | 8bb27de233 | ||
|  | 37e2f097ba | ||
|  | 1966d87ce6 | ||
|  | 7b8c86e1e3 | ||
|  | de634da513 | ||
|  | 96836e2d6c | ||
|  | 8a9d576f61 | ||
|  | 791d12fbb4 | ||
|  | d1329be2fa | ||
|  | 3ed6561702 | ||
|  | 7a0587f433 | ||
|  | 0fe682bfe6 | ||
|  | 0f685e8789 | ||
|  | 420771c233 | ||
|  | 5e3e9271ca | ||
|  | 1e603c0833 | ||
|  | 03e1673e92 | ||
|  | 9f992f003d | ||
|  | f50244a41f | ||
|  | 8b9607f9b5 | ||
|  | af107ad5e8 | ||
|  | 8926d62165 | ||
|  | 45344ee347 | ||
|  | baf9ebab15 | ||
|  | b7dab817f2 | ||
|  | fb2fa54480 | ||
|  | 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 | 
							
								
								
									
										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/*" | ||||||
| @@ -1,3 +1 @@ | |||||||
| src_dir: . | src_dir: . | ||||||
| coverage_clover: storage/coverage/clover.xml |  | ||||||
| json_path: storage/coverage/coveralls-upload.json |  | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								.env.example
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								.env.example
									
									
									
									
									
								
							| @@ -1,6 +1,7 @@ | |||||||
| APP_ENV=production | APP_ENV=production | ||||||
| APP_DEBUG=false | APP_DEBUG=false | ||||||
| APP_KEY=SomeRandomString | APP_KEY=SomeRandomStringOf32CharsExactly | ||||||
|  |  | ||||||
|  |  | ||||||
| DB_CONNECTION=mysql | DB_CONNECTION=mysql | ||||||
| DB_HOST=localhost | DB_HOST=localhost | ||||||
| @@ -11,8 +12,19 @@ DB_PASSWORD=secret | |||||||
| CACHE_DRIVER=file | CACHE_DRIVER=file | ||||||
| SESSION_DRIVER=file | SESSION_DRIVER=file | ||||||
|  |  | ||||||
|  | DEFAULT_CURRENCY=EUR | ||||||
|  | DEFAULT_LANGUAGE=en_US | ||||||
|  |  | ||||||
| EMAIL_SMTP= | EMAIL_SMTP= | ||||||
| EMAIL_DRIVER=smtp | EMAIL_DRIVER=smtp | ||||||
| EMAIL_USERNAME= | EMAIL_USERNAME= | ||||||
| EMAIL_PASSWORD= | EMAIL_PASSWORD= | ||||||
| ANALYTICS_ID= | EMAIL_PRETEND=false | ||||||
|  |  | ||||||
|  | SHOW_INCOMPLETE_TRANSLATIONS=false | ||||||
|  |  | ||||||
|  | ANALYTICS_ID= | ||||||
|  | RUNCLEANUP=true | ||||||
|  | SITE_OWNER=mail@example.com | ||||||
|  |  | ||||||
|  | BLOCKED_DOMAINS= | ||||||
| @@ -14,4 +14,5 @@ SESSION_DRIVER=array | |||||||
| EMAIL_SMTP= | EMAIL_SMTP= | ||||||
| EMAIL_USERNAME= | EMAIL_USERNAME= | ||||||
| EMAIL_PASSWORD= | EMAIL_PASSWORD= | ||||||
| ANALYTICS_ID=ABC | ANALYTICS_ID=ABC | ||||||
|  | EMAIL_PRETEND=true | ||||||
							
								
								
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -5,7 +5,7 @@ Thumbs.db | |||||||
| .idea/ | .idea/ | ||||||
| tests/_output/* | tests/_output/* | ||||||
| _ide_helper.php | _ide_helper.php | ||||||
| /build/logs/clover.xml | /build/logs | ||||||
| index.html* | index.html* | ||||||
| app/storage/firefly-export* | app/storage/firefly-export* | ||||||
| .vagrant | .vagrant | ||||||
| @@ -31,3 +31,6 @@ addNewLines.php | |||||||
| .phpstorm.meta.php | .phpstorm.meta.php | ||||||
| .env.backup | .env.backup | ||||||
| .env.local | .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 | ||||||
							
								
								
									
										10
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								.travis.yml
									
									
									
									
									
								
							| @@ -6,17 +6,13 @@ php: | |||||||
|   - 5.5 |   - 5.5 | ||||||
|   - 5.6 |   - 5.6 | ||||||
|  |  | ||||||
| addons: |  | ||||||
|   code_climate: |  | ||||||
|     repo_token: 26489f9e854fcdf7e7660ba29c1455694685465b1f90329a79f7d2bf448acb61 |  | ||||||
|  |  | ||||||
| install: | install: | ||||||
|   - composer update |   - composer update | ||||||
|   - php artisan env |   - php artisan env | ||||||
|   - mv -v .env.testing .env |   - mv -v .env.testing .env | ||||||
|  |   - touch storage/database/testing.db | ||||||
|  |   - php artisan migrate --env=testing | ||||||
|  |   - php artisan migrate --seed --env=testing | ||||||
|  |  | ||||||
| script: | script: | ||||||
|   - phpunit |   - phpunit | ||||||
|  |  | ||||||
| after_script: |  | ||||||
|   - php vendor/bin/coveralls |  | ||||||
|   | |||||||
							
								
								
									
										156
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										156
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,88 +1,130 @@ | |||||||
| Firefly III (v3.4.0.3) | # Firefly III | ||||||
| =========== |  | ||||||
|  |  | ||||||
| [](https://travis-ci.org/JC5/firefly-iii) | [](https://packagist.org/packages/grumpydictator/firefly-iii) | ||||||
| [](http://stillmaintained.com/JC5/firefly-iii) | [](https://packagist.org/packages/grumpydictator/firefly-iii) | ||||||
| [](https://insight.sensiolabs.com/projects/d44c7012-5f50-41ad-add8-8445330e4102) |  | ||||||
| [](https://codeclimate.com/github/JC5/firefly-iii) |  | ||||||
| [](https://coveralls.io/r/JC5/firefly-iii?branch=master) |  | ||||||
| [](https://coveralls.io/r/JC5/firefly-iii?branch=develop) |  | ||||||
|  |  | ||||||
| [](https://packagist.org/packages/grumpydictator/firefly-iii) | [](https://scrutinizer-ci.com/g/JC5/firefly-iii/?branch=master) | ||||||
| [](https://packagist.org/packages/grumpydictator/firefly-iii) | [](https://scrutinizer-ci.com/g/JC5/firefly-iii/build-status/master) | ||||||
| [](https://packagist.org/packages/grumpydictator/firefly-iii) |  | ||||||
| [](https://packagist.org/packages/grumpydictator/firefly-iii) |  | ||||||
|  |  | ||||||
| Firefly III is a tool to help you manage your finances. Please read the full description [in the wiki](https://github.com/JC5/firefly-iii/wiki/full-description). | ## About | ||||||
|  |  | ||||||
| Firefly Mark III is a new version of Firefly built upon best practices and lessons learned | "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  | ||||||
| from building [Firefly](https://github.com/JC5/Firefly). It's Mark III since the original Firefly never made it outside of my | household accounts and savings accounts! It's pretty fancy. You should use it to save and organise money. | ||||||
| laptop and [Firefly II](https://github.com/JC5/Firefly) is live. |  | ||||||
|  |  | ||||||
| If you're not sure if this tool is for you, please read the [full description](https://github.com/JC5/firefly-iii/wiki/full-description). |  | ||||||
|  |  | ||||||
| To install and use Firefly III, 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. | 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. | ||||||
|  |  | ||||||
|  | #### A quick technical overview | ||||||
|  |  | ||||||
|  | Firefly is a system you'll have install yourself on webhosting of your choosing. It needs PHP and MySQL. The current version of Firefly III requires PHP 5.6.4 or | ||||||
|  | higher. Soon, this will be PHP 7.0.0 or higher. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #### 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 | ## Current features | ||||||
|  |  | ||||||
| - [A double-entry bookkeeping system](https://en.wikipedia.org/wiki/Double-entry_bookkeeping_system); | - [A double-entry bookkeeping system](https://en.wikipedia.org/wiki/Double-entry_bookkeeping_system); | ||||||
| - You can store, edit and remove withdrawals, deposits and transfers. This allows you full financial management; | - 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 | - You can manage different types of accounts; | ||||||
|   - Asset accounts |   - [Asset](https://en.wikipedia.org/wiki/Asset) accounts | ||||||
|   - Shared asset accounts (household accounts) |   - Shared [asset accounts](https://en.wikipedia.org/wiki/Asset) ([household accounts](https://en.wikipedia.org/wiki/Household)) | ||||||
|   - Saving accounts |   - Saving accounts | ||||||
|   - Credit cards |   - Credit cards | ||||||
| - It's possible to create, change and manage money using _[budgets](https://en.wikipedia.org/wiki/Envelope_system)_; | - It's possible to create, change and manage money using _[budgets](https://en.wikipedia.org/wiki/Envelope_system)_; | ||||||
| - Organize transactions using categories; | - Organize transactions using categories; | ||||||
| - Save towards a goal using piggy banks; | - Save towards a goal using [piggy banks](https://en.wikipedia.org/wiki/Piggy_bank); | ||||||
| - Predict and anticipate bills; | - Predict and anticipate [bills](https://en.wikipedia.org/wiki/Invoice); | ||||||
| - View income / expense reports; | - View income / expense [reports](https://en.wikipedia.org/wiki/Financial_statement); | ||||||
| - Lots of help text in case you don't get it; | - Organize expenses using tags; | ||||||
|  | - Lots of help text in case you don't get it. | ||||||
|  |  | ||||||
| Everything is organised: | Everything is organised: | ||||||
|  |  | ||||||
| - Clear views that should show you how you're doing; | - Clear views that should show you how you're doing; | ||||||
| - Easy navigation through your records; | - Easy navigation through your records; | ||||||
| - Browse back and forth to see previous months or even years; | - Browse back and forth to see previous months or even years; | ||||||
| - Lots of charts because we all love them. | - Lots of charts because we all love them; | ||||||
| - Financial reporting showing you how well you are doing; | - Financial reporting showing you how well you are doing. | ||||||
|  |  | ||||||
| ## Changes |  | ||||||
|  |  | ||||||
| Firefly III will feature, but does not feature yet: |  | ||||||
|  |  | ||||||
|  |  | ||||||
| - More control over other resources outside of personal finance |  | ||||||
|   - Debts |  | ||||||
| - More test-coverage; |  | ||||||
| - 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. |  | ||||||
| - Any other features I might not have thought of. |  | ||||||
|  |  | ||||||
| Some stuff has been removed: |  | ||||||
|  |  | ||||||
| - The nesting of budgets, categories and beneficiaries is removed because it was pretty pointless. |  | ||||||
|  |  | ||||||
| ## Screenshots | ## 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 month. It's a trial. | ||||||
|  |  | ||||||
|  | ## Security | ||||||
|  |  | ||||||
|  | You should always run Firefly III on a site with TLS enabled (https://). Please note that although some parts of the | ||||||
|  | database are encrypted (transaction descriptions, names, etc.) some parts are _not_ (amounts, dates, etc). If you need | ||||||
|  | more security, you must enable transparent database encryption or a comparable technology. Please remember that this | ||||||
|  | is open source software under active development, and it is in no way guaranteed to be safe or secure. | ||||||
|  |  | ||||||
|  | ## Translations | ||||||
|  |  | ||||||
|  | Firefly III is currently available in Dutch and English. Support for other languages is being worked on. I could use | ||||||
|  | your help. Checkout [Crowdin](https://crowdin.com/project/firefly-iii) for more information. | ||||||
|  |  | ||||||
|  | ## 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)) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ## Current state | ## Current state | ||||||
| I have the basics up and running. Test coverage is currently coming, slowly. |  | ||||||
|  |  | ||||||
| Questions, ideas or other things to contribute? [Let me know](https://github.com/JC5/firefly-iii/issues/new)! | Firefly III is pretty much all grown up. Full test coverage (nerd alert!) is coming. Translations are a work in progress. | ||||||
|  |  | ||||||
|  | Questions, ideas, bugs or other things to contribute? [Let me know](https://github.com/JC5/firefly-iii/issues/new)! | ||||||
|  |  | ||||||
|  | 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). | ||||||
|  |  | ||||||
|  | [](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) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ | |||||||
| /** | /** | ||||||
|  * Class Command |  * Class Command | ||||||
|  * |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  * @package FireflyIII\Commands |  * @package FireflyIII\Commands | ||||||
|  */ |  */ | ||||||
| abstract class Command | abstract class Command | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ use Illuminate\Foundation\Console\Kernel as ConsoleKernel; | |||||||
| /** | /** | ||||||
|  * Class Kernel |  * Class Kernel | ||||||
|  * |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  * @package FireflyIII\Console |  * @package FireflyIII\Console | ||||||
|  */ |  */ | ||||||
| class Kernel extends ConsoleKernel | class Kernel extends ConsoleKernel | ||||||
| @@ -25,6 +26,8 @@ class Kernel extends ConsoleKernel | |||||||
|      * |      * | ||||||
|      * @param  \Illuminate\Console\Scheduling\Schedule $schedule |      * @param  \Illuminate\Console\Scheduling\Schedule $schedule | ||||||
|      * |      * | ||||||
|  |      * @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||||
|  |      * | ||||||
|      * @return void |      * @return void | ||||||
|      */ |      */ | ||||||
|     protected function schedule(Schedule $schedule) |     protected function schedule(Schedule $schedule) | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ | |||||||
| /** | /** | ||||||
|  * Class Event |  * Class Event | ||||||
|  * |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  * @package FireflyIII\Events |  * @package FireflyIII\Events | ||||||
|  */ |  */ | ||||||
| abstract class Event | abstract class Event | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ use Illuminate\Queue\SerializesModels; | |||||||
| /** | /** | ||||||
|  * Class JournalCreated |  * Class JournalCreated | ||||||
|  * |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  * @package FireflyIII\Events |  * @package FireflyIII\Events | ||||||
|  */ |  */ | ||||||
| class JournalCreated extends Event | class JournalCreated extends Event | ||||||
|   | |||||||
| @@ -1,24 +0,0 @@ | |||||||
| <?php namespace FireflyIII\Events; |  | ||||||
|  |  | ||||||
| use Illuminate\Queue\SerializesModels; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Class JournalDeleted |  | ||||||
|  * |  | ||||||
|  * @package FireflyIII\Events |  | ||||||
|  */ |  | ||||||
| class JournalDeleted extends Event |  | ||||||
| { |  | ||||||
|  |  | ||||||
|     use SerializesModels; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Create a new event instance. |  | ||||||
|      * |  | ||||||
|      */ |  | ||||||
|     public function __construct() |  | ||||||
|     { |  | ||||||
|         // |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @@ -6,6 +6,7 @@ use Illuminate\Queue\SerializesModels; | |||||||
| /** | /** | ||||||
|  * Class JournalSaved |  * Class JournalSaved | ||||||
|  * |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  * @package FireflyIII\Events |  * @package FireflyIII\Events | ||||||
|  */ |  */ | ||||||
| class JournalSaved extends Event | class JournalSaved extends Event | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ namespace FireflyIII\Exceptions; | |||||||
| /** | /** | ||||||
|  * Class FireflyException |  * Class FireflyException | ||||||
|  * |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  * @package FireflyIII\Exceptions |  * @package FireflyIII\Exceptions | ||||||
|  */ |  */ | ||||||
| class FireflyException extends \Exception | class FireflyException extends \Exception | ||||||
|   | |||||||
| @@ -2,10 +2,12 @@ | |||||||
|  |  | ||||||
| use Exception; | use Exception; | ||||||
| use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; | use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; | ||||||
|  | use Symfony\Component\HttpKernel\Exception\HttpException; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class Handler |  * Class Handler | ||||||
|  * |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  * @package FireflyIII\Exceptions |  * @package FireflyIII\Exceptions | ||||||
|  */ |  */ | ||||||
| class Handler extends ExceptionHandler | class Handler extends ExceptionHandler | ||||||
| @@ -26,12 +28,13 @@ class Handler extends ExceptionHandler | |||||||
|      * |      * | ||||||
|      * @param  \Illuminate\Http\Request $request |      * @param  \Illuminate\Http\Request $request | ||||||
|      * @param  \Exception               $e |      * @param  \Exception               $e | ||||||
|  |      * @SuppressWarnings(PHPMD.ShortVariable) | ||||||
|      * |      * | ||||||
|      * @return \Illuminate\Http\Response |      * @return \Illuminate\Http\Response | ||||||
|      */ |      */ | ||||||
|     public function render($request, Exception $e) |     public function render($request, Exception $e) | ||||||
|     { |     { | ||||||
|         if ($this->isHttpException($e)) { |         if ($e instanceof HttpException) { | ||||||
|             return $this->renderHttpException($e); |             return $this->renderHttpException($e); | ||||||
|         } else { |         } else { | ||||||
|             return parent::render($request, $e); |             return parent::render($request, $e); | ||||||
| @@ -42,6 +45,7 @@ class Handler extends ExceptionHandler | |||||||
|      * Report or log an exception. |      * Report or log an exception. | ||||||
|      * |      * | ||||||
|      * This is a great spot to send exceptions to Sentry, Bugsnag, etc. |      * This is a great spot to send exceptions to Sentry, Bugsnag, etc. | ||||||
|  |      * @SuppressWarnings(PHPMD.ShortVariable) | ||||||
|      * |      * | ||||||
|      * @param  \Exception $e |      * @param  \Exception $e | ||||||
|      * |      * | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ namespace FireflyIII\Exceptions; | |||||||
| /** | /** | ||||||
|  * Class NotImplementedException |  * Class NotImplementedException | ||||||
|  * |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  * @package FireflyIII\Exceptions |  * @package FireflyIII\Exceptions | ||||||
|  */ |  */ | ||||||
| class NotImplementedException extends \Exception | class NotImplementedException extends \Exception | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ namespace FireflyIII\Exceptions; | |||||||
| /** | /** | ||||||
|  * Class ValidationExceptions |  * Class ValidationExceptions | ||||||
|  * |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  * @package FireflyIII\Exception |  * @package FireflyIII\Exception | ||||||
|  */ |  */ | ||||||
| class ValidationException extends \Exception | class ValidationException extends \Exception | ||||||
|   | |||||||
							
								
								
									
										43
									
								
								app/Generator/Chart/Account/AccountChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								app/Generator/Chart/Account/AccountChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | |||||||
|  | <?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 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); | ||||||
|  | } | ||||||
							
								
								
									
										187
									
								
								app/Generator/Chart/Account/ChartJsAccountChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								app/Generator/Chart/Account/ChartJsAccountChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,187 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace FireflyIII\Generator\Chart\Account; | ||||||
|  |  | ||||||
|  | use Carbon\Carbon; | ||||||
|  | use FireflyIII\Models\Account; | ||||||
|  | use Illuminate\Support\Collection; | ||||||
|  | use Steam; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Class ChartJsAccountChartGenerator | ||||||
|  |  * | ||||||
|  |  * @package FireflyIII\Generator\Chart\Account | ||||||
|  |  */ | ||||||
|  | class ChartJsAccountChartGenerator implements AccountChartGenerator | ||||||
|  | { | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @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: | ||||||
|  |         $format  = trans('config.month_and_day'); | ||||||
|  |         $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; | ||||||
|  |             $range    = Steam::balanceInRange($account, $start, clone $end); | ||||||
|  |             $previous = array_values($range)[0]; | ||||||
|  |             while ($current <= $end) { | ||||||
|  |                 $format  = $current->format('Y-m-d'); | ||||||
|  |                 $balance = isset($range[$format]) ? $range[$format] : $previous; | ||||||
|  |  | ||||||
|  |                 $set['data'][] = $balance; | ||||||
|  |                 $previous      = $balance; | ||||||
|  |                 $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: | ||||||
|  |         $format = trans('config.month_and_day'); | ||||||
|  |  | ||||||
|  |         $data     = [ | ||||||
|  |             'count'    => 1, | ||||||
|  |             'labels'   => [], | ||||||
|  |             'datasets' => [ | ||||||
|  |                 [ | ||||||
|  |                     'label' => $account->name, | ||||||
|  |                     'data'  => [] | ||||||
|  |                 ] | ||||||
|  |             ], | ||||||
|  |         ]; | ||||||
|  |         $range    = Steam::balanceInRange($account, $start, $end); | ||||||
|  |         $current  = clone $start; | ||||||
|  |         $previous = array_values($range)[0]; | ||||||
|  |  | ||||||
|  |         while ($end >= $current) { | ||||||
|  |             $theDate = $current->format('Y-m-d'); | ||||||
|  |             $balance = isset($range[$theDate]) ? $range[$theDate] : $previous; | ||||||
|  |  | ||||||
|  |             $data['labels'][]              = $current->formatLocalized($format); | ||||||
|  |             $data['datasets'][0]['data'][] = $balance; | ||||||
|  |             $previous                      = $balance; | ||||||
|  |             $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 string $paid | ||||||
|  |      * @param string $unpaid | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function frontpage($paid, $unpaid); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param Bill       $bill | ||||||
|  |      * @param Collection $entries | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function single(Bill $bill, Collection $entries); | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										89
									
								
								app/Generator/Chart/Bill/ChartJsBillChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								app/Generator/Chart/Bill/ChartJsBillChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace FireflyIII\Generator\Chart\Bill; | ||||||
|  |  | ||||||
|  | use FireflyIII\Models\Bill; | ||||||
|  | use FireflyIII\Models\TransactionJournal; | ||||||
|  | use Illuminate\Support\Collection; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Class ChartJsBillChartGenerator | ||||||
|  |  * | ||||||
|  |  * @package FireflyIII\Generator\Chart\Bill | ||||||
|  |  */ | ||||||
|  | class ChartJsBillChartGenerator implements BillChartGenerator | ||||||
|  | { | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param string $paid | ||||||
|  |      * @param string $unpaid | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function frontpage($paid, $unpaid) | ||||||
|  |     { | ||||||
|  |         bcscale(2); | ||||||
|  |         $data = [ | ||||||
|  |             [ | ||||||
|  |                 'value'     => round($unpaid, 2), | ||||||
|  |                 'color'     => 'rgba(53, 124, 165,0.7)', | ||||||
|  |                 'highlight' => 'rgba(53, 124, 165,0.9)', | ||||||
|  |                 'label'     => trans('firefly.unpaid'), | ||||||
|  |             ], | ||||||
|  |             [ | ||||||
|  |                 'value'     => round($paid * -1, 2), // paid is negative, must be positive. | ||||||
|  |                 '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) | ||||||
|  |     { | ||||||
|  |         $format       = trans('config.month'); | ||||||
|  |         $data         = [ | ||||||
|  |             'count'    => 3, | ||||||
|  |             'labels'   => [], | ||||||
|  |             'datasets' => [], | ||||||
|  |         ]; | ||||||
|  |         $minAmount    = []; | ||||||
|  |         $maxAmount    = []; | ||||||
|  |         $actualAmount = []; | ||||||
|  |         /** @var TransactionJournal $entry */ | ||||||
|  |         foreach ($entries as $entry) { | ||||||
|  |             $data['labels'][] = $entry->date->formatLocalized($format); | ||||||
|  |             $minAmount[]      = round($bill->amount_min, 2); | ||||||
|  |             $maxAmount[]      = round($bill->amount_max, 2); | ||||||
|  |             /* | ||||||
|  |              * journalAmount has been collected in BillRepository::getJournals | ||||||
|  |              */ | ||||||
|  |             $actualAmount[] = round(($entry->journalAmount * -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; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										50
									
								
								app/Generator/Chart/Budget/BudgetChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								app/Generator/Chart/Budget/BudgetChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | |||||||
|  | <?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 $entries | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function multiYear(Collection $entries); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param Collection $budgets | ||||||
|  |      * @param Collection $entries | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function year(Collection $budgets, Collection $entries); | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										176
									
								
								app/Generator/Chart/Budget/ChartJsBudgetChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								app/Generator/Chart/Budget/ChartJsBudgetChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,176 @@ | |||||||
|  | <?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', env('DEFAULT_LANGUAGE', 'en_US'))->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' => [], | ||||||
|  |         ]; | ||||||
|  |         $left      = []; | ||||||
|  |         $spent     = []; | ||||||
|  |         $overspent = []; | ||||||
|  |         $filtered  = $entries->filter( | ||||||
|  |             function ($entry) { | ||||||
|  |                 return ($entry[1] != 0 || $entry[2] != 0 || $entry[3] != 0); | ||||||
|  |             } | ||||||
|  |         ); | ||||||
|  |         foreach ($filtered as $entry) { | ||||||
|  |             $data['labels'][] = $entry[0]; | ||||||
|  |             $left[]           = round($entry[1], 2); | ||||||
|  |             $spent[]          = round($entry[2] * -1, 2); // spent is coming in negative, must be positive | ||||||
|  |             $overspent[]      = round($entry[3] * -1, 2); // same | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         $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: | ||||||
|  |         $format = trans('config.month'); | ||||||
|  |  | ||||||
|  |         $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; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param Collection $entries | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function multiYear(Collection $entries) | ||||||
|  |     { | ||||||
|  |         // dataset: | ||||||
|  |         $data = [ | ||||||
|  |             'count'    => 0, | ||||||
|  |             'labels'   => [], | ||||||
|  |             'datasets' => [], | ||||||
|  |         ]; | ||||||
|  |         // get labels from one of the budgets (assuming there's at least one): | ||||||
|  |         $first = $entries->first(); | ||||||
|  |         foreach ($first['budgeted'] as $year => $noInterest) { | ||||||
|  |             $data['labels'][] = strval($year); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // then, loop all entries and create datasets: | ||||||
|  |         foreach ($entries as $entry) { | ||||||
|  |             $name               = $entry['name']; | ||||||
|  |             $spent              = $entry['spent']; | ||||||
|  |             $budgeted           = $entry['budgeted']; | ||||||
|  |             $data['datasets'][] = ['label' => 'Spent on ' . $name, 'data' => array_values($spent)]; | ||||||
|  |             $data['datasets'][] = ['label' => 'Budgeted for ' . $name, 'data' => array_values($budgeted)]; | ||||||
|  |         } | ||||||
|  |         $data['count'] = count($data['datasets']); | ||||||
|  |  | ||||||
|  |         return $data; | ||||||
|  |  | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										58
									
								
								app/Generator/Chart/Category/CategoryChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								app/Generator/Chart/Category/CategoryChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | |||||||
|  | <?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 $categories | ||||||
|  |      * @param Collection $entries | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function earnedInPeriod(Collection $categories, Collection $entries); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param Collection $entries | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function frontpage(Collection $entries); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param Collection $entries | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function multiYear(Collection $entries); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param Collection $entries | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function period(Collection $entries); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param Collection $categories | ||||||
|  |      * @param Collection $entries | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function spentInPeriod(Collection $categories, Collection $entries); | ||||||
|  | } | ||||||
							
								
								
									
										194
									
								
								app/Generator/Chart/Category/ChartJsCategoryChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								app/Generator/Chart/Category/ChartJsCategoryChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,194 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace FireflyIII\Generator\Chart\Category; | ||||||
|  |  | ||||||
|  | use Illuminate\Support\Collection; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 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 $categories | ||||||
|  |      * @param Collection $entries | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function earnedInPeriod(Collection $categories, Collection $entries) | ||||||
|  |     { | ||||||
|  |  | ||||||
|  |         // language: | ||||||
|  |         $format = trans('config.month'); | ||||||
|  |  | ||||||
|  |         $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 $entries | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function frontpage(Collection $entries) | ||||||
|  |     { | ||||||
|  |         $data = [ | ||||||
|  |             'count'    => 1, | ||||||
|  |             'labels'   => [], | ||||||
|  |             'datasets' => [ | ||||||
|  |                 [ | ||||||
|  |                     'label' => trans('firefly.spent'), | ||||||
|  |                     'data'  => [] | ||||||
|  |                 ] | ||||||
|  |             ], | ||||||
|  |         ]; | ||||||
|  |         foreach ($entries as $entry) { | ||||||
|  |             if ($entry->spent != 0) { | ||||||
|  |                 $data['labels'][]              = $entry->name; | ||||||
|  |                 $data['datasets'][0]['data'][] = round(($entry->spent * -1), 2); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return $data; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param Collection $entries | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function multiYear(Collection $entries) | ||||||
|  |     { | ||||||
|  |         // dataset: | ||||||
|  |         $data = [ | ||||||
|  |             'count'    => 0, | ||||||
|  |             'labels'   => [], | ||||||
|  |             'datasets' => [], | ||||||
|  |         ]; | ||||||
|  |         // get labels from one of the categories (assuming there's at least one): | ||||||
|  |         $first = $entries->first(); | ||||||
|  |         foreach ($first['spent'] as $year => $noInterest) { | ||||||
|  |             $data['labels'][] = strval($year); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // then, loop all entries and create datasets: | ||||||
|  |         foreach ($entries as $entry) { | ||||||
|  |             $name   = $entry['name']; | ||||||
|  |             $spent  = $entry['spent']; | ||||||
|  |             $earned = $entry['earned']; | ||||||
|  |             if (array_sum(array_values($spent)) != 0) { | ||||||
|  |                 $data['datasets'][] = ['label' => 'Spent in category ' . $name, 'data' => array_values($spent)]; | ||||||
|  |             } | ||||||
|  |             if (array_sum(array_values($earned)) != 0) { | ||||||
|  |                 $data['datasets'][] = ['label' => 'Earned in category ' . $name, 'data' => array_values($earned)]; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         $data['count'] = count($data['datasets']); | ||||||
|  |  | ||||||
|  |         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 spentInPeriod(Collection $categories, Collection $entries) | ||||||
|  |     { | ||||||
|  |  | ||||||
|  |         // language: | ||||||
|  |         $format = trans('config.month'); | ||||||
|  |  | ||||||
|  |         $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,49 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace FireflyIII\Generator\Chart\PiggyBank; | ||||||
|  |  | ||||||
|  | use Carbon\Carbon; | ||||||
|  | use Illuminate\Support\Collection; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Class ChartJsPiggyBankChartGenerator | ||||||
|  |  * | ||||||
|  |  * @package FireflyIII\Generator\Chart\PiggyBank | ||||||
|  |  */ | ||||||
|  | class ChartJsPiggyBankChartGenerator implements PiggyBankChartGenerator | ||||||
|  | { | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param Collection $set | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function history(Collection $set) | ||||||
|  |     { | ||||||
|  |  | ||||||
|  |         // language: | ||||||
|  |         $format = trans('config.month_and_day'); | ||||||
|  |  | ||||||
|  |         $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); | ||||||
|  | } | ||||||
							
								
								
									
										144
									
								
								app/Generator/Chart/Report/ChartJsReportChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								app/Generator/Chart/Report/ChartJsReportChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,144 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace FireflyIII\Generator\Chart\Report; | ||||||
|  |  | ||||||
|  | use Illuminate\Support\Collection; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Class ChartJsReportChartGenerator | ||||||
|  |  * | ||||||
|  |  * @package FireflyIII\Generator\Chart\Report | ||||||
|  |  */ | ||||||
|  | class ChartJsReportChartGenerator implements ReportChartGenerator | ||||||
|  | { | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Same as above but other translations. | ||||||
|  |      * | ||||||
|  |      * @param Collection $entries | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function multiYearInOut(Collection $entries) | ||||||
|  |     { | ||||||
|  |         $data = [ | ||||||
|  |             'count'    => 2, | ||||||
|  |             'labels'   => [], | ||||||
|  |             'datasets' => [ | ||||||
|  |                 [ | ||||||
|  |                     'label' => trans('firefly.income'), | ||||||
|  |                     'data'  => [] | ||||||
|  |                 ], | ||||||
|  |                 [ | ||||||
|  |                     'label' => trans('firefly.expenses'), | ||||||
|  |                     'data'  => [] | ||||||
|  |                 ] | ||||||
|  |             ], | ||||||
|  |         ]; | ||||||
|  |  | ||||||
|  |         foreach ($entries as $entry) { | ||||||
|  |             $data['labels'][]              = $entry[0]->formatLocalized('%Y'); | ||||||
|  |             $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 multiYearInOutSummarized($income, $expense, $count) | ||||||
|  |     { | ||||||
|  |         $data                          = [ | ||||||
|  |             'count'    => 2, | ||||||
|  |             'labels'   => [trans('firefly.sum_of_years'), trans('firefly.average_of_years')], | ||||||
|  |             '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; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param Collection $entries | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function yearInOut(Collection $entries) | ||||||
|  |     { | ||||||
|  |         // language: | ||||||
|  |         $format = trans('config.month'); | ||||||
|  |  | ||||||
|  |         $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; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										47
									
								
								app/Generator/Chart/Report/ReportChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								app/Generator/Chart/Report/ReportChartGenerator.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | |||||||
|  | <?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 multiYearInOut(Collection $entries); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param string $income | ||||||
|  |      * @param string $expense | ||||||
|  |      * @param int    $count | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function multiYearInOutSummarized($income, $expense, $count); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @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); | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -4,9 +4,7 @@ use Auth; | |||||||
| use FireflyIII\Events\JournalCreated; | use FireflyIII\Events\JournalCreated; | ||||||
| use FireflyIII\Models\PiggyBank; | use FireflyIII\Models\PiggyBank; | ||||||
| use FireflyIII\Models\PiggyBankEvent; | use FireflyIII\Models\PiggyBankEvent; | ||||||
| use FireflyIII\Models\Transaction; |  | ||||||
| use FireflyIII\Models\TransactionJournal; | use FireflyIII\Models\TransactionJournal; | ||||||
| use Log; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class ConnectJournalToPiggyBank |  * Class ConnectJournalToPiggyBank | ||||||
| @@ -19,6 +17,8 @@ class ConnectJournalToPiggyBank | |||||||
|     /** |     /** | ||||||
|      * Create the event handler. |      * Create the event handler. | ||||||
|      * |      * | ||||||
|  |      * @codeCoverageIgnore | ||||||
|  |      * | ||||||
|      */ |      */ | ||||||
|     public function __construct() |     public function __construct() | ||||||
|     { |     { | ||||||
| @@ -30,67 +30,40 @@ class ConnectJournalToPiggyBank | |||||||
|      * |      * | ||||||
|      * @param  JournalCreated $event |      * @param  JournalCreated $event | ||||||
|      * |      * | ||||||
|      * @return void |      * @return boolean | ||||||
|      */ |      */ | ||||||
|     public function handle(JournalCreated $event) |     public function handle(JournalCreated $event) | ||||||
|     { |     { | ||||||
|         /** @var TransactionJournal $journal */ |         /** @var TransactionJournal $journal */ | ||||||
|         $journal     = $event->journal; |         $journal     = $event->journal; | ||||||
|         $piggyBankId = $event->piggyBankId; |         $piggyBankId = $event->piggyBankId; | ||||||
|         if (intval($piggyBankId) < 1) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         Log::debug('JournalCreated event: ' . $journal->id . ', ' . $piggyBankId); |  | ||||||
|  |  | ||||||
|         /** @var PiggyBank $piggyBank */ |         /** @var PiggyBank $piggyBank */ | ||||||
|         $piggyBank = Auth::user()->piggybanks()->where('piggy_banks.id', $piggyBankId)->first(['piggy_banks.*']); |         $piggyBank = Auth::user()->piggybanks()->where('piggy_banks.id', $piggyBankId)->first(['piggy_banks.*']); | ||||||
|  |  | ||||||
|         if (is_null($piggyBank) || $journal->transactionType->type != 'Transfer') { |         if (is_null($piggyBank)) { | ||||||
|             return; |             return false; | ||||||
|         } |  | ||||||
|         Log::debug('Found a piggy bank'); |  | ||||||
|         $amount = $journal->amount; |  | ||||||
|         Log::debug('Amount: ' . $amount); |  | ||||||
|         if ($amount == 0) { |  | ||||||
|             return; |  | ||||||
|         } |         } | ||||||
|         // update piggy bank rep for date of transaction journal. |         // update piggy bank rep for date of transaction journal. | ||||||
|         $repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first(); |         $repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first(); | ||||||
|         if (is_null($repetition)) { |         if (is_null($repetition)) { | ||||||
|             Log::debug('Found no repetition for piggy bank for date ' . $journal->date->format('Y M d')); |             return false; | ||||||
|  |         } | ||||||
|  |         bcscale(2); | ||||||
|  |  | ||||||
|             return; |         $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; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         Log::debug('Found rep! ' . $repetition->id); |  | ||||||
|  |  | ||||||
|         /* |         $repetition->currentamount = bcadd($repetition->currentamount, $amount); | ||||||
|          * Add amount when |  | ||||||
|          */ |  | ||||||
|         /** @var Transaction $transaction */ |  | ||||||
|         foreach ($journal->transactions()->get() as $transaction) { |  | ||||||
|             if ($transaction->account_id == $piggyBank->account_id) { |  | ||||||
|                 if ($transaction->amount < 0) { |  | ||||||
|                     $amount = $amount * -1; |  | ||||||
|                     Log::debug('Transaction is away from piggy, so amount becomes ' . $amount); |  | ||||||
|                 } else { |  | ||||||
|                     Log::debug('Transaction is to from piggy, so amount stays ' . $amount); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         $repetition->currentamount += $amount; |  | ||||||
|         $repetition->save(); |         $repetition->save(); | ||||||
|  |  | ||||||
|         PiggyBankEvent::create( |         PiggyBankEvent::create(['piggy_bank_id' => $piggyBank->id, 'transaction_journal_id' => $journal->id, 'date' => $journal->date, 'amount' => $amount]); | ||||||
|             [ |  | ||||||
|                 'piggy_bank_id'          => $piggyBank->id, |         return true; | ||||||
|                 'transaction_journal_id' => $journal->id, |  | ||||||
|                 'date'                   => $journal->date, |  | ||||||
|                 'amount'                 => $amount |  | ||||||
|             ] |  | ||||||
|         ); |  | ||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,35 +0,0 @@ | |||||||
| <?php namespace FireflyIII\Handlers\Events; |  | ||||||
|  |  | ||||||
| use FireflyIII\Events\JournalDeleted; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Class JournalDeletedHandler |  | ||||||
|  * |  | ||||||
|  * @package FireflyIII\Handlers\Events |  | ||||||
|  */ |  | ||||||
| class JournalDeletedHandler |  | ||||||
| { |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Create the event handler. |  | ||||||
|      * |  | ||||||
|      */ |  | ||||||
|     public function __construct() |  | ||||||
|     { |  | ||||||
|         // |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Handle the event. |  | ||||||
|      * |  | ||||||
|      * @param  JournalDeleted $event |  | ||||||
|      * |  | ||||||
|      * @return void |  | ||||||
|      */ |  | ||||||
|     public function handle(JournalDeleted $event) |  | ||||||
|     { |  | ||||||
|         // |  | ||||||
|  |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @@ -1,12 +1,12 @@ | |||||||
| <?php namespace FireflyIII\Handlers\Events; | <?php namespace FireflyIII\Handlers\Events; | ||||||
|  |  | ||||||
| use App; |  | ||||||
| use FireflyIII\Events\JournalSaved; | use FireflyIII\Events\JournalSaved; | ||||||
| use Log; | use Log; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class RescanJournal |  * Class RescanJournal | ||||||
|  * |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  * @package FireflyIII\Handlers\Events |  * @package FireflyIII\Handlers\Events | ||||||
|  */ |  */ | ||||||
| class RescanJournal | class RescanJournal | ||||||
| @@ -35,7 +35,7 @@ class RescanJournal | |||||||
|         Log::debug('Triggered saved event for journal #' . $journal->id . ' (' . $journal->description . ')'); |         Log::debug('Triggered saved event for journal #' . $journal->id . ' (' . $journal->description . ')'); | ||||||
|  |  | ||||||
|         /** @var \FireflyIII\Repositories\Bill\BillRepositoryInterface $repository */ |         /** @var \FireflyIII\Repositories\Bill\BillRepositoryInterface $repository */ | ||||||
|         $repository = App::make('FireflyIII\Repositories\Bill\BillRepositoryInterface'); |         $repository = app('FireflyIII\Repositories\Bill\BillRepositoryInterface'); | ||||||
|         $list       = $journal->user->bills()->where('active', 1)->where('automatch', 1)->get(); |         $list       = $journal->user->bills()->where('active', 1)->where('automatch', 1)->get(); | ||||||
|  |  | ||||||
|         Log::debug('Found ' . $list->count() . ' bills to check.'); |         Log::debug('Found ' . $list->count() . ' bills to check.'); | ||||||
|   | |||||||
| @@ -2,10 +2,12 @@ | |||||||
|  |  | ||||||
| use FireflyIII\Events\JournalSaved; | use FireflyIII\Events\JournalSaved; | ||||||
| use FireflyIII\Models\PiggyBankEvent; | use FireflyIII\Models\PiggyBankEvent; | ||||||
|  | use FireflyIII\Models\PiggyBankRepetition; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class UpdateJournalConnection |  * Class UpdateJournalConnection | ||||||
|  * |  * | ||||||
|  |  * @codeCoverageIgnore | ||||||
|  * @package FireflyIII\Handlers\Events |  * @package FireflyIII\Handlers\Events | ||||||
|  */ |  */ | ||||||
| class UpdateJournalConnection | class UpdateJournalConnection | ||||||
| @@ -38,15 +40,21 @@ class UpdateJournalConnection | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         $piggyBank  = $event->piggyBank()->first(); |         $piggyBank  = $event->piggyBank()->first(); | ||||||
|         $repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first(); |         $repetition = null; | ||||||
|  |         if ($piggyBank) { | ||||||
|  |             /** @var PiggyBankRepetition $repetition */ | ||||||
|  |             $repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         if (is_null($repetition)) { |         if (is_null($repetition)) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         $amount = $journal->amount; |         bcscale(2); | ||||||
|         $diff   = $amount - $event->amount;// update current repetition |  | ||||||
|  |  | ||||||
|         $repetition->currentamount += $diff; |         $amount = $journal->amount; | ||||||
|  |         $diff   = bcsub($amount, $event->amount); // update current repetition | ||||||
|  |  | ||||||
|  |         $repetition->currentamount = bcadd($repetition->currentamount, $diff); | ||||||
|         $repetition->save(); |         $repetition->save(); | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										224
									
								
								app/Helpers/Attachments/AttachmentHelper.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								app/Helpers/Attachments/AttachmentHelper.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,224 @@ | |||||||
|  | <?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 { | ||||||
|  |             if (!is_null($files)) { | ||||||
|  |                 $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; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										133
									
								
								app/Helpers/Collection/BalanceLine.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								app/Helpers/Collection/BalanceLine.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace FireflyIII\Helpers\Collection; | ||||||
|  |  | ||||||
|  | use FireflyIII\Models\Budget as BudgetModel; | ||||||
|  | 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; | ||||||
|  |  | ||||||
|  |     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 Collection | ||||||
|  |      */ | ||||||
|  |     public function getBalanceEntries() | ||||||
|  |     { | ||||||
|  |         return $this->balanceEntries; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param Collection $balanceEntries | ||||||
|  |      */ | ||||||
|  |     public function setBalanceEntries($balanceEntries) | ||||||
|  |     { | ||||||
|  |         $this->balanceEntries = $balanceEntries; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @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; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @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 ''; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 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 = isset($this->budget->amount) ? $this->budget->amount : 0; | ||||||
|  |         /** @var BalanceEntry $balanceEntry */ | ||||||
|  |         foreach ($this->getBalanceEntries() as $balanceEntry) { | ||||||
|  |             $start += $balanceEntry->getSpent(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return $start; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										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; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										78
									
								
								app/Helpers/Collection/Category.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								app/Helpers/Collection/Category.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | |||||||
|  | <?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); | ||||||
|  |             $this->addTotal($category->spent); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @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->sortBy( | ||||||
|  |             function (CategoryModel $category) { | ||||||
|  |                 return $category->spent; | ||||||
|  |             } | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         return $set; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @return string | ||||||
|  |      */ | ||||||
|  |     public function getTotal() | ||||||
|  |     { | ||||||
|  |         return strval(round($this->total, 2)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										101
									
								
								app/Helpers/Collection/Expense.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								app/Helpers/Collection/Expense.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace FireflyIII\Helpers\Collection; | ||||||
|  |  | ||||||
|  | use Crypt; | ||||||
|  | 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) | ||||||
|  |     { | ||||||
|  |         bcscale(2); | ||||||
|  |  | ||||||
|  |         $accountId = $entry->account_id; | ||||||
|  |         $amount    = strval(round($entry->journalAmount, 2)); | ||||||
|  |         if (bccomp('0', $amount) === -1) { | ||||||
|  |             $amount = bcmul($amount, '-1'); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (!$this->expenses->has($accountId)) { | ||||||
|  |             $newObject         = new stdClass; | ||||||
|  |             $newObject->amount = $amount; | ||||||
|  |             $newObject->name   = Crypt::decrypt($entry->account_name); | ||||||
|  |             $newObject->count  = 1; | ||||||
|  |             $newObject->id     = $accountId; | ||||||
|  |             $this->expenses->put($accountId, $newObject); | ||||||
|  |         } else { | ||||||
|  |             $existing         = $this->expenses->get($accountId); | ||||||
|  |             $existing->amount = bcadd($existing->amount, $amount); | ||||||
|  |             $existing->count++; | ||||||
|  |             $this->expenses->put($accountId, $existing); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param $add | ||||||
|  |      */ | ||||||
|  |     public function addToTotal($add) | ||||||
|  |     { | ||||||
|  |         bcscale(2); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         $add = strval(round($add, 2)); | ||||||
|  |         if (bccomp('0', $add) === -1) { | ||||||
|  |             $add = bcmul($add, '-1'); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // if amount is positive, the original transaction | ||||||
|  |         // was a transfer. But since this is an expense report, | ||||||
|  |         // that amount must be negative. | ||||||
|  |  | ||||||
|  |         $this->total = bcadd($this->total, $add); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @return Collection | ||||||
|  |      */ | ||||||
|  |     public function getExpenses() | ||||||
|  |     { | ||||||
|  |         $set = $this->expenses->sortBy( | ||||||
|  |             function (stdClass $object) { | ||||||
|  |                 return $object->amount; | ||||||
|  |             } | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         return $set; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @return string | ||||||
|  |      */ | ||||||
|  |     public function getTotal() | ||||||
|  |     { | ||||||
|  |         return strval(round($this->total, 2)); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										89
									
								
								app/Helpers/Collection/Income.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								app/Helpers/Collection/Income.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace FireflyIII\Helpers\Collection; | ||||||
|  |  | ||||||
|  | use Crypt; | ||||||
|  | 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->journalAmount, 2)); | ||||||
|  |             $newObject->name   = Crypt::decrypt($entry->account_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->journalAmount); | ||||||
|  |             $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; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										39
									
								
								app/Helpers/Csv/Converter/Date.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								app/Helpers/Csv/Converter/Date.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | <?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 static | ||||||
|  |      * @throws FireflyException | ||||||
|  |      */ | ||||||
|  |     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->getTransactionType(); | ||||||
|  |         /** @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', TransactionType::DEPOSIT)->first(); | ||||||
|  |         if ($this->importData['amount'] < 0) { | ||||||
|  |             $transactionType = TransactionType::where('type', TransactionType::WITHDRAWAL)->first(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (in_array($this->importData['opposing-account-object']->accountType->type, ['Asset account', 'Default account'])) { | ||||||
|  |             $transactionType = TransactionType::where('type', TransactionType::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', env('DEFAULT_CURRENCY', '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; | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param array $data | ||||||
|  |      */ | ||||||
|  |     public function setData($data) | ||||||
|  |     { | ||||||
|  |         $this->data = $data; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param array $row | ||||||
|  |      */ | ||||||
|  |     public function setRow($row) | ||||||
|  |     { | ||||||
|  |         $this->row = $row; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 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: "******".'); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										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); | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -17,6 +17,8 @@ class Help implements HelpInterface | |||||||
| { | { | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * @codeCoverageIgnore | ||||||
|  |      * | ||||||
|      * @param $key |      * @param $key | ||||||
|      * |      * | ||||||
|      * @return string |      * @return string | ||||||
| @@ -27,16 +29,20 @@ class Help implements HelpInterface | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * @codeCoverageIgnore | ||||||
|  |      * | ||||||
|      * @param $route |      * @param $route | ||||||
|      * |      * | ||||||
|      * @return array |      * @return array | ||||||
|      */ |      */ | ||||||
|     public function getFromGithub($route) |     public function getFromGithub($route) | ||||||
|     { |     { | ||||||
|         $uri     = 'https://raw.githubusercontent.com/JC5/firefly-iii-help/master/' . e($route) . '.md'; |         $uri        = 'https://raw.githubusercontent.com/JC5/firefly-iii-help/master/en/' . e($route) . '.md'; | ||||||
|         $content = [ |         $routeIndex = str_replace('.', '-', $route); | ||||||
|  |         $title      = trans('help.' . $routeIndex); | ||||||
|  |         $content    = [ | ||||||
|             'text'  => '<p>There is no help for this route!</p>', |             'text'  => '<p>There is no help for this route!</p>', | ||||||
|             'title' => $route, |             'title' => $title, | ||||||
|         ]; |         ]; | ||||||
|         try { |         try { | ||||||
|             $content['text'] = file_get_contents($uri); |             $content['text'] = file_get_contents($uri); | ||||||
| @@ -54,6 +60,8 @@ class Help implements HelpInterface | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * @codeCoverageIgnore | ||||||
|  |      * | ||||||
|      * @param $route |      * @param $route | ||||||
|      * |      * | ||||||
|      * @return bool |      * @return bool | ||||||
| @@ -64,6 +72,20 @@ class Help implements HelpInterface | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  |      * @codeCoverageIgnore | ||||||
|  |      * | ||||||
|  |      * @param $route | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function inCache($route) | ||||||
|  |     { | ||||||
|  |         return Cache::has('help.' . $route . '.title') && Cache::has('help.' . $route . '.text'); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @codeCoverageIgnore | ||||||
|  |      * | ||||||
|      * @param       $route |      * @param       $route | ||||||
|      * @param array $content |      * @param array $content | ||||||
|      * |      * | ||||||
| @@ -74,14 +96,4 @@ class Help implements HelpInterface | |||||||
|         Cache::put('help.' . $route . '.text', $content['text'], 10080); // a week. |         Cache::put('help.' . $route . '.text', $content['text'], 10080); // a week. | ||||||
|         Cache::put('help.' . $route . '.title', $content['title'], 10080); |         Cache::put('help.' . $route . '.title', $content['title'], 10080); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * @param $route |  | ||||||
|      * |  | ||||||
|      * @return bool |  | ||||||
|      */ |  | ||||||
|     public function inCache($route) |  | ||||||
|     { |  | ||||||
|         return Cache::has('help.' . $route . '.title') && Cache::has('help.' . $route . '.text'); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,145 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| namespace FireflyIII\Helpers\Reminders; |  | ||||||
|  |  | ||||||
| use Amount; |  | ||||||
| use Auth; |  | ||||||
| use Carbon\Carbon; |  | ||||||
| use FireflyIII\Models\PiggyBank; |  | ||||||
| use FireflyIII\Models\Reminder; |  | ||||||
| use Navigation; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Class ReminderHelper |  | ||||||
|  * |  | ||||||
|  * @package FireflyIII\Helpers\Reminders |  | ||||||
|  */ |  | ||||||
| class ReminderHelper implements ReminderHelperInterface |  | ||||||
| { |  | ||||||
|     /** |  | ||||||
|      * @param PiggyBank $piggyBank |  | ||||||
|      * @param Carbon    $start |  | ||||||
|      * @param Carbon    $end |  | ||||||
|      * |  | ||||||
|      * @return Reminder |  | ||||||
|      */ |  | ||||||
|     public function createReminder(PiggyBank $piggyBank, Carbon $start, Carbon $end) |  | ||||||
|     { |  | ||||||
|         $reminder = Auth::user()->reminders()->where('remindersable_id', $piggyBank->id)->onDates($start, $end)->first(); |  | ||||||
|         if (is_null($reminder)) { |  | ||||||
|  |  | ||||||
|             if (!is_null($piggyBank->targetdate)) { |  | ||||||
|                 // get ranges again, but now for the start date |  | ||||||
|                 $ranges      = $this->getReminderRanges($piggyBank, $start); |  | ||||||
|                 $currentRep  = $piggyBank->currentRelevantRep(); |  | ||||||
|                 $left        = $piggyBank->targetamount - $currentRep->currentamount; |  | ||||||
|                 $perReminder = $left / count($ranges); |  | ||||||
|             } else { |  | ||||||
|                 $perReminder = null; |  | ||||||
|                 $ranges      = []; |  | ||||||
|                 $left        = 0; |  | ||||||
|             } |  | ||||||
|             $metaData = [ |  | ||||||
|                 'perReminder' => $perReminder, |  | ||||||
|                 'rangesCount' => count($ranges), |  | ||||||
|                 'ranges'      => $ranges, |  | ||||||
|                 'leftToSave'  => $left, |  | ||||||
|             ]; |  | ||||||
|  |  | ||||||
|  |  | ||||||
|             // create one: |  | ||||||
|             $reminder = new Reminder; |  | ||||||
|             $reminder->user()->associate(Auth::user()); |  | ||||||
|             $reminder->startdate = $start; |  | ||||||
|             $reminder->enddate   = $end; |  | ||||||
|             $reminder->active    = true; |  | ||||||
|             $reminder->metadata  = $metaData; |  | ||||||
|             $reminder->notnow    = false; |  | ||||||
|             $reminder->remindersable()->associate($piggyBank); |  | ||||||
|             $reminder->save(); |  | ||||||
|  |  | ||||||
|             return $reminder; |  | ||||||
|  |  | ||||||
|         } else { |  | ||||||
|             return $reminder; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * This routine will return an array consisting of two dates which indicate the start |  | ||||||
|      * and end date for each reminder that this piggy bank will have, if the piggy bank has |  | ||||||
|      * any reminders. For example: |  | ||||||
|      * |  | ||||||
|      * [12 mar - 15 mar] |  | ||||||
|      * [15 mar - 18 mar] |  | ||||||
|      * |  | ||||||
|      * etcetera. |  | ||||||
|      * |  | ||||||
|      * Array is filled with tiny arrays with Carbon objects in them. |  | ||||||
|      * |  | ||||||
|      * @param PiggyBank $piggyBank |  | ||||||
|      * @param Carbon    $date ; |  | ||||||
|      * |  | ||||||
|      * @return array |  | ||||||
|      */ |  | ||||||
|     public function getReminderRanges(PiggyBank $piggyBank, Carbon $date = null) |  | ||||||
|     { |  | ||||||
|         $ranges = []; |  | ||||||
|         if (is_null($date)) { |  | ||||||
|             $date = new Carbon; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if ($piggyBank->remind_me === false) { |  | ||||||
|             return $ranges; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (!is_null($piggyBank->targetdate)) { |  | ||||||
|             // count back until now. |  | ||||||
|             $start = $piggyBank->targetdate; |  | ||||||
|             $end   = $piggyBank->startdate; |  | ||||||
|  |  | ||||||
|             while ($start > $end) { |  | ||||||
|                 $currentEnd   = clone $start; |  | ||||||
|                 $start        = Navigation::subtractPeriod($start, $piggyBank->reminder, 1); |  | ||||||
|                 $currentStart = clone $start; |  | ||||||
|                 $ranges[]     = ['start' => clone $currentStart, 'end' => clone $currentEnd]; |  | ||||||
|             } |  | ||||||
|         } else { |  | ||||||
|             $start = clone $piggyBank->startdate; |  | ||||||
|             while ($start < $date) { |  | ||||||
|                 $currentStart = clone $start; |  | ||||||
|                 $start        = Navigation::addPeriod($start, $piggyBank->reminder, 0); |  | ||||||
|                 $currentEnd   = clone $start; |  | ||||||
|                 $ranges[]     = ['start' => clone $currentStart, 'end' => clone $currentEnd]; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return $ranges; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Takes a reminder, finds the piggy bank and tells you what to do now. |  | ||||||
|      * Aka how much money to put in. |  | ||||||
|      * |  | ||||||
|      * |  | ||||||
|      * @param Reminder $reminder |  | ||||||
|      * |  | ||||||
|      * @return string |  | ||||||
|      */ |  | ||||||
|     public function getReminderText(Reminder $reminder) |  | ||||||
|     { |  | ||||||
|         /** @var PiggyBank $piggyBank */ |  | ||||||
|         $piggyBank = $reminder->remindersable; |  | ||||||
|  |  | ||||||
|         if (is_null($piggyBank)) { |  | ||||||
|             return 'Piggy bank no longer exists.'; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (is_null($piggyBank->targetdate)) { |  | ||||||
|             return 'Add money to this piggy bank to reach your target of ' . Amount::format($piggyBank->targetamount); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return 'Add ' . Amount::format($reminder->metadata->perReminder) . ' to fill this piggy bank on ' . $piggyBank->targetdate->format('jS F Y'); |  | ||||||
|  |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,52 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| namespace FireflyIII\Helpers\Reminders; |  | ||||||
|  |  | ||||||
| use Carbon\Carbon; |  | ||||||
| use FireflyIII\Models\PiggyBank; |  | ||||||
| use FireflyIII\Models\Reminder; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Interface ReminderHelperInterface |  | ||||||
|  * |  | ||||||
|  * @package FireflyIII\Helpers\Reminders |  | ||||||
|  */ |  | ||||||
| interface ReminderHelperInterface |  | ||||||
| { |  | ||||||
|     /** |  | ||||||
|      * Takes a reminder, finds the piggy bank and tells you what to do now. |  | ||||||
|      * Aka how much money to put in. |  | ||||||
|      * |  | ||||||
|      * @param Reminder $reminder |  | ||||||
|      * |  | ||||||
|      * @return string |  | ||||||
|      */ |  | ||||||
|     public function getReminderText(Reminder $reminder); |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * This routine will return an array consisting of two dates which indicate the start |  | ||||||
|      * and end date for each reminder that this piggy bank will have, if the piggy bank has |  | ||||||
|      * any reminders. For example: |  | ||||||
|      * |  | ||||||
|      * [12 mar - 15 mar] |  | ||||||
|      * [15 mar - 18 mar] |  | ||||||
|      * |  | ||||||
|      * etcetera. |  | ||||||
|      * |  | ||||||
|      * Array is filled with tiny arrays with Carbon objects in them. |  | ||||||
|      * |  | ||||||
|      * @param PiggyBank $piggyBank |  | ||||||
|      * |  | ||||||
|      * @return array |  | ||||||
|      */ |  | ||||||
|     public function getReminderRanges(PiggyBank $piggyBank); |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * @param PiggyBank $piggyBank |  | ||||||
|      * @param Carbon    $start |  | ||||||
|      * @param Carbon    $end |  | ||||||
|      * |  | ||||||
|      * @return Reminder |  | ||||||
|      */ |  | ||||||
|     public function createReminder(PiggyBank $piggyBank, Carbon $start, Carbon $end); |  | ||||||
| } |  | ||||||
| @@ -2,13 +2,27 @@ | |||||||
|  |  | ||||||
| namespace FireflyIII\Helpers\Report; | namespace FireflyIII\Helpers\Report; | ||||||
|  |  | ||||||
| use App; |  | ||||||
| use Auth; |  | ||||||
| use Carbon\Carbon; | use Carbon\Carbon; | ||||||
|  | use DB; | ||||||
|  | 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\Account; | ||||||
| use Illuminate\Database\Query\JoinClause; | use FireflyIII\Models\Bill; | ||||||
|  | use FireflyIII\Models\Budget as BudgetModel; | ||||||
|  | use FireflyIII\Models\LimitRepetition; | ||||||
|  | use FireflyIII\Models\Tag; | ||||||
|  | use FireflyIII\Models\TransactionJournal; | ||||||
| use Illuminate\Support\Collection; | use Illuminate\Support\Collection; | ||||||
| use Steam; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class ReportHelper |  * Class ReportHelper | ||||||
| @@ -18,66 +32,44 @@ use Steam; | |||||||
| class ReportHelper implements ReportHelperInterface | class ReportHelper implements ReportHelperInterface | ||||||
| { | { | ||||||
|  |  | ||||||
|     /** |     /** @var ReportQueryInterface */ | ||||||
|      * This methods fails to take in account transfers FROM shared accounts. |     protected $query; | ||||||
|      * |  | ||||||
|      * @param Carbon $start |  | ||||||
|      * @param Carbon $end |  | ||||||
|      * @param int    $limit |  | ||||||
|      * |  | ||||||
|      * @return Collection |  | ||||||
|      */ |  | ||||||
|     public function expensesGroupedByAccount(Carbon $start, Carbon $end, $limit = 15) |  | ||||||
|     { |  | ||||||
|         $result  = $this->_queries->journalsByExpenseAccount($start, $end); |  | ||||||
|         $array   = $this->_helper->makeArray($result); |  | ||||||
|         $limited = $this->_helper->limitArray($array, $limit); |  | ||||||
|  |  | ||||||
|         return $limited; |     /** | ||||||
|  |      * @codeCoverageIgnore | ||||||
|  |      * | ||||||
|  |      * @param ReportQueryInterface $query | ||||||
|  |      * | ||||||
|  |      */ | ||||||
|  |     public function __construct(ReportQueryInterface $query) | ||||||
|  |     { | ||||||
|  |         $this->query = $query; | ||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * This method gets some kind of list for a monthly overview. |      * @param Carbon     $start | ||||||
|  |      * @param Carbon     $end | ||||||
|  |      * @param Collection $accounts | ||||||
|      * |      * | ||||||
|      * @param Carbon $date |      * @return CategoryCollection | ||||||
|      * @param bool   $showSharedReports |  | ||||||
|      * |  | ||||||
|      * @return Collection |  | ||||||
|      */ |      */ | ||||||
|     public function getBudgetsForMonth(Carbon $date, $showSharedReports = false) |     public function getCategoryReport(Carbon $start, Carbon $end, Collection $accounts) | ||||||
|     { |     { | ||||||
|         /** @var \FireflyIII\Helpers\Report\ReportQueryInterface $query */ |         $object = new CategoryCollection; | ||||||
|         $query = App::make('FireflyIII\Helpers\Report\ReportQueryInterface'); |  | ||||||
|  |  | ||||||
|         $start = clone $date; |         /** | ||||||
|         $start->startOfMonth(); |          * GET CATEGORIES: | ||||||
|         $end = clone $date; |          */ | ||||||
|         $end->endOfMonth(); |         /** @var \FireflyIII\Repositories\Category\CategoryRepositoryInterface $repository */ | ||||||
|         $set = Auth::user()->budgets()->orderBy('budgets.name', 'ASC') |         $repository = app('FireflyIII\Repositories\Category\CategoryRepositoryInterface'); | ||||||
|                    ->leftJoin( |  | ||||||
|                        'budget_limits', function (JoinClause $join) use ($date) { |  | ||||||
|                        $join->on('budget_limits.budget_id', '=', 'budgets.id')->where('budget_limits.startdate', '=', $date->format('Y-m-d')); |  | ||||||
|                    } |  | ||||||
|                    ) |  | ||||||
|                    ->get(['budgets.*', 'budget_limits.amount as queryAmount']); |  | ||||||
|  |  | ||||||
|         $budgets                   = Steam::makeArray($set); |         $set = $repository->spentForAccountsPerMonth($accounts, $start, $end); | ||||||
|         $amountSet                 = $query->journalsByBudget($start, $end, $showSharedReports); |         foreach ($set as $category) { | ||||||
|         $amounts                   = Steam::makeArray($amountSet); |             $object->addCategory($category); | ||||||
|         $budgets                   = Steam::mergeArrays($budgets, $amounts); |  | ||||||
|         $budgets[0]['spent']       = isset($budgets[0]['spent']) ? $budgets[0]['spent'] : 0.0; |  | ||||||
|         $budgets[0]['queryAmount'] = isset($budgets[0]['queryAmount']) ? $budgets[0]['queryAmount'] : 0.0; |  | ||||||
|         $budgets[0]['name']        = 'No budget'; |  | ||||||
|  |  | ||||||
|         // find transactions to shared asset accounts, which are without a budget by default: |  | ||||||
|         // which is only relevant when shared asset accounts are hidden. |  | ||||||
|         if ($showSharedReports === false) { |  | ||||||
|             $transfers = $query->sharedExpenses($start, $end)->sum('queryAmount'); |  | ||||||
|             $budgets[0]['spent'] += floatval($transfers) * -1; |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return $budgets; |         return $object; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -87,13 +79,27 @@ class ReportHelper implements ReportHelperInterface | |||||||
|      */ |      */ | ||||||
|     public function listOfMonths(Carbon $date) |     public function listOfMonths(Carbon $date) | ||||||
|     { |     { | ||||||
|  |  | ||||||
|         $start  = clone $date; |         $start  = clone $date; | ||||||
|         $end    = Carbon::now(); |         $end    = Carbon::now(); | ||||||
|         $months = []; |         $months = []; | ||||||
|         while ($start <= $end) { |         while ($start <= $end) { | ||||||
|             $year            = $start->year; |             $year = $start->year; | ||||||
|             $months[$year][] = [ |  | ||||||
|                 'formatted' => $start->format('F Y'), |             if (!isset($months[$year])) { | ||||||
|  |                 $months[$year] = [ | ||||||
|  |                     'start'  => Carbon::createFromDate($year, 1, 1)->format('Y-m-d'), | ||||||
|  |                     'end'    => Carbon::createFromDate($year, 12, 31)->format('Y-m-d'), | ||||||
|  |                     'months' => [], | ||||||
|  |                 ]; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             $currentEnd = clone $start; | ||||||
|  |             $currentEnd->endOfMonth(); | ||||||
|  |             $months[$year]['months'][] = [ | ||||||
|  |                 'formatted' => $start->formatLocalized('%B %Y'), | ||||||
|  |                 'start'     => $start->format('Y-m-d'), | ||||||
|  |                 'end'       => $currentEnd->format('Y-m-d'), | ||||||
|                 'month'     => $start->month, |                 'month'     => $start->month, | ||||||
|                 'year'      => $year, |                 'year'      => $year, | ||||||
|             ]; |             ]; | ||||||
| @@ -104,75 +110,405 @@ class ReportHelper implements ReportHelperInterface | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * @param Carbon $date |      * This method generates a full report for the given period on all | ||||||
|  |      * given accounts | ||||||
|      * |      * | ||||||
|      * @return array |      * @param Carbon     $start | ||||||
|  |      * @param Carbon     $end | ||||||
|  |      * @param Collection $accounts | ||||||
|  |      * | ||||||
|  |      * @return AccountCollection | ||||||
|      */ |      */ | ||||||
|     public function listOfYears(Carbon $date) |     public function getAccountReport(Carbon $start, Carbon $end, Collection $accounts) | ||||||
|     { |     { | ||||||
|         $start = clone $date; |         $startAmount = '0'; | ||||||
|         $end   = Carbon::now(); |         $endAmount   = '0'; | ||||||
|         $years = []; |         $diff        = '0'; | ||||||
|         while ($start <= $end) { |         $ids         = $accounts->pluck('id')->toArray(); | ||||||
|             $years[] = $start->year; |  | ||||||
|             $start->addYear(); |  | ||||||
|         } |  | ||||||
|         $years[] = Carbon::now()->year; |  | ||||||
|         // force the current year. |  | ||||||
|         $years = array_unique($years); |  | ||||||
|  |  | ||||||
|         return $years; |         $yesterday = clone $start; | ||||||
|  |         $yesterday->subDay(); | ||||||
|  |  | ||||||
|  |         bcscale(2); | ||||||
|  |  | ||||||
|  |         // get balances for start. | ||||||
|  |         $startSet = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id') | ||||||
|  |                            ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') | ||||||
|  |                            ->whereIn('accounts.id', $ids) | ||||||
|  |                            ->whereNull('transaction_journals.deleted_at') | ||||||
|  |                            ->whereNull('transactions.deleted_at') | ||||||
|  |                            ->where('transaction_journals.date', '<=', $yesterday->format('Y-m-d')) | ||||||
|  |                            ->groupBy('accounts.id') | ||||||
|  |                            ->get(['accounts.id', DB::Raw('SUM(`transactions`.`amount`) as `balance`')]); | ||||||
|  |  | ||||||
|  |         // and for end: | ||||||
|  |         $endSet = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id') | ||||||
|  |                          ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') | ||||||
|  |                          ->whereIn('accounts.id', $ids) | ||||||
|  |                          ->whereNull('transaction_journals.deleted_at') | ||||||
|  |                          ->whereNull('transactions.deleted_at') | ||||||
|  |                          ->where('transaction_journals.date', '<=', $end->format('Y-m-d')) | ||||||
|  |                          ->groupBy('accounts.id') | ||||||
|  |                          ->get(['accounts.id', DB::Raw('SUM(`transactions`.`amount`) as `balance`')]); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         $accounts->each( | ||||||
|  |             function (Account $account) use ($startSet, $endSet) { | ||||||
|  |                 /** | ||||||
|  |                  * The balance for today always incorporates transactions | ||||||
|  |                  * made on today. So to get todays "start" balance, we sub one | ||||||
|  |                  * day. | ||||||
|  |                  */ | ||||||
|  |                 // | ||||||
|  |                 $currentStart = $startSet->filter( | ||||||
|  |                     function (Account $entry) use ($account) { | ||||||
|  |                         return $account->id == $entry->id; | ||||||
|  |                     } | ||||||
|  |                 ); | ||||||
|  |                 if ($currentStart->first()) { | ||||||
|  |                     $account->startBalance = $currentStart->first()->balance; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 $currentEnd = $endSet->filter( | ||||||
|  |                     function (Account $entry) use ($account) { | ||||||
|  |                         return $account->id == $entry->id; | ||||||
|  |                     } | ||||||
|  |                 ); | ||||||
|  |                 if ($currentEnd->first()) { | ||||||
|  |                     $account->endBalance = $currentEnd->first()->balance; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         // summarize: | ||||||
|  |         foreach ($accounts as $account) { | ||||||
|  |             $startAmount = bcadd($startAmount, $account->startBalance); | ||||||
|  |             $endAmount   = bcadd($endAmount, $account->endBalance); | ||||||
|  |             $diff        = bcadd($diff, bcsub($account->endBalance, $account->startBalance)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         $object = new AccountCollection; | ||||||
|  |         $object->setStart($startAmount); | ||||||
|  |         $object->setEnd($endAmount); | ||||||
|  |         $object->setDifference($diff); | ||||||
|  |         $object->setAccounts($accounts); | ||||||
|  |  | ||||||
|  |         return $object; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * @param Carbon $date |      * Get a full report on the users incomes during the period for the given accounts. | ||||||
|      * @param bool   $showSharedReports |  | ||||||
|      * |      * | ||||||
|      * @return array |      * @param Carbon     $start | ||||||
|  |      * @param Carbon     $end | ||||||
|  |      * @param Collection $accounts | ||||||
|  |      * | ||||||
|  |      * @return Income | ||||||
|      */ |      */ | ||||||
|     public function yearBalanceReport(Carbon $date, $showSharedReports = false) |     public function getIncomeReport($start, $end, Collection $accounts) | ||||||
|     { |     { | ||||||
|         $start          = clone $date; |         $object = new Income; | ||||||
|         $end            = clone $date; |         $set    = $this->query->income($accounts, $start, $end); | ||||||
|         $sharedAccounts = []; |  | ||||||
|         if ($showSharedReports === false) { |  | ||||||
|             $sharedCollection = Auth::user()->accounts() |  | ||||||
|                                      ->leftJoin('account_meta', 'account_meta.account_id', '=', 'accounts.id') |  | ||||||
|                                      ->where('account_meta.name', '=', 'accountRole') |  | ||||||
|                                      ->where('account_meta.data', '=', json_encode('sharedAsset')) |  | ||||||
|                                      ->get(['accounts.id']); |  | ||||||
|  |  | ||||||
|             foreach ($sharedCollection as $account) { |         foreach ($set as $entry) { | ||||||
|                 $sharedAccounts[] = $account->id; |             $object->addToTotal($entry->journalAmount); | ||||||
|             } |             $object->addOrCreateIncome($entry); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         $accounts = Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->orderBy('accounts.name', 'ASC')->get(['accounts.*']) |         return $object; | ||||||
|                         ->filter( |     } | ||||||
|                             function (Account $account) use ($sharedAccounts) { |  | ||||||
|                                 if (!in_array($account->id, $sharedAccounts)) { |  | ||||||
|                                     return $account; |  | ||||||
|                                 } |  | ||||||
|  |  | ||||||
|                                 return null; |     /** | ||||||
|                             } |      * Get a full report on the users expenses during the period for a list of accounts. | ||||||
|                         ); |      * | ||||||
|         $report   = []; |      * @param Carbon     $start | ||||||
|         $start->startOfYear()->subDay(); |      * @param Carbon     $end | ||||||
|         $end->endOfYear(); |      * @param Collection $accounts | ||||||
|  |      * | ||||||
|  |      * @return Expense | ||||||
|  |      */ | ||||||
|  |     public function getExpenseReport($start, $end, Collection $accounts) | ||||||
|  |     { | ||||||
|  |         $object = new Expense; | ||||||
|  |         $set    = $this->query->expense($accounts, $start, $end); | ||||||
|  |  | ||||||
|  |         foreach ($set as $entry) { | ||||||
|  |             $object->addToTotal($entry->journalAmount); // can be positive, if it's a transfer | ||||||
|  |             $object->addOrCreateExpense($entry); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return $object; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param Carbon     $start | ||||||
|  |      * @param Carbon     $end | ||||||
|  |      * @param Collection $accounts | ||||||
|  |      * | ||||||
|  |      * @return BudgetCollection | ||||||
|  |      */ | ||||||
|  |     public function getBudgetReport(Carbon $start, Carbon $end, Collection $accounts) | ||||||
|  |     { | ||||||
|  |         $object = new BudgetCollection; | ||||||
|  |         /** @var \FireflyIII\Repositories\Budget\BudgetRepositoryInterface $repository */ | ||||||
|  |         $repository     = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface'); | ||||||
|  |         $set            = $repository->getBudgets(); | ||||||
|  |         $allRepetitions = $repository->getAllBudgetLimitRepetitions($start, $end); | ||||||
|  |         $allTotalSpent  = $repository->spentAllPerDayForAccounts($accounts, $start, $end); | ||||||
|  |         bcscale(2); | ||||||
|  |  | ||||||
|  |         foreach ($set as $budget) { | ||||||
|  |  | ||||||
|  |             $repetitions = $allRepetitions->filter( | ||||||
|  |                 function (LimitRepetition $rep) use ($budget) { | ||||||
|  |                     return $rep->budget_id == $budget->id; | ||||||
|  |                 } | ||||||
|  |             ); | ||||||
|  |             $totalSpent  = isset($allTotalSpent[$budget->id]) ? $allTotalSpent[$budget->id] : []; | ||||||
|  |  | ||||||
|  |             // no repetition(s) for this budget: | ||||||
|  |             if ($repetitions->count() == 0) { | ||||||
|  |                 $spent      = array_sum($totalSpent); | ||||||
|  |                 $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 = $this->getSumOfRange($start, $end, $totalSpent); | ||||||
|  |  | ||||||
|  |                 // 200 en -100 is 100, vergeleken met 0 === 1 | ||||||
|  |                 // 200 en -200 is 0, vergeleken met 0 === 0 | ||||||
|  |                 // 200 en -300 is -100, vergeleken met 0 === -1 | ||||||
|  |  | ||||||
|  |                 $left      = bccomp(bcadd($repetition->amount, $expenses), '0') === 1 ? bcadd($repetition->amount, $expenses) : 0; | ||||||
|  |                 $spent     = bccomp(bcadd($repetition->amount, $expenses), '0') === 1 ? $expenses : '0'; | ||||||
|  |                 $overspent = bccomp(bcadd($repetition->amount, $expenses), '0') === 1 ? '0' : bcadd($expenses, $repetition->amount); | ||||||
|  |  | ||||||
|  |                 $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); | ||||||
|  |         $budgetLine->setSpent($noBudget); | ||||||
|  |         $object->addOverspent($noBudget); | ||||||
|  |         $object->addBudgetLine($budgetLine); | ||||||
|  |  | ||||||
|  |         return $object; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param Carbon     $start | ||||||
|  |      * @param Carbon     $end | ||||||
|  |      * @param Collection $accounts | ||||||
|  |      * | ||||||
|  |      * @return Balance | ||||||
|  |      */ | ||||||
|  |     public function getBalanceReport(Carbon $start, Carbon $end, Collection $accounts) | ||||||
|  |     { | ||||||
|  |         /** @var \FireflyIII\Repositories\Budget\BudgetRepositoryInterface $repository */ | ||||||
|  |         $repository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface'); | ||||||
|  |  | ||||||
|  |         /** @var \FireflyIII\Repositories\Tag\TagRepositoryInterface $tagRepository */ | ||||||
|  |         $tagRepository = app('FireflyIII\Repositories\Tag\TagRepositoryInterface'); | ||||||
|  |  | ||||||
|  |         $balance = new Balance; | ||||||
|  |  | ||||||
|  |         // build a balance header: | ||||||
|  |         $header    = new BalanceHeader; | ||||||
|  |         $budgets   = $repository->getBudgetsAndLimitsInRange($start, $end); | ||||||
|  |         $spentData = $repository->spentPerBudgetPerAccount($budgets, $accounts, $start, $end); | ||||||
|  |         foreach ($accounts as $account) { | ||||||
|  |             $header->addAccount($account); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /** @var BudgetModel $budget */ | ||||||
|  |         foreach ($budgets as $budget) { | ||||||
|  |             $line = new BalanceLine; | ||||||
|  |             $line->setBudget($budget); | ||||||
|  |  | ||||||
|  |             // loop accounts: | ||||||
|  |             foreach ($accounts as $account) { | ||||||
|  |                 $balanceEntry = new BalanceEntry; | ||||||
|  |                 $balanceEntry->setAccount($account); | ||||||
|  |  | ||||||
|  |                 // get spent: | ||||||
|  |                 $entry = $spentData->filter( | ||||||
|  |                     function (TransactionJournal $model) use ($budget, $account) { | ||||||
|  |                         return $model->account_id == $account->id && $model->budget_id == $budget->id; | ||||||
|  |                     } | ||||||
|  |                 ); | ||||||
|  |                 $spent = 0; | ||||||
|  |                 if (!is_null($entry->first())) { | ||||||
|  |                     $spent = $entry->first()->spent; | ||||||
|  |                 } | ||||||
|  |                 $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: | ||||||
|  |         // and one for "left unbalanced". | ||||||
|  |         $empty    = new BalanceLine; | ||||||
|  |         $tags     = new BalanceLine; | ||||||
|  |         $diffLine = new BalanceLine; | ||||||
|  |         $tagsLeft = $tagRepository->allCoveredByBalancingActs($accounts, $start, $end); | ||||||
|  |  | ||||||
|  |         $tags->setRole(BalanceLine::ROLE_TAGROLE); | ||||||
|  |         $diffLine->setRole(BalanceLine::ROLE_DIFFROLE); | ||||||
|  |  | ||||||
|         foreach ($accounts as $account) { |         foreach ($accounts as $account) { | ||||||
|             $startBalance = Steam::balance($account, $start); |             $entry = $spentData->filter( | ||||||
|             $endBalance   = Steam::balance($account, $end); |                 function (TransactionJournal $model) use ($budget, $account) { | ||||||
|             $report[]     = [ |                     return $model->account_id == $account->id && is_null($model->budget_id); | ||||||
|                 'start'   => $startBalance, |                 } | ||||||
|                 'end'     => $endBalance, |             ); | ||||||
|                 'hide'    => ($startBalance == 0 && $endBalance == 0), |             $spent = 0; | ||||||
|                 'account' => $account, |             if (!is_null($entry->first())) { | ||||||
|                 'shared'  => $account->accountRole == 'sharedAsset' |                 $spent = $entry->first()->spent; | ||||||
|             ]; |             } | ||||||
|  |             $leftEntry = $tagsLeft->filter( | ||||||
|  |                 function (Tag $tag) use ($account) { | ||||||
|  |                     return $tag->account_id == $account->id; | ||||||
|  |                 } | ||||||
|  |             ); | ||||||
|  |             $left      = 0; | ||||||
|  |             if (!is_null($leftEntry->first())) { | ||||||
|  |                 $left = $leftEntry->first()->sum; | ||||||
|  |             } | ||||||
|  |             bcscale(2); | ||||||
|  |             $diff = bcadd($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); | ||||||
|  |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return $report; |         $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. | ||||||
|  |      * | ||||||
|  |      * Excludes bills which have not had a payment on the mentioned accounts. | ||||||
|  |      * | ||||||
|  |      * @param Carbon     $start | ||||||
|  |      * @param Carbon     $end | ||||||
|  |      * @param Collection $accounts | ||||||
|  |      * | ||||||
|  |      * @return BillCollection | ||||||
|  |      */ | ||||||
|  |     public function getBillReport(Carbon $start, Carbon $end, Collection $accounts) | ||||||
|  |     { | ||||||
|  |         /** @var \FireflyIII\Repositories\Bill\BillRepositoryInterface $repository */ | ||||||
|  |         $repository = app('FireflyIII\Repositories\Bill\BillRepositoryInterface'); | ||||||
|  |         $bills      = $repository->getBillsForAccounts($accounts); | ||||||
|  |         $journals   = $repository->getAllJournalsInRange($bills, $start, $end); | ||||||
|  |         $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); | ||||||
|  |  | ||||||
|  |             $entry = $journals->filter( | ||||||
|  |                 function (TransactionJournal $journal) use ($bill) { | ||||||
|  |                     return $journal->bill_id == $bill->id; | ||||||
|  |                 } | ||||||
|  |             ); | ||||||
|  |             if (!is_null($entry->first())) { | ||||||
|  |                 $billLine->setAmount($entry->first()->journalAmount); | ||||||
|  |                 $billLine->setHit(true); | ||||||
|  |             } else { | ||||||
|  |                 $billLine->setHit(false); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             $collection->addBill($billLine); | ||||||
|  |  | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return $collection; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Take the array as returned by SingleCategoryRepositoryInterface::spentPerDay and SingleCategoryRepositoryInterface::earnedByDay | ||||||
|  |      * and sum up everything in the array in the given range. | ||||||
|  |      * | ||||||
|  |      * @param Carbon $start | ||||||
|  |      * @param Carbon $end | ||||||
|  |      * @param array  $array | ||||||
|  |      * | ||||||
|  |      * @return string | ||||||
|  |      */ | ||||||
|  |     protected function getSumOfRange(Carbon $start, Carbon $end, array $array) | ||||||
|  |     { | ||||||
|  |         bcscale(2); | ||||||
|  |         $sum          = '0'; | ||||||
|  |         $currentStart = clone $start; // to not mess with the original one | ||||||
|  |         $currentEnd   = clone $end; // to not mess with the original one | ||||||
|  |  | ||||||
|  |         while ($currentStart <= $currentEnd) { | ||||||
|  |             $date = $currentStart->format('Y-m-d'); | ||||||
|  |             if (isset($array[$date])) { | ||||||
|  |                 $sum = bcadd($sum, $array[$date]); | ||||||
|  |             } | ||||||
|  |             $currentStart->addDay(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return $sum; | ||||||
|  |     } | ||||||
|  | } | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user