mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 10:47:00 +00:00 
			
		
		
		
	Compare commits
	
		
			1648 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 4b47f99829 | ||
|  | 35aaf40003 | ||
|  | cc5b4a1e02 | ||
|  | 7079521e8c | ||
|  | b5025560a5 | ||
|  | 3f4bdd7f0e | ||
|  | e94bb9b549 | ||
|  | 1ddaacbef5 | ||
|  | e8b40518e0 | ||
|  | 0f88cbb41b | ||
|  | 780d137b76 | ||
|  | ad8a9717d1 | ||
|  | 9d6ea6b2f6 | ||
|  | 7559383089 | ||
|  | f84381c927 | ||
|  | cb0122a43f | ||
|  | 6776b20989 | ||
|  | e98d556022 | ||
|  | 5bf18b69d7 | ||
|  | ea17f045a7 | ||
|  | 526f565ea7 | ||
|  | 4aff9d6e73 | ||
|  | bf516d4d21 | ||
|  | ae92e409d9 | ||
|  | 4d017dc8a9 | ||
|  | 707f4e2965 | ||
|  | 1c3bffdc50 | ||
|  | e54ddcb8b0 | ||
|  | ddefb0debc | ||
|  | 92d8dde90d | ||
|  | 1bb0508ddf | ||
|  | a280a326b9 | ||
|  | 683e9b7c2c | ||
|  | a44e5da421 | ||
|  | 8cd2c90ad7 | ||
|  | 5e57a390a2 | ||
|  | 620848272e | ||
|  | 1e86794416 | ||
|  | e36717259b | ||
|  | 75b9238b90 | ||
|  | ce5b20027e | ||
|  | 0de1242c83 | ||
|  | 8bd445ab19 | ||
|  | fdef0de163 | ||
|  | b1b03a4325 | ||
|  | 0587d96474 | ||
|  | c2241567e4 | ||
|  | 7ac24ba418 | ||
|  | c933ffec66 | ||
|  | e587d934b1 | ||
|  | f354e90656 | ||
|  | 1b0bc7ec6e | ||
|  | ee1acb9c00 | ||
|  | 06862a2812 | ||
|  | 5fa87e18db | ||
|  | 77989e2720 | ||
|  | 3a1102fa4e | ||
|  | 8a9974ce53 | ||
|  | 4be8f1ca03 | ||
|  | 1ec2970ee3 | ||
|  | 81b3a22606 | ||
|  | f81a475cc9 | ||
|  | d7ee03d4f9 | ||
|  | c1c06410c2 | ||
|  | 657d16bb60 | ||
|  | e65a4c1010 | ||
|  | e23d3f5661 | ||
|  | e13611f7af | ||
|  | 596cd09489 | ||
|  | 0be5b27d34 | ||
|  | a27471ae55 | ||
|  | e27e3622a8 | ||
|  | e95273b72b | ||
|  | 583d4f3249 | ||
|  | d6967c4516 | ||
|  | 40b3097374 | ||
|  | 1a1f127993 | ||
|  | a0f34a7ce1 | ||
|  | db020db34b | ||
|  | 681167bc1b | ||
|  | 40e49ffc37 | ||
|  | 834b1afb38 | ||
|  | 62d5a1da87 | ||
|  | 8d8308e557 | ||
|  | e1aa63487a | ||
|  | b7fbe110d4 | ||
|  | 58859eb35a | ||
|  | 4b7e1ae1c6 | ||
|  | 3a06a6ac07 | ||
|  | db0f269dc8 | ||
|  | 3cabe6ca5a | ||
|  | d483005219 | ||
|  | fea9bc4e7e | ||
|  | d579992c98 | ||
|  | ad1c61d959 | ||
|  | bb1da31830 | ||
|  | a50949e554 | ||
|  | 14dce8a10b | ||
|  | 1240c8f685 | ||
|  | cc7c2e952c | ||
|  | 409ec2e086 | ||
|  | a7f6848e53 | ||
|  | 4b0b79199d | ||
|  | d1d6c48d9b | ||
|  | 21631780bb | ||
|  | b935e32340 | ||
|  | 72dd064932 | ||
|  | 2e75446665 | ||
|  | be17e4481e | ||
|  | 616c849b1f | ||
|  | 71947c097f | ||
|  | 546787802d | ||
|  | 294d0e388a | ||
|  | 193a1b0325 | ||
|  | 12743217a2 | ||
|  | b252b9da66 | ||
|  | cdef9c3c7e | ||
|  | 71dcebb744 | ||
|  | 25f248c60a | ||
|  | d5cbc17831 | ||
|  | 7a10217511 | ||
|  | 7559efab77 | ||
|  | 8254efbd03 | ||
|  | 4ae24225a5 | ||
|  | 67d9154563 | ||
|  | ad0319c188 | ||
|  | eb650ea3ec | ||
|  | 7eba33e805 | ||
|  | e1cb9d387e | ||
|  | 2ace7c3ca0 | ||
|  | 58014f0592 | ||
|  | 1d4938bb09 | ||
|  | bbf4007c3e | ||
|  | 4d5124fb4c | ||
|  | 14a7cd05b1 | ||
|  | 946be80eef | ||
|  | 9ad8b1a980 | ||
|  | f733216fcb | ||
|  | ffc6139e21 | ||
|  | 571cac6644 | ||
|  | 2738ac5a5c | ||
|  | 7dfde51b84 | ||
|  | 2d2f18e538 | ||
|  | 3af0dd2e3b | ||
|  | 349e077802 | ||
|  | 812aae358f | ||
|  | c3c59d0627 | ||
|  | 89518b412d | ||
|  | f43b026162 | ||
|  | b806c70f52 | ||
|  | 10bff3c0b8 | ||
|  | 65c12fd0b2 | ||
|  | 50f71c4130 | ||
|  | 8e401a53dc | ||
|  | 64a289a47c | ||
|  | 8f2c37061b | ||
|  | 39f2de6b90 | ||
|  | 855ba8d4f3 | ||
|  | 74f098e718 | ||
|  | 56c8a84691 | ||
|  | 8bbf319032 | ||
|  | afbca4ae65 | ||
|  | 0ef6d2f91a | ||
|  | fbe4435599 | ||
|  | 34be565dd1 | ||
|  | af838e4ed1 | ||
|  | 60fe8ce011 | ||
|  | 8ece341467 | ||
|  | dfa6bdbcb8 | ||
|  | fb2481ebaa | ||
|  | 4874c116cf | ||
|  | e19c44efbd | ||
|  | 4b687b9bdc | ||
|  | 6af79ef601 | ||
|  | 352b996ad2 | ||
|  | 4a93bb35f8 | ||
|  | 8e1f493daf | ||
|  | 59ee153375 | ||
|  | 60f7f1fc16 | ||
|  | b7433683d8 | ||
|  | 42799b9273 | ||
|  | 860a0f790e | ||
|  | 8daccbfbb4 | ||
|  | 285b77dcb7 | ||
|  | 6e48827d3f | ||
|  | f0c20cc706 | ||
|  | 8916c0a3de | ||
|  | 7193a77840 | ||
|  | 61930b5b51 | ||
|  | 11a494cacf | ||
|  | 17f9bf0339 | ||
|  | 3d9755ca8c | ||
|  | b5cf2d03e6 | ||
|  | e3b35b8f35 | ||
|  | 1c1fe672bd | ||
|  | 6c71f68ed8 | ||
|  | 8f2f912cdf | ||
|  | bf6ea16acb | ||
|  | 288546c2b9 | ||
|  | 724db6c34c | ||
|  | 067c451c1d | ||
|  | 11e3696191 | ||
|  | 41e20664de | ||
|  | d8de90d6f3 | ||
|  | b01e8299d3 | ||
|  | 1ec11e3e2e | ||
|  | 422f429725 | ||
|  | 5c55fa5fbb | ||
|  | 80d845fdf2 | ||
|  | 601fe68346 | ||
|  | 9e050fb059 | ||
|  | 99d4adf5e6 | ||
|  | 85f8d1e8e9 | ||
|  | 8334d3d99f | ||
|  | cff08d19eb | ||
|  | 2d86390bc1 | ||
|  | 7a20835571 | ||
|  | ff3c9676b5 | ||
|  | 055f97dab1 | ||
|  | 8a867e71a1 | ||
|  | b8275b4734 | ||
|  | 36b951b146 | ||
|  | c5a5f17643 | ||
|  | 16b909c4df | ||
|  | 92b7648e03 | ||
|  | ca46ebe3b2 | ||
|  | 676e48254a | ||
|  | b15b55227d | ||
|  | 3c3b723913 | ||
|  | f05002c729 | ||
|  | 1c2cbd5b40 | ||
|  | 54c6ca9f45 | ||
|  | c10efbb170 | ||
|  | a496ad5814 | ||
|  | 50cf7f6a3b | ||
|  | f946f10afd | ||
|  | eecb4db34c | ||
|  | 1f865d3ea4 | ||
|  | 623bb4b350 | ||
|  | dc8ad673a6 | ||
|  | 4914ad821e | ||
|  | f099cbadc3 | ||
|  | 42cda384c8 | ||
|  | 23c91b9990 | ||
|  | ff0379182e | ||
|  | e08a23948f | ||
|  | bd56de6d36 | ||
|  | 42970aea80 | ||
|  | 003a05ee8d | ||
|  | ffb11b01a6 | ||
|  | e426f5d5da | ||
|  | 6989f61e1b | ||
|  | 0e6677ccb3 | ||
|  | 8f104d555a | ||
|  | b1d3158db1 | ||
|  | 7645005d5a | ||
|  | 411f77fd29 | ||
|  | 568ab26db1 | ||
|  | 29652108f0 | ||
|  | f07e4dc711 | ||
|  | 8a2ac457c2 | ||
|  | 9e54eecfaa | ||
|  | 95ef691077 | ||
|  | 7a0ad5a587 | ||
|  | 42b49d0e4b | ||
|  | 9217c2f003 | ||
|  | fbdf66998d | ||
|  | deda9d3c54 | ||
|  | a5d78f20ae | ||
|  | 5ed09e3f38 | ||
|  | 3e9774cd66 | ||
|  | 54387c8fdf | ||
|  | 7eec949a13 | ||
|  | 4113c4ff40 | ||
|  | 1bf0968bfe | ||
|  | 374b90fb00 | ||
|  | 064e60e9d5 | ||
|  | b637455970 | ||
|  | 68158937d1 | ||
|  | adb1356b7a | ||
|  | d880ccb8e0 | ||
|  | 050fb1d1ef | ||
|  | 6580752bde | ||
|  | c9df265c9b | ||
|  | 098e5bc162 | ||
|  | 4b2dcc74d4 | ||
|  | a9254c5c9a | ||
|  | 7ce57e6ccb | ||
|  | 0fcb32a66f | ||
|  | 9946535f01 | ||
|  | 2b17396d6b | ||
|  | b01d5bc237 | ||
|  | b123860304 | ||
|  | 033f5b67db | ||
|  | 6280448dfb | ||
|  | 01cd3333e4 | ||
|  | 63050907b9 | ||
|  | beedf7d780 | ||
|  | 6b8194261f | ||
|  | dbb1c4d534 | ||
|  | e6263f9ff5 | ||
|  | 6ca119c4db | ||
|  | c483a1ab3a | ||
|  | 2e7edd033c | ||
|  | c576902501 | ||
|  | 66c2951594 | ||
|  | b812881cdb | ||
|  | cdeac2c6db | ||
|  | bca2ddd529 | ||
|  | e7285c6499 | ||
|  | bdff275672 | ||
|  | bec58a1ee6 | ||
|  | f64616748c | ||
|  | 512ce15973 | ||
|  | ed8b301574 | ||
|  | d22a6c019c | ||
|  | a0cb1b9d9e | ||
|  | a5294c62ea | ||
|  | e155d3311c | ||
|  | 0a372b0daf | ||
|  | 69143399d1 | ||
|  | 3270d3bf96 | ||
|  | 3896a66122 | ||
|  | b94781aef1 | ||
|  | bed1adc367 | ||
|  | ae54497efa | ||
|  | 06b747c221 | ||
|  | f159beee0d | ||
|  | 49d7dea086 | ||
|  | 3e65733dc5 | ||
|  | cc375d58bb | ||
|  | 911c7c662a | ||
|  | aae003be33 | ||
|  | aede03d8b2 | ||
|  | f0f5ada7de | ||
|  | 58365121a3 | ||
|  | d5a154d2e6 | ||
|  | b20f369aef | ||
|  | abb8aa0b29 | ||
|  | 5368a0f1d7 | ||
|  | d3897eece7 | ||
|  | a82b829da9 | ||
|  | 9f5058e81a | ||
|  | 5b19263720 | ||
|  | 9d5a0db0d9 | ||
|  | 4bd8a7014f | ||
|  | 353e96d951 | ||
|  | 149a6f92b0 | ||
|  | d66426c137 | ||
|  | 4fc9966392 | ||
|  | 417766f0db | ||
|  | de9ac97887 | ||
|  | 6be42f112a | ||
|  | 3895ae63c7 | ||
|  | 607d416d54 | ||
|  | 038693dc86 | ||
|  | cc9be13544 | ||
|  | 9c1474087f | ||
|  | 831de2bcf4 | ||
|  | eb687333bb | ||
|  | 5cc7966d54 | ||
|  | d1a34e7a6f | ||
|  | d63d791717 | ||
|  | 015570c741 | ||
|  | 8400ebc9c6 | ||
|  | 9f99e7c0af | ||
|  | 392c1fc399 | ||
|  | d3cea7a89c | ||
|  | 1dcf7407e6 | ||
|  | d543c033a3 | ||
|  | aaa186be5e | ||
|  | 2054b5b3dd | ||
|  | 98ae5b0ca0 | ||
|  | 36c8171d0f | ||
|  | 3603eb94cc | ||
|  | 0e068d4ccf | ||
|  | 199f348ff4 | ||
|  | b22655fb7c | ||
|  | 06cc9618ba | ||
|  | b9019c8c7f | ||
|  | 77e133e67c | ||
|  | 571e7df807 | ||
|  | 22f4d2979a | ||
|  | e46e366694 | ||
|  | 7b4bc23815 | ||
|  | 9ca79f767c | ||
|  | 274dba7408 | ||
|  | 31708ca29e | ||
|  | 671b025588 | ||
|  | a7956e4856 | ||
|  | 355862025a | ||
|  | a2a39ee0f8 | ||
|  | ec8e39c16f | ||
|  | 88f714999e | ||
|  | c0c2aa3be0 | ||
|  | 822044820e | ||
|  | 6ffc182142 | ||
|  | 3d54a78573 | ||
|  | 8ddf7d953a | ||
|  | 8b9e9ad103 | ||
|  | 5737224c40 | ||
|  | ec9aacbcae | ||
|  | 9395454997 | ||
|  | 66198a8d98 | ||
|  | 96ed9a4256 | ||
|  | 10e54b2263 | ||
|  | cf00922ad2 | ||
|  | 84e8e007a5 | ||
|  | d07b2e773b | ||
|  | 506ef7b0b9 | ||
|  | 2cd5dae8e2 | ||
|  | a1cd49c111 | ||
|  | aca2973aef | ||
|  | 0a7a691c95 | ||
|  | 72906a7afd | ||
|  | d1a4a83570 | ||
|  | e0396b29e8 | ||
|  | 536833cfe0 | ||
|  | 317b02d1b9 | ||
|  | 75e279ea0d | ||
|  | dc2ad21f4c | ||
|  | 484d49aae1 | ||
|  | ca39438ad4 | ||
|  | 49a65ebff4 | ||
|  | befdc05084 | ||
|  | 1fbffe761b | ||
|  | 36aad379ff | ||
|  | 540cfa072e | ||
|  | 3b049c15cc | ||
|  | 3e93ed0a17 | ||
|  | d7d9358136 | ||
|  | 5cf0939ff9 | ||
|  | 8dc6f91d3c | ||
|  | a3a25db230 | ||
|  | c06f18c815 | ||
|  | 6802f04036 | ||
|  | beeccdf345 | ||
|  | 58241ed39d | ||
|  | 31128020f0 | ||
|  | 6c48afc37b | ||
|  | 7a2f169dfc | ||
|  | ed910b99a7 | ||
|  | 54195c0826 | ||
|  | cefbbcd1df | ||
|  | cc01592085 | ||
|  | 5a98a5252d | ||
|  | 184e8b1132 | ||
|  | 2b6b896c2e | ||
|  | 96d06b7a93 | ||
|  | f54f1611b5 | ||
|  | 69ad757e8b | ||
|  | e0beb796ad | ||
|  | f331e7d820 | ||
|  | cbb62d3d78 | ||
|  | c85bc59c1d | ||
|  | 8081eeb007 | ||
|  | 56f91bd10d | ||
|  | 8e20b78731 | ||
|  | 23a09b7081 | ||
|  | 67fdd27499 | ||
|  | e1941daedd | ||
|  | f28bc568a4 | ||
|  | f24cfe39aa | ||
|  | 59d2bf3f79 | ||
|  | 3176e54614 | ||
|  | eb090f7265 | ||
|  | 6d3a9bfd18 | ||
|  | 76f08b7acb | ||
|  | 1ff99346aa | ||
|  | 369695ab32 | ||
|  | 7e23dd1d66 | ||
|  | 0205d3fc5c | ||
|  | 4660cf2ad5 | ||
|  | e26d08d674 | ||
|  | 0932bf2797 | ||
|  | f560fc6d76 | ||
|  | aa6209af00 | ||
|  | 4a51176193 | ||
|  | bb84f7a434 | ||
|  | 48168b1ef0 | ||
|  | 8281c7c83e | ||
|  | a07c1e3c71 | ||
|  | 0766bb31fe | ||
|  | ff4472c1a5 | ||
|  | 17424740e5 | ||
|  | dad0b2fcd3 | ||
|  | c48dbf030f | ||
|  | 617808d603 | ||
|  | 845149deee | ||
|  | 1a9e009327 | ||
|  | ae90815708 | ||
|  | 1c460343b7 | ||
|  | 26079622f9 | ||
|  | 06c6d6096f | ||
|  | c8183aea51 | ||
|  | 7531134ad2 | ||
|  | cd0c6439c2 | ||
|  | c918c93f51 | ||
|  | 97d3bd68ed | ||
|  | 75f1e034ae | ||
|  | 8e72f218f1 | ||
|  | d643e05c5a | ||
|  | fea44834d0 | ||
|  | 195a2d7523 | ||
|  | b2fd346ef8 | ||
|  | 1ff8b62cb7 | ||
|  | c7ae15a41a | ||
|  | efe6f59f79 | ||
|  | 8e31d0491d | ||
|  | 73d4a10351 | ||
|  | 81d9d4dbc7 | ||
|  | 184ec13f99 | ||
|  | dee0422eff | ||
|  | 81a2975f1a | ||
|  | 5cd2ef4a5e | ||
|  | 466c2a68c2 | ||
|  | 0fb9fba531 | ||
|  | 356dd2c6cd | ||
|  | 32c4661233 | ||
|  | a245b504ec | ||
|  | a2f5fbdfd3 | ||
|  | 04be26adc5 | ||
|  | be0adb7cf2 | ||
|  | 84fd92bf5a | ||
|  | ee4e061739 | ||
|  | 4a2b01cd9a | ||
|  | efdd6460fb | ||
|  | 803827e05c | ||
|  | a41d5e9ab3 | ||
|  | e94333f877 | ||
|  | 6dbb80d687 | ||
|  | 31a1031624 | ||
|  | f8e9ce0d52 | ||
|  | 11baa968cd | ||
|  | 3e5e5b376f | ||
|  | bda18f296d | ||
|  | 287d110c84 | ||
|  | c98275e73a | ||
|  | aa573cc951 | ||
|  | 883d3d86e3 | ||
|  | fb047bd5f4 | ||
|  | 66a04d8365 | ||
|  | a0e501f9fd | ||
|  | 8b40d3346d | ||
|  | eddf5cd250 | ||
|  | ee5c534ca3 | ||
|  | fd4e77ae0f | ||
|  | b747c50aa3 | ||
|  | deebdd86a6 | ||
|  | b2db79cc10 | ||
|  | bbab370b1e | ||
|  | db4adf399d | ||
|  | 0683c87e52 | ||
|  | 3f62b647fc | ||
|  | 2562a5b30d | ||
|  | e232f2e223 | ||
|  | 21644ff4dd | ||
|  | be96a4fce5 | ||
|  | a1cabcbed3 | ||
|  | ce933b1f06 | ||
|  | 51ae130922 | ||
|  | da1bc18a47 | ||
|  | e7165a526b | ||
|  | 6081cc399f | ||
|  | 7c5c24e15d | ||
|  | e3e55b4347 | ||
|  | 40d8e7d1ad | ||
|  | 59e23b89f2 | ||
|  | cc33af8193 | ||
|  | 0e1e7eb2a9 | ||
|  | 52a28a7758 | ||
|  | 3f752d6832 | ||
|  | fe714e9989 | ||
|  | 0d3213a379 | ||
|  | 44056629e8 | ||
|  | 54125c05d3 | ||
|  | 7d32e50f25 | ||
|  | 4af9ff49a0 | ||
|  | 23faef845c | ||
|  | 41dad4091a | ||
|  | daf859b977 | ||
|  | f47ba6c977 | ||
|  | 4b9b207d92 | ||
|  | 875cbf66af | ||
|  | 412d6d4fd7 | ||
|  | 91c6deeb1f | ||
|  | 6d1978fd9a | ||
|  | 52d23b6ef5 | ||
|  | 0656ccbdd9 | ||
|  | e774ebd0a3 | ||
|  | edbda32a84 | ||
|  | 721fa04e3c | ||
|  | 9fd8d8915d | ||
|  | 7a9f5ebdd1 | ||
|  | a3423f0321 | ||
|  | c37e9a4467 | ||
|  | 6157d82a0b | ||
|  | 38b27fec92 | ||
|  | c43439bb68 | ||
|  | 8d9561d7a5 | ||
|  | 2a72cce3b7 | ||
|  | d3bbb6fb1f | ||
|  | 7b6723e9a2 | ||
|  | 1ee741460d | ||
|  | 967b0b493b | ||
|  | b53aaf7dde | ||
|  | 714c13bdbf | ||
|  | 651a4fd3cc | ||
|  | 505aee22bb | ||
|  | ca3d59dc33 | ||
|  | 13890e32a1 | ||
|  | df8976eabe | ||
|  | 3e01daa172 | ||
|  | f6999f355b | ||
|  | 5c06b45eb1 | ||
|  | 1802bb967a | ||
|  | d8d92f147f | ||
|  | 4a95bdd8ba | ||
|  | db5d94d956 | ||
|  | 06f2e34bb5 | ||
|  | 2ef7a01945 | ||
|  | d3f642551d | ||
|  | 490997157e | ||
|  | 2432af7883 | ||
|  | 7abeece3f0 | ||
|  | 3851652821 | ||
|  | 1d67d2250a | ||
|  | 37f40d8637 | ||
|  | 0224d1d59b | ||
|  | 587b94153d | ||
|  | 5124ce0302 | ||
|  | 950c4045b0 | ||
|  | 9c8ba66873 | ||
|  | 25d1d1be1b | ||
|  | 339c352505 | ||
|  | c587081fe4 | ||
|  | 8f9b1b866b | ||
|  | ff5ecf6182 | ||
|  | 05670cf393 | ||
|  | f10f5d30bf | ||
|  | 0d336727e8 | ||
|  | bf354275b3 | ||
|  | 1932bf277a | ||
|  | 192db4bb6e | ||
|  | 701efb943d | ||
|  | b2674971f1 | ||
|  | c907cb4cf1 | ||
|  | bb1462b4d9 | ||
|  | 1035f0e139 | ||
|  | 8475757716 | ||
|  | 20ffd8d61b | ||
|  | 8601428c4c | ||
|  | 59998573ee | ||
|  | 293cd72001 | ||
|  | 22ab9ebb2f | ||
|  | 9136e592d3 | ||
|  | ed8e392616 | ||
|  | e57ce6e644 | ||
|  | 8204e46086 | ||
|  | 9e365d9f80 | ||
|  | 6b40a933e9 | ||
|  | 8520a5002f | ||
|  | b38ed06f6e | ||
|  | 48427b1143 | ||
|  | 5d505f4ed0 | ||
|  | 0c02a08954 | ||
|  | 0221bd0f80 | ||
|  | 28216cbcb5 | ||
|  | 3e08a8cd6b | ||
|  | 67fafdeef7 | ||
|  | cc82505b66 | ||
|  | fd5f075f63 | ||
|  | a115960411 | ||
|  | e9fa4ca816 | ||
|  | 75d92bc7f0 | ||
|  | 74aa6e911e | ||
|  | 9d000c1898 | ||
|  | b2254875b2 | ||
|  | 78d04230d5 | ||
|  | 1c04477393 | ||
|  | 2a9679c94e | ||
|  | 6009f8ecde | ||
|  | 35cdbec70a | ||
|  | 0faef542c1 | ||
|  | 8b085af6a1 | ||
|  | e3b11a9eb2 | ||
|  | 72fc88f3c6 | ||
|  | a5b759f268 | ||
|  | 6a9ffae25d | ||
|  | 64c031c7fe | ||
|  | 720926c50d | ||
|  | 36ec974284 | ||
|  | cff77c39e2 | ||
|  | 056a0a1736 | ||
|  | f301da83c6 | ||
|  | 5362231efa | ||
|  | 4bb14cad73 | ||
|  | 7f5188f5a4 | ||
|  | a80b7aac6c | ||
|  | 83f32478fa | ||
|  | 7578ec6801 | ||
|  | e14a32f76f | ||
|  | 58faa189ac | ||
|  | 9b4f87d44a | ||
|  | 7830a64170 | ||
|  | 8f0fa02107 | ||
|  | e000fb5d80 | ||
|  | 566fadad15 | ||
|  | cf23858c10 | ||
|  | 216a223617 | ||
|  | 638f38d823 | ||
|  | 98ee70f04e | ||
|  | b365db5a4b | ||
|  | 02e55496df | ||
|  | e11e53913a | ||
|  | f8a5fb4225 | ||
|  | 3a49450461 | ||
|  | 3c375fb955 | ||
|  | 011fea2cc6 | ||
|  | a079eec2cb | ||
|  | 776b37f4ea | ||
|  | a4d8bbe3da | ||
|  | 72166743fa | ||
|  | c4312c0b11 | ||
|  | 38ba645415 | ||
|  | ac12a47071 | ||
|  | bea321939e | ||
|  | 210f84b6ea | ||
|  | d4c642741f | ||
|  | e6b1b58379 | ||
|  | 8d982c1a90 | ||
|  | be10e836dc | ||
|  | 9be05e7e17 | ||
|  | bd96b2819f | ||
|  | f601af3da0 | ||
|  | 70a01c082b | ||
|  | bcf066ead7 | ||
|  | 24dd3578ed | ||
|  | d5c39d54d8 | ||
|  | 6e3f6abc67 | ||
|  | 463201df2c | ||
|  | a7501c396f | ||
|  | 4c8bc49a7e | ||
|  | f254674f88 | ||
|  | a97c267378 | ||
|  | eaa947894b | ||
|  | fb3a26510b | ||
|  | bfe8b14e49 | ||
|  | afb47eb742 | ||
|  | ba97f96288 | ||
|  | ecbafb8f4b | ||
|  | 12d3800d67 | ||
|  | d586b82372 | ||
|  | ba9877c9b4 | ||
|  | 907933f3df | ||
|  | 2e91d21a88 | ||
|  | dca395a018 | ||
|  | 625070a5b9 | ||
|  | f875c7cbf5 | ||
|  | eed88fc103 | ||
|  | 6fc54d1d27 | ||
|  | 0ef52bf909 | ||
|  | 95e34af6ef | ||
|  | 650b99ead2 | ||
|  | 57941a19de | ||
|  | 6157db0b6a | ||
|  | c9358acf5d | ||
|  | ed29eb8a5d | ||
|  | bcf7452312 | ||
|  | b9000519e4 | ||
|  | 2694297466 | ||
|  | 53ff5c1490 | ||
|  | 32a036b076 | ||
|  | aae2ab2693 | ||
|  | 4ef23e28a3 | ||
|  | 38beb7f8d2 | ||
|  | 0129a66906 | ||
|  | 45bced7b34 | ||
|  | 7f5a55dffb | ||
|  | 80289df6d3 | ||
|  | 2115c3ced8 | ||
|  | 1c2d0e6618 | ||
|  | ea4f7f79ce | ||
|  | b17f8ac311 | ||
|  | 6870d13b72 | ||
|  | 81fa304fd2 | ||
|  | a663ddb0d9 | ||
|  | f7969afc22 | ||
|  | 52ce4cd313 | ||
|  | 247175881f | ||
|  | fcf5009338 | ||
|  | 12542d8f63 | ||
|  | e94194e28b | ||
|  | 115499f3b2 | ||
|  | 12af05b94f | ||
|  | 88b83d8164 | ||
|  | fcc22c692a | ||
|  | a876e8005c | ||
|  | 2288e3705a | ||
|  | e8b58154e0 | ||
|  | 4393475af3 | ||
|  | 3fc560597c | ||
|  | 9f9af0b693 | ||
|  | a83fe2caea | ||
|  | 30c5376217 | ||
|  | 6dddd6629d | ||
|  | f80de12cb5 | ||
|  | 544ffca3a5 | ||
|  | e0730c7b39 | ||
|  | 3d59d141c4 | ||
|  | ccddc2623d | ||
|  | fcc47b58b4 | ||
|  | f67ac2e25e | ||
|  | 26127c9ccf | ||
|  | d624efa799 | ||
|  | ed3d40a4e0 | ||
|  | 6e90ce5496 | ||
|  | ab851b1be4 | ||
|  | 340de53825 | ||
|  | a867b60af0 | ||
|  | 26eafb0bd2 | ||
|  | 0dbe44764b | ||
|  | 2159df6802 | ||
|  | 23389b9f17 | ||
|  | 6d3e3b894a | ||
|  | 55340aefa3 | ||
|  | 94bc751e41 | ||
|  | 89259c11e2 | ||
|  | 6bbaf1523c | ||
|  | fa3f18b60f | ||
|  | 3dc794002f | ||
|  | f50b133f2e | ||
|  | 1d6f6d28c9 | ||
|  | c913de3c8b | ||
|  | bbc7b54a38 | ||
|  | 05fa1b40d1 | ||
|  | 6a88c8634d | ||
|  | 8ae1efa230 | ||
|  | ab8df4c8ab | ||
|  | c259a46ed3 | ||
|  | 5dc0677599 | ||
|  | 7ed662ecc2 | ||
|  | 4361cc69d4 | ||
|  | 461cbcbc28 | ||
|  | 09ae6c488b | ||
|  | 271a0ade26 | ||
|  | 4b076d227a | ||
|  | 3c4e7158a1 | ||
|  | 0b16765f37 | ||
|  | 20c2ff3443 | ||
|  | 96f2e598f4 | ||
|  | 7374f0f9dd | ||
|  | ccc44a74a0 | ||
|  | 66cd63a68d | ||
|  | decf7e5485 | ||
|  | 063c8025aa | ||
|  | 2fa7d2bd56 | ||
|  | e55e7bce74 | ||
|  | f572445a65 | ||
|  | 8b4f656d90 | ||
|  | 6c1e093ebd | ||
|  | 6dd1b4537a | ||
|  | 39ca9bea72 | ||
|  | 999103277e | ||
|  | 3cc57ab89c | ||
|  | 4e830079de | ||
|  | ea7231e9fe | ||
|  | ddfaca6d0c | ||
|  | 3b11bd0593 | ||
|  | 3f89057528 | ||
|  | 2f1073712f | ||
|  | 678e504c48 | ||
|  | e69545fd95 | ||
|  | a7ed025cd6 | ||
|  | 3d8e1f2484 | ||
|  | c38c9608da | ||
|  | 2396b75e3c | ||
|  | e5c19b7562 | ||
|  | 114788567d | ||
|  | 17ae4b7d2a | ||
|  | 12d652bd0e | ||
|  | ff1bed97b8 | ||
|  | 56490f0e84 | ||
|  | 0b028a8923 | ||
|  | 43ac541cb8 | ||
|  | 5218443678 | ||
|  | d9028ed9b7 | ||
|  | 9b9bd11ebb | ||
|  | 07011ec5f7 | ||
|  | c3990ac32f | ||
|  | 081ff3ff55 | ||
|  | 93996ada96 | ||
|  | a60671d4c1 | ||
|  | 3f716cc369 | ||
|  | 9f23cffd1b | ||
|  | 07c416cfbf | ||
|  | 389fcc1c8d | ||
|  | fa07811375 | ||
|  | fc91a50979 | ||
|  | f9c518f321 | ||
|  | 015b439f0d | ||
|  | 0675622508 | ||
|  | e9969bdd5f | ||
|  | 1139f950ed | ||
|  | 284732c7a6 | ||
|  | 0cb0720d8b | ||
|  | 8ad1ede0c5 | ||
|  | a349aac8a4 | ||
|  | 83b169c6ef | ||
|  | 49c37baac5 | ||
|  | 8d62088576 | ||
|  | f5437a17f8 | ||
|  | 92af4e5c96 | ||
|  | 0619adb0cd | ||
|  | 65a5107854 | ||
|  | 0fcc1e252b | ||
|  | 4b7f817475 | ||
|  | 0439599971 | ||
|  | fa344d5308 | ||
|  | f0316f09ed | ||
|  | b1af6bab28 | ||
|  | ad2aebb54d | ||
|  | 23fc652092 | ||
|  | f0a5756f25 | ||
|  | 14c7ad201a | ||
|  | 08ca3c89d3 | ||
|  | edda470bf8 | ||
|  | 7183d72e5c | ||
|  | 5e38ebfce5 | ||
|  | 56e36847a5 | ||
|  | 6dba916d02 | ||
|  | fd57086ffd | ||
|  | d98d366eea | ||
|  | b261b0b447 | ||
|  | c6042a9053 | ||
|  | ae1245abec | ||
|  | e26d2376fc | ||
|  | bb36ad64a7 | ||
|  | 262d4f92d4 | ||
|  | 675530458c | ||
|  | 19e34b460f | ||
|  | dddb8cdbc0 | ||
|  | 0d0df5f143 | ||
|  | d1cf683f57 | ||
|  | d099c33e5b | ||
|  | 21fb41545b | ||
|  | 4c56814785 | ||
|  | cffe05e22b | ||
|  | 4237850299 | ||
|  | b5fc36a8e1 | ||
|  | 4586c1ef52 | ||
|  | 2722f0b749 | ||
|  | d6cf7c4872 | ||
|  | 3aedfed432 | ||
|  | edeaf13259 | ||
|  | c1290c4e9b | ||
|  | b2c1527b17 | ||
|  | a4a65ea56e | ||
|  | ccf0e1875e | ||
|  | 9c009aceaf | ||
|  | da4b1c7276 | ||
|  | add098d5c0 | ||
|  | aca096548c | ||
|  | 75aa3abcae | ||
|  | e685d262cc | ||
|  | d2599d6ef9 | ||
|  | cd5223d98d | ||
|  | 7b68d9047d | ||
|  | 9a7ea06d66 | ||
|  | c69ef34ac9 | ||
|  | 021999d05f | ||
|  | 6054430a5e | ||
|  | 8f578ed95a | ||
|  | fc5c339e27 | ||
|  | defad3d820 | ||
|  | c0f96aa948 | ||
|  | f2eae2fc98 | ||
|  | 0e4f786978 | ||
|  | d36b2318fd | ||
|  | d83b508bbc | ||
|  | 5b9c2cdc13 | ||
|  | 49066c282a | ||
|  | 3e28c0c00a | ||
|  | 220d689f69 | ||
|  | 5a0a28a04c | ||
|  | b44e69e09b | ||
|  | fcbe10f5ec | ||
|  | 182fe170fd | ||
|  | 184e9bdaf6 | ||
|  | 0096f50cde | ||
|  | 460f14deca | ||
|  | 910ad45bee | ||
|  | 74e319855d | ||
|  | 9af0fb4cd5 | ||
|  | 185f5cce29 | ||
|  | aca1174566 | ||
|  | e791f7fde2 | ||
|  | 7bba7fcf66 | ||
|  | 1d78f98ec8 | ||
|  | 7ed2e03654 | ||
|  | 549e0f3477 | ||
|  | 7785ec0222 | ||
|  | ca504965f9 | ||
|  | 3841259779 | ||
|  | 169d1065cc | ||
|  | e864f5507a | ||
|  | 434b4ded4a | ||
|  | 3d01669cea | ||
|  | 1499b2cd40 | ||
|  | 6b54ef8398 | ||
|  | 07ad43f7a2 | ||
|  | 72e72c60c2 | ||
|  | f9a242d33e | ||
|  | b0f43eaa07 | ||
|  | b02046b884 | ||
|  | 864c931ee9 | ||
|  | 5cd8da6d91 | ||
|  | 4a4671c2ae | ||
|  | 8de142cd9a | ||
|  | 1a42bec51c | ||
|  | 577e38759e | ||
|  | 9cdf43a2c9 | ||
|  | 62d43c2cb2 | ||
|  | 2dc67d1674 | ||
|  | fb1c78c657 | ||
|  | 37e58ac13a | ||
|  | de715c14be | ||
|  | c4d8a0da05 | ||
|  | 1b54b14671 | ||
|  | a92efbc55f | ||
|  | 1bd02529e0 | ||
|  | bc16298b6e | ||
|  | 804a97cad7 | ||
|  | ab52bdec15 | ||
|  | ddc3e82c14 | ||
|  | 57691471bb | ||
|  | c502dd445b | ||
|  | ed475b1b9c | ||
|  | df165a817c | ||
|  | d16015d625 | ||
|  | a4b3bf3ef4 | ||
|  | 6b006853e6 | ||
|  | 6001180e29 | ||
|  | 662fbed1d0 | ||
|  | 19c7e08c5d | ||
|  | 72f04aaedc | ||
|  | 2998382969 | ||
|  | 37fe79944f | ||
|  | 536735519a | ||
|  | 6b0a711395 | ||
|  | 13d3d40376 | ||
|  | 6873336aca | ||
|  | c2d2eb53e8 | ||
|  | 210d597a48 | ||
|  | e41ede0a6b | ||
|  | 4a8b17ac7c | ||
|  | 1f5f515d72 | ||
|  | 1e6242b89f | ||
|  | dde09f9f89 | ||
|  | 916d85c3fe | ||
|  | b243ed93aa | ||
|  | 70d28bbf6e | ||
|  | 3c76da7132 | ||
|  | 3254565c09 | ||
|  | cd0033791f | ||
|  | 2427ee44a5 | ||
|  | ff0e617b2a | ||
|  | e6cfe040b5 | ||
|  | 94e2f9b6dc | ||
|  | 512b81ad93 | ||
|  | fc0e76f431 | ||
|  | 9da69358e2 | ||
|  | aa246b0b2b | ||
|  | 6ed649bc8a | ||
|  | 725f5b7110 | ||
|  | 5a890c5c3a | ||
|  | 7752329b94 | ||
|  | 5f48f13890 | ||
|  | a734e04561 | ||
|  | 5aa1db293f | ||
|  | f89aee37f5 | ||
|  | 538018fed1 | ||
|  | a2327c50ec | ||
|  | c2711023e2 | ||
|  | cac30f0b4c | ||
|  | 4bb17019a4 | ||
|  | ba2a40bdf3 | ||
|  | f3460cca49 | ||
|  | 64ce53ac30 | ||
|  | a43238360c | ||
|  | b2cbadf5d8 | ||
|  | 81640ba06d | ||
|  | 9327430484 | ||
|  | a24c90eae8 | ||
|  | 1d3987ece6 | ||
|  | 83f5b5e293 | ||
|  | f231263085 | ||
|  | 4ad67a87f1 | ||
|  | b766d93d9a | ||
|  | 0905ceb1d5 | ||
|  | 2fbf837354 | ||
|  | 4bd79c880c | ||
|  | 4af041e015 | ||
|  | 8dc3e3ec93 | ||
|  | f4b68d26d6 | ||
|  | 1887977b92 | ||
|  | 8eb84acf4f | ||
|  | 1b685da3e3 | ||
|  | 406b658801 | ||
|  | bba1ee1264 | ||
|  | 02b6191d47 | ||
|  | c5a3de09cd | ||
|  | 0afe2a680e | ||
|  | 03e0510c4f | ||
|  | 1068dcb8a4 | ||
|  | 10a93df653 | ||
|  | 79ff67852f | ||
|  | a36cab969f | ||
|  | 45447646fa | ||
|  | 8a0f76ab68 | ||
|  | 037135e764 | ||
|  | 21e89c3b64 | ||
|  | bd11ec69fa | ||
|  | 9e2b34bc12 | ||
|  | 0faebc290f | ||
|  | fc0ef4b79d | ||
|  | 027b954b50 | ||
|  | 33c830a432 | ||
|  | a7887f1e25 | ||
|  | fa7a59572a | ||
|  | d9c2df5b0d | ||
|  | a854b2c17e | ||
|  | 7d4006b205 | ||
|  | 86ecca6011 | ||
|  | 0ea5cf2caa | ||
|  | a950e02e9b | ||
|  | 9eec6641dd | ||
|  | 18f46676fd | ||
|  | 9735ef6d41 | ||
|  | d3e8ceee00 | ||
|  | 144e329eca | ||
|  | 21d5420b2a | ||
|  | 3011b5074d | ||
|  | 83190572c7 | ||
|  | 9cf9e5f865 | ||
|  | 5bdef7f1c7 | ||
|  | ba285a2d2d | ||
|  | 0dff371e62 | ||
|  | ce4a2a5851 | ||
|  | 2c978dc89a | ||
|  | 4b8b819109 | ||
|  | c230b3a806 | ||
|  | df08b9c5c6 | ||
|  | eca65376a3 | ||
|  | 88e3705636 | ||
|  | 5476509ef5 | ||
|  | 0bd6636453 | ||
|  | 105894e00d | ||
|  | 230a319510 | ||
|  | ae16a2b14f | ||
|  | da0c0742bf | ||
|  | 61d60a9048 | ||
|  | 3e28e9a016 | ||
|  | 423f9fefa9 | ||
|  | 5707dc7579 | ||
|  | 3be1cdb249 | ||
|  | 426d3d948c | ||
|  | 9a3aed8038 | ||
|  | fb58bf1bf5 | ||
|  | a6dbd912c6 | ||
|  | 65ce277a20 | ||
|  | 0b2d423c87 | ||
|  | da056092fb | ||
|  | 45aa85d690 | ||
|  | 5c35fee0c2 | ||
|  | 24bdc319dd | ||
|  | f1dcc41e42 | ||
|  | 550f301ba2 | ||
|  | d9bf4d1c0d | ||
|  | c3c1a6eb22 | ||
|  | 2c4454418e | ||
|  | e44de572f5 | ||
|  | f27919f91b | ||
|  | ba9968bde0 | ||
|  | 05ea8216ff | ||
|  | fa1695672a | ||
|  | ac6f98fc47 | ||
|  | 1a1f89f555 | ||
|  | 6c3262e176 | ||
|  | b4bdb48f1e | ||
|  | 823afe877b | ||
|  | cb8e082414 | ||
|  | 98c1fcc68f | ||
|  | 8c439a2852 | ||
|  | 50c6109be7 | ||
|  | 6e362663b5 | ||
|  | 74c9feb53f | ||
|  | 402e8588cf | ||
|  | 778a42bcc0 | ||
|  | 584f7ced84 | ||
|  | 8e892e7ea5 | ||
|  | 3386c8b455 | ||
|  | 6fa73ee28d | ||
|  | 8ec8042045 | ||
|  | cddc123539 | ||
|  | 4c2938c5cd | ||
|  | 6d03ddadcc | ||
|  | 64311da4b4 | ||
|  | 0cbb50ae9d | ||
|  | 7e96054dc2 | ||
|  | 578298580e | ||
|  | ee5afaa6bc | ||
|  | 15b023d116 | ||
|  | 1ef96c0b4d | ||
|  | 8c3ae40de1 | ||
|  | 94fcfacec4 | ||
|  | ba7c01c6bc | ||
|  | 9f92e1b7bd | ||
|  | 1f0e692ee2 | ||
|  | 0acd75a24f | ||
|  | eedf27f8a5 | ||
|  | b451e207e2 | ||
|  | c0c37eec7b | ||
|  | 89363ecfa3 | ||
|  | 593e799ca1 | ||
|  | 8fc055cad9 | ||
|  | 75f86462e2 | ||
|  | 40892ccfa7 | ||
|  | 87fbf9c1a5 | ||
|  | 4944b233b6 | ||
|  | 9f23462c42 | ||
|  | 84a24f0333 | ||
|  | 7a885bfc3c | ||
|  | 3ba0cf1454 | ||
|  | 2d67a3159d | ||
|  | 290f25f1a0 | ||
|  | 1659904f81 | ||
|  | 230bd6e40a | ||
|  | ce27e97b92 | ||
|  | 18c1223c7b | ||
|  | 8ef659f5de | ||
|  | 037452e525 | ||
|  | e3482011d5 | ||
|  | 62748fa255 | ||
|  | 7a9df05f6b | ||
|  | 335279e728 | ||
|  | 0332104738 | ||
|  | 9f04854902 | ||
|  | 73008a35fe | ||
|  | eae96cd2af | ||
|  | cb670bb27d | ||
|  | fe1fb23e5b | ||
|  | c2dd61e96b | ||
|  | 80f5e61b6b | ||
|  | dbcae16b75 | ||
|  | 886dcae822 | ||
|  | ed495ec600 | ||
|  | ddb60ccdc5 | ||
|  | 335e2083af | ||
|  | 7b1d9d4962 | ||
|  | da6ff9f90a | ||
|  | 48f26c7bf1 | ||
|  | 3ce317b170 | ||
|  | b741565f57 | ||
|  | d8fea44968 | ||
|  | 778300b67e | ||
|  | cb2b44fef3 | ||
|  | cdb5875d6b | ||
|  | 01c5e15bcd | ||
|  | f0babb4be7 | ||
|  | 10b00da874 | ||
|  | e9f391b2eb | ||
|  | 50be39b054 | ||
|  | a94e0bb3da | ||
|  | 3f65d5d760 | ||
|  | 48cb528ae4 | ||
|  | e62e0345df | ||
|  | 441f011fba | ||
|  | af1349160a | ||
|  | 2072607889 | ||
|  | 073fd5aa0d | ||
|  | 7b4703e4ff | ||
|  | 1484621300 | ||
|  | 40709c8367 | ||
|  | b6ab5770a2 | ||
|  | 83b7cb4ff9 | ||
|  | 256dba66b2 | ||
|  | 6ac12f8ffa | ||
|  | 82e438d29b | ||
|  | e86547645c | ||
|  | 8b901084fe | ||
|  | 1a0cbbdb31 | ||
|  | 30ac62ffb7 | ||
|  | 8ab294e90b | ||
|  | f5edb15f43 | ||
|  | eed6107ce7 | ||
|  | d49dc599a2 | ||
|  | 3c5179f145 | ||
|  | 067d17c09c | ||
|  | 4c88c9af86 | ||
|  | 1c84afe186 | ||
|  | 9d4c4be468 | ||
|  | de7db8db78 | ||
|  | 407ba4dd6d | ||
|  | 5135be3000 | ||
|  | b8ab7d1a14 | ||
|  | 6211fd8496 | ||
|  | a4f273b48b | ||
|  | 68d820a97c | ||
|  | ebadfd6358 | ||
|  | cf93a88adc | ||
|  | bd2c4252bb | ||
|  | 84e7af04b9 | ||
|  | 37c63bc6b5 | ||
|  | e7d3716549 | ||
|  | 73bc5372c0 | ||
|  | b999a8f0fb | ||
|  | 16678aa5e1 | ||
|  | f9ab49911d | ||
|  | 3fabe2e9fb | ||
|  | 9a8a3e94d6 | ||
|  | 32ef2ef801 | ||
|  | 76cd3d35e2 | ||
|  | 900dea2c66 | ||
|  | 8e6ca0dd05 | ||
|  | 4b4ad7f1a8 | ||
|  | 21a0a5d573 | ||
|  | 3cfa3f3b27 | ||
|  | c77b43458e | ||
|  | 9ab0a83f7c | ||
|  | d3cda8811d | ||
|  | 55740c0d97 | ||
|  | c0a524c8a3 | ||
|  | e51c2d10f0 | ||
|  | 7af55b7268 | ||
|  | 7350b1da1b | ||
|  | 136adbe723 | ||
|  | cb2863eaf3 | ||
|  | d054f9b92f | ||
|  | 9c83c18137 | ||
|  | 999a7481e4 | ||
|  | a3b684b4ed | ||
|  | cb312ca025 | ||
|  | 1335a52db3 | ||
|  | 727221e2cb | ||
|  | 360f286ed3 | ||
|  | 6aecd77b77 | ||
|  | ca85cab6fb | ||
|  | 742479bb01 | ||
|  | 68e54a9297 | ||
|  | 056d83eda4 | ||
|  | 42ec55d0db | ||
|  | c89bd89d9a | ||
|  | 31a0be5bb4 | ||
|  | 07610ae8fb | ||
|  | dbc95dd878 | ||
|  | 792e8a9947 | ||
|  | d774cde109 | ||
|  | cc111d14b0 | ||
|  | bb3ba42ce2 | ||
|  | f4ecf2d1aa | ||
|  | 1997666196 | ||
|  | 3aa9057c5f | ||
|  | 834f8382e9 | ||
|  | 357638a26c | ||
|  | 919a0c01e4 | ||
|  | 6ff618e388 | ||
|  | ac765b7e4c | ||
|  | 2134e87c31 | ||
|  | 0d37288129 | ||
|  | 7cbd41137d | ||
|  | ba43d7063f | ||
|  | c9b2e29ba0 | ||
|  | 4720519aef | ||
|  | d7b0106e7d | ||
|  | 0a2cbaa047 | ||
|  | 3e5f615ffc | ||
|  | 00dc73e6d9 | ||
|  | aa5b9a1727 | ||
|  | f63a287a6c | ||
|  | b9d4c8dcd6 | ||
|  | 94433f1714 | ||
|  | a4dd4358b4 | ||
|  | 4e79b43395 | ||
|  | 6bb54bfa85 | ||
|  | 0df6c3a8dc | ||
|  | dc25086eab | ||
|  | 3299188edf | ||
|  | f6afb46f6f | ||
|  | 98993cfa9b | ||
|  | 5a920d5efd | ||
|  | 935276af88 | ||
|  | 5a505c8469 | ||
|  | 2c2abe8b8e | ||
|  | 638099d989 | ||
|  | 0f32f6be4c | ||
|  | 1f7c98bdcf | ||
|  | 72068a4b78 | ||
|  | c8038e0774 | ||
|  | 6b39beecb4 | ||
|  | b1ba64db12 | ||
|  | ad53832766 | ||
|  | d5bffc8ed7 | ||
|  | 69b36ddd1d | ||
|  | 9f926394a6 | ||
|  | 1e7ecbdf9d | ||
|  | beb8a461cf | ||
|  | e235a57e2f | ||
|  | 114b27079e | ||
|  | 6e19bc01f5 | ||
|  | f9dfdeafb3 | ||
|  | f05d626e38 | ||
|  | 918041258e | ||
|  | a5b13aa67f | ||
|  | 1383cbd4d5 | ||
|  | e9b7e82aea | ||
|  | fd6e7fc1ab | ||
|  | 743deb4227 | ||
|  | b051278d2e | ||
|  | bfda4bc199 | ||
|  | 4456ef2326 | ||
|  | 7336367eff | ||
|  | 9cb6c7697e | ||
|  | cd44f51072 | ||
|  | d8976379b1 | ||
|  | 8aa847c718 | ||
|  | 6691b238f7 | ||
|  | cca2758138 | ||
|  | 4a74e68e31 | ||
|  | 3d3842b9d6 | ||
|  | 9d889d05e4 | ||
|  | 9f920bcfe3 | ||
|  | 1bb49fa496 | ||
|  | 6b1d8d3aaa | ||
|  | c6b6ed7fa8 | ||
|  | 34454261d2 | ||
|  | ddf9f52737 | ||
|  | 10b969a074 | ||
|  | 5df0634380 | ||
|  | f0f965421c | ||
|  | 6381408fba | ||
|  | 43e738cb44 | ||
|  | 6d4303aa3f | ||
|  | 13c2db5378 | ||
|  | 36f6bda525 | ||
|  | 78886e7b1f | ||
|  | 3dce194930 | ||
|  | ec776bb6eb | ||
|  | 243d942a6e | ||
|  | ea6aba62c4 | ||
|  | 73743721b1 | ||
|  | 61eb5b341d | ||
|  | d758f72393 | ||
|  | 1b1367f4c2 | ||
|  | 07388dd58a | ||
|  | 359c71ef2f | ||
|  | 93d4d3df1d | ||
|  | d3a7596be2 | ||
|  | 114d3812cc | ||
|  | b2d4dcfbf1 | ||
|  | 0baf8f6d18 | ||
|  | 2f8e3a0707 | ||
|  | d7a4bf22c6 | ||
|  | 0c2f9d22b9 | ||
|  | e75c5aac49 | ||
|  | 77e5024f54 | ||
|  | 7329c0b200 | ||
|  | 0afe3c48a1 | ||
|  | 1ab5e923bc | ||
|  | 90b3bd77e7 | ||
|  | 9c60443f97 | ||
|  | 058e5602a3 | ||
|  | eebac2a66d | ||
|  | 7e8f5c9548 | ||
|  | d34b49bd48 | ||
|  | ccffae287d | ||
|  | ad69011ac5 | ||
|  | f8ea0f971d | ||
|  | 9918410954 | ||
|  | 4f4e6fac16 | ||
|  | 15e99bd672 | ||
|  | 696e9a6fde | ||
|  | 36cbb3d71f | ||
|  | f69598c6aa | ||
|  | 5fc31f3c1e | ||
|  | 6581ee0ee0 | ||
|  | 69e7501d47 | ||
|  | 314abbea8b | ||
|  | 82c9a75578 | ||
|  | 651101912c | ||
|  | fb0d463040 | ||
|  | 8c254554eb | ||
|  | 2d9c89375a | ||
|  | 61aba29df7 | ||
|  | 8c949e6190 | ||
|  | 6eb9188690 | ||
|  | 6832f2ebd0 | ||
|  | 3e02b50ea1 | ||
|  | 7b7743c03e | ||
|  | de20563275 | ||
|  | 9e720c3a38 | ||
|  | 54685c1f5f | ||
|  | eb8f8fa935 | ||
|  | 9adbbd872c | ||
|  | 4bd38f97a2 | ||
|  | 78ab1e200a | ||
|  | 11280e473d | ||
|  | f9750a64f8 | ||
|  | ac2ab65471 | ||
|  | 0530c0402c | ||
|  | a58a560bbb | ||
|  | 96ab112b22 | ||
|  | b388dcc7d4 | ||
|  | f511a25c94 | ||
|  | 58d8b6f95b | ||
|  | 953d68c3a2 | ||
|  | 9e2f7af59b | ||
|  | 840dfa6696 | ||
|  | 4a20c008ff | ||
|  | 981ffe4194 | ||
|  | 2597633b0e | ||
|  | 71d174d765 | ||
|  | 4aa9a04516 | ||
|  | 258d6a1688 | ||
|  | 2e2c12d6a4 | ||
|  | 44d189d7d3 | ||
|  | ab508a3d9e | ||
|  | 4e166c7d2e | ||
|  | 7f175a4870 | ||
|  | 0a627f6f9e | ||
|  | d34cc65984 | ||
|  | 78d034d366 | ||
|  | 638fa9005f | ||
|  | 5cb9907bf8 | ||
|  | f08fcc36fb | ||
|  | d231cd9f61 | ||
|  | 86a586f866 | ||
|  | 9d4cba1620 | ||
|  | e9afd55e9d | ||
|  | 9fa326f630 | ||
|  | af9473c126 | ||
|  | cb08df0770 | ||
|  | d49ca2eb11 | ||
|  | a3f8841ec3 | ||
|  | fd678c286d | ||
|  | 2a3f9b621b | ||
|  | 359e1b3943 | ||
|  | 754336b3cf | ||
|  | 4918f1c4cb | ||
|  | 5d5e308942 | ||
|  | 6a18f81cec | ||
|  | 1ff135d172 | ||
|  | e666e5e9e3 | ||
|  | 9874e77ddf | ||
|  | 27e3ec693a | ||
|  | 6bb1415ad7 | ||
|  | 83594e6f1f | ||
|  | 0f6008705c | ||
|  | c58b653bb7 | ||
|  | f69b6f9b4e | ||
|  | 7750b06476 | ||
|  | 873384a34b | ||
|  | ac299e7279 | ||
|  | 7895d7f5d0 | ||
|  | fe05d218fc | ||
|  | 8196313ac0 | ||
|  | 6d8f84654f | ||
|  | ab4f34a96b | ||
|  | 139d985904 | ||
|  | 44705f0e18 | ||
|  | ddea7d696a | ||
|  | f814f45e36 | ||
|  | f7117d47c2 | ||
|  | 01b0a1058d | ||
|  | 21f362c7b9 | ||
|  | aaab7f8e0e | ||
|  | 09e1f68c69 | ||
|  | 03729aa5ae | ||
|  | ef39f31ea1 | ||
|  | 0f1437dd6a | ||
|  | 03aac2f744 | ||
|  | 2f8b10e82c | ||
|  | 3231effd20 | ||
|  | f7722c1189 | ||
|  | 70c2450ac4 | ||
|  | 2d5b0d0f99 | ||
|  | f0c0002a6d | ||
|  | dd9f08d4fa | ||
|  | de2e384225 | ||
|  | ffcd1fde0f | ||
|  | d5e1da5948 | ||
|  | ad479a5c7f | ||
|  | 0707603b63 | ||
|  | 2f9c383004 | ||
|  | 8ad0d7af93 | ||
|  | 9b4391c0bf | ||
|  | da7802a0a4 | ||
|  | 9c69949e8c | ||
|  | b1d7a9451a | ||
|  | 004488d453 | ||
|  | fc91372dd0 | ||
|  | 5970a9dc91 | ||
|  | 264cac4f9b | ||
|  | 633328a965 | ||
|  | 4d4b62a766 | ||
|  | aeb2c7deeb | ||
|  | c323942d92 | ||
|  | a0afa25145 | ||
|  | 4533b46436 | ||
|  | e5f8db78f9 | ||
|  | 899f61671f | ||
|  | d84d88cc10 | ||
|  | 97e7ac4052 | ||
|  | ba4ffa44d2 | ||
|  | 07caeccf68 | ||
|  | d54832f61f | ||
|  | b212753633 | ||
|  | f38d80cbf5 | ||
|  | 8bea1acd8e | ||
|  | 42458ce11d | ||
|  | aceb683d07 | ||
|  | b7517b49ed | ||
|  | 849b711b79 | ||
|  | 25585b28c7 | ||
|  | 073da8fb2a | ||
|  | a787ff3f3c | ||
|  | 733b6d7eb7 | ||
|  | 36d8dee853 | ||
|  | 65a2e07d24 | ||
|  | 7c97c558ab | ||
|  | a6bb61050c | ||
|  | b184aa2315 | ||
|  | e4595333e7 | ||
|  | 41dd139bde | ||
|  | c577dd302a | ||
|  | 0ab87de78b | ||
|  | 8a22509b41 | ||
|  | b024c18441 | ||
|  | d9ac681a68 | ||
|  | 637a5579ec | ||
|  | 4794156e80 | ||
|  | 5f4db7874c | ||
|  | b4ea1839a5 | ||
|  | 6a6d889983 | ||
|  | 287c2e7af8 | ||
|  | 0fe6acc8cf | ||
|  | 7d2dab7ca0 | ||
|  | f68c1aff26 | 
							
								
								
									
										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 +1,3 @@ | ||||
| src_dir: . | ||||
| coverage_clover: build/logs/clover.xml | ||||
| json_path: build/logs/coveralls-upload.json | ||||
|   | ||||
							
								
								
									
										21
									
								
								.env.example
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								.env.example
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| APP_ENV=production | ||||
| APP_DEBUG=false | ||||
| APP_KEY=SomeRandomString | ||||
|  | ||||
| DB_CONNECTION=mysql | ||||
| DB_HOST=localhost | ||||
| DB_DATABASE=homestead | ||||
| DB_USERNAME=homestead | ||||
| DB_PASSWORD=secret | ||||
|  | ||||
| CACHE_DRIVER=file | ||||
| SESSION_DRIVER=file | ||||
|  | ||||
| EMAIL_SMTP= | ||||
| EMAIL_DRIVER=smtp | ||||
| EMAIL_USERNAME= | ||||
| EMAIL_PASSWORD= | ||||
| ANALYTICS_ID= | ||||
| EMAIL_PRETEND=false | ||||
| RUNCLEANUP=true | ||||
| SITE_OWNER=mail@example.com | ||||
							
								
								
									
										18
									
								
								.env.testing
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								.env.testing
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| APP_ENV=testing | ||||
| APP_DEBUG=true | ||||
| APP_KEY=SomeRandomString | ||||
|  | ||||
| DB_CONNECTION=sqlite | ||||
| DB_HOST=localhost | ||||
| DB_DATABASE=homestead | ||||
| DB_USERNAME=homestead | ||||
| DB_PASSWORD=secret | ||||
|  | ||||
| CACHE_DRIVER=array | ||||
| SESSION_DRIVER=array | ||||
|  | ||||
| EMAIL_SMTP= | ||||
| EMAIL_USERNAME= | ||||
| EMAIL_PASSWORD= | ||||
| ANALYTICS_ID=ABC | ||||
| EMAIL_PRETEND=true | ||||
							
								
								
									
										25
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,10 +1,6 @@ | ||||
| /bootstrap/compiled.php | ||||
| /vendor | ||||
| composer.phar | ||||
| composer.lock | ||||
| .env.*.php | ||||
| .env.php | ||||
| .DS_Store | ||||
| Thumbs.db | ||||
| .idea/ | ||||
| tests/_output/* | ||||
| @@ -14,3 +10,24 @@ index.html* | ||||
| app/storage/firefly-export* | ||||
| .vagrant | ||||
| firefly-iii-import-*.json | ||||
| tests/_output/* | ||||
| testing.sqlite | ||||
| _ide_helper_models.php | ||||
| clean.sqlite | ||||
| tests/acceptance/AcceptanceTester.php | ||||
| tests/functional/FunctionalTester.php | ||||
| tests/unit/UnitTester.php | ||||
| pi.php | ||||
| tests/_data/db.sqlite | ||||
| tests/_data/dump.sql | ||||
| db.sqlite_snapshot | ||||
| c3.php | ||||
| db.sqlite-journal | ||||
| tests/_output/* | ||||
| .env | ||||
| clover.xml | ||||
| node_modules/ | ||||
| addNewLines.php | ||||
| .phpstorm.meta.php | ||||
| .env.backup | ||||
| .env.local | ||||
|   | ||||
							
								
								
									
										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" | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										5
									
								
								.scrutinizer.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.scrutinizer.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| # .scrutinizer.yml | ||||
| tools: | ||||
|   external_code_coverage: | ||||
|     timeout: 1800    # Timeout in seconds. | ||||
|     runs: 2 | ||||
							
								
								
									
										17
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								.travis.yml
									
									
									
									
									
								
							| @@ -1,13 +1,22 @@ | ||||
| language: php | ||||
| sudo: false | ||||
|  | ||||
|  | ||||
| php: | ||||
|   - 5.5 | ||||
|   - 5.4 | ||||
|   - hhvm | ||||
|   - 5.6 | ||||
|  | ||||
| install: | ||||
|   - composer install | ||||
|   - composer update | ||||
|   - php artisan env | ||||
|   - mv -v .env.testing .env | ||||
|  | ||||
| script: | ||||
|   - phpunit | ||||
|  | ||||
| after_script: | ||||
|   - php vendor/bin/coveralls | ||||
|  | ||||
|   - CODECLIMATE_REPO_TOKEN=26489f9e854fcdf7e7660ba29c1455694685465b1f90329a79f7d2bf448acb61 ./vendor/bin/test-reporter --stdout > codeclimate.json | ||||
|   - "curl -X POST -d @codeclimate.json -H 'Content-Type: application/json' -H 'User-Agent: Code Climate (PHP Test Reporter v0.1.1)' https://codeclimate.com/test_reports" | ||||
|   - wget https://scrutinizer-ci.com/ocular.phar | ||||
|   - php ocular.phar code-coverage:upload --format=php-clover build/logs/clover.xml | ||||
|   | ||||
							
								
								
									
										117
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										117
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,64 +1,99 @@ | ||||
| firefly-iii | ||||
| =========== | ||||
| # Firefly III (v3.4.5) | ||||
|  | ||||
| [](https://travis-ci.org/JC5/firefly-iii) | ||||
|  | ||||
| [](https://scrutinizer-ci.com/g/JC5/firefly-iii/?branch=master) | ||||
| [](https://scrutinizer-ci.com/g/JC5/firefly-iii/?branch=master) | ||||
| [](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) | ||||
| [](https://packagist.org/packages/grumpydictator/firefly-iii) | ||||
| [](https://packagist.org/packages/grumpydictator/firefly-iii) | ||||
| ## About | ||||
|  | ||||
| Firefly Mark III is a new version of Firefly built upon best practices and lessons learned | ||||
| from building [Firefly](https://github.com/JC5/Firefly). It's Mark III since the original Firefly never made it outside of my | ||||
| laptop and [Firefly II](https://github.com/JC5/Firefly) is live. | ||||
| "Firefly III" is a financial manager. It can help you keep track of expenses, income, budgets and everything in between. It even supports credit cards, shared  | ||||
| household accounts and savings accounts! It's pretty fancy. You should use it to save and organise money. | ||||
|   | ||||
| _Firefly is a system you'll have install yourself on webhosting of your choosing._ | ||||
|  | ||||
| Personal financial management is pretty difficult, and everybody has their own approach to it. Some people | ||||
| make budgets, other people limit their cashflow by throwing away their credit cards, others try to increase | ||||
| their current cashflow. There are tons of ways to save and earn money. | ||||
|  | ||||
| Firefly works on the principle that if you know where you're money is going, you can stop it from going there. | ||||
|  | ||||
|   | ||||
| To get to know Firefly, and to see if it fits you, check out these resources: | ||||
|  | ||||
| - The screenshots below on this very page. | ||||
| - The featurelist below, also on this very page. | ||||
| - The [full description](https://github.com/JC5/firefly-iii/wiki/full-description), which will tell you how Firefly works, | ||||
| and the philosophy behind it. | ||||
|  | ||||
|  | ||||
| #### About the name (should you care) | ||||
|  | ||||
| It's III, or 3, because [version 2](https://github.com/JC5/Firefly) and version 1 (not online) preceded it. It has been growing steadily ever since. | ||||
|  | ||||
| ## Current features | ||||
|  | ||||
| - [A double-entry bookkeeping system](http://en.wikipedia.org/wiki/Double-entry_bookkeeping_system). | ||||
| - You can store, edit and remove withdrawals, deposits and transfers. This allows you full financial management; | ||||
| - It's possible to create, change and manage money using _budgets_; | ||||
| - [A double-entry bookkeeping system](https://en.wikipedia.org/wiki/Double-entry_bookkeeping_system); | ||||
| - You can store, edit and remove [withdrawals, deposits and transfers](https://en.wikipedia.org/wiki/Financial_transaction). This allows you full financial management; | ||||
| - You can manage different types of accounts; | ||||
|   - [Asset](https://en.wikipedia.org/wiki/Asset) accounts | ||||
|   - Shared [asset accounts](https://en.wikipedia.org/wiki/Asset) ([household accounts](https://en.wikipedia.org/wiki/Household)) | ||||
|   - Saving accounts | ||||
|   - Credit cards | ||||
| - It's possible to create, change and manage money using _[budgets](https://en.wikipedia.org/wiki/Envelope_system)_; | ||||
| - Organize transactions using categories; | ||||
| - Save towards a goal using piggy banks; | ||||
| - Predict and anticipate large expenses using "repeated expenses" (ie. yearly taxes); | ||||
| - Predict and anticipate bills using "recurring transactions" (rent for example). | ||||
| - Save towards a goal using [piggy banks](https://en.wikipedia.org/wiki/Piggy_bank); | ||||
| - Predict and anticipate [bills](https://en.wikipedia.org/wiki/Invoice); | ||||
| - View income / expense [reports](https://en.wikipedia.org/wiki/Financial_statement); | ||||
| - Organize expenses using tags; | ||||
| - Lots of help text in case you don't get it. | ||||
|  | ||||
| Everything is organised: | ||||
|  | ||||
| - Clear views that should show you how you're doing; | ||||
| - Easy navigation through your records; | ||||
| - Browse back and forth to see previous months or even years; | ||||
| - Lots of help text in case you don't get it; | ||||
| - 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. | ||||
|  | ||||
| ## Changes | ||||
| ## Screenshots | ||||
|  | ||||
| Firefly III will feature, but does not feature yet: | ||||
| _Please note that everything in these screenshots is fictional and may not be realistic._ | ||||
|  | ||||
| - Financial reporting showing you how well you are doing; | ||||
| - More control over other resources outside of personal finance | ||||
|   - Accounts shared with a partner (household accounts) | ||||
|   - Debts | ||||
|   - Credit cards | ||||
| - More test-coverage (aka: actual 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. | ||||
| - Transfers and transactions are combined into one internal datatype which is more consistent with what you're actually doing: moving money from A to B. The fact that A or B or both are yours should not matter. | ||||
| - Any other features I might not have thought of. | ||||
|  | ||||
|  | ||||
| Some stuff has been removed: | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ## 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. | ||||
|  | ||||
| - The nesting of budgets, categories and beneficiaries is removed because it was pretty pointless. | ||||
| - Firefly will not encrypt the content of the (MySQL) tables. Old versions of Firefly had this capability but it sucks when searching, sorting and organizing entries. | ||||
|  | ||||
| ## Current state | ||||
| I have the basics up and running. Test coverage is currently non-existent. | ||||
|  | ||||
| Although I have not checked extensively, some forms and views have CSRF vulnerabilities. This is because not all | ||||
| views escape all characters by default. Will be fixed. | ||||
| Firefly III is pretty much all grown up. Full test coverage (nerd alert!) is coming. One of the things on the todo-list | ||||
| is adding translations. | ||||
|  | ||||
| The current layout / look & feel is a pretty basic Bootstrap3 template. I am currently working on a more consistent, | ||||
| expanded layout which will feature shiny AJAX things and data tables and all the Web 3.0 goodies you've come to expect | ||||
| from social media sites. | ||||
| Questions, ideas, bugs or other things to contribute? [Let me know](https://github.com/JC5/firefly-iii/issues/new)! | ||||
|  | ||||
| Questions, ideas 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) | ||||
|  | ||||
|   | ||||
							
								
								
									
										12
									
								
								app/Commands/Command.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								app/Commands/Command.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| <?php namespace FireflyIII\Commands; | ||||
| /** | ||||
|  * Class Command | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Commands | ||||
|  */ | ||||
| abstract class Command | ||||
| { | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										37
									
								
								app/Console/Kernel.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								app/Console/Kernel.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| <?php namespace FireflyIII\Console; | ||||
|  | ||||
| use Illuminate\Console\Scheduling\Schedule; | ||||
| use Illuminate\Foundation\Console\Kernel as ConsoleKernel; | ||||
|  | ||||
| /** | ||||
|  * Class Kernel | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Console | ||||
|  */ | ||||
| class Kernel extends ConsoleKernel | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * The Artisan commands provided by your application. | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $commands | ||||
|         = [ | ||||
|         ]; | ||||
|  | ||||
|     /** | ||||
|      * Define the application's command schedule. | ||||
|      * | ||||
|      * @param  \Illuminate\Console\Scheduling\Schedule $schedule | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     protected function schedule(Schedule $schedule) | ||||
|     { | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										14
									
								
								app/Events/Event.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								app/Events/Event.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| <?php namespace FireflyIII\Events; | ||||
|  | ||||
| /** | ||||
|  * Class Event | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Events | ||||
|  */ | ||||
| abstract class Event | ||||
| { | ||||
|  | ||||
|     // | ||||
|  | ||||
| } | ||||
							
								
								
									
										34
									
								
								app/Events/JournalCreated.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								app/Events/JournalCreated.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| <?php namespace FireflyIII\Events; | ||||
|  | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Illuminate\Queue\SerializesModels; | ||||
|  | ||||
| /** | ||||
|  * Class JournalCreated | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Events | ||||
|  */ | ||||
| class JournalCreated extends Event | ||||
| { | ||||
|  | ||||
|     use SerializesModels; | ||||
|  | ||||
|     public $journal; | ||||
|     public $piggyBankId; | ||||
|  | ||||
|     /** | ||||
|      * Create a new event instance. | ||||
|      * | ||||
|      * @param TransactionJournal $journal | ||||
|      * @param                    $piggyBankId | ||||
|      */ | ||||
|     public function __construct(TransactionJournal $journal, $piggyBankId) | ||||
|     { | ||||
|         // | ||||
|         $this->journal     = $journal; | ||||
|         $this->piggyBankId = $piggyBankId; | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										25
									
								
								app/Events/JournalDeleted.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								app/Events/JournalDeleted.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| <?php namespace FireflyIII\Events; | ||||
|  | ||||
| use Illuminate\Queue\SerializesModels; | ||||
|  | ||||
| /** | ||||
|  * Class JournalDeleted | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Events | ||||
|  */ | ||||
| class JournalDeleted extends Event | ||||
| { | ||||
|  | ||||
|     use SerializesModels; | ||||
|  | ||||
|     /** | ||||
|      * Create a new event instance. | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         // | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										30
									
								
								app/Events/JournalSaved.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								app/Events/JournalSaved.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| <?php namespace FireflyIII\Events; | ||||
|  | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Illuminate\Queue\SerializesModels; | ||||
|  | ||||
| /** | ||||
|  * Class JournalSaved | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Events | ||||
|  */ | ||||
| class JournalSaved extends Event | ||||
| { | ||||
|  | ||||
|     use SerializesModels; | ||||
|  | ||||
|     public $journal; | ||||
|  | ||||
|     /** | ||||
|      * Create a new event instance. | ||||
|      * | ||||
|      * @param TransactionJournal $journal | ||||
|      */ | ||||
|     public function __construct(TransactionJournal $journal) | ||||
|     { | ||||
|         // | ||||
|         $this->journal = $journal; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										15
									
								
								app/Exceptions/FireflyException.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								app/Exceptions/FireflyException.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Exceptions; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Class FireflyException | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Exceptions | ||||
|  */ | ||||
| class FireflyException extends \Exception | ||||
| { | ||||
|  | ||||
| }  | ||||
							
								
								
									
										59
									
								
								app/Exceptions/Handler.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								app/Exceptions/Handler.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| <?php namespace FireflyIII\Exceptions; | ||||
|  | ||||
| use Exception; | ||||
| use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; | ||||
| use Symfony\Component\HttpKernel\Exception\HttpException; | ||||
|  | ||||
| /** | ||||
|  * Class Handler | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Exceptions | ||||
|  */ | ||||
| class Handler extends ExceptionHandler | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * A list of the exception types that should not be reported. | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $dontReport | ||||
|         = [ | ||||
|             'Symfony\Component\HttpKernel\Exception\HttpException' | ||||
|         ]; | ||||
|  | ||||
|     /** | ||||
|      * Render an exception into an HTTP response. | ||||
|      * | ||||
|      * @param  \Illuminate\Http\Request $request | ||||
|      * @param  \Exception               $e | ||||
|      * @SuppressWarnings(PHPMD.ShortVariable) | ||||
|      * | ||||
|      * @return \Illuminate\Http\Response | ||||
|      */ | ||||
|     public function render($request, Exception $e) | ||||
|     { | ||||
|         if ($e instanceof HttpException) { | ||||
|             return $this->renderHttpException($e); | ||||
|         } else { | ||||
|             return parent::render($request, $e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Report or log an exception. | ||||
|      * | ||||
|      * This is a great spot to send exceptions to Sentry, Bugsnag, etc. | ||||
|      * @SuppressWarnings(PHPMD.ShortVariable) | ||||
|      * | ||||
|      * @param  \Exception $e | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function report(Exception $e) | ||||
|     { | ||||
|         parent::report($e); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										14
									
								
								app/Exceptions/NotImplementedException.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								app/Exceptions/NotImplementedException.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| <?php | ||||
| namespace FireflyIII\Exceptions; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Class NotImplementedException | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Exceptions | ||||
|  */ | ||||
| class NotImplementedException extends \Exception | ||||
| { | ||||
|  | ||||
| }  | ||||
							
								
								
									
										13
									
								
								app/Exceptions/ValidationException.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								app/Exceptions/ValidationException.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| <?php | ||||
| namespace FireflyIII\Exceptions; | ||||
|  | ||||
| /** | ||||
|  * Class ValidationExceptions | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Exception | ||||
|  */ | ||||
| class ValidationException extends \Exception | ||||
| { | ||||
|  | ||||
| }  | ||||
							
								
								
									
										67
									
								
								app/Handlers/Events/ConnectJournalToPiggyBank.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								app/Handlers/Events/ConnectJournalToPiggyBank.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| <?php namespace FireflyIII\Handlers\Events; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Events\JournalCreated; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Models\PiggyBankEvent; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
|  | ||||
| /** | ||||
|  * Class ConnectJournalToPiggyBank | ||||
|  * | ||||
|  * @package FireflyIII\Handlers\Events | ||||
|  */ | ||||
| class ConnectJournalToPiggyBank | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * Create the event handler. | ||||
|      * | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         // | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Handle the event when journal is saved. | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * | ||||
|      * @param  JournalCreated $event | ||||
|      * | ||||
|      * @return boolean | ||||
|      */ | ||||
|     public function handle(JournalCreated $event) | ||||
|     { | ||||
|         /** @var TransactionJournal $journal */ | ||||
|         $journal     = $event->journal; | ||||
|         $piggyBankId = $event->piggyBankId; | ||||
|  | ||||
|         /** @var PiggyBank $piggyBank */ | ||||
|         $piggyBank = Auth::user()->piggybanks()->where('piggy_banks.id', $piggyBankId)->first(['piggy_banks.*']); | ||||
|  | ||||
|         if (is_null($piggyBank)) { | ||||
|             return false; | ||||
|         } | ||||
|         // update piggy bank rep for date of transaction journal. | ||||
|         $repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first(); | ||||
|         if (is_null($repetition)) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $amount = $journal->correct_amount; | ||||
|         bcscale(2); | ||||
|         $repetition->currentamount = bcadd($repetition->currentamount, $amount); | ||||
|         $repetition->save(); | ||||
|  | ||||
|         PiggyBankEvent::create(['piggy_bank_id' => $piggyBank->id, 'transaction_journal_id' => $journal->id, 'date' => $journal->date, 'amount' => $amount]); | ||||
|  | ||||
|         return true; | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										53
									
								
								app/Handlers/Events/RescanJournal.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								app/Handlers/Events/RescanJournal.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| <?php namespace FireflyIII\Handlers\Events; | ||||
|  | ||||
| use App; | ||||
| use FireflyIII\Events\JournalSaved; | ||||
| use Log; | ||||
|  | ||||
| /** | ||||
|  * Class RescanJournal | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Handlers\Events | ||||
|  */ | ||||
| class RescanJournal | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * Create the event handler. | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         // | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Handle the event. | ||||
|      * | ||||
|      * @param  JournalSaved $event | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function handle(JournalSaved $event) | ||||
|     { | ||||
|         $journal = $event->journal; | ||||
|  | ||||
|         Log::debug('Triggered saved event for journal #' . $journal->id . ' (' . $journal->description . ')'); | ||||
|  | ||||
|         /** @var \FireflyIII\Repositories\Bill\BillRepositoryInterface $repository */ | ||||
|         $repository = App::make('FireflyIII\Repositories\Bill\BillRepositoryInterface'); | ||||
|         $list       = $journal->user->bills()->where('active', 1)->where('automatch', 1)->get(); | ||||
|  | ||||
|         Log::debug('Found ' . $list->count() . ' bills to check.'); | ||||
|  | ||||
|         /** @var \FireflyIII\Models\Bill $bill */ | ||||
|         foreach ($list as $bill) { | ||||
|             Log::debug('Now calling bill #' . $bill->id . ' (' . $bill->name . ')'); | ||||
|             $repository->scan($bill, $journal); | ||||
|         } | ||||
|  | ||||
|         Log::debug('Done!'); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										63
									
								
								app/Handlers/Events/UpdateJournalConnection.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								app/Handlers/Events/UpdateJournalConnection.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| <?php namespace FireflyIII\Handlers\Events; | ||||
|  | ||||
| use FireflyIII\Events\JournalSaved; | ||||
| use FireflyIII\Models\PiggyBankEvent; | ||||
| use FireflyIII\Models\PiggyBankRepetition; | ||||
|  | ||||
| /** | ||||
|  * Class UpdateJournalConnection | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Handlers\Events | ||||
|  */ | ||||
| class UpdateJournalConnection | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * Create the event handler. | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         // | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Handle the event. | ||||
|      * | ||||
|      * @param  JournalSaved $event | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function handle(JournalSaved $event) | ||||
|     { | ||||
|         $journal = $event->journal; | ||||
|  | ||||
|         // get the event connected to this journal: | ||||
|         /** @var PiggyBankEvent $event */ | ||||
|         $event = PiggyBankEvent::where('transaction_journal_id', $journal->id)->first(); | ||||
|         if (is_null($event)) { | ||||
|             return; | ||||
|         } | ||||
|         $piggyBank  = $event->piggyBank()->first(); | ||||
|         $repetition = null; | ||||
|         if ($piggyBank) { | ||||
|             /** @var PiggyBankRepetition $repetition */ | ||||
|             $repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first(); | ||||
|         } | ||||
|  | ||||
|         if (is_null($repetition)) { | ||||
|             return; | ||||
|         } | ||||
|         $amount = $journal->amount; | ||||
|         $diff   = $amount - $event->amount; // update current repetition | ||||
|  | ||||
|         $repetition->currentamount += $diff; | ||||
|         $repetition->save(); | ||||
|  | ||||
|  | ||||
|         $event->amount = $amount; | ||||
|         $event->save(); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										90
									
								
								app/Helpers/Collection/Account.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								app/Helpers/Collection/Account.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,90 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * Class Account | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class Account | ||||
| { | ||||
|  | ||||
|     /** @var Collection */ | ||||
|     protected $accounts; | ||||
|     /** @var float */ | ||||
|     protected $difference; | ||||
|     /** @var float */ | ||||
|     protected $end; | ||||
|     /** @var float */ | ||||
|     protected $start; | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Support\Collection | ||||
|      */ | ||||
|     public function getAccounts() | ||||
|     { | ||||
|         return $this->accounts; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param \Illuminate\Support\Collection $accounts | ||||
|      */ | ||||
|     public function setAccounts($accounts) | ||||
|     { | ||||
|         $this->accounts = $accounts; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return float | ||||
|      */ | ||||
|     public function getDifference() | ||||
|     { | ||||
|         return $this->difference; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $difference | ||||
|      */ | ||||
|     public function setDifference($difference) | ||||
|     { | ||||
|         $this->difference = $difference; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return float | ||||
|      */ | ||||
|     public function getEnd() | ||||
|     { | ||||
|         return $this->end; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $end | ||||
|      */ | ||||
|     public function setEnd($end) | ||||
|     { | ||||
|         $this->end = $end; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return float | ||||
|      */ | ||||
|     public function getStart() | ||||
|     { | ||||
|         return $this->start; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $start | ||||
|      */ | ||||
|     public function setStart($start) | ||||
|     { | ||||
|         $this->start = $start; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										64
									
								
								app/Helpers/Collection/Balance.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								app/Helpers/Collection/Balance.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * | ||||
|  * Class Balance | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class Balance | ||||
| { | ||||
|  | ||||
|     /** @var  BalanceHeader */ | ||||
|     protected $balanceHeader; | ||||
|  | ||||
|     /** @var  Collection */ | ||||
|     protected $balanceLines; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->balanceLines = new Collection; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BalanceLine $line | ||||
|      */ | ||||
|     public function addBalanceLine(BalanceLine $line) | ||||
|     { | ||||
|         $this->balanceLines->push($line); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return BalanceHeader | ||||
|      */ | ||||
|     public function getBalanceHeader() | ||||
|     { | ||||
|         return $this->balanceHeader; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BalanceHeader $balanceHeader | ||||
|      */ | ||||
|     public function setBalanceHeader($balanceHeader) | ||||
|     { | ||||
|         $this->balanceHeader = $balanceHeader; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Support\Collection | ||||
|      */ | ||||
|     public function getBalanceLines() | ||||
|     { | ||||
|         return $this->balanceLines; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										74
									
								
								app/Helpers/Collection/BalanceEntry.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								app/Helpers/Collection/BalanceEntry.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use FireflyIII\Models\Account as AccountModel; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * | ||||
|  * Class BalanceEntry | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class BalanceEntry | ||||
| { | ||||
|  | ||||
|  | ||||
|     /** @var  AccountModel */ | ||||
|     protected $account; | ||||
|     /** @var float */ | ||||
|     protected $left = 0.0; | ||||
|     /** @var float */ | ||||
|     protected $spent = 0.0; | ||||
|  | ||||
|     /** | ||||
|      * @return AccountModel | ||||
|      */ | ||||
|     public function getAccount() | ||||
|     { | ||||
|         return $this->account; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param AccountModel $account | ||||
|      */ | ||||
|     public function setAccount($account) | ||||
|     { | ||||
|         $this->account = $account; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return float | ||||
|      */ | ||||
|     public function getLeft() | ||||
|     { | ||||
|         return $this->left; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $left | ||||
|      */ | ||||
|     public function setLeft($left) | ||||
|     { | ||||
|         $this->left = $left; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return float | ||||
|      */ | ||||
|     public function getSpent() | ||||
|     { | ||||
|         return $this->spent; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $spent | ||||
|      */ | ||||
|     public function setSpent($spent) | ||||
|     { | ||||
|         $this->spent = $spent; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										46
									
								
								app/Helpers/Collection/BalanceHeader.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								app/Helpers/Collection/BalanceHeader.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use FireflyIII\Models\Account as AccountModel; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * | ||||
|  * Class BalanceHeader | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class BalanceHeader | ||||
| { | ||||
|  | ||||
|     /** @var  Collection */ | ||||
|     protected $accounts; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->accounts = new Collection; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param AccountModel $account | ||||
|      */ | ||||
|     public function addAccount(AccountModel $account) | ||||
|     { | ||||
|         $this->accounts->push($account); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getAccounts() | ||||
|     { | ||||
|         return $this->accounts; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										173
									
								
								app/Helpers/Collection/BalanceLine.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								app/Helpers/Collection/BalanceLine.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,173 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use FireflyIII\Models\Budget as BudgetModel; | ||||
| use FireflyIII\Models\LimitRepetition; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * | ||||
|  * Class BalanceLine | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class BalanceLine | ||||
| { | ||||
|  | ||||
|     const ROLE_DEFAULTROLE = 1; | ||||
|     const ROLE_TAGROLE     = 2; | ||||
|     const ROLE_DIFFROLE    = 3; | ||||
|  | ||||
|     /** @var  Collection */ | ||||
|     protected $balanceEntries; | ||||
|  | ||||
|     /** @var BudgetModel */ | ||||
|     protected $budget; | ||||
|  | ||||
|     /** @var  LimitRepetition */ | ||||
|     protected $repetition; | ||||
|  | ||||
|     protected $role = self::ROLE_DEFAULTROLE; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->balanceEntries = new Collection; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BalanceEntry $balanceEntry | ||||
|      */ | ||||
|     public function addBalanceEntry(BalanceEntry $balanceEntry) | ||||
|     { | ||||
|         $this->balanceEntries->push($balanceEntry); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getTitle() | ||||
|     { | ||||
|         if ($this->getBudget() instanceof BudgetModel) { | ||||
|             return $this->getBudget()->name; | ||||
|         } | ||||
|         if ($this->getRole() == self::ROLE_DEFAULTROLE) { | ||||
|             return trans('firefly.noBudget'); | ||||
|         } | ||||
|         if ($this->getRole() == self::ROLE_TAGROLE) { | ||||
|             return trans('firefly.coveredWithTags'); | ||||
|         } | ||||
|         if ($this->getRole() == self::ROLE_DIFFROLE) { | ||||
|             return trans('firefly.leftUnbalanced'); | ||||
|         } | ||||
|  | ||||
|         return ''; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return BudgetModel | ||||
|      */ | ||||
|     public function getBudget() | ||||
|     { | ||||
|         return $this->budget; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BudgetModel $budget | ||||
|      */ | ||||
|     public function setBudget($budget) | ||||
|     { | ||||
|         $this->budget = $budget; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return int | ||||
|      */ | ||||
|     public function getRole() | ||||
|     { | ||||
|         return $this->role; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param int $role | ||||
|      */ | ||||
|     public function setRole($role) | ||||
|     { | ||||
|         $this->role = $role; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * If a BalanceLine has a budget/repetition, each BalanceEntry in this BalanceLine | ||||
|      * should have a "spent" value, which is the amount of money that has been spent | ||||
|      * on the given budget/repetition. If you subtract all those amounts from the budget/repetition's | ||||
|      * total amount, this is returned: | ||||
|      * | ||||
|      * @return float | ||||
|      */ | ||||
|     public function leftOfRepetition() | ||||
|     { | ||||
|         $start = $this->getRepetition() ? $this->getRepetition()->amount : 0; | ||||
|         /** @var BalanceEntry $balanceEntry */ | ||||
|         foreach ($this->getBalanceEntries() as $balanceEntry) { | ||||
|             $start += $balanceEntry->getSpent(); | ||||
|         } | ||||
|  | ||||
|         return $start; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return LimitRepetition | ||||
|      */ | ||||
|     public function getRepetition() | ||||
|     { | ||||
|         return $this->repetition; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param LimitRepetition $repetition | ||||
|      */ | ||||
|     public function setRepetition($repetition) | ||||
|     { | ||||
|         $this->repetition = $repetition; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getBalanceEntries() | ||||
|     { | ||||
|         return $this->balanceEntries; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $balanceEntries | ||||
|      */ | ||||
|     public function setBalanceEntries($balanceEntries) | ||||
|     { | ||||
|         $this->balanceEntries = $balanceEntries; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * If the BalanceEntries for a BalanceLine have a "left" value, the amount | ||||
|      * of money left in the entire BalanceLine is returned here: | ||||
|      * | ||||
|      * @return float | ||||
|      */ | ||||
|     public function sumOfLeft() | ||||
|     { | ||||
|         $sum = '0'; | ||||
|         bcscale(2); | ||||
|         /** @var BalanceEntry $balanceEntry */ | ||||
|         foreach ($this->getBalanceEntries() as $balanceEntry) { | ||||
|             $sum = bcadd($sum, $balanceEntry->getLeft()); | ||||
|         } | ||||
|  | ||||
|         return $sum; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										56
									
								
								app/Helpers/Collection/Bill.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								app/Helpers/Collection/Bill.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
|  | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * Class Bill | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class Bill | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @var Collection | ||||
|      */ | ||||
|     protected $bills; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->bills = new Collection; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BillLine $bill | ||||
|      */ | ||||
|     public function addBill(BillLine $bill) | ||||
|     { | ||||
|         $this->bills->push($bill); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getBills() | ||||
|     { | ||||
|         $set = $this->bills->sortBy( | ||||
|             function (BillLine $bill) { | ||||
|                 $active = intval($bill->getBill()->active) == 0 ? 1 : 0; | ||||
|                 $name   = $bill->getBill()->name; | ||||
|  | ||||
|                 return $active . $name; | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|  | ||||
|         return $set; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										127
									
								
								app/Helpers/Collection/BillLine.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								app/Helpers/Collection/BillLine.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,127 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use FireflyIII\Models\Bill as BillModel; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * | ||||
|  * Class BillLine | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class BillLine | ||||
| { | ||||
|  | ||||
|     /** @var  bool */ | ||||
|     protected $active; | ||||
|     /** @var  string */ | ||||
|     protected $amount; | ||||
|     /** @var  BillModel */ | ||||
|     protected $bill; | ||||
|     /** @var  bool */ | ||||
|     protected $hit; | ||||
|     /** @var  string */ | ||||
|     protected $max; | ||||
|     /** @var  string */ | ||||
|     protected $min; | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getAmount() | ||||
|     { | ||||
|         return $this->amount; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $amount | ||||
|      */ | ||||
|     public function setAmount($amount) | ||||
|     { | ||||
|         $this->amount = $amount; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return BillModel | ||||
|      */ | ||||
|     public function getBill() | ||||
|     { | ||||
|         return $this->bill; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BillModel $bill | ||||
|      */ | ||||
|     public function setBill($bill) | ||||
|     { | ||||
|         $this->bill = $bill; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getMax() | ||||
|     { | ||||
|         return $this->max; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $max | ||||
|      */ | ||||
|     public function setMax($max) | ||||
|     { | ||||
|         $this->max = $max; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getMin() | ||||
|     { | ||||
|         return $this->min; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $min | ||||
|      */ | ||||
|     public function setMin($min) | ||||
|     { | ||||
|         $this->min = $min; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return boolean | ||||
|      */ | ||||
|     public function isActive() | ||||
|     { | ||||
|         return $this->active; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param boolean $active | ||||
|      */ | ||||
|     public function setActive($active) | ||||
|     { | ||||
|         $this->active = $active; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return boolean | ||||
|      */ | ||||
|     public function isHit() | ||||
|     { | ||||
|         return $this->hit; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param boolean $hit | ||||
|      */ | ||||
|     public function setHit($hit) | ||||
|     { | ||||
|         $this->hit = $hit; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										156
									
								
								app/Helpers/Collection/Budget.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								app/Helpers/Collection/Budget.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,156 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * | ||||
|  * Class Budget | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class Budget | ||||
| { | ||||
|     /** @var  Collection */ | ||||
|     protected $budgetLines; | ||||
|     /** @var string */ | ||||
|     protected $budgeted = '0'; | ||||
|     /** @var string */ | ||||
|     protected $left = '0'; | ||||
|     /** @var string */ | ||||
|     protected $overspent = '0'; | ||||
|     /** @var string */ | ||||
|     protected $spent = '0'; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->budgetLines = new Collection; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BudgetLine $budgetLine | ||||
|      */ | ||||
|     public function addBudgetLine(BudgetLine $budgetLine) | ||||
|     { | ||||
|         $this->budgetLines->push($budgetLine); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $add | ||||
|      */ | ||||
|     public function addBudgeted($add) | ||||
|     { | ||||
|         $add = strval(round($add, 2)); | ||||
|         bcscale(2); | ||||
|         $this->budgeted = bcadd($this->budgeted, $add); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $add | ||||
|      */ | ||||
|     public function addLeft($add) | ||||
|     { | ||||
|         $add = strval(round($add, 2)); | ||||
|         bcscale(2); | ||||
|         $this->left = bcadd($this->left, $add); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $add | ||||
|      */ | ||||
|     public function addOverspent($add) | ||||
|     { | ||||
|         $add = strval(round($add, 2)); | ||||
|         bcscale(2); | ||||
|         $this->overspent = bcadd($this->overspent, $add); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $add | ||||
|      */ | ||||
|     public function addSpent($add) | ||||
|     { | ||||
|         $add = strval(round($add, 2)); | ||||
|         bcscale(2); | ||||
|         $this->spent = bcadd($this->spent, $add); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Support\Collection | ||||
|      */ | ||||
|     public function getBudgetLines() | ||||
|     { | ||||
|         return $this->budgetLines; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getBudgeted() | ||||
|     { | ||||
|         return $this->budgeted; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $budgeted | ||||
|      */ | ||||
|     public function setBudgeted($budgeted) | ||||
|     { | ||||
|         $this->budgeted = $budgeted; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getLeft() | ||||
|     { | ||||
|         return $this->left; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $left | ||||
|      */ | ||||
|     public function setLeft($left) | ||||
|     { | ||||
|         $this->left = $left; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getOverspent() | ||||
|     { | ||||
|         return $this->overspent; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $overspent | ||||
|      */ | ||||
|     public function setOverspent($overspent) | ||||
|     { | ||||
|         $this->overspent = strval(round($overspent, 2)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getSpent() | ||||
|     { | ||||
|         return $this->spent; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $spent | ||||
|      */ | ||||
|     public function setSpent($spent) | ||||
|     { | ||||
|         $this->spent = strval(round($spent, 2)); | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										128
									
								
								app/Helpers/Collection/BudgetLine.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								app/Helpers/Collection/BudgetLine.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use FireflyIII\Models\Budget as BudgetModel; | ||||
| use FireflyIII\Models\LimitRepetition; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * | ||||
|  * Class BudgetLine | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class BudgetLine | ||||
| { | ||||
|  | ||||
|     /** @var  BudgetModel */ | ||||
|     protected $budget; | ||||
|     /** @var float */ | ||||
|     protected $budgeted = 0; | ||||
|     /** @var float */ | ||||
|     protected $left = 0; | ||||
|     /** @var float */ | ||||
|     protected $overspent = 0; | ||||
|     /** @var  LimitRepetition */ | ||||
|     protected $repetition; | ||||
|     /** @var float */ | ||||
|     protected $spent = 0; | ||||
|  | ||||
|     /** | ||||
|      * @return BudgetModel | ||||
|      */ | ||||
|     public function getBudget() | ||||
|     { | ||||
|         return $this->budget; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BudgetModel $budget | ||||
|      */ | ||||
|     public function setBudget($budget) | ||||
|     { | ||||
|         $this->budget = $budget; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return float | ||||
|      */ | ||||
|     public function getBudgeted() | ||||
|     { | ||||
|         return $this->budgeted; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $budgeted | ||||
|      */ | ||||
|     public function setBudgeted($budgeted) | ||||
|     { | ||||
|         $this->budgeted = $budgeted; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return float | ||||
|      */ | ||||
|     public function getLeft() | ||||
|     { | ||||
|         return $this->left; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $left | ||||
|      */ | ||||
|     public function setLeft($left) | ||||
|     { | ||||
|         $this->left = $left; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return float | ||||
|      */ | ||||
|     public function getOverspent() | ||||
|     { | ||||
|         return $this->overspent; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $overspent | ||||
|      */ | ||||
|     public function setOverspent($overspent) | ||||
|     { | ||||
|         $this->overspent = $overspent; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return LimitRepetition | ||||
|      */ | ||||
|     public function getRepetition() | ||||
|     { | ||||
|         return $this->repetition; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param LimitRepetition $repetition | ||||
|      */ | ||||
|     public function setRepetition($repetition) | ||||
|     { | ||||
|         $this->repetition = $repetition; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return float | ||||
|      */ | ||||
|     public function getSpent() | ||||
|     { | ||||
|         return $this->spent; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $spent | ||||
|      */ | ||||
|     public function setSpent($spent) | ||||
|     { | ||||
|         $this->spent = $spent; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										76
									
								
								app/Helpers/Collection/Category.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								app/Helpers/Collection/Category.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| <?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) | ||||
|     { | ||||
|         if ($category->spent > 0) { | ||||
|             $this->categories->push($category); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param float $add | ||||
|      */ | ||||
|     public function addTotal($add) | ||||
|     { | ||||
|         $add = strval(round($add, 2)); | ||||
|         bcscale(2); | ||||
|         $this->total = bcadd($this->total, $add); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getCategories() | ||||
|     { | ||||
|         $set = $this->categories->sortByDesc( | ||||
|             function (CategoryModel $category) { | ||||
|                 return $category->spent; | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|  | ||||
|         return $set; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getTotal() | ||||
|     { | ||||
|         return strval(round($this->total, 2)); | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										85
									
								
								app/Helpers/Collection/Expense.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								app/Helpers/Collection/Expense.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Illuminate\Support\Collection; | ||||
| use stdClass; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * | ||||
|  * Class Expense | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class Expense | ||||
| { | ||||
|     /** @var Collection */ | ||||
|     protected $expenses; | ||||
|     /** @var string */ | ||||
|     protected $total = '0'; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->expenses = new Collection; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionJournal $entry | ||||
|      */ | ||||
|     public function addOrCreateExpense(TransactionJournal $entry) | ||||
|     { | ||||
|  | ||||
|         $accountId = $entry->account_id; | ||||
|         if (!$this->expenses->has($accountId)) { | ||||
|             $newObject         = new stdClass; | ||||
|             $newObject->amount = strval(round($entry->amount, 2)); | ||||
|             $newObject->name   = $entry->name; | ||||
|             $newObject->count  = 1; | ||||
|             $newObject->id     = $accountId; | ||||
|             $this->expenses->put($accountId, $newObject); | ||||
|         } else { | ||||
|             bcscale(2); | ||||
|             $existing         = $this->expenses->get($accountId); | ||||
|             $existing->amount = bcadd($existing->amount, $entry->amount); | ||||
|             $existing->count++; | ||||
|             $this->expenses->put($accountId, $existing); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $add | ||||
|      */ | ||||
|     public function addToTotal($add) | ||||
|     { | ||||
|         $add = strval(round($add, 2)); | ||||
|         bcscale(2); | ||||
|         $this->total = bcadd($this->total, $add); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getExpenses() | ||||
|     { | ||||
|         $set = $this->expenses->sortByDesc( | ||||
|             function (stdClass $object) { | ||||
|                 return $object->amount; | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         return $set; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getTotal() | ||||
|     { | ||||
|         return strval(round($this->total, 2)); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										88
									
								
								app/Helpers/Collection/Income.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								app/Helpers/Collection/Income.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Illuminate\Support\Collection; | ||||
| use stdClass; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * | ||||
|  * Class Income | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Collection | ||||
|  */ | ||||
| class Income | ||||
| { | ||||
|  | ||||
|     /** @var Collection */ | ||||
|     protected $incomes; | ||||
|     /** @var string */ | ||||
|     protected $total; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->incomes = new Collection; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionJournal $entry | ||||
|      */ | ||||
|     public function addOrCreateIncome(TransactionJournal $entry) | ||||
|     { | ||||
|  | ||||
|         $accountId = $entry->account_id; | ||||
|         if (!$this->incomes->has($accountId)) { | ||||
|             $newObject         = new stdClass; | ||||
|             $newObject->amount = strval(round($entry->amount, 2)); | ||||
|             $newObject->name   = $entry->name; | ||||
|             $newObject->count  = 1; | ||||
|             $newObject->id     = $accountId; | ||||
|             $this->incomes->put($accountId, $newObject); | ||||
|         } else { | ||||
|             bcscale(2); | ||||
|             $existing         = $this->incomes->get($accountId); | ||||
|             $existing->amount = bcadd($existing->amount, $entry->amount); | ||||
|             $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)); | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										97
									
								
								app/Helpers/Help/Help.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								app/Helpers/Help/Help.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,97 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Help; | ||||
|  | ||||
| use Cache; | ||||
| use ErrorException; | ||||
| use League\CommonMark\CommonMarkConverter; | ||||
| use Log; | ||||
| use Route; | ||||
|  | ||||
| /** | ||||
|  * Class Help | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Help | ||||
|  */ | ||||
| class Help implements HelpInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @param $key | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getFromCache($key) | ||||
|     { | ||||
|         return Cache::get($key); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @param $route | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getFromGithub($route) | ||||
|     { | ||||
|         $uri     = 'https://raw.githubusercontent.com/JC5/firefly-iii-help/master/en/' . e($route) . '.md'; | ||||
|         $content = [ | ||||
|             'text'  => '<p>There is no help for this route!</p>', | ||||
|             'title' => $route, | ||||
|         ]; | ||||
|         try { | ||||
|             $content['text'] = file_get_contents($uri); | ||||
|         } catch (ErrorException $e) { | ||||
|             Log::error(trim($e->getMessage())); | ||||
|         } | ||||
|         if (strlen(trim($content['text'])) == 0) { | ||||
|             $content['text'] = '<p>There is no help for this route.</p>'; | ||||
|         } | ||||
|         $converter       = new CommonMarkConverter(); | ||||
|         $content['text'] = $converter->convertToHtml($content['text']); | ||||
|  | ||||
|         return $content; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @param $route | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function hasRoute($route) | ||||
|     { | ||||
|         return Route::has($route); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @param       $route | ||||
|      * @param array $content | ||||
|      * | ||||
|      * @internal param $title | ||||
|      */ | ||||
|     public function putInCache($route, array $content) | ||||
|     { | ||||
|         Cache::put('help.' . $route . '.text', $content['text'], 10080); // a week. | ||||
|         Cache::put('help.' . $route . '.title', $content['title'], 10080); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @param $route | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function inCache($route) | ||||
|     { | ||||
|         return Cache::has('help.' . $route . '.title') && Cache::has('help.' . $route . '.text'); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										48
									
								
								app/Helpers/Help/HelpInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								app/Helpers/Help/HelpInterface.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Help; | ||||
|  | ||||
| /** | ||||
|  * Interface HelpInterface | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Help | ||||
|  */ | ||||
| interface HelpInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param $key | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getFromCache($key); | ||||
|  | ||||
|     /** | ||||
|      * @param $route | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getFromGithub($route); | ||||
|  | ||||
|     /** | ||||
|      * @param $route | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function hasRoute($route); | ||||
|  | ||||
|     /** | ||||
|      * @param $route | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function inCache($route); | ||||
|  | ||||
|     /** | ||||
|      * @param       $route | ||||
|      * @param array $content | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function putInCache($route, array $content); | ||||
| } | ||||
							
								
								
									
										176
									
								
								app/Helpers/Reminders/ReminderHelper.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								app/Helpers/Reminders/ReminderHelper.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,176 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Reminders; | ||||
|  | ||||
| use Amount; | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use Config; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Models\Reminder; | ||||
| use Navigation; | ||||
| use Preferences; | ||||
|  | ||||
| /** | ||||
|  * 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 = count($ranges) == 0 ? $left : $left / count($ranges); | ||||
|             } else { | ||||
|                 $perReminder = null; | ||||
|                 $ranges      = []; | ||||
|                 $left        = 0; | ||||
|             } | ||||
|             $metaData = [ | ||||
|                 'perReminder' => $perReminder, | ||||
|                 'rangesCount' => count($ranges), | ||||
|                 'ranges'      => $ranges, | ||||
|                 'leftToSave'  => $left, | ||||
|             ]; | ||||
|  | ||||
|             $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; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Create all reminders for a piggy bank for a given date. | ||||
|      * | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @param Carbon    $date | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function createReminders(PiggyBank $piggyBank, Carbon $date) | ||||
|     { | ||||
|         $ranges = $this->getReminderRanges($piggyBank); | ||||
|  | ||||
|         foreach ($ranges as $range) { | ||||
|             if ($date < $range['end'] && $date > $range['start']) { | ||||
|                 // create a reminder here! | ||||
|                 $this->createReminder($piggyBank, $range['start'], $range['end']); | ||||
|                 // stop looping, we're done. | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 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 trans('firefly.piggy_bank_not_exists'); | ||||
|         } | ||||
|  | ||||
|         if (is_null($piggyBank->targetdate)) { | ||||
|             return trans('firefly.add_any_amount_to_piggy', ['amount' => Amount::format($piggyBank->targetamount)]); | ||||
|         } | ||||
|  | ||||
|         $lang = Preferences::get('language', 'en')->data; | ||||
|  | ||||
|         return trans( | ||||
|             'firefly.add_set_amount_to_piggy', | ||||
|             [ | ||||
|                 'amount' => Amount::format($reminder->metadata->perReminder), | ||||
|                 'date'   => $piggyBank->targetdate->formatLocalized(Config::get('firefly.monthAndDay.' . $lang)) | ||||
|             ] | ||||
|         ); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										63
									
								
								app/Helpers/Reminders/ReminderHelperInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								app/Helpers/Reminders/ReminderHelperInterface.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| <?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); | ||||
|  | ||||
|     /** | ||||
|      * Create all reminders for a piggy bank for a given date. | ||||
|      * | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @param Carbon    $date | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function createReminders(PiggyBank $piggyBank, Carbon $date); | ||||
| } | ||||
							
								
								
									
										403
									
								
								app/Helpers/Report/ReportHelper.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										403
									
								
								app/Helpers/Report/ReportHelper.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,403 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Report; | ||||
|  | ||||
| use App; | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Helpers\Collection\Account as AccountCollection; | ||||
| use FireflyIII\Helpers\Collection\Balance; | ||||
| use FireflyIII\Helpers\Collection\BalanceEntry; | ||||
| use FireflyIII\Helpers\Collection\BalanceHeader; | ||||
| use FireflyIII\Helpers\Collection\BalanceLine; | ||||
| use FireflyIII\Helpers\Collection\Bill as BillCollection; | ||||
| use FireflyIII\Helpers\Collection\BillLine; | ||||
| use FireflyIII\Helpers\Collection\Budget as BudgetCollection; | ||||
| use FireflyIII\Helpers\Collection\BudgetLine; | ||||
| use FireflyIII\Helpers\Collection\Category as CategoryCollection; | ||||
| use FireflyIII\Helpers\Collection\Expense; | ||||
| use FireflyIII\Helpers\Collection\Income; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Models\Budget as BudgetModel; | ||||
| use FireflyIII\Models\LimitRepetition; | ||||
|  | ||||
| /** | ||||
|  * Class ReportHelper | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Report | ||||
|  */ | ||||
| class ReportHelper implements ReportHelperInterface | ||||
| { | ||||
|  | ||||
|     /** @var ReportQueryInterface */ | ||||
|     protected $query; | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @param ReportQueryInterface $query | ||||
|      * | ||||
|      */ | ||||
|     public function __construct(ReportQueryInterface $query) | ||||
|     { | ||||
|         $this->query = $query; | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * This method generates a full report for the given period on all | ||||
|      * the users asset and cash accounts. | ||||
|      * | ||||
|      * @param Carbon $date | ||||
|      * @param Carbon $end | ||||
|      * @param        $shared | ||||
|      * | ||||
|      * @return AccountCollection | ||||
|      */ | ||||
|     public function getAccountReport(Carbon $date, Carbon $end, $shared) | ||||
|     { | ||||
|  | ||||
|  | ||||
|         $accounts = $this->query->getAllAccounts($date, $end, $shared); | ||||
|         $start    = 0; | ||||
|         $end      = 0; | ||||
|         $diff     = 0; | ||||
|  | ||||
|         // remove cash account, if any: | ||||
|         $accounts = $accounts->filter( | ||||
|             function (Account $account) { | ||||
|                 if ($account->accountType->type != 'Cash account') { | ||||
|                     return $account; | ||||
|                 } | ||||
|  | ||||
|                 return null; | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         // summarize: | ||||
|         foreach ($accounts as $account) { | ||||
|             $start += $account->startBalance; | ||||
|             $end += $account->endBalance; | ||||
|             $diff += ($account->endBalance - $account->startBalance); | ||||
|         } | ||||
|  | ||||
|         $object = new AccountCollection; | ||||
|         $object->setStart($start); | ||||
|         $object->setEnd($end); | ||||
|         $object->setDifference($diff); | ||||
|         $object->setAccounts($accounts); | ||||
|  | ||||
|         return $object; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * The balance report contains a Balance object which in turn contains: | ||||
|      * | ||||
|      * A BalanceHeader object which contains all relevant user asset accounts for the report. | ||||
|      * | ||||
|      * A number of BalanceLine objects, which hold: | ||||
|      * - A budget | ||||
|      * - A number of BalanceEntry objects. | ||||
|      * | ||||
|      * The BalanceEntry object holds: | ||||
|      *   - The same budget (again) | ||||
|      *   - A user asset account as mentioned in the BalanceHeader | ||||
|      *   - The amount of money spent on the budget by the user asset account | ||||
|      * | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return Balance | ||||
|      */ | ||||
|     public function getBalanceReport(Carbon $start, Carbon $end, $shared) | ||||
|     { | ||||
|         $repository    = App::make('FireflyIII\Repositories\Budget\BudgetRepositoryInterface'); | ||||
|         $tagRepository = App::make('FireflyIII\Repositories\Tag\TagRepositoryInterface'); | ||||
|         $balance       = new Balance; | ||||
|  | ||||
|         // build a balance header: | ||||
|         $header = new BalanceHeader; | ||||
|  | ||||
|         $accounts = $this->query->getAllAccounts($start, $end, $shared); | ||||
|         $budgets  = $repository->getBudgets(); | ||||
|         foreach ($accounts as $account) { | ||||
|             $header->addAccount($account); | ||||
|         } | ||||
|  | ||||
|         /** @var BudgetModel $budget */ | ||||
|         foreach ($budgets as $budget) { | ||||
|             $line = new BalanceLine; | ||||
|             $line->setBudget($budget); | ||||
|  | ||||
|             // get budget amount for current period: | ||||
|             $rep = $repository->getCurrentRepetition($budget, $start); | ||||
|             $line->setRepetition($rep); | ||||
|  | ||||
|             // loop accounts: | ||||
|             foreach ($accounts as $account) { | ||||
|                 $balanceEntry = new BalanceEntry; | ||||
|                 $balanceEntry->setAccount($account); | ||||
|  | ||||
|                 // get spent: | ||||
|                 $spent = $this->query->spentInBudgetCorrected($account, $budget, $start, $end); // I think shared is irrelevant. | ||||
|  | ||||
|                 $balanceEntry->setSpent($spent); | ||||
|                 $line->addBalanceEntry($balanceEntry); | ||||
|             } | ||||
|             // add line to balance: | ||||
|             $balance->addBalanceLine($line); | ||||
|         } | ||||
|  | ||||
|         // then a new line for without budget. | ||||
|         // and one for the tags: | ||||
|         $empty    = new BalanceLine; | ||||
|         $tags     = new BalanceLine; | ||||
|         $diffLine = new BalanceLine; | ||||
|  | ||||
|         $tags->setRole(BalanceLine::ROLE_TAGROLE); | ||||
|         $diffLine->setRole(BalanceLine::ROLE_DIFFROLE); | ||||
|  | ||||
|         foreach ($accounts as $account) { | ||||
|             $spent = $this->query->spentNoBudget($account, $start, $end); | ||||
|             $left  = $tagRepository->coveredByBalancingActs($account, $start, $end); | ||||
|             bcscale(2); | ||||
|             $diff = bcsub($spent, $left); | ||||
|  | ||||
|             // budget | ||||
|             $budgetEntry = new BalanceEntry; | ||||
|             $budgetEntry->setAccount($account); | ||||
|             $budgetEntry->setSpent($spent); | ||||
|             $empty->addBalanceEntry($budgetEntry); | ||||
|  | ||||
|             // balanced by tags | ||||
|             $tagEntry = new BalanceEntry; | ||||
|             $tagEntry->setAccount($account); | ||||
|             $tagEntry->setLeft($left); | ||||
|             $tags->addBalanceEntry($tagEntry); | ||||
|  | ||||
|             // difference: | ||||
|             $diffEntry = new BalanceEntry; | ||||
|             $diffEntry->setAccount($account); | ||||
|             $diffEntry->setSpent($diff); | ||||
|             $diffLine->addBalanceEntry($diffEntry); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         $balance->addBalanceLine($empty); | ||||
|         $balance->addBalanceLine($tags); | ||||
|         $balance->addBalanceLine($diffLine); | ||||
|  | ||||
|         $balance->setBalanceHeader($header); | ||||
|  | ||||
|         return $balance; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * This method generates a full report for the given period on all | ||||
|      * the users bills and their payments. | ||||
|      * | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return BillCollection | ||||
|      */ | ||||
|     public function getBillReport(Carbon $start, Carbon $end, $shared) | ||||
|     { | ||||
|         /** @var \FireflyIII\Repositories\Bill\BillRepositoryInterface $repository */ | ||||
|         $repository = App::make('FireflyIII\Repositories\Bill\BillRepositoryInterface'); | ||||
|         $bills      = $repository->getBills(); | ||||
|         $collection = new BillCollection; | ||||
|  | ||||
|         /** @var Bill $bill */ | ||||
|         foreach ($bills as $bill) { | ||||
|             $billLine = new BillLine; | ||||
|             $billLine->setBill($bill); | ||||
|             $billLine->setActive(intval($bill->active) == 1); | ||||
|             $billLine->setMin($bill->amount_min); | ||||
|             $billLine->setMax($bill->amount_max); | ||||
|  | ||||
|             // is hit in period? | ||||
|             bcscale(2); | ||||
|             $set = $repository->getJournalsInRange($bill, $start, $end); | ||||
|             if ($set->count() == 0) { | ||||
|                 $billLine->setHit(false); | ||||
|             } else { | ||||
|                 $billLine->setHit(true); | ||||
|                 $amount = '0'; | ||||
|                 foreach ($set as $entry) { | ||||
|                     $amount = bcadd($amount, $entry->amount); | ||||
|                 } | ||||
|                 $billLine->setAmount($amount); | ||||
|             } | ||||
|  | ||||
|             $collection->addBill($billLine); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         return $collection; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return BudgetCollection | ||||
|      */ | ||||
|     public function getBudgetReport(Carbon $start, Carbon $end, $shared) | ||||
|     { | ||||
|         $object = new BudgetCollection; | ||||
|         /** @var \FireflyIII\Repositories\Budget\BudgetRepositoryInterface $repository */ | ||||
|         $repository = App::make('FireflyIII\Repositories\Budget\BudgetRepositoryInterface'); | ||||
|         $set        = $repository->getBudgets(); | ||||
|  | ||||
|         foreach ($set as $budget) { | ||||
|  | ||||
|             $repetitions = $repository->getBudgetLimitRepetitions($budget, $start, $end); | ||||
|  | ||||
|             // no repetition(s) for this budget: | ||||
|             if ($repetitions->count() == 0) { | ||||
|                 $spent      = $repository->spentInPeriodCorrected($budget, $start, $end, $shared); | ||||
|                 $budgetLine = new BudgetLine; | ||||
|                 $budgetLine->setBudget($budget); | ||||
|                 $budgetLine->setOverspent($spent); | ||||
|                 $object->addOverspent($spent); | ||||
|                 $object->addBudgetLine($budgetLine); | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             // one or more repetitions for budget: | ||||
|             /** @var LimitRepetition $repetition */ | ||||
|             foreach ($repetitions as $repetition) { | ||||
|                 $budgetLine = new BudgetLine; | ||||
|                 $budgetLine->setBudget($budget); | ||||
|                 $budgetLine->setRepetition($repetition); | ||||
|                 $expenses  = $repository->spentInPeriodCorrected($budget, $repetition->startdate, $repetition->enddate, $shared); | ||||
|                 $left      = $expenses < floatval($repetition->amount) ? floatval($repetition->amount) - $expenses : 0; | ||||
|                 $spent     = $expenses > floatval($repetition->amount) ? 0 : $expenses; | ||||
|                 $overspent = $expenses > floatval($repetition->amount) ? $expenses - floatval($repetition->amount) : 0; | ||||
|  | ||||
|                 $budgetLine->setLeft($left); | ||||
|                 $budgetLine->setSpent($spent); | ||||
|                 $budgetLine->setOverspent($overspent); | ||||
|                 $budgetLine->setBudgeted($repetition->amount); | ||||
|  | ||||
|                 $object->addBudgeted($repetition->amount); | ||||
|                 $object->addSpent($spent); | ||||
|                 $object->addLeft($left); | ||||
|                 $object->addOverspent($overspent); | ||||
|                 $object->addBudgetLine($budgetLine); | ||||
|  | ||||
|             } | ||||
|  | ||||
|         } | ||||
|  | ||||
|         // stuff outside of budgets: | ||||
|         $noBudget   = $repository->getWithoutBudgetSum($start, $end); | ||||
|         $budgetLine = new BudgetLine; | ||||
|         $budgetLine->setOverspent($noBudget); | ||||
|         $object->addOverspent($noBudget); | ||||
|         $object->addBudgetLine($budgetLine); | ||||
|  | ||||
|         return $object; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return CategoryCollection | ||||
|      */ | ||||
|     public function getCategoryReport(Carbon $start, Carbon $end, $shared) | ||||
|     { | ||||
|         $object = new CategoryCollection; | ||||
|  | ||||
|  | ||||
|         /** | ||||
|          * GET CATEGORIES: | ||||
|          */ | ||||
|         /** @var \FireflyIII\Repositories\Category\CategoryRepositoryInterface $repository */ | ||||
|         $repository = App::make('FireflyIII\Repositories\Category\CategoryRepositoryInterface'); | ||||
|         $set        = $repository->getCategories(); | ||||
|         foreach ($set as $category) { | ||||
|             $spent           = $repository->spentInPeriodCorrected($category, $start, $end, $shared); | ||||
|             $category->spent = $spent; | ||||
|             $object->addCategory($category); | ||||
|             $object->addTotal($spent); | ||||
|         } | ||||
|  | ||||
|         return $object; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get a full report on the users expenses during the period. | ||||
|      * | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return Expense | ||||
|      */ | ||||
|     public function getExpenseReport($start, $end, $shared) | ||||
|     { | ||||
|         $object = new Expense; | ||||
|         $set    = $this->query->expenseInPeriodCorrected($start, $end, $shared); | ||||
|         foreach ($set as $entry) { | ||||
|             $object->addToTotal($entry->amount); | ||||
|             $object->addOrCreateExpense($entry); | ||||
|         } | ||||
|  | ||||
|         return $object; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get a full report on the users incomes during the period. | ||||
|      * | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return Income | ||||
|      */ | ||||
|     public function getIncomeReport($start, $end, $shared) | ||||
|     { | ||||
|         $object = new Income; | ||||
|         $set    = $this->query->incomeInPeriodCorrected($start, $end, $shared); | ||||
|         foreach ($set as $entry) { | ||||
|             $object->addToTotal($entry->amount); | ||||
|             $object->addOrCreateIncome($entry); | ||||
|         } | ||||
|  | ||||
|         return $object; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon $date | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function listOfMonths(Carbon $date) | ||||
|     { | ||||
|  | ||||
|         $start  = clone $date; | ||||
|         $end    = Carbon::now(); | ||||
|         $months = []; | ||||
|         while ($start <= $end) { | ||||
|             $year            = $start->year; | ||||
|             $months[$year][] = [ | ||||
|                 'formatted' => $start->formatLocalized('%B %Y'), | ||||
|                 'month'     => $start->month, | ||||
|                 'year'      => $year, | ||||
|             ]; | ||||
|             $start->addMonth(); | ||||
|         } | ||||
|  | ||||
|         return $months; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										102
									
								
								app/Helpers/Report/ReportHelperInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								app/Helpers/Report/ReportHelperInterface.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Report; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Helpers\Collection\Account as AccountCollection; | ||||
| use FireflyIII\Helpers\Collection\Balance; | ||||
| use FireflyIII\Helpers\Collection\Bill as BillCollection; | ||||
| use FireflyIII\Helpers\Collection\Budget as BudgetCollection; | ||||
| use FireflyIII\Helpers\Collection\Category as CategoryCollection; | ||||
| use FireflyIII\Helpers\Collection\Expense; | ||||
| use FireflyIII\Helpers\Collection\Income; | ||||
|  | ||||
| /** | ||||
|  * Interface ReportHelperInterface | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Report | ||||
|  */ | ||||
| interface ReportHelperInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * This method generates a full report for the given period on all | ||||
|      * the users asset and cash accounts. | ||||
|      * | ||||
|      * @param Carbon  $date | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return AccountCollection | ||||
|      */ | ||||
|     public function getAccountReport(Carbon $date, Carbon $end, $shared); | ||||
|  | ||||
|     /** | ||||
|      * This method generates a full report for the given period on all | ||||
|      * the users bills and their payments. | ||||
|      * | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return BillCollection | ||||
|      */ | ||||
|     public function getBillReport(Carbon $start, Carbon $end, $shared); | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return Balance | ||||
|      */ | ||||
|     public function getBalanceReport(Carbon $start, Carbon $end, $shared); | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return BudgetCollection | ||||
|      */ | ||||
|     public function getBudgetReport(Carbon $start, Carbon $end, $shared); | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return CategoryCollection | ||||
|      */ | ||||
|     public function getCategoryReport(Carbon $start, Carbon $end, $shared); | ||||
|  | ||||
|     /** | ||||
|      * Get a full report on the users expenses during the period. | ||||
|      * | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return Expense | ||||
|      */ | ||||
|     public function getExpenseReport($start, $end, $shared); | ||||
|  | ||||
|     /** | ||||
|      * Get a full report on the users incomes during the period. | ||||
|      * | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param boolean $shared | ||||
|      * | ||||
|      * @return Income | ||||
|      */ | ||||
|     public function getIncomeReport($start, $end, $shared); | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon $date | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function listOfMonths(Carbon $date); | ||||
|  | ||||
| } | ||||
							
								
								
									
										283
									
								
								app/Helpers/Report/ReportQuery.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										283
									
								
								app/Helpers/Report/ReportQuery.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,283 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Report; | ||||
|  | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use Crypt; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\Budget; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Illuminate\Database\Eloquent\Builder; | ||||
| use Illuminate\Database\Query\JoinClause; | ||||
| use Illuminate\Support\Collection; | ||||
| use Steam; | ||||
|  | ||||
| /** | ||||
|  * Class ReportQuery | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Report | ||||
|  */ | ||||
| class ReportQuery implements ReportQueryInterface | ||||
| { | ||||
|     /** | ||||
|      * See ReportQueryInterface::incomeInPeriodCorrected | ||||
|      * | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * @param bool   $includeShared | ||||
|      * | ||||
|      * @return Collection | ||||
|      * | ||||
|      */ | ||||
|     public function expenseInPeriodCorrected(Carbon $start, Carbon $end, $includeShared = false) | ||||
|     { | ||||
|         $query = $this->queryJournalsWithTransactions($start, $end); | ||||
|         if ($includeShared === false) { | ||||
|             $query->where( | ||||
|                 function (Builder $query) { | ||||
|                     $query->where( | ||||
|                         function (Builder $q) { // only get withdrawals not from a shared account | ||||
|                             $q->where('transaction_types.type', 'Withdrawal'); | ||||
|                             $q->where('acm_from.data', '!=', '"sharedAsset"'); | ||||
|                         } | ||||
|                     ); | ||||
|                     $query->orWhere( | ||||
|                         function (Builder $q) { // and transfers from a shared account. | ||||
|                             $q->where('transaction_types.type', 'Transfer'); | ||||
|                             $q->where('acm_to.data', '=', '"sharedAsset"'); | ||||
|                         } | ||||
|                     ); | ||||
|                 } | ||||
|             ); | ||||
|         } else { | ||||
|             $query->where('transaction_types.type', 'Withdrawal'); // any withdrawal is fine. | ||||
|         } | ||||
|         $query->orderBy('transaction_journals.date'); | ||||
|  | ||||
|         // get everything | ||||
|         $data = $query->get( | ||||
|             ['transaction_journals.*', 'transaction_types.type', 'ac_to.name as name', 'ac_to.id as account_id', 'ac_to.encrypted as account_encrypted'] | ||||
|         ); | ||||
|  | ||||
|         $data->each( | ||||
|             function (TransactionJournal $journal) { | ||||
|                 if (intval($journal->account_encrypted) == 1) { | ||||
|                     $journal->name = Crypt::decrypt($journal->name); | ||||
|                 } | ||||
|             } | ||||
|         ); | ||||
|         $data = $data->filter( | ||||
|             function (TransactionJournal $journal) { | ||||
|                 if ($journal->amount != 0) { | ||||
|                     return $journal; | ||||
|                 } | ||||
|  | ||||
|                 return null; | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get a users accounts combined with various meta-data related to the start and end date. | ||||
|      * | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * @param bool   $includeShared | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getAllAccounts(Carbon $start, Carbon $end, $includeShared = false) | ||||
|     { | ||||
|         $query = Auth::user()->accounts()->orderBy('accounts.name', 'ASC') | ||||
|                      ->accountTypeIn(['Default account', 'Asset account', 'Cash account']); | ||||
|         if ($includeShared === false) { | ||||
|             $query->leftJoin( | ||||
|                 'account_meta', function (JoinClause $join) { | ||||
|                 $join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole'); | ||||
|             } | ||||
|             ) | ||||
|                   ->where( | ||||
|                       function (Builder $query) { | ||||
|  | ||||
|                           $query->where('account_meta.data', '!=', '"sharedAsset"'); | ||||
|                           $query->orWhereNull('account_meta.data'); | ||||
|  | ||||
|                       } | ||||
|                   ); | ||||
|         } | ||||
|         $set = $query->get(['accounts.*']); | ||||
|         $set->each( | ||||
|             function (Account $account) use ($start, $end) { | ||||
|                 /** | ||||
|                  * The balance for today always incorporates transactions | ||||
|                  * made on today. So to get todays "start" balance, we sub one | ||||
|                  * day. | ||||
|                  */ | ||||
|                 $yesterday = clone $start; | ||||
|                 $yesterday->subDay(); | ||||
|  | ||||
|                 /** @noinspection PhpParamsInspection */ | ||||
|                 $account->startBalance = Steam::balance($account, $yesterday); | ||||
|                 $account->endBalance   = Steam::balance($account, $end); | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         return $set; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * This method works the same way as ReportQueryInterface::incomeInPeriod does, but instead of returning results | ||||
|      * will simply list the transaction journals only. This should allow any follow up counting to be accurate with | ||||
|      * regards to tags. | ||||
|      * | ||||
|      * This method returns all "income" journals in a certain period, which are both transfers from a shared account | ||||
|      * and "ordinary" deposits. The query used is almost equal to ReportQueryInterface::journalsByRevenueAccount but it does | ||||
|      * not group and returns different fields. | ||||
|      * | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * @param bool   $includeShared | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function incomeInPeriodCorrected(Carbon $start, Carbon $end, $includeShared = false) | ||||
|     { | ||||
|         $query = $this->queryJournalsWithTransactions($start, $end); | ||||
|         if ($includeShared === false) { | ||||
|             // only get deposits not to a shared account | ||||
|             // and transfers to a shared account. | ||||
|             $query->where( | ||||
|                 function (Builder $query) { | ||||
|                     $query->where( | ||||
|                         function (Builder $q) { | ||||
|                             $q->where('transaction_types.type', 'Deposit'); | ||||
|                             $q->where('acm_to.data', '!=', '"sharedAsset"'); | ||||
|                         } | ||||
|                     ); | ||||
|                     $query->orWhere( | ||||
|                         function (Builder $q) { | ||||
|                             $q->where('transaction_types.type', 'Transfer'); | ||||
|                             $q->where('acm_from.data', '=', '"sharedAsset"'); | ||||
|                         } | ||||
|                     ); | ||||
|                 } | ||||
|             ); | ||||
|         } else { | ||||
|             // any deposit is fine. | ||||
|             $query->where('transaction_types.type', 'Deposit'); | ||||
|         } | ||||
|         $query->orderBy('transaction_journals.date'); | ||||
|  | ||||
|         // get everything | ||||
|         $data = $query->get( | ||||
|             ['transaction_journals.*', 'transaction_types.type', 'ac_from.name as name', 'ac_from.id as account_id', 'ac_from.encrypted as account_encrypted'] | ||||
|         ); | ||||
|  | ||||
|         $data->each( | ||||
|             function (TransactionJournal $journal) { | ||||
|                 if (intval($journal->account_encrypted) == 1) { | ||||
|                     $journal->name = Crypt::decrypt($journal->name); | ||||
|                 } | ||||
|             } | ||||
|         ); | ||||
|         $data = $data->filter( | ||||
|             function (TransactionJournal $journal) { | ||||
|                 if ($journal->amount != 0) { | ||||
|                     return $journal; | ||||
|                 } | ||||
|  | ||||
|                 return null; | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Covers tags | ||||
|      * | ||||
|      * @param Account $account | ||||
|      * @param Budget  $budget | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * | ||||
|      * @return float | ||||
|      */ | ||||
|     public function spentInBudgetCorrected(Account $account, Budget $budget, Carbon $start, Carbon $end) | ||||
|     { | ||||
|  | ||||
|         return floatval( | ||||
|                    Auth::user()->transactionjournals() | ||||
|                        ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') | ||||
|                        ->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') | ||||
|                        ->transactionTypes(['Withdrawal']) | ||||
|                        ->where('transactions.account_id', $account->id) | ||||
|                        ->before($end) | ||||
|                        ->after($start) | ||||
|                        ->where('budget_transaction_journal.budget_id', $budget->id) | ||||
|                        ->get(['transaction_journals.*'])->sum('amount') | ||||
|                ) * -1; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Account $account | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param bool    $shared | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function spentNoBudget(Account $account, Carbon $start, Carbon $end, $shared = false) | ||||
|     { | ||||
|         return | ||||
|             Auth::user()->transactionjournals() | ||||
|                 ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') | ||||
|                 ->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') | ||||
|                 ->transactionTypes(['Withdrawal']) | ||||
|                 ->where('transactions.account_id', $account->id) | ||||
|                 ->before($end) | ||||
|                 ->after($start) | ||||
|                 ->whereNull('budget_transaction_journal.budget_id')->get(['transaction_journals.*'])->sum('amount'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return Builder | ||||
|      */ | ||||
|     protected function queryJournalsWithTransactions(Carbon $start, Carbon $end) | ||||
|     { | ||||
|         $query = TransactionJournal:: | ||||
|         leftJoin( | ||||
|             'transactions as t_from', function (JoinClause $join) { | ||||
|             $join->on('t_from.transaction_journal_id', '=', 'transaction_journals.id')->where('t_from.amount', '<', 0); | ||||
|         } | ||||
|         ) | ||||
|                                    ->leftJoin('accounts as ac_from', 't_from.account_id', '=', 'ac_from.id') | ||||
|                                    ->leftJoin( | ||||
|                                        'account_meta as acm_from', function (JoinClause $join) { | ||||
|                                        $join->on('ac_from.id', '=', 'acm_from.account_id')->where('acm_from.name', '=', 'accountRole'); | ||||
|                                    } | ||||
|                                    ) | ||||
|                                    ->leftJoin( | ||||
|                                        'transactions as t_to', function (JoinClause $join) { | ||||
|                                        $join->on('t_to.transaction_journal_id', '=', 'transaction_journals.id')->where('t_to.amount', '>', 0); | ||||
|                                    } | ||||
|                                    ) | ||||
|                                    ->leftJoin('accounts as ac_to', 't_to.account_id', '=', 'ac_to.id') | ||||
|                                    ->leftJoin( | ||||
|                                        'account_meta as acm_to', function (JoinClause $join) { | ||||
|                                        $join->on('ac_to.id', '=', 'acm_to.account_id')->where('acm_to.name', '=', 'accountRole'); | ||||
|                                    } | ||||
|                                    ) | ||||
|                                    ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id'); | ||||
|         $query->before($end)->after($start)->where('transaction_journals.user_id', Auth::user()->id); | ||||
|  | ||||
|         return $query; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										81
									
								
								app/Helpers/Report/ReportQueryInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								app/Helpers/Report/ReportQueryInterface.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Report; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\Budget; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * Interface ReportQueryInterface | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Report | ||||
|  */ | ||||
| interface ReportQueryInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * See ReportQueryInterface::incomeInPeriodCorrected | ||||
|      * | ||||
|      * This method returns all "expense" journals in a certain period, which are both transfers to a shared account | ||||
|      * and "ordinary" withdrawals. The query used is almost equal to ReportQueryInterface::journalsByRevenueAccount but it does | ||||
|      * not group and returns different fields. | ||||
|      * | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * @param bool   $includeShared | ||||
|      * | ||||
|      * @return Collection | ||||
|      * | ||||
|      */ | ||||
|     public function expenseInPeriodCorrected(Carbon $start, Carbon $end, $includeShared = false); | ||||
|  | ||||
|     /** | ||||
|      * Get a users accounts combined with various meta-data related to the start and end date. | ||||
|      * | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * @param bool   $includeShared | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getAllAccounts(Carbon $start, Carbon $end, $includeShared = false); | ||||
|  | ||||
|     /** | ||||
|      * This method works the same way as ReportQueryInterface::incomeInPeriod does, but instead of returning results | ||||
|      * will simply list the transaction journals only. This should allow any follow up counting to be accurate with | ||||
|      * regards to tags. | ||||
|      * | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * @param bool   $includeShared | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function incomeInPeriodCorrected(Carbon $start, Carbon $end, $includeShared = false); | ||||
|  | ||||
|     /** | ||||
|      * Covers tags as well. | ||||
|      * | ||||
|      * @param Account $account | ||||
|      * @param Budget  $budget | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * | ||||
|      * @return float | ||||
|      */ | ||||
|     public function spentInBudgetCorrected(Account $account, Budget $budget, Carbon $start, Carbon $end); | ||||
|  | ||||
|     /** | ||||
|      * @param Account $account | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param bool    $shared | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function spentNoBudget(Account $account, Carbon $start, Carbon $end, $shared = false); | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										266
									
								
								app/Http/Controllers/AccountController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										266
									
								
								app/Http/Controllers/AccountController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,266 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use Config; | ||||
| use FireflyIII\Http\Requests\AccountFormRequest; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use Input; | ||||
| use Preferences; | ||||
| use Redirect; | ||||
| use Session; | ||||
| use Steam; | ||||
| use URL; | ||||
| use View; | ||||
|  | ||||
| /** | ||||
|  * Class AccountController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers | ||||
|  */ | ||||
| class AccountController extends Controller | ||||
| { | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         View::share('mainTitleIcon', 'fa-credit-card'); | ||||
|         View::share('title', trans('firefly.accounts')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $what | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function create($what = 'asset') | ||||
|     { | ||||
|         $subTitleIcon = Config::get('firefly.subIconsByIdentifier.' . $what); | ||||
|         $subTitle     = trans('firefly.make_new_' . $what . '_account'); | ||||
|  | ||||
|         // put previous url in session if not redirect from store (not "create another"). | ||||
|         if (Session::get('accounts.create.fromStore') !== true) { | ||||
|             Session::put('accounts.create.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('accounts.create.fromStore'); | ||||
|         Session::flash('gaEventCategory', 'accounts'); | ||||
|         Session::flash('gaEventAction', 'create-' . $what); | ||||
|  | ||||
|         return view('accounts.create', compact('subTitleIcon', 'what', 'subTitle')); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Account $account | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function delete(Account $account) | ||||
|     { | ||||
|         $typeName = Config::get('firefly.shortNamesByFullName.' . $account->accountType->type); | ||||
|         $subTitle = trans('firefly.delete_' . $typeName . '_account', ['name' => $account->name]); | ||||
|  | ||||
|         // put previous url in session | ||||
|         Session::put('accounts.delete.url', URL::previous()); | ||||
|         Session::flash('gaEventCategory', 'accounts'); | ||||
|         Session::flash('gaEventAction', 'delete-' . $typeName); | ||||
|  | ||||
|         return view('accounts.delete', compact('account', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * @param Account                    $account | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function destroy(AccountRepositoryInterface $repository, Account $account) | ||||
|     { | ||||
|  | ||||
|         $type     = $account->accountType->type; | ||||
|         $typeName = Config::get('firefly.shortNamesByFullName.' . $type); | ||||
|         $name     = $account->name; | ||||
|  | ||||
|         $repository->destroy($account); | ||||
|  | ||||
|         Session::flash('success', trans('firefly.' . $typeName . '_deleted', ['name' => $name])); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         return Redirect::to(Session::get('accounts.delete.url')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * @param Account                    $account | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function edit(AccountRepositoryInterface $repository, Account $account) | ||||
|     { | ||||
|  | ||||
|         $what           = Config::get('firefly.shortNamesByFullName')[$account->accountType->type]; | ||||
|         $subTitle       = trans('firefly.edit_' . $what . '_account', ['name' => $account->name]); | ||||
|         $subTitleIcon   = Config::get('firefly.subIconsByIdentifier.' . $what); | ||||
|         $openingBalance = $repository->openingBalanceTransaction($account); | ||||
|  | ||||
|         // put previous url in session if not redirect from store (not "return_to_edit"). | ||||
|         if (Session::get('accounts.edit.fromUpdate') !== true) { | ||||
|             Session::put('accounts.edit.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('accounts.edit.fromUpdate'); | ||||
|  | ||||
|         // pre fill some useful values. | ||||
|  | ||||
|         // the opening balance is tricky: | ||||
|         $openingBalanceAmount = null; | ||||
|  | ||||
|         if ($openingBalance) { | ||||
|             $transaction          = $repository->getFirstTransaction($openingBalance, $account); | ||||
|             $openingBalanceAmount = $transaction->amount; | ||||
|         } | ||||
|  | ||||
|         $preFilled = [ | ||||
|             'accountRole'          => $account->getMeta('accountRole'), | ||||
|             'ccType'               => $account->getMeta('ccType'), | ||||
|             'ccMonthlyPaymentDate' => $account->getMeta('ccMonthlyPaymentDate'), | ||||
|             'openingBalanceDate'   => $openingBalance ? $openingBalance->date->format('Y-m-d') : null, | ||||
|             'openingBalance'       => $openingBalanceAmount, | ||||
|             'virtualBalance'       => floatval($account->virtual_balance) | ||||
|         ]; | ||||
|         Session::flash('preFilled', $preFilled); | ||||
|         Session::flash('gaEventCategory', 'accounts'); | ||||
|         Session::flash('gaEventAction', 'edit-' . $what); | ||||
|  | ||||
|         return view('accounts.edit', compact('account', 'subTitle', 'subTitleIcon', 'openingBalance', 'what')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * @param                            $what | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function index(AccountRepositoryInterface $repository, $what) | ||||
|     { | ||||
|         $subTitle     = trans('firefly.' . $what . '_accounts'); | ||||
|         $subTitleIcon = Config::get('firefly.subIconsByIdentifier.' . $what); | ||||
|         $types        = Config::get('firefly.accountTypesByIdentifier.' . $what); | ||||
|         $accounts     = $repository->getAccounts($types); | ||||
|         // last activity: | ||||
|         /** | ||||
|          * HERE WE ARE | ||||
|          */ | ||||
|         $start = clone Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $start->subDay(); | ||||
|         $accounts->each( | ||||
|             function (Account $account) use ($start, $repository) { | ||||
|                 $account->lastActivityDate = $repository->getLastActivity($account); | ||||
|                 $account->startBalance     = Steam::balance($account, $start); | ||||
|                 $account->endBalance       = Steam::balance($account, clone Session::get('end', Carbon::now()->endOfMonth())); | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         return view('accounts.index', compact('what', 'subTitleIcon', 'subTitle', 'accounts')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * @param Account                    $account | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function show(AccountRepositoryInterface $repository, Account $account) | ||||
|     { | ||||
|         $page         = intval(Input::get('page')) == 0 ? 1 : intval(Input::get('page')); | ||||
|         $subTitleIcon = Config::get('firefly.subTitlesByIdentifier.' . $account->accountType->type); | ||||
|         $what         = Config::get('firefly.shortNamesByFullName.' . $account->accountType->type); | ||||
|         $journals     = $repository->getJournals($account, $page); | ||||
|         $subTitle     = trans('firefly.details_for_' . $what, ['name' => $account->name]); | ||||
|         $journals->setPath('accounts/show/' . $account->id); | ||||
|  | ||||
|  | ||||
|         return view('accounts.show', compact('account', 'what', 'subTitleIcon', 'journals', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param AccountFormRequest         $request | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function store(AccountFormRequest $request, AccountRepositoryInterface $repository) | ||||
|     { | ||||
|         $accountData = [ | ||||
|             'name'                   => $request->input('name'), | ||||
|             'accountType'            => $request->input('what'), | ||||
|             'virtualBalance'         => floatval($request->input('virtualBalance')), | ||||
|             'active'                 => true, | ||||
|             'user'                   => Auth::user()->id, | ||||
|             'accountRole'            => $request->input('accountRole'), | ||||
|             'openingBalance'         => floatval($request->input('openingBalance')), | ||||
|             'openingBalanceDate'     => new Carbon((string)$request->input('openingBalanceDate')), | ||||
|             'openingBalanceCurrency' => intval($request->input('balance_currency_id')), | ||||
|  | ||||
|         ]; | ||||
|         $account     = $repository->store($accountData); | ||||
|  | ||||
|         Session::flash('success', 'New account "' . $account->name . '" stored!'); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         if (intval(Input::get('create_another')) === 1) { | ||||
|             // set value so create routine will not overwrite URL: | ||||
|             Session::put('accounts.create.fromStore', true); | ||||
|  | ||||
|             return Redirect::route('accounts.create')->withInput(); | ||||
|         } | ||||
|  | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('accounts.create.url')); | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param AccountFormRequest         $request | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * @param Account                    $account | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function update(AccountFormRequest $request, AccountRepositoryInterface $repository, Account $account) | ||||
|     { | ||||
|  | ||||
|         $accountData = [ | ||||
|             'name'                   => $request->input('name'), | ||||
|             'active'                 => $request->input('active'), | ||||
|             'user'                   => Auth::user()->id, | ||||
|             'accountRole'            => $request->input('accountRole'), | ||||
|             'virtualBalance'         => floatval($request->input('virtualBalance')), | ||||
|             'openingBalance'         => floatval($request->input('openingBalance')), | ||||
|             'openingBalanceDate'     => new Carbon((string)$request->input('openingBalanceDate')), | ||||
|             'openingBalanceCurrency' => intval($request->input('balance_currency_id')), | ||||
|             'ccType'                 => $request->input('ccType'), | ||||
|             'ccMonthlyPaymentDate'   => $request->input('ccMonthlyPaymentDate'), | ||||
|         ]; | ||||
|  | ||||
|         $repository->update($account, $accountData); | ||||
|  | ||||
|         Session::flash('success', 'Account "' . $account->name . '" updated.'); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         if (intval(Input::get('return_to_edit')) === 1) { | ||||
|             // set value so edit routine will not overwrite URL: | ||||
|             Session::put('accounts.edit.fromUpdate', true); | ||||
|  | ||||
|             return Redirect::route('accounts.edit', [$account->id])->withInput(['return_to_edit' => 1]); | ||||
|         } | ||||
|  | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('accounts.edit.url')); | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										151
									
								
								app/Http/Controllers/Auth/AuthController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								app/Http/Controllers/Auth/AuthController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,151 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers\Auth; | ||||
|  | ||||
| use App; | ||||
| use Auth; | ||||
| use FireflyIII\Http\Controllers\Controller; | ||||
| use FireflyIII\Models\Role; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Mail\Message; | ||||
| use Mail; | ||||
| use Session; | ||||
| use Twig; | ||||
| use Validator; | ||||
|  | ||||
| /** | ||||
|  * Class AuthController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers\Auth | ||||
|  */ | ||||
| class AuthController extends Controller | ||||
| { | ||||
|  | ||||
|     /* | ||||
|     |-------------------------------------------------------------------------- | ||||
|     | Registration & Login Controller | ||||
|     |-------------------------------------------------------------------------- | ||||
|     | | ||||
|     | This controller handles the registration of new users, as well as the | ||||
|     | authentication of existing users. By default, this controller uses | ||||
|     | a simple trait to add these behaviors. Why don't you explore it? | ||||
|     | | ||||
|     */ | ||||
|  | ||||
|     use AuthenticatesAndRegistersUsers; | ||||
|  | ||||
|     public $redirectTo = '/'; | ||||
|  | ||||
|     /** | ||||
|      * Create a new authentication controller instance. | ||||
|      * | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->middleware('guest', ['except' => 'getLogout']); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show the application login form. | ||||
|      * | ||||
|      * @codeCoverageIgnore | ||||
|      * @return \Illuminate\Http\Response | ||||
|      * | ||||
|      */ | ||||
|     public function getLogin() | ||||
|     { | ||||
|         return Twig::render('auth.login'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Handle a registration request for the application. | ||||
|      * | ||||
|      * @param  Request $request | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function postRegister(Request $request) | ||||
|     { | ||||
|         $validator = $this->validator($request->all()); | ||||
|  | ||||
|         if ($validator->fails()) { | ||||
|             $this->throwValidationException( | ||||
|                 $request, $validator | ||||
|             ); | ||||
|             // @codeCoverageIgnoreStart | ||||
|         } | ||||
|         // @codeCoverageIgnoreEnd | ||||
|  | ||||
|         $data             = $request->all(); | ||||
|         $data['password'] = bcrypt($data['password']); | ||||
|  | ||||
|         Auth::login($this->create($data)); | ||||
|  | ||||
|         // get the email address | ||||
|         if (Auth::user() instanceof User) { | ||||
|             $email   = Auth::user()->email; | ||||
|             $address = route('index'); | ||||
|             // send email. | ||||
|             Mail::send( | ||||
|                 ['emails.registered-html', 'emails.registered'], ['address' => $address], function (Message $message) use ($email) { | ||||
|                 $message->to($email, $email)->subject('Welcome to Firefly III! '); | ||||
|             } | ||||
|             ); | ||||
|  | ||||
|             // set flash message | ||||
|             Session::flash('success', 'You have registered successfully!'); | ||||
|             Session::flash('gaEventCategory', 'user'); | ||||
|             Session::flash('gaEventAction', 'new-registration'); | ||||
|  | ||||
|             // first user ever? | ||||
|             if (User::count() == 1) { | ||||
|                 $admin = Role::where('name', 'owner')->first(); | ||||
|                 Auth::user()->attachRole($admin); | ||||
|             } | ||||
|  | ||||
|  | ||||
|             return redirect($this->redirectPath()); | ||||
|         } | ||||
|         // @codeCoverageIgnoreStart | ||||
|         App::abort(500, 'Not a user!'); | ||||
|  | ||||
|         return redirect('/'); | ||||
|         // @codeCoverageIgnoreEnd | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get a validator for an incoming registration request. | ||||
|      * | ||||
|      * @param  array $data | ||||
|      * | ||||
|      * @return \Illuminate\Contracts\Validation\Validator | ||||
|      */ | ||||
|     public function validator(array $data) | ||||
|     { | ||||
|         return Validator::make( | ||||
|             $data, [ | ||||
|                      'email'    => 'required|email|max:255|unique:users', | ||||
|                      'password' => 'required|confirmed|min:6', | ||||
|                  ] | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Create a new user instance after a valid registration. | ||||
|      * | ||||
|      * @param  array $data | ||||
|      * | ||||
|      * @return User | ||||
|      */ | ||||
|     public function create(array $data) | ||||
|     { | ||||
|         return User::create( | ||||
|             [ | ||||
|                 'email'    => $data['email'], | ||||
|                 'password' => $data['password'], | ||||
|             ] | ||||
|         ); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										43
									
								
								app/Http/Controllers/Auth/PasswordController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								app/Http/Controllers/Auth/PasswordController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers\Auth; | ||||
|  | ||||
| use FireflyIII\Http\Controllers\Controller; | ||||
| use Illuminate\Foundation\Auth\ResetsPasswords; | ||||
|  | ||||
| /** | ||||
|  * Class PasswordController | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Http\Controllers\Auth | ||||
|  */ | ||||
| class PasswordController extends Controller | ||||
| { | ||||
|  | ||||
|     /* | ||||
|     |-------------------------------------------------------------------------- | ||||
|     | Password Reset Controller | ||||
|     |-------------------------------------------------------------------------- | ||||
|     | | ||||
|     | This controller is responsible for handling password reset requests | ||||
|     | and uses a simple trait to include this behavior. You're free to | ||||
|     | explore this trait and override any methods you wish to tweak. | ||||
|     | | ||||
|     */ | ||||
|  | ||||
|     use ResetsPasswords; | ||||
|  | ||||
|  | ||||
|     protected $redirectPath = '/'; | ||||
|  | ||||
|     /** | ||||
|      * Create a new password controller instance. | ||||
|      * | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|  | ||||
|         $this->middleware('guest'); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										220
									
								
								app/Http/Controllers/BillController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										220
									
								
								app/Http/Controllers/BillController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,220 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Config; | ||||
| use FireflyIII\Http\Requests\BillFormRequest; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Repositories\Bill\BillRepositoryInterface; | ||||
| use Input; | ||||
| use Preferences; | ||||
| use Redirect; | ||||
| use Session; | ||||
| use URL; | ||||
| use View; | ||||
|  | ||||
| /** | ||||
|  * Class BillController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers | ||||
|  */ | ||||
| class BillController extends Controller | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         View::share('title', trans('firefly.bills')); | ||||
|         View::share('mainTitleIcon', 'fa-calendar-o'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function create() | ||||
|     { | ||||
|         $periods  = Config::get('firefly.periods_to_text'); | ||||
|         $subTitle = trans('firefly.create_new_bill'); | ||||
|  | ||||
|  | ||||
|         // put previous url in session if not redirect from store (not "create another"). | ||||
|         if (Session::get('bills.create.fromStore') !== true) { | ||||
|             Session::put('bills.create.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('bills.create.fromStore'); | ||||
|         Session::flash('gaEventCategory', 'bills'); | ||||
|         Session::flash('gaEventAction', 'create'); | ||||
|  | ||||
|         return view('bills.create', compact('periods', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Bill $bill | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function delete(Bill $bill) | ||||
|     { | ||||
|         // put previous url in session | ||||
|         Session::put('bills.delete.url', URL::previous()); | ||||
|         Session::flash('gaEventCategory', 'bills'); | ||||
|         Session::flash('gaEventAction', 'delete'); | ||||
|         $subTitle = trans('firefly.delete_bill', ['name' => $bill->name]); | ||||
|  | ||||
|         return view('bills.delete', compact('bill', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BillRepositoryInterface $repository | ||||
|      * @param Bill                    $bill | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function destroy(BillRepositoryInterface $repository, Bill $bill) | ||||
|     { | ||||
|         $repository->destroy($bill); | ||||
|  | ||||
|         Session::flash('success', 'The bill was deleted.'); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         return Redirect::to(Session::get('bills.delete.url')); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Bill $bill | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function edit(Bill $bill) | ||||
|     { | ||||
|         $periods  = Config::get('firefly.periods_to_text'); | ||||
|         $subTitle = trans('firefly.edit_bill', ['name' => $bill->name]); | ||||
|  | ||||
|         // put previous url in session if not redirect from store (not "return_to_edit"). | ||||
|         if (Session::get('bills.edit.fromUpdate') !== true) { | ||||
|             Session::put('bills.edit.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('bills.edit.fromUpdate'); | ||||
|         Session::flash('gaEventCategory', 'bills'); | ||||
|         Session::flash('gaEventAction', 'edit'); | ||||
|  | ||||
|         return view('bills.edit', compact('subTitle', 'periods', 'bill')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BillRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function index(BillRepositoryInterface $repository) | ||||
|     { | ||||
|         $bills = $repository->getBills(); | ||||
|         $bills->each( | ||||
|             function (Bill $bill) use ($repository) { | ||||
|                 $bill->nextExpectedMatch = $repository->nextExpectedMatch($bill); | ||||
|                 $bill->lastFoundMatch    = $repository->lastFoundMatch($bill); | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         return view('bills.index', compact('bills')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BillRepositoryInterface $repository | ||||
|      * @param Bill                    $bill | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function rescan(BillRepositoryInterface $repository, Bill $bill) | ||||
|     { | ||||
|         if (intval($bill->active) == 0) { | ||||
|             Session::flash('warning', 'Inactive bills cannot be scanned.'); | ||||
|  | ||||
|             return Redirect::to(URL::previous()); | ||||
|         } | ||||
|  | ||||
|         $journals = $repository->getPossiblyRelatedJournals($bill); | ||||
|         /** @var TransactionJournal $journal */ | ||||
|         foreach ($journals as $journal) { | ||||
|             $repository->scan($bill, $journal); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         Session::flash('success', 'Rescanned everything.'); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         return Redirect::to(URL::previous()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BillRepositoryInterface $repository | ||||
|      * @param Bill                    $bill | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function show(BillRepositoryInterface $repository, Bill $bill) | ||||
|     { | ||||
|         $journals                = $repository->getJournals($bill); | ||||
|         $bill->nextExpectedMatch = $repository->nextExpectedMatch($bill); | ||||
|         $hideBill                = true; | ||||
|         $subTitle                = e($bill->name); | ||||
|  | ||||
|         return view('bills.show', compact('journals', 'hideBill', 'bill', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BillFormRequest         $request | ||||
|      * @param BillRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function store(BillFormRequest $request, BillRepositoryInterface $repository) | ||||
|     { | ||||
|         $billData = $request->getBillData(); | ||||
|         $bill     = $repository->store($billData); | ||||
|         Session::flash('success', 'Bill "' . e($bill->name) . '" stored.'); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         if (intval(Input::get('create_another')) === 1) { | ||||
|             // set value so create routine will not overwrite URL: | ||||
|             Session::put('bills.create.fromStore', true); | ||||
|  | ||||
|             return Redirect::route('bills.create')->withInput(); | ||||
|         } | ||||
|  | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('bills.create.url')); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BillFormRequest         $request | ||||
|      * @param BillRepositoryInterface $repository | ||||
|      * @param Bill                    $bill | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function update(BillFormRequest $request, BillRepositoryInterface $repository, Bill $bill) | ||||
|     { | ||||
|         $billData = $request->getBillData(); | ||||
|         $bill     = $repository->update($bill, $billData); | ||||
|  | ||||
|         Session::flash('success', 'Bill "' . e($bill->name) . '" updated.'); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         if (intval(Input::get('return_to_edit')) === 1) { | ||||
|             // set value so edit routine will not overwrite URL: | ||||
|             Session::put('bills.edit.fromUpdate', true); | ||||
|  | ||||
|             return Redirect::route('bills.edit', [$bill->id])->withInput(['return_to_edit' => 1]); | ||||
|         } | ||||
|  | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('bills.edit.url')); | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										307
									
								
								app/Http/Controllers/BudgetController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										307
									
								
								app/Http/Controllers/BudgetController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,307 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Amount; | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Http\Requests\BudgetFormRequest; | ||||
| use FireflyIII\Models\Budget; | ||||
| use FireflyIII\Models\LimitRepetition; | ||||
| use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; | ||||
| use Input; | ||||
| use Preferences; | ||||
| use Redirect; | ||||
| use Response; | ||||
| use Session; | ||||
| use URL; | ||||
| use View; | ||||
|  | ||||
| /** | ||||
|  * Class BudgetController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers | ||||
|  * @SuppressWarnings(PHPMD.TooManyMethods) | ||||
|  */ | ||||
| class BudgetController extends Controller | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         View::share('title', trans('firefly.budgets')); | ||||
|         View::share('mainTitleIcon', 'fa-tasks'); | ||||
|         View::share('hideBudgets', true); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
|      * @param Budget                    $budget | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function amount(BudgetRepositoryInterface $repository, Budget $budget) | ||||
|     { | ||||
|         $amount          = intval(Input::get('amount')); | ||||
|         $date            = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $limitRepetition = $repository->updateLimitAmount($budget, $date, $amount); | ||||
|         if ($amount == 0) { | ||||
|             $limitRepetition = null; | ||||
|         } | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         return Response::json(['name' => $budget->name, 'repetition' => $limitRepetition ? $limitRepetition->id : 0]); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function create() | ||||
|     { | ||||
|         // put previous url in session if not redirect from store (not "create another"). | ||||
|         if (Session::get('budgets.create.fromStore') !== true) { | ||||
|             Session::put('budgets.create.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('budgets.create.fromStore'); | ||||
|         Session::flash('gaEventCategory', 'budgets'); | ||||
|         Session::flash('gaEventAction', 'create'); | ||||
|         $subTitle = trans('firefly.create_new_budget'); | ||||
|  | ||||
|         return view('budgets.create', compact('subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function delete(Budget $budget) | ||||
|     { | ||||
|         $subTitle = trans('firefly.delete_budget', ['name' => $budget->name]); | ||||
|  | ||||
|         // put previous url in session | ||||
|         Session::put('budgets.delete.url', URL::previous()); | ||||
|         Session::flash('gaEventCategory', 'budgets'); | ||||
|         Session::flash('gaEventAction', 'delete'); | ||||
|  | ||||
|         return view('budgets.delete', compact('budget', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Budget                    $budget | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function destroy(Budget $budget, BudgetRepositoryInterface $repository) | ||||
|     { | ||||
|  | ||||
|         $name = $budget->name; | ||||
|         $repository->destroy($budget); | ||||
|  | ||||
|  | ||||
|         Session::flash('success', 'The  budget "' . e($name) . '" was deleted.'); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|  | ||||
|         return Redirect::to(Session::get('budgets.delete.url')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function edit(Budget $budget) | ||||
|     { | ||||
|         $subTitle = trans('firefly.edit_budget', ['name' => $budget->name]); | ||||
|  | ||||
|         // put previous url in session if not redirect from store (not "return_to_edit"). | ||||
|         if (Session::get('budgets.edit.fromUpdate') !== true) { | ||||
|             Session::put('budgets.edit.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('budgets.edit.fromUpdate'); | ||||
|         Session::flash('gaEventCategory', 'budgets'); | ||||
|         Session::flash('gaEventAction', 'edit'); | ||||
|  | ||||
|         return view('budgets.edit', compact('budget', 'subTitle')); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function index(BudgetRepositoryInterface $repository) | ||||
|     { | ||||
|         $budgets  = $repository->getActiveBudgets(); | ||||
|         $inactive = $repository->getInactiveBudgets(); | ||||
|         $spent    = '0'; | ||||
|         $budgeted = '0'; | ||||
|         bcscale(2); | ||||
|         /** | ||||
|          * Do some cleanup: | ||||
|          */ | ||||
|         $repository->cleanupBudgets(); | ||||
|  | ||||
|  | ||||
|         // loop the budgets: | ||||
|         /** @var Budget $budget */ | ||||
|         foreach ($budgets as $budget) { | ||||
|             $date               = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|             $end                = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|             $budget->spent      = $repository->spentInPeriodCorrected($budget, $date, $end); | ||||
|             $budget->currentRep = $repository->getCurrentRepetition($budget, $date); | ||||
|             if ($budget->currentRep) { | ||||
|                 $budgeted = bcadd($budgeted, $budget->currentRep->amount); | ||||
|             } | ||||
|             $spent = bcadd($spent, $budget->spent); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         $dateAsString      = Session::get('start', Carbon::now()->startOfMonth())->format('FY'); | ||||
|         $budgetIncomeTotal = Preferences::get('budgetIncomeTotal' . $dateAsString, 1000)->data; | ||||
|         $budgetMaximum     = Preferences::get('budgetMaximum', 1000)->data; | ||||
|         $defaultCurrency   = Amount::getDefaultCurrency(); | ||||
|  | ||||
|         return view( | ||||
|             'budgets.index', compact('budgetMaximum', 'budgetIncomeTotal', 'defaultCurrency', 'inactive', 'budgets', 'spent', 'budgeted') | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function noBudget(BudgetRepositoryInterface $repository) | ||||
|     { | ||||
|         $start    = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end      = Session::get('end', Carbon::now()->startOfMonth()); | ||||
|         $list     = $repository->getWithoutBudget($start, $end); | ||||
|         $subTitle = trans( | ||||
|             'firefly.without_budget_between', | ||||
|             ['start' => $start->formatLocalized($this->monthAndDayFormat), 'end' => $end->formatLocalized($this->monthAndDayFormat)] | ||||
|         ); | ||||
|  | ||||
|         return view('budgets.noBudget', compact('list', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function postUpdateIncome() | ||||
|     { | ||||
|  | ||||
|         $date = Session::get('start', Carbon::now()->startOfMonth())->format('FY'); | ||||
|         Preferences::set('budgetIncomeTotal' . $date, intval(Input::get('amount'))); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         return Redirect::route('budgets.index'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
|      * @param Budget                    $budget | ||||
|      * @param LimitRepetition           $repetition | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function show(BudgetRepositoryInterface $repository, Budget $budget, LimitRepetition $repetition = null) | ||||
|     { | ||||
|         if (!is_null($repetition->id) && $repetition->budgetLimit->budget->id != $budget->id) { | ||||
|             $message = 'Invalid selection.'; | ||||
|  | ||||
|             return view('error', compact('message')); | ||||
|         } | ||||
|  | ||||
|         $journals = $repository->getJournals($budget, $repetition); | ||||
|  | ||||
|         if (is_null($repetition->id)) { | ||||
|             $limits   = $repository->getBudgetLimits($budget); | ||||
|             $subTitle = e($budget->name); | ||||
|         } else { | ||||
|             $limits   = [$repetition->budgetLimit]; | ||||
|             $subTitle = trans('firefly.budget_in_month', ['name' => $budget->name, 'month' => $repetition->startdate->formatLocalized($this->monthFormat)]); | ||||
|         } | ||||
|  | ||||
|         $journals->setPath('/budgets/show/' . $budget->id); | ||||
|  | ||||
|         return view('budgets.show', compact('limits', 'budget', 'repetition', 'journals', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BudgetFormRequest         $request | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function store(BudgetFormRequest $request, BudgetRepositoryInterface $repository) | ||||
|     { | ||||
|         $budgetData = [ | ||||
|             'name' => $request->input('name'), | ||||
|             'user' => Auth::user()->id, | ||||
|         ]; | ||||
|         $budget     = $repository->store($budgetData); | ||||
|  | ||||
|         Session::flash('success', 'New budget "' . $budget->name . '" stored!'); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         if (intval(Input::get('create_another')) === 1) { | ||||
|             // set value so create routine will not overwrite URL: | ||||
|             Session::put('budgets.create.fromStore', true); | ||||
|  | ||||
|             return Redirect::route('budgets.create')->withInput(); | ||||
|         } | ||||
|  | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('budgets.create.url')); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BudgetFormRequest         $request | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
|      * @param Budget                    $budget | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function update(BudgetFormRequest $request, BudgetRepositoryInterface $repository, Budget $budget) | ||||
|     { | ||||
|         $budgetData = [ | ||||
|             'name'   => $request->input('name'), | ||||
|             'active' => intval($request->input('active')) == 1 | ||||
|         ]; | ||||
|  | ||||
|         $repository->update($budget, $budgetData); | ||||
|  | ||||
|         Session::flash('success', 'Budget "' . $budget->name . '" updated.'); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         if (intval(Input::get('return_to_edit')) === 1) { | ||||
|             // set value so edit routine will not overwrite URL: | ||||
|             Session::put('budgets.edit.fromUpdate', true); | ||||
|  | ||||
|             return Redirect::route('budgets.edit', [$budget->id])->withInput(['return_to_edit' => 1]); | ||||
|         } | ||||
|  | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('budgets.edit.url')); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function updateIncome() | ||||
|     { | ||||
|         $date   = Session::get('start', Carbon::now()->startOfMonth())->format('FY'); | ||||
|         $amount = Preferences::get('budgetIncomeTotal' . $date, 1000); | ||||
|  | ||||
|         return view('budgets.income', compact('amount')); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										217
									
								
								app/Http/Controllers/CategoryController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								app/Http/Controllers/CategoryController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,217 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Http\Requests\CategoryFormRequest; | ||||
| use FireflyIII\Models\Category; | ||||
| use FireflyIII\Repositories\Category\CategoryRepositoryInterface; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use Input; | ||||
| use Preferences; | ||||
| use Redirect; | ||||
| use Session; | ||||
| use URL; | ||||
| use View; | ||||
|  | ||||
| /** | ||||
|  * Class CategoryController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers | ||||
|  */ | ||||
| class CategoryController extends Controller | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         View::share('title', trans('firefly.categories')); | ||||
|         View::share('mainTitleIcon', 'fa-bar-chart'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function create() | ||||
|     { | ||||
|         // put previous url in session if not redirect from store (not "create another"). | ||||
|         if (Session::get('categories.create.fromStore') !== true) { | ||||
|             Session::put('categories.create.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('categories.create.fromStore'); | ||||
|         Session::flash('gaEventCategory', 'categories'); | ||||
|         Session::flash('gaEventAction', 'create'); | ||||
|         $subTitle = trans('firefly.create_new_category'); | ||||
|  | ||||
|         return view('categories.create', compact('subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Category $category | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function delete(Category $category) | ||||
|     { | ||||
|         $subTitle = trans('firefly.delete_category', ['name' => $category->name]); | ||||
|  | ||||
|         // put previous url in session | ||||
|         Session::put('categories.delete.url', URL::previous()); | ||||
|         Session::flash('gaEventCategory', 'categories'); | ||||
|         Session::flash('gaEventAction', 'delete'); | ||||
|  | ||||
|         return view('categories.delete', compact('category', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param CategoryRepositoryInterface $repository | ||||
|      * @param Category                    $category | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function destroy(CategoryRepositoryInterface $repository, Category $category) | ||||
|     { | ||||
|  | ||||
|         $name = $category->name; | ||||
|         $repository->destroy($category); | ||||
|  | ||||
|         Session::flash('success', 'The  category "' . e($name) . '" was deleted.'); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         return Redirect::to(Session::get('categories.delete.url')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Category $category | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function edit(Category $category) | ||||
|     { | ||||
|         $subTitle = trans('firefly.edit_category', ['name' => $category->name]); | ||||
|  | ||||
|         // put previous url in session if not redirect from store (not "return_to_edit"). | ||||
|         if (Session::get('categories.edit.fromUpdate') !== true) { | ||||
|             Session::put('categories.edit.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('categories.edit.fromUpdate'); | ||||
|         Session::flash('gaEventCategory', 'categories'); | ||||
|         Session::flash('gaEventAction', 'edit'); | ||||
|  | ||||
|         return view('categories.edit', compact('category', 'subTitle')); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param CategoryRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function index(CategoryRepositoryInterface $repository) | ||||
|     { | ||||
|         $categories = $repository->getCategories(); | ||||
|  | ||||
|         $categories->each( | ||||
|             function (Category $category) use ($repository) { | ||||
|                 $category->lastActivity = $repository->getLatestActivity($category); | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         return view('categories.index', compact('categories')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param CategoryRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function noCategory(CategoryRepositoryInterface $repository) | ||||
|     { | ||||
|         $start    = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end      = Session::get('end', Carbon::now()->startOfMonth()); | ||||
|         $list     = $repository->getWithoutCategory($start, $end); | ||||
|         $subTitle = trans( | ||||
|             'firefly.without_category_between', | ||||
|             ['start' => $start->formatLocalized($this->monthAndDayFormat), 'end' => $end->formatLocalized($this->monthAndDayFormat)] | ||||
|         ); | ||||
|  | ||||
|         return view('categories.noCategory', compact('list', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param CategoryRepositoryInterface $repository | ||||
|      * @param Category                    $category | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function show(CategoryRepositoryInterface $repository, Category $category) | ||||
|     { | ||||
|         $hideCategory = true; // used in list. | ||||
|         $page         = intval(Input::get('page')); | ||||
|         $set          = $repository->getJournals($category, $page); | ||||
|         $count        = $repository->countJournals($category); | ||||
|         $journals     = new LengthAwarePaginator($set, $count, 50, $page); | ||||
|         $journals->setPath('categories/show/' . $category->id); | ||||
|  | ||||
|         return view('categories.show', compact('category', 'journals', 'hideCategory')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param CategoryFormRequest         $request | ||||
|      * @param CategoryRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function store(CategoryFormRequest $request, CategoryRepositoryInterface $repository) | ||||
|     { | ||||
|         $categoryData = [ | ||||
|             'name' => $request->input('name'), | ||||
|             'user' => Auth::user()->id, | ||||
|         ]; | ||||
|         $category     = $repository->store($categoryData); | ||||
|  | ||||
|         Session::flash('success', 'New category "' . $category->name . '" stored!'); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         if (intval(Input::get('create_another')) === 1) { | ||||
|             Session::put('categories.create.fromStore', true); | ||||
|  | ||||
|             return Redirect::route('categories.create')->withInput(); | ||||
|         } | ||||
|  | ||||
|         return Redirect::route('categories.index'); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @param CategoryFormRequest         $request | ||||
|      * @param CategoryRepositoryInterface $repository | ||||
|      * @param Category                    $category | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function update(CategoryFormRequest $request, CategoryRepositoryInterface $repository, Category $category) | ||||
|     { | ||||
|         $categoryData = [ | ||||
|             'name' => $request->input('name'), | ||||
|         ]; | ||||
|  | ||||
|         $repository->update($category, $categoryData); | ||||
|  | ||||
|         Session::flash('success', 'Category "' . $category->name . '" updated.'); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         if (intval(Input::get('return_to_edit')) === 1) { | ||||
|             Session::put('categories.edit.fromUpdate', true); | ||||
|  | ||||
|             return Redirect::route('categories.edit', [$category->id]); | ||||
|         } | ||||
|  | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('categories.edit.url')); | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										197
									
								
								app/Http/Controllers/Chart/AccountController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								app/Http/Controllers/Chart/AccountController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,197 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Http\Controllers\Chart; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Http\Controllers\Controller; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Support\CacheProperties; | ||||
| use Grumpydictator\Gchart\GChart; | ||||
| use Illuminate\Support\Collection; | ||||
| use Preferences; | ||||
| use Response; | ||||
| use Session; | ||||
| use Steam; | ||||
|  | ||||
| /** | ||||
|  * Class AccountController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers\Chart | ||||
|  */ | ||||
| class AccountController extends Controller | ||||
| { | ||||
|     /** | ||||
|      * Shows the balances for all the user's accounts. | ||||
|      * | ||||
|      * @param GChart                     $chart | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * | ||||
|      * @param                            $year | ||||
|      * @param                            $month | ||||
|      * @param bool                       $shared | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function all(GChart $chart, AccountRepositoryInterface $repository, $year, $month, $shared = false) | ||||
|     { | ||||
|         $start = new Carbon($year . '-' . $month . '-01'); | ||||
|         $end   = clone $start; | ||||
|         $end->endOfMonth(); | ||||
|  | ||||
|         // chart properties for cache: | ||||
|         $cache = new CacheProperties(); | ||||
|         $cache->addProperty($start); | ||||
|         $cache->addProperty($end); | ||||
|         $cache->addProperty('all'); | ||||
|         $cache->addProperty('accounts'); | ||||
|         if ($cache->has()) { | ||||
|             return Response::json($cache->get()); // @codeCoverageIgnore | ||||
|         } | ||||
|  | ||||
|  | ||||
|         $chart->addColumn(trans('firefly.dayOfMonth'), 'date'); | ||||
|  | ||||
|         /** @var Collection $accounts */ | ||||
|         $accounts = $repository->getAccounts(['Default account', 'Asset account']); | ||||
|         if ($shared === false) { | ||||
|             /** @var Account $account */ | ||||
|             foreach ($accounts as $index => $account) { | ||||
|                 if ($account->getMeta('accountRole') == 'sharedAsset') { | ||||
|                     $accounts->forget($index); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // | ||||
|  | ||||
|         $index = 1; | ||||
|         /** @var Account $account */ | ||||
|         foreach ($accounts as $account) { | ||||
|             $chart->addColumn(trans('firefly.balanceFor', ['name' => $account->name]), 'number'); | ||||
|             $chart->addCertainty($index); | ||||
|             $index++; | ||||
|         } | ||||
|         $current = clone $start; | ||||
|         $current->subDay(); | ||||
|         $today = Carbon::now(); | ||||
|         while ($end >= $current) { | ||||
|             $row     = [clone $current]; | ||||
|             $certain = $current < $today; | ||||
|             foreach ($accounts as $account) { | ||||
|                 $row[] = Steam::balance($account, $current); | ||||
|                 $row[] = $certain; | ||||
|             } | ||||
|             $chart->addRowArray($row); | ||||
|             $current->addDay(); | ||||
|         } | ||||
|         $chart->generate(); | ||||
|  | ||||
|         $data = $chart->getData(); | ||||
|         $cache->store($data); | ||||
|  | ||||
|         return Response::json($data); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Shows the balances for all the user's frontpage accounts. | ||||
|      * | ||||
|      * @param GChart                     $chart | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function frontpage(GChart $chart, AccountRepositoryInterface $repository) | ||||
|     { | ||||
|         $chart->addColumn(trans('firefly.dayOfMonth'), 'date'); | ||||
|  | ||||
|         $frontPage = Preferences::get('frontPageAccounts', []); | ||||
|         $start     = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end       = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|         $accounts  = $repository->getFrontpageAccounts($frontPage); | ||||
|  | ||||
|         // chart properties for cache: | ||||
|         $cache = new CacheProperties(); | ||||
|         $cache->addProperty($start); | ||||
|         $cache->addProperty($end); | ||||
|         $cache->addProperty('frontpage'); | ||||
|         $cache->addProperty('accounts'); | ||||
|         if ($cache->has()) { | ||||
|             return Response::json($cache->get()); // @codeCoverageIgnore | ||||
|         } | ||||
|  | ||||
|  | ||||
|         $index = 1; | ||||
|         /** @var Account $account */ | ||||
|         foreach ($accounts as $account) { | ||||
|             $chart->addColumn(trans('firefly.balanceFor', ['name' => $account->name]), 'number'); | ||||
|             $chart->addCertainty($index); | ||||
|             $index++; | ||||
|         } | ||||
|         $current = clone $start; | ||||
|         $current->subDay(); | ||||
|         $today = Carbon::now(); | ||||
|         while ($end >= $current) { | ||||
|             $row     = [clone $current]; | ||||
|             $certain = $current < $today; | ||||
|             foreach ($accounts as $account) { | ||||
|                 $row[] = Steam::balance($account, $current); | ||||
|                 $row[] = $certain; | ||||
|             } | ||||
|             $chart->addRowArray($row); | ||||
|             $current->addDay(); | ||||
|         } | ||||
|         $chart->generate(); | ||||
|  | ||||
|         $data = $chart->getData(); | ||||
|         $cache->store($data); | ||||
|  | ||||
|         return Response::json($data); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Shows an account's balance for a single month. | ||||
|      * | ||||
|      * @param GChart  $chart | ||||
|      * @param Account $account | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function single(GChart $chart, Account $account) | ||||
|     { | ||||
|         $chart->addColumn(trans('firefly.dayOfMonth'), 'date'); | ||||
|         $chart->addColumn(trans('firefly.balanceFor', ['name' => $account->name]), 'number'); | ||||
|         $chart->addCertainty(1); | ||||
|  | ||||
|         $start   = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end     = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|         $current = clone $start; | ||||
|         $today   = new Carbon; | ||||
|  | ||||
|         // chart properties for cache: | ||||
|         $cache = new CacheProperties(); | ||||
|         $cache->addProperty($start); | ||||
|         $cache->addProperty($end); | ||||
|         $cache->addProperty('frontpage'); | ||||
|         $cache->addProperty('single'); | ||||
|         $cache->addProperty($account->id); | ||||
|         if ($cache->has()) { | ||||
|             return Response::json($cache->get()); // @codeCoverageIgnore | ||||
|         } | ||||
|  | ||||
|         while ($end >= $current) { | ||||
|             $certain = $current < $today; | ||||
|             $chart->addRow(clone $current, Steam::balance($account, $current), $certain); | ||||
|             $current->addDay(); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         $chart->generate(); | ||||
|  | ||||
|         $data = $chart->getData(); | ||||
|         $cache->store($data); | ||||
|  | ||||
|         return Response::json($data); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										167
									
								
								app/Http/Controllers/Chart/BillController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								app/Http/Controllers/Chart/BillController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,167 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Http\Controllers\Chart; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Http\Controllers\Controller; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Repositories\Bill\BillRepositoryInterface; | ||||
| use FireflyIII\Support\CacheProperties; | ||||
| use Grumpydictator\Gchart\GChart; | ||||
| use Illuminate\Support\Collection; | ||||
| use Response; | ||||
| use Session; | ||||
| use Steam; | ||||
|  | ||||
| /** | ||||
|  * Class BillController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers\Chart | ||||
|  */ | ||||
| class BillController extends Controller | ||||
| { | ||||
|     /** | ||||
|      * Shows the overview for a bill. The min/max amount and matched journals. | ||||
|      * | ||||
|      * @param GChart                  $chart | ||||
|      * @param BillRepositoryInterface $repository | ||||
|      * @param Bill                    $bill | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function single(GChart $chart, BillRepositoryInterface $repository, Bill $bill) | ||||
|     { | ||||
|  | ||||
|         $chart->addColumn(trans('firefly.date'), 'date'); | ||||
|         $chart->addColumn(trans('firefly.maxAmount'), 'number'); | ||||
|         $chart->addColumn(trans('firefly.minAmount'), 'number'); | ||||
|         $chart->addColumn(trans('firefly.billEntry'), 'number'); | ||||
|  | ||||
|         $cache = new CacheProperties; | ||||
|         $cache->addProperty('single'); | ||||
|         $cache->addProperty('bill'); | ||||
|         $cache->addProperty($bill->id); | ||||
|         if ($cache->has()) { | ||||
|             return Response::json($cache->get()); // @codeCoverageIgnore | ||||
|         } | ||||
|  | ||||
|         // get first transaction or today for start: | ||||
|         $results = $repository->getJournals($bill); | ||||
|         /** @var TransactionJournal $result */ | ||||
|         foreach ($results as $result) { | ||||
|             $chart->addRow(clone $result->date, floatval($bill->amount_max), floatval($bill->amount_min), floatval($result->amount)); | ||||
|         } | ||||
|  | ||||
|         $chart->generate(); | ||||
|  | ||||
|         $data = $chart->getData(); | ||||
|         $cache->store($data); | ||||
|  | ||||
|         return Response::json($data); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Shows all bills and whether or not theyve been paid this month (pie chart). | ||||
|      * | ||||
|      * @param GChart                     $chart | ||||
|      * | ||||
|      * @param BillRepositoryInterface    $repository | ||||
|      * @param AccountRepositoryInterface $accounts | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function frontpage(GChart $chart, BillRepositoryInterface $repository, AccountRepositoryInterface $accounts) | ||||
|     { | ||||
|         $chart->addColumn(trans('firefly.name'), 'string'); | ||||
|         $chart->addColumn(trans('firefly.amount'), 'number'); | ||||
|  | ||||
|         $start = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end   = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|  | ||||
|  | ||||
|         // chart properties for cache: | ||||
|         $cache = new CacheProperties(); | ||||
|         $cache->addProperty($start); | ||||
|         $cache->addProperty($end); | ||||
|         $cache->addProperty('bills'); | ||||
|         $cache->addProperty('frontpage'); | ||||
|         if ($cache->has()) { | ||||
|             return Response::json($cache->get()); // @codeCoverageIgnore | ||||
|         } | ||||
|  | ||||
|         $bills  = $repository->getActiveBills(); | ||||
|         $paid   = new Collection; // journals. | ||||
|         $unpaid = new Collection; // bills | ||||
|         // loop paid and create single entry: | ||||
|         $paidDescriptions   = []; | ||||
|         $paidAmount         = 0; | ||||
|         $unpaidDescriptions = []; | ||||
|         $unpaidAmount       = 0; | ||||
|  | ||||
|         /** @var Bill $bill */ | ||||
|         foreach ($bills as $bill) { | ||||
|             $ranges = $repository->getRanges($bill, $start, $end); | ||||
|  | ||||
|             foreach ($ranges as $range) { | ||||
|                 // paid a bill in this range? | ||||
|                 $journals = $repository->getJournalsInRange($bill, $range['start'], $range['end']); | ||||
|                 if ($journals->count() == 0) { | ||||
|                     $unpaid->push([$bill, $range['start']]); | ||||
|                 } else { | ||||
|                     $paid = $paid->merge($journals); | ||||
|                 } | ||||
|  | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $creditCards = $accounts->getCreditCards(); | ||||
|         foreach ($creditCards as $creditCard) { | ||||
|             $balance = Steam::balance($creditCard, $end, true); | ||||
|             $date    = new Carbon($creditCard->getMeta('ccMonthlyPaymentDate')); | ||||
|             if ($balance < 0) { | ||||
|                 // unpaid! create a fake bill that matches the amount. | ||||
|                 $description = $creditCard->name; | ||||
|                 $amount      = $balance * -1; | ||||
|                 $fakeBill    = $repository->createFakeBill($description, $date, $amount); | ||||
|                 unset($description, $amount); | ||||
|                 $unpaid->push([$fakeBill, $date]); | ||||
|             } | ||||
|             if ($balance == 0) { | ||||
|                 // find transfer(s) TO the credit card which should account for | ||||
|                 // anything paid. If not, the CC is not yet used. | ||||
|                 $journals = $accounts->getTransfersInRange($creditCard, $start, $end); | ||||
|                 $paid     = $paid->merge($journals); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|         /** @var TransactionJournal $entry */ | ||||
|         foreach ($paid as $entry) { | ||||
|  | ||||
|             $paidDescriptions[] = $entry->description; | ||||
|             $paidAmount += floatval($entry->amount); | ||||
|         } | ||||
|  | ||||
|         // loop unpaid: | ||||
|         /** @var Bill $entry */ | ||||
|         foreach ($unpaid as $entry) { | ||||
|             $description          = $entry[0]->name . ' (' . $entry[1]->format('jS M Y') . ')'; | ||||
|             $amount               = ($entry[0]->amount_max + $entry[0]->amount_min) / 2; | ||||
|             $unpaidDescriptions[] = $description; | ||||
|             $unpaidAmount += $amount; | ||||
|             unset($amount, $description); | ||||
|         } | ||||
|  | ||||
|         $chart->addRow(trans('firefly.unpaid') . ': ' . join(', ', $unpaidDescriptions), $unpaidAmount); | ||||
|         $chart->addRow(trans('firefly.paid') . ': ' . join(', ', $paidDescriptions), $paidAmount); | ||||
|  | ||||
|         $chart->generate(); | ||||
|  | ||||
|         $data = $chart->getData(); | ||||
|         $cache->store($data); | ||||
|  | ||||
|         return Response::json($data); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										263
									
								
								app/Http/Controllers/Chart/BudgetController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										263
									
								
								app/Http/Controllers/Chart/BudgetController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,263 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Http\Controllers\Chart; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Http\Controllers\Controller; | ||||
| use FireflyIII\Models\Budget; | ||||
| use FireflyIII\Models\LimitRepetition; | ||||
| use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; | ||||
| use FireflyIII\Support\CacheProperties; | ||||
| use Grumpydictator\Gchart\GChart; | ||||
| use Illuminate\Support\Collection; | ||||
| use Navigation; | ||||
| use Preferences; | ||||
| use Response; | ||||
| use Session; | ||||
|  | ||||
| /** | ||||
|  * Class BudgetController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers\Chart | ||||
|  */ | ||||
| class BudgetController extends Controller | ||||
| { | ||||
|     /** | ||||
|      * @param GChart                    $chart | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
|      * @param Budget                    $budget | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function budget(GChart $chart, BudgetRepositoryInterface $repository, Budget $budget) | ||||
|     { | ||||
|         $chart->addColumn(trans('firefly.period'), 'date'); | ||||
|         $chart->addColumn(trans('firefly.spent'), 'number'); | ||||
|  | ||||
|  | ||||
|         $first = $repository->getFirstBudgetLimitDate($budget); | ||||
|         $range = Preferences::get('viewRange', '1M')->data; | ||||
|         $last  = Session::get('end', new Carbon); | ||||
|         $final = clone $last; | ||||
|         $final->addYears(2); | ||||
|         $last = Navigation::endOfX($last, $range, $final); | ||||
|  | ||||
|         // chart properties for cache: | ||||
|         $cache = new CacheProperties(); | ||||
|         $cache->addProperty($first); | ||||
|         $cache->addProperty($last); | ||||
|         $cache->addProperty('budget'); | ||||
|         $cache->addProperty('budget'); | ||||
|         if ($cache->has()) { | ||||
|             return Response::json($cache->get()); // @codeCoverageIgnore | ||||
|         } | ||||
|  | ||||
|  | ||||
|         while ($first < $last) { | ||||
|             $end = Navigation::addPeriod($first, $range, 0); | ||||
|             $end->subDay(); | ||||
|  | ||||
|             // start date for chart. | ||||
|             $chartDate = clone $end; | ||||
|             $chartDate->startOfMonth(); | ||||
|  | ||||
|             $spent = $repository->spentInPeriodCorrected($budget, $first, $end); | ||||
|             $chart->addRow($chartDate, $spent); | ||||
|  | ||||
|             $first = Navigation::addPeriod($first, $range, 0); | ||||
|  | ||||
|  | ||||
|         } | ||||
|  | ||||
|         $chart->generate(); | ||||
|  | ||||
|         $data = $chart->getData(); | ||||
|  | ||||
|  | ||||
|         $cache->store($data); | ||||
|  | ||||
|         return Response::json($data); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Shows the amount left in a specific budget limit. | ||||
|      * | ||||
|      * @param GChart                    $chart | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
|      * @param Budget                    $budget | ||||
|      * @param LimitRepetition           $repetition | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function budgetLimit(GChart $chart, BudgetRepositoryInterface $repository, Budget $budget, LimitRepetition $repetition) | ||||
|     { | ||||
|         $start = clone $repetition->startdate; | ||||
|         $end   = $repetition->enddate; | ||||
|  | ||||
|         // chart properties for cache: | ||||
|         $cache = new CacheProperties(); | ||||
|         $cache->addProperty($start); | ||||
|         $cache->addProperty($end); | ||||
|         $cache->addProperty('budget'); | ||||
|         $cache->addProperty('limit'); | ||||
|         $cache->addProperty($budget->id); | ||||
|         $cache->addProperty($repetition->id); | ||||
|         if ($cache->has()) { | ||||
|             return Response::json($cache->get()); // @codeCoverageIgnore | ||||
|         } | ||||
|  | ||||
|         $chart->addColumn(trans('firefly.day'), 'date'); | ||||
|         $chart->addColumn(trans('firefly.left'), 'number'); | ||||
|  | ||||
|  | ||||
|         $amount = $repetition->amount; | ||||
|  | ||||
|         while ($start <= $end) { | ||||
|             /* | ||||
|              * Sum of expenses on this day: | ||||
|              */ | ||||
|             $sum = $repository->expensesOnDayCorrected($budget, $start); | ||||
|             $amount += $sum; | ||||
|             $chart->addRow(clone $start, $amount); | ||||
|             $start->addDay(); | ||||
|         } | ||||
|         $chart->generate(); | ||||
|  | ||||
|         $data = $chart->getData(); | ||||
|         $cache->store($data); | ||||
|  | ||||
|         return Response::json($data); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Shows a budget list with spent/left/overspent. | ||||
|      * | ||||
|      * @param GChart                    $chart | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function frontpage(GChart $chart, BudgetRepositoryInterface $repository) | ||||
|     { | ||||
|         $chart->addColumn(trans('firefly.budget'), 'string'); | ||||
|         $chart->addColumn(trans('firefly.left'), 'number'); | ||||
|         $chart->addColumn(trans('firefly.spent'), 'number'); | ||||
|         $chart->addColumn(trans('firefly.overspent'), 'number'); | ||||
|  | ||||
|         $budgets    = $repository->getBudgets(); | ||||
|         $start      = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end        = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|         $allEntries = new Collection; | ||||
|  | ||||
|         // chart properties for cache: | ||||
|         $cache = new CacheProperties(); | ||||
|         $cache->addProperty($start); | ||||
|         $cache->addProperty($end); | ||||
|         $cache->addProperty('budget'); | ||||
|         $cache->addProperty('all'); | ||||
|         if ($cache->has()) { | ||||
|             return Response::json($cache->get()); // @codeCoverageIgnore | ||||
|         } | ||||
|  | ||||
|  | ||||
|         /** @var Budget $budget */ | ||||
|         foreach ($budgets as $budget) { | ||||
|             $repetitions = $repository->getBudgetLimitRepetitions($budget, $start, $end); | ||||
|             if ($repetitions->count() == 0) { | ||||
|                 $expenses = $repository->spentInPeriodCorrected($budget, $start, $end, true); | ||||
|                 $allEntries->push([$budget->name, 0, 0, $expenses]); | ||||
|                 continue; | ||||
|             } | ||||
|             /** @var LimitRepetition $repetition */ | ||||
|             foreach ($repetitions as $repetition) { | ||||
|                 $expenses  = $repository->spentInPeriodCorrected($budget, $repetition->startdate, $repetition->enddate, true); | ||||
|                 $left      = $expenses < floatval($repetition->amount) ? floatval($repetition->amount) - $expenses : 0; | ||||
|                 $spent     = $expenses > floatval($repetition->amount) ? floatval($repetition->amount) : $expenses; | ||||
|                 $overspent = $expenses > floatval($repetition->amount) ? $expenses - floatval($repetition->amount) : 0; | ||||
|                 $allEntries->push( | ||||
|                     [$budget->name . ' (' . $repetition->startdate->formatLocalized($this->monthAndDayFormat) . ')', | ||||
|                      $left, | ||||
|                      $spent, | ||||
|                      $overspent | ||||
|                     ] | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $noBudgetExpenses = $repository->getWithoutBudgetSum($start, $end) * -1; | ||||
|         $allEntries->push([trans('firefly.noBudget'), 0, 0, $noBudgetExpenses]); | ||||
|  | ||||
|         foreach ($allEntries as $entry) { | ||||
|             if ($entry[1] != 0 || $entry[2] != 0 || $entry[3] != 0) { | ||||
|                 $chart->addRow($entry[0], $entry[1], $entry[2], $entry[3]); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $chart->generate(); | ||||
|  | ||||
|         $data = $chart->getData(); | ||||
|         $cache->store($data); | ||||
|  | ||||
|         return Response::json($data); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show a yearly overview for a budget. | ||||
|      * | ||||
|      * @param GChart                    $chart | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
|      * @param                           $year | ||||
|      * @param bool                      $shared | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function year(GChart $chart, BudgetRepositoryInterface $repository, $year, $shared = false) | ||||
|     { | ||||
|         $start   = new Carbon($year . '-01-01'); | ||||
|         $end     = new Carbon($year . '-12-31'); | ||||
|         $shared  = $shared == 'shared' ? true : false; | ||||
|         $budgets = $repository->getBudgets(); | ||||
|  | ||||
|         // chart properties for cache: | ||||
|         $cache = new CacheProperties(); | ||||
|         $cache->addProperty($start); | ||||
|         $cache->addProperty($end); | ||||
|         $cache->addProperty('budget'); | ||||
|         $cache->addProperty('year'); | ||||
|         if ($cache->has()) { | ||||
|             return Response::json($cache->get()); // @codeCoverageIgnore | ||||
|         } | ||||
|  | ||||
|         // add columns: | ||||
|         $chart->addColumn(trans('firefly.month'), 'date'); | ||||
|         foreach ($budgets as $budget) { | ||||
|             $chart->addColumn($budget->name, 'number'); | ||||
|         } | ||||
|  | ||||
|         while ($start < $end) { | ||||
|             // month is the current end of the period: | ||||
|             $month = clone $start; | ||||
|             $month->endOfMonth(); | ||||
|             // make a row: | ||||
|             $row = [clone $start]; | ||||
|  | ||||
|             // each budget, fill the row: | ||||
|             foreach ($budgets as $budget) { | ||||
|                 $spent = $repository->spentInPeriodCorrected($budget, $start, $month, $shared); | ||||
|                 $row[] = $spent; | ||||
|             } | ||||
|             $chart->addRowArray($row); | ||||
|  | ||||
|             $start->endOfMonth()->addDay(); | ||||
|         } | ||||
|  | ||||
|         $chart->generate(); | ||||
|  | ||||
|         $data = $chart->getData(); | ||||
|         $cache->store($data); | ||||
|  | ||||
|         return Response::json($data); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										193
									
								
								app/Http/Controllers/Chart/CategoryController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								app/Http/Controllers/Chart/CategoryController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,193 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Http\Controllers\Chart; | ||||
|  | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Http\Controllers\Controller; | ||||
| use FireflyIII\Models\Category; | ||||
| use FireflyIII\Repositories\Category\CategoryRepositoryInterface; | ||||
| use FireflyIII\Support\CacheProperties; | ||||
| use Grumpydictator\Gchart\GChart; | ||||
| use Navigation; | ||||
| use Preferences; | ||||
| use Response; | ||||
| use Session; | ||||
|  | ||||
| /** | ||||
|  * Class CategoryController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers\Chart | ||||
|  */ | ||||
| class CategoryController extends Controller | ||||
| { | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Show an overview for a category for all time, per month/week/year. | ||||
|      * | ||||
|      * @param GChart                      $chart | ||||
|      * @param CategoryRepositoryInterface $repository | ||||
|      * @param Category                    $category | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function all(GChart $chart, CategoryRepositoryInterface $repository, Category $category) | ||||
|     { | ||||
|         // oldest transaction in category: | ||||
|         $start = $repository->getFirstActivityDate($category); | ||||
|         $range = Preferences::get('viewRange', '1M')->data; | ||||
|         // jump to start of week / month / year / etc | ||||
|         $start = Navigation::startOfPeriod($start, $range); | ||||
|  | ||||
|         $chart->addColumn(trans('firefly.period'), 'date'); | ||||
|         $chart->addColumn(trans('firefly.spent'), 'number'); | ||||
|  | ||||
|  | ||||
|         $end = new Carbon; | ||||
|         while ($start <= $end) { | ||||
|  | ||||
|             $currentEnd = Navigation::endOfPeriod($start, $range); | ||||
|             $spent      = $repository->spentInPeriodCorrected($category, $start, $currentEnd); | ||||
|             $chart->addRow(clone $start, $spent); | ||||
|  | ||||
|             $start = Navigation::addPeriod($start, $range, 0); | ||||
|         } | ||||
|  | ||||
|         $chart->generate(); | ||||
|  | ||||
|         return Response::json($chart->getData()); | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show this month's category overview. | ||||
|      * | ||||
|      * @param GChart                      $chart | ||||
|      * @param CategoryRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function frontpage(GChart $chart, CategoryRepositoryInterface $repository) | ||||
|     { | ||||
|         $chart->addColumn(trans('firefly.category'), 'string'); | ||||
|         $chart->addColumn(trans('firefly.spent'), 'number'); | ||||
|  | ||||
|         $start = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end   = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|  | ||||
|         // chart properties for cache: | ||||
|         $cache = new CacheProperties; | ||||
|         $cache->addProperty($start); | ||||
|         $cache->addProperty($end); | ||||
|         $cache->addProperty('category'); | ||||
|         $cache->addProperty('frontpage'); | ||||
|         if ($cache->has()) { | ||||
|             return Response::json($cache->get()); // @codeCoverageIgnore | ||||
|         } | ||||
|  | ||||
|         $set = $repository->getCategoriesAndExpensesCorrected($start, $end); | ||||
|  | ||||
|         // sort by callback: | ||||
|         uasort( | ||||
|             $set, | ||||
|             function ($left, $right) { | ||||
|                 if ($left['sum'] == $right['sum']) { | ||||
|                     return 0; | ||||
|                 } | ||||
|  | ||||
|                 return ($left['sum'] < $right['sum']) ? 1 : -1; | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|  | ||||
|         foreach ($set as $entry) { | ||||
|             $sum = floatval($entry['sum']); | ||||
|             if ($sum != 0) { | ||||
|                 $chart->addRow($entry['name'], $sum); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $chart->generate(); | ||||
|  | ||||
|         $data = $chart->getData(); | ||||
|         $cache->store($data); | ||||
|  | ||||
|         return Response::json($data); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param GChart                      $chart | ||||
|      * @param CategoryRepositoryInterface $repository | ||||
|      * @param Category                    $category | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function month(GChart $chart, CategoryRepositoryInterface $repository, Category $category) | ||||
|     { | ||||
|         $start = clone Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end   = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|  | ||||
|         $chart->addColumn(trans('firefly.period'), 'date'); | ||||
|         $chart->addColumn(trans('firefly.spent'), 'number'); | ||||
|  | ||||
|         while ($start <= $end) { | ||||
|             $spent = $repository->spentOnDaySumCorrected($category, $start); | ||||
|             $chart->addRow(clone $start, $spent); | ||||
|             $start->addDay(); | ||||
|         } | ||||
|  | ||||
|         $chart->generate(); | ||||
|  | ||||
|         return Response::json($chart->getData()); | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * This chart will only show expenses. | ||||
|      * | ||||
|      * @param GChart                      $chart | ||||
|      * @param CategoryRepositoryInterface $repository | ||||
|      * @param                             $year | ||||
|      * @param bool                        $shared | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function year(GChart $chart, CategoryRepositoryInterface $repository, $year, $shared = false) | ||||
|     { | ||||
|         $start      = new Carbon($year . '-01-01'); | ||||
|         $end        = new Carbon($year . '-12-31'); | ||||
|         $shared     = $shared == 'shared' ? true : false; | ||||
|         $categories = $repository->getCategories(); | ||||
|  | ||||
|         // add columns: | ||||
|         $chart->addColumn(trans('firefly.month'), 'date'); | ||||
|         foreach ($categories as $category) { | ||||
|             $chart->addColumn($category->name, 'number'); | ||||
|         } | ||||
|  | ||||
|         while ($start < $end) { | ||||
|             // month is the current end of the period: | ||||
|             $month = clone $start; | ||||
|             $month->endOfMonth(); | ||||
|             // make a row: | ||||
|             $row = [clone $start]; | ||||
|  | ||||
|             // each budget, fill the row: | ||||
|             foreach ($categories as $category) { | ||||
|                 $spent = $repository->spentInPeriodCorrected($category, $start, $month, $shared); | ||||
|                 $row[] = $spent; | ||||
|             } | ||||
|             $chart->addRowArray($row); | ||||
|  | ||||
|             $start->addMonth(); | ||||
|         } | ||||
|  | ||||
|         $chart->generate(); | ||||
|  | ||||
|         return Response::json($chart->getData()); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										49
									
								
								app/Http/Controllers/Chart/PiggyBankController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								app/Http/Controllers/Chart/PiggyBankController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Http\Controllers\Chart; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Http\Controllers\Controller; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; | ||||
| use Grumpydictator\Gchart\GChart; | ||||
| use Illuminate\Support\Collection; | ||||
| use Response; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Class PiggyBankController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers\Chart | ||||
|  */ | ||||
| class PiggyBankController extends Controller | ||||
| { | ||||
|     /** | ||||
|      * Shows the piggy bank history. | ||||
|      * | ||||
|      * @param GChart                       $chart | ||||
|      * @param PiggyBankRepositoryInterface $repository | ||||
|      * @param PiggyBank                    $piggyBank | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function history(GChart $chart, PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank) | ||||
|     { | ||||
|         $chart->addColumn(trans('firefly.date'), 'date'); | ||||
|         $chart->addColumn(trans('firefly.balance'), 'number'); | ||||
|  | ||||
|         /** @var Collection $set */ | ||||
|         $set = $repository->getEventSummarySet($piggyBank); | ||||
|         $sum = 0; | ||||
|  | ||||
|         foreach ($set as $entry) { | ||||
|             $sum += floatval($entry->sum); | ||||
|             $chart->addRow(new Carbon($entry->date), $sum); | ||||
|         } | ||||
|  | ||||
|         $chart->generate(); | ||||
|  | ||||
|         return Response::json($chart->getData()); | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										101
									
								
								app/Http/Controllers/Chart/ReportController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								app/Http/Controllers/Chart/ReportController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Http\Controllers\Chart; | ||||
|  | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Helpers\Report\ReportQueryInterface; | ||||
| use FireflyIII\Http\Controllers\Controller; | ||||
| use Grumpydictator\Gchart\GChart; | ||||
| use Response; | ||||
|  | ||||
| /** | ||||
|  * Class ReportController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers\Chart | ||||
|  */ | ||||
| class ReportController extends Controller | ||||
| { | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Summarizes all income and expenses, per month, for a given year. | ||||
|      * | ||||
|      * @param GChart               $chart | ||||
|      * @param ReportQueryInterface $query | ||||
|      * @param                      $year | ||||
|      * @param bool                 $shared | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function yearInOut(GChart $chart, ReportQueryInterface $query, $year, $shared = false) | ||||
|     { | ||||
|         // get start and end of year | ||||
|         $start  = new Carbon($year . '-01-01'); | ||||
|         $end    = new Carbon($year . '-12-31'); | ||||
|         $shared = $shared == 'shared' ? true : false; | ||||
|  | ||||
|         $chart->addColumn(trans('firefly.month'), 'date'); | ||||
|         $chart->addColumn(trans('firefly.income'), 'number'); | ||||
|         $chart->addColumn(trans('firefly.expenses'), 'number'); | ||||
|  | ||||
|         while ($start < $end) { | ||||
|             $month = clone $start; | ||||
|             $month->endOfMonth(); | ||||
|             // total income and total expenses: | ||||
|             $incomeSum  = floatval($query->incomeInPeriodCorrected($start, $month, $shared)->sum('amount')); | ||||
|             $expenseSum = floatval($query->expenseInPeriodCorrected($start, $month, $shared)->sum('amount')); | ||||
|  | ||||
|             $chart->addRow(clone $start, $incomeSum, $expenseSum); | ||||
|             $start->addMonth(); | ||||
|         } | ||||
|         $chart->generate(); | ||||
|  | ||||
|         return Response::json($chart->getData()); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Summarizes all income and expenses for a given year. Gives a total and an average. | ||||
|      * | ||||
|      * @param GChart               $chart | ||||
|      * @param ReportQueryInterface $query | ||||
|      * @param                      $year | ||||
|      * @param bool                 $shared | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function yearInOutSummarized(GChart $chart, ReportQueryInterface $query, $year, $shared = false) | ||||
|     { | ||||
|         $start   = new Carbon($year . '-01-01'); | ||||
|         $end     = new Carbon($year . '-12-31'); | ||||
|         $shared  = $shared == 'shared' ? true : false; | ||||
|         $income  = 0; | ||||
|         $expense = 0; | ||||
|         $count   = 0; | ||||
|  | ||||
|         $chart->addColumn(trans('firefly.summary'), 'string'); | ||||
|         $chart->addColumn(trans('firefly.income'), 'number'); | ||||
|         $chart->addColumn(trans('firefly.expenses'), 'number'); | ||||
|  | ||||
|         while ($start < $end) { | ||||
|             $month = clone $start; | ||||
|             $month->endOfMonth(); | ||||
|             // total income and total expenses: | ||||
|             $income += floatval($query->incomeInPeriodCorrected($start, $month, $shared)->sum('amount')); | ||||
|             $expense += floatval($query->expenseInPeriodCorrected($start, $month, $shared)->sum('amount')); | ||||
|             $count++; | ||||
|             $start->addMonth(); | ||||
|         } | ||||
|  | ||||
|         // add total + average: | ||||
|         $chart->addRow(trans('firefly.sum'), $income, $expense); | ||||
|         $count = $count > 0 ? $count : 1; | ||||
|         $chart->addRow(trans('firefly.average'), ($income / $count), ($expense / $count)); | ||||
|  | ||||
|         $chart->generate(); | ||||
|  | ||||
|         return Response::json($chart->getData()); | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										47
									
								
								app/Http/Controllers/Controller.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								app/Http/Controllers/Controller.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Auth; | ||||
| use Config; | ||||
| use Illuminate\Foundation\Bus\DispatchesJobs; | ||||
| use Illuminate\Foundation\Validation\ValidatesRequests; | ||||
| use Illuminate\Routing\Controller as BaseController; | ||||
| use Preferences; | ||||
| use View; | ||||
|  | ||||
| /** | ||||
|  * Class Controller | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers | ||||
|  */ | ||||
| abstract class Controller extends BaseController | ||||
| { | ||||
|  | ||||
|     use DispatchesJobs, ValidatesRequests; | ||||
|  | ||||
|     /** @var string */ | ||||
|     protected $monthAndDayFormat; | ||||
|     /** @var string */ | ||||
|     protected $monthFormat; | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         View::share('hideBudgets', false); | ||||
|         View::share('hideCategories', false); | ||||
|         View::share('hideBills', false); | ||||
|         View::share('hideTags', false); | ||||
|  | ||||
|         if (Auth::check()) { | ||||
|             $pref                    = Preferences::get('language', 'en'); | ||||
|             $lang                    = $pref->data; | ||||
|             $this->monthFormat       = Config::get('firefly.month.' . $lang); | ||||
|             $this->monthAndDayFormat = Config::get('firefly.monthAndDay.' . $lang); | ||||
|  | ||||
|             View::share('monthFormat', $this->monthFormat); | ||||
|             View::share('monthAndDayFormat', $this->monthAndDayFormat); | ||||
|             View::share('language', $lang); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										218
									
								
								app/Http/Controllers/CurrencyController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										218
									
								
								app/Http/Controllers/CurrencyController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,218 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Auth; | ||||
| use Cache; | ||||
| use FireflyIII\Http\Requests\CurrencyFormRequest; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | ||||
| use Input; | ||||
| use Preferences; | ||||
| use Redirect; | ||||
| use Session; | ||||
| use URL; | ||||
| use View; | ||||
|  | ||||
| /** | ||||
|  * Class CurrencyController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers | ||||
|  */ | ||||
| class CurrencyController extends Controller | ||||
| { | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         View::share('title', trans('firefly.currencies')); | ||||
|         View::share('mainTitleIcon', 'fa-usd'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function create() | ||||
|     { | ||||
|         $subTitleIcon = 'fa-plus'; | ||||
|         $subTitle     = trans('firefly.create_currency'); | ||||
|  | ||||
|         // put previous url in session if not redirect from store (not "create another"). | ||||
|         if (Session::get('currency.create.fromStore') !== true) { | ||||
|             Session::put('currency.create.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('currency.create.fromStore'); | ||||
|         Session::flash('gaEventCategory', 'currency'); | ||||
|         Session::flash('gaEventAction', 'create'); | ||||
|  | ||||
|         return view('currency.create', compact('subTitleIcon', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionCurrency $currency | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function defaultCurrency(TransactionCurrency $currency) | ||||
|     { | ||||
|  | ||||
|         Preferences::set('currencyPreference', $currency->code); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         Session::flash('success', $currency->name . ' is now the default currency.'); | ||||
|         Cache::forget('FFCURRENCYSYMBOL'); | ||||
|         Cache::forget('FFCURRENCYCODE'); | ||||
|  | ||||
|         return Redirect::route('currency.index'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param CurrencyRepositoryInterface $repository | ||||
|      * @param TransactionCurrency         $currency | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse|View | ||||
|      */ | ||||
|     public function delete(CurrencyRepositoryInterface $repository, TransactionCurrency $currency) | ||||
|     { | ||||
|  | ||||
|         if ($repository->countJournals($currency) > 0) { | ||||
|             Session::flash('error', 'Cannot delete ' . e($currency->name) . ' because there are still transactions attached to it.'); | ||||
|  | ||||
|             return Redirect::route('currency.index'); | ||||
|         } | ||||
|  | ||||
|         // put previous url in session | ||||
|         Session::put('currency.delete.url', URL::previous()); | ||||
|         Session::flash('gaEventCategory', 'currency'); | ||||
|         Session::flash('gaEventAction', 'delete'); | ||||
|         $subTitle = trans('form.delete_currency', ['name' => $currency->name]); | ||||
|  | ||||
|  | ||||
|         return view('currency.delete', compact('currency', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param CurrencyRepositoryInterface $repository | ||||
|      * @param TransactionCurrency         $currency | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      * @throws \Exception | ||||
|      */ | ||||
|     public function destroy(CurrencyRepositoryInterface $repository, TransactionCurrency $currency) | ||||
|     { | ||||
|         if ($repository->countJournals($currency) > 0) { | ||||
|             Session::flash('error', 'Cannot destroy ' . e($currency->name) . ' because there are still transactions attached to it.'); | ||||
|  | ||||
|             return Redirect::route('currency.index'); | ||||
|         } | ||||
|  | ||||
|         Session::flash('success', 'Currency "' . e($currency->name) . '" deleted'); | ||||
|         if (Auth::user()->hasRole('owner')) { | ||||
|             $currency->delete(); | ||||
|         } | ||||
|  | ||||
|         return Redirect::to(Session::get('currency.delete.url')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionCurrency $currency | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function edit(TransactionCurrency $currency) | ||||
|     { | ||||
|         $subTitleIcon     = 'fa-pencil'; | ||||
|         $subTitle         = trans('firefly.edit_currency', ['name' => $currency->name]); | ||||
|         $currency->symbol = htmlentities($currency->symbol); | ||||
|  | ||||
|         // put previous url in session if not redirect from store (not "return_to_edit"). | ||||
|         if (Session::get('currency.edit.fromUpdate') !== true) { | ||||
|             Session::put('currency.edit.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('currency.edit.fromUpdate'); | ||||
|         Session::flash('gaEventCategory', 'currency'); | ||||
|         Session::flash('gaEventAction', 'edit'); | ||||
|  | ||||
|         return view('currency.edit', compact('currency', 'subTitle', 'subTitleIcon')); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param CurrencyRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function index(CurrencyRepositoryInterface $repository) | ||||
|     { | ||||
|         $currencies      = $repository->get(); | ||||
|         $defaultCurrency = $repository->getCurrencyByPreference(Preferences::get('currencyPreference', 'EUR')); | ||||
|  | ||||
|  | ||||
|         if (!Auth::user()->hasRole('owner')) { | ||||
|             Session::flash('warning', 'Please ask ' . env('SITE_OWNER') . ' to add, remove or edit currencies.'); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         return view('currency.index', compact('currencies', 'defaultCurrency')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * @param CurrencyFormRequest         $request | ||||
|      * @param CurrencyRepositoryInterface $repository | ||||
|      * | ||||
|      * @return $this|\Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function store(CurrencyFormRequest $request, CurrencyRepositoryInterface $repository) | ||||
|     { | ||||
|         $data = $request->getCurrencyData(); | ||||
|         if (Auth::user()->hasRole('owner')) { | ||||
|             $currency = $repository->store($data); | ||||
|             Session::flash('success', 'Currency "' . $currency->name . '" created'); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         if (intval(Input::get('create_another')) === 1) { | ||||
|             Session::put('currency.create.fromStore', true); | ||||
|  | ||||
|             return Redirect::route('currency.create')->withInput(); | ||||
|         } | ||||
|  | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('currency.create.url')); | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param CurrencyFormRequest         $request | ||||
|      * @param CurrencyRepositoryInterface $repository | ||||
|      * @param TransactionCurrency         $currency | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function update(CurrencyFormRequest $request, CurrencyRepositoryInterface $repository, TransactionCurrency $currency) | ||||
|     { | ||||
|         $data = $request->getCurrencyData(); | ||||
|         if (Auth::user()->hasRole('owner')) { | ||||
|             $currency = $repository->update($currency, $data); | ||||
|         } | ||||
|         Session::flash('success', 'Currency "' . e($currency->name) . '" updated.'); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|  | ||||
|         if (intval(Input::get('return_to_edit')) === 1) { | ||||
|             Session::put('currency.edit.fromUpdate', true); | ||||
|  | ||||
|             return Redirect::route('currency.edit', [$currency->id]); | ||||
|         } | ||||
|  | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('currency.edit.url')); | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										51
									
								
								app/Http/Controllers/HelpController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								app/Http/Controllers/HelpController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use FireflyIII\Helpers\Help\HelpInterface; | ||||
| use Log; | ||||
| use Response; | ||||
|  | ||||
| /** | ||||
|  * Class HelpController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers | ||||
|  */ | ||||
| class HelpController extends Controller | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param HelpInterface $help | ||||
|      * @param               $route | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function show(HelpInterface $help, $route) | ||||
|     { | ||||
|         $content = [ | ||||
|             'text'  => '<p>There is no help for this route!</p>', | ||||
|             'title' => 'Help', | ||||
|         ]; | ||||
|  | ||||
|         if (!$help->hasRoute($route)) { | ||||
|             Log::error('No such route: ' . $route); | ||||
|  | ||||
|             return Response::json($content); | ||||
|         } | ||||
|  | ||||
|         if ($help->inCache($route)) { | ||||
|             $content = [ | ||||
|                 'text'  => $help->getFromCache('help.' . $route . '.text'), | ||||
|                 'title' => $help->getFromCache('help.' . $route . '.title'), | ||||
|             ]; | ||||
|  | ||||
|             return Response::json($content); | ||||
|         } | ||||
|         $content = $help->getFromGithub($route); | ||||
|  | ||||
|         $help->putInCache($route, $content); | ||||
|  | ||||
|         return Response::json($content); | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										114
									
								
								app/Http/Controllers/HomeController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								app/Http/Controllers/HomeController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,114 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use Config; | ||||
| use FireflyIII\Models\Tag; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use Input; | ||||
| use Preferences; | ||||
| use Redirect; | ||||
| use Session; | ||||
| use Steam; | ||||
|  | ||||
| /** | ||||
|  * Class HomeController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers | ||||
|  */ | ||||
| class HomeController extends Controller | ||||
| { | ||||
|  | ||||
|     public function dateRange() | ||||
|     { | ||||
|         $start = new Carbon(Input::get('start')); | ||||
|         $end   = new Carbon(Input::get('end')); | ||||
|  | ||||
|         $diff = $start->diffInDays($end); | ||||
|  | ||||
|         if ($diff > 50) { | ||||
|             Session::flash('warning', $diff . ' days of data may take a while to load.'); | ||||
|         } | ||||
|  | ||||
|         Session::put('start', $start); | ||||
|         Session::put('end', $end); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function flush() | ||||
|     { | ||||
|         // get all tags. | ||||
|         // update all counts: | ||||
|         $tags = Tag::get(); | ||||
|  | ||||
|         /** @var Tag $tag */ | ||||
|         foreach ($tags as $tag) { | ||||
|             foreach ($tag->transactionjournals()->get() as $journal) { | ||||
|                 $count              = $journal->tags()->count(); | ||||
|                 $journal->tag_count = $count; | ||||
|                 $journal->save(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|         Session::clear(); | ||||
|  | ||||
|         return Redirect::route('index'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View | ||||
|      */ | ||||
|     public function index(AccountRepositoryInterface $repository) | ||||
|     { | ||||
|         $types = Config::get('firefly.accountTypesByIdentifier.asset'); | ||||
|         $count = $repository->countAccounts($types); | ||||
|  | ||||
|  | ||||
|         if ($count == 0) { | ||||
|             return Redirect::route('new-user.index'); | ||||
|         } | ||||
|  | ||||
|         $title         = 'Firefly'; | ||||
|         $subTitle      = trans('firefly.welcomeBack'); | ||||
|         $mainTitleIcon = 'fa-fire'; | ||||
|         $transactions  = []; | ||||
|         $frontPage     = Preferences::get('frontPageAccounts', []); | ||||
|         $start         = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end           = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|  | ||||
|         $accounts = $repository->getFrontpageAccounts($frontPage); | ||||
|         $savings  = $repository->getSavingsAccounts(); | ||||
|  | ||||
|         $piggyBankAccounts = $repository->getPiggyBankAccounts(); | ||||
|  | ||||
|  | ||||
|         $savingsTotal = 0; | ||||
|         foreach ($savings as $savingAccount) { | ||||
|             $savingsTotal += Steam::balance($savingAccount, $end); | ||||
|         } | ||||
|  | ||||
|         $sum = $repository->sumOfEverything(); | ||||
|  | ||||
|         if ($sum != 0) { | ||||
|             Session::flash( | ||||
|                 'error', 'Your transactions are unbalanced. This means a' | ||||
|                          . ' withdrawal, deposit or transfer was not stored properly. ' | ||||
|                          . 'Please check your accounts and transactions for errors.' | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         foreach ($accounts as $account) { | ||||
|             $set = $repository->getFrontpageTransactions($account, $start, $end); | ||||
|  | ||||
|             if (count($set) > 0) { | ||||
|                 $transactions[] = [$set, $account]; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return view('index', compact('count', 'title', 'savings', 'subTitle', 'mainTitleIcon', 'transactions', 'savingsTotal', 'piggyBankAccounts')); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										296
									
								
								app/Http/Controllers/JsonController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										296
									
								
								app/Http/Controllers/JsonController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,296 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Amount; | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Helpers\Report\ReportQueryInterface; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Repositories\Bill\BillRepositoryInterface; | ||||
| use FireflyIII\Repositories\Category\CategoryRepositoryInterface; | ||||
| use FireflyIII\Repositories\Journal\JournalRepositoryInterface; | ||||
| use FireflyIII\Repositories\Tag\TagRepositoryInterface; | ||||
| use FireflyIII\Support\CacheProperties; | ||||
| use Illuminate\Support\Collection; | ||||
| use Response; | ||||
| use Session; | ||||
| use Steam; | ||||
|  | ||||
| /** | ||||
|  * Class JsonController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers | ||||
|  */ | ||||
| class JsonController extends Controller | ||||
| { | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @param BillRepositoryInterface    $repository | ||||
|      * | ||||
|      * @param AccountRepositoryInterface $accountRepository | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function boxBillsPaid(BillRepositoryInterface $repository, AccountRepositoryInterface $accountRepository) | ||||
|     { | ||||
|         $start = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end   = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|  | ||||
|         // works for json too! | ||||
|         $cache = new CacheProperties; | ||||
|         $cache->addProperty($start); | ||||
|         $cache->addProperty($end); | ||||
|         $cache->addProperty('box-bills-paid'); | ||||
|         if ($cache->has()) { | ||||
|             return Response::json($cache->get()); // @codeCoverageIgnore | ||||
|         } | ||||
|  | ||||
|         $amount = 0; | ||||
|  | ||||
|  | ||||
|         // these two functions are the same as the chart | ||||
|         $bills = $repository->getActiveBills(); | ||||
|  | ||||
|         /** @var Bill $bill */ | ||||
|         foreach ($bills as $bill) { | ||||
|             $amount += $repository->billPaymentsInRange($bill, $start, $end); | ||||
|         } | ||||
|         unset($bill, $bills); | ||||
|  | ||||
|         /** | ||||
|          * Find credit card accounts and possibly unpaid credit card bills. | ||||
|          */ | ||||
|         $creditCards = $accountRepository->getCreditCards(); | ||||
|         // if the balance is not zero, the monthly payment is still underway. | ||||
|         /** @var Account $creditCard */ | ||||
|         foreach ($creditCards as $creditCard) { | ||||
|             $balance = Steam::balance($creditCard, $end, true); | ||||
|             if ($balance == 0) { | ||||
|                 // find a transfer TO the credit card which should account for | ||||
|                 // anything paid. If not, the CC is not yet used. | ||||
|                 $amount += $accountRepository->getTransfersInRange($creditCard, $start, $end)->sum('amount'); | ||||
|             } | ||||
|         } | ||||
|         $data = ['box' => 'bills-paid', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount]; | ||||
|         $cache->store($data); | ||||
|  | ||||
|  | ||||
|         return Response::json($data); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BillRepositoryInterface    $repository | ||||
|      * @param AccountRepositoryInterface $accountRepository | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function boxBillsUnpaid(BillRepositoryInterface $repository, AccountRepositoryInterface $accountRepository) | ||||
|     { | ||||
|         $amount = 0; | ||||
|         $start  = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end    = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|  | ||||
|         // works for json too! | ||||
|         $cache = new CacheProperties; | ||||
|         $cache->addProperty($start); | ||||
|         $cache->addProperty($end); | ||||
|         $cache->addProperty('box-bills-unpaid'); | ||||
|         if ($cache->has()) { | ||||
|             return Response::json($cache->get()); // @codeCoverageIgnore | ||||
|         } | ||||
|  | ||||
|         $bills  = $repository->getActiveBills(); | ||||
|         $unpaid = new Collection; // bills | ||||
|  | ||||
|         /** @var Bill $bill */ | ||||
|         foreach ($bills as $bill) { | ||||
|             $ranges = $repository->getRanges($bill, $start, $end); | ||||
|  | ||||
|             foreach ($ranges as $range) { | ||||
|                 $journals = $repository->getJournalsInRange($bill, $range['start'], $range['end']); | ||||
|                 if ($journals->count() == 0) { | ||||
|                     $unpaid->push([$bill, $range['start']]); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         unset($bill, $bills, $range, $ranges); | ||||
|  | ||||
|         $creditCards = $accountRepository->getCreditCards(); | ||||
|         foreach ($creditCards as $creditCard) { | ||||
|             $balance = Steam::balance($creditCard, $end, true); | ||||
|             $date    = new Carbon($creditCard->getMeta('ccMonthlyPaymentDate')); | ||||
|             if ($balance < 0) { | ||||
|                 // unpaid! create a fake bill that matches the amount. | ||||
|                 $description = $creditCard->name; | ||||
|                 $fakeAmount  = $balance * -1; | ||||
|                 $fakeBill    = $repository->createFakeBill($description, $date, $fakeAmount); | ||||
|                 $unpaid->push([$fakeBill, $date]); | ||||
|             } | ||||
|         } | ||||
|         /** @var Bill $entry */ | ||||
|         foreach ($unpaid as $entry) { | ||||
|             $current = ($entry[0]->amount_max + $entry[0]->amount_min) / 2; | ||||
|             $amount += $current; | ||||
|         } | ||||
|  | ||||
|         $data = ['box' => 'bills-unpaid', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount]; | ||||
|         $cache->store($data); | ||||
|  | ||||
|         return Response::json($data); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param ReportQueryInterface $reportQuery | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function boxIn(ReportQueryInterface $reportQuery) | ||||
|     { | ||||
|         $start = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end   = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|  | ||||
|         // works for json too! | ||||
|         $cache = new CacheProperties; | ||||
|         $cache->addProperty($start); | ||||
|         $cache->addProperty($end); | ||||
|         $cache->addProperty('box-in'); | ||||
|         if ($cache->has()) { | ||||
|             return Response::json($cache->get()); // @codeCoverageIgnore | ||||
|         } | ||||
|  | ||||
|         $amount = $reportQuery->incomeInPeriodCorrected($start, $end, true)->sum('amount'); | ||||
|  | ||||
|         $data = ['box' => 'in', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount]; | ||||
|         $cache->store($data); | ||||
|  | ||||
|         return Response::json($data); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param ReportQueryInterface $reportQuery | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function boxOut(ReportQueryInterface $reportQuery) | ||||
|     { | ||||
|         $start = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end   = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|  | ||||
|  | ||||
|         // works for json too! | ||||
|         $cache = new CacheProperties; | ||||
|         $cache->addProperty($start); | ||||
|         $cache->addProperty($end); | ||||
|         $cache->addProperty('box-out'); | ||||
|         if ($cache->has()) { | ||||
|             return Response::json($cache->get()); // @codeCoverageIgnore | ||||
|         } | ||||
|  | ||||
|         $amount = $reportQuery->expenseInPeriodCorrected($start, $end, true)->sum('amount'); | ||||
|  | ||||
|         $data = ['box' => 'out', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount]; | ||||
|         $cache->store($data); | ||||
|  | ||||
|         return Response::json($data); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns a list of categories. | ||||
|      * | ||||
|      * @param CategoryRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function categories(CategoryRepositoryInterface $repository) | ||||
|     { | ||||
|         $list   = $repository->getCategories(); | ||||
|         $return = []; | ||||
|         foreach ($list as $entry) { | ||||
|             $return[] = $entry->name; | ||||
|         } | ||||
|         sort($return); | ||||
|  | ||||
|         return Response::json($return); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns a JSON list of all beneficiaries. | ||||
|      * | ||||
|      * @param AccountRepositoryInterface $accountRepository | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function expenseAccounts(AccountRepositoryInterface $accountRepository) | ||||
|     { | ||||
|         $list   = $accountRepository->getAccounts(['Expense account', 'Beneficiary account']); | ||||
|         $return = []; | ||||
|         foreach ($list as $entry) { | ||||
|             $return[] = $entry->name; | ||||
|         } | ||||
|  | ||||
|         return Response::json($return); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param AccountRepositoryInterface $accountRepository | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function revenueAccounts(AccountRepositoryInterface $accountRepository) | ||||
|     { | ||||
|         $list   = $accountRepository->getAccounts(['Revenue account']); | ||||
|         $return = []; | ||||
|         foreach ($list as $entry) { | ||||
|             $return[] = $entry->name; | ||||
|         } | ||||
|  | ||||
|         return Response::json($return); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns a JSON list of all beneficiaries. | ||||
|      * | ||||
|      * @param TagRepositoryInterface $tagRepository | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function tags(TagRepositoryInterface $tagRepository) | ||||
|     { | ||||
|         $list   = $tagRepository->get(); | ||||
|         $return = []; | ||||
|         foreach ($list as $entry) { | ||||
|             $return[] = $entry->tag; | ||||
|         } | ||||
|  | ||||
|         return Response::json($return); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param JournalRepositoryInterface $repository | ||||
|      * @param                            $what | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function transactionJournals(JournalRepositoryInterface $repository, $what) | ||||
|     { | ||||
|         $descriptions = []; | ||||
|         $dbType       = $repository->getTransactionType($what); | ||||
|  | ||||
|         $journals = $repository->getJournalsOfType($dbType); | ||||
|         foreach ($journals as $j) { | ||||
|             $descriptions[] = $j->description; | ||||
|         } | ||||
|  | ||||
|         $descriptions = array_unique($descriptions); | ||||
|         sort($descriptions); | ||||
|  | ||||
|         return Response::json($descriptions); | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										111
									
								
								app/Http/Controllers/NewUserController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								app/Http/Controllers/NewUserController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,111 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use Config; | ||||
| use FireflyIII\Http\Requests\NewUserFormRequest; | ||||
| use FireflyIII\Models\AccountMeta; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use Preferences; | ||||
| use Redirect; | ||||
| use Session; | ||||
| use View; | ||||
|  | ||||
| /** | ||||
|  * Class NewUserController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers | ||||
|  */ | ||||
| class NewUserController extends Controller | ||||
| { | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * | ||||
|      * @@return \Illuminate\Http\RedirectResponse|\Illuminate\View\View | ||||
|      */ | ||||
|     public function index(AccountRepositoryInterface $repository) | ||||
|     { | ||||
|         View::share('title', 'Welcome to Firefly!'); | ||||
|         View::share('mainTitleIcon', 'fa-fire'); | ||||
|  | ||||
|  | ||||
|         $types = Config::get('firefly.accountTypesByIdentifier.asset'); | ||||
|         $count = $repository->countAccounts($types); | ||||
|  | ||||
|         if ($count > 0) { | ||||
|             return Redirect::route('index'); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         return view('new-user.index'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param NewUserFormRequest         $request | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function submit(NewUserFormRequest $request, AccountRepositoryInterface $repository) | ||||
|     { | ||||
|  | ||||
|         // create normal asset account: | ||||
|         $assetAccount = [ | ||||
|             'name'                   => $request->get('bank_name'), | ||||
|             'accountType'            => 'asset', | ||||
|             'virtualBalance'         => 0, | ||||
|             'active'                 => true, | ||||
|             'user'                   => Auth::user()->id, | ||||
|             'accountRole'            => 'defaultAsset', | ||||
|             'openingBalance'         => floatval($request->input('bank_balance')), | ||||
|             'openingBalanceDate'     => new Carbon, | ||||
|             'openingBalanceCurrency' => intval($request->input('balance_currency_id')), | ||||
|         ]; | ||||
|  | ||||
|         $repository->store($assetAccount); | ||||
|  | ||||
|         // create savings account | ||||
|         if (strlen($request->get('savings_balance') > 0)) { | ||||
|             $savingsAccount = [ | ||||
|                 'name'                   => $request->get('bank_name') . ' savings account', | ||||
|                 'accountType'            => 'asset', | ||||
|                 'virtualBalance'         => 0, | ||||
|                 'active'                 => true, | ||||
|                 'user'                   => Auth::user()->id, | ||||
|                 'accountRole'            => 'savingAsset', | ||||
|                 'openingBalance'         => floatval($request->input('savings_balance')), | ||||
|                 'openingBalanceDate'     => new Carbon, | ||||
|                 'openingBalanceCurrency' => intval($request->input('balance_currency_id')), | ||||
|             ]; | ||||
|             $repository->store($savingsAccount); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         // create credit card. | ||||
|         if (strlen($request->get('credit_card_limit') > 0)) { | ||||
|             $creditAccount = [ | ||||
|                 'name'                   => 'Credit card', | ||||
|                 'accountType'            => 'asset', | ||||
|                 'virtualBalance'         => floatval($request->get('credit_card_limit')), | ||||
|                 'active'                 => true, | ||||
|                 'user'                   => Auth::user()->id, | ||||
|                 'accountRole'            => 'ccAsset', | ||||
|                 'openingBalance'         => null, | ||||
|                 'openingBalanceDate'     => null, | ||||
|                 'openingBalanceCurrency' => intval($request->input('balance_currency_id')), | ||||
|             ]; | ||||
|             $creditCard    = $repository->store($creditAccount); | ||||
|  | ||||
|             // store meta for CC: | ||||
|             AccountMeta::create(['name' => 'ccType', 'data' => 'monthlyFull', 'account_id' => $creditCard->id,]); | ||||
|             AccountMeta::create(['name' => 'ccMonthlyPaymentDate', 'data' => Carbon::now()->year . '-01-01', 'account_id' => $creditCard->id,]); | ||||
|  | ||||
|         } | ||||
|         Session::flash('success', 'New account(s) created!'); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         return Redirect::route('index'); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										387
									
								
								app/Http/Controllers/PiggyBankController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										387
									
								
								app/Http/Controllers/PiggyBankController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,387 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Amount; | ||||
| use Carbon\Carbon; | ||||
| use Config; | ||||
| use ExpandedForm; | ||||
| use FireflyIII\Http\Requests\PiggyBankFormRequest; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; | ||||
| use Illuminate\Support\Collection; | ||||
| use Input; | ||||
| use Preferences; | ||||
| use Redirect; | ||||
| use Session; | ||||
| use Steam; | ||||
| use URL; | ||||
| use View; | ||||
|  | ||||
| /** | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.TooManyMethods) | ||||
|  * | ||||
|  * Class PiggyBankController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers | ||||
|  */ | ||||
| class PiggyBankController extends Controller | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         View::share('title', trans('firefly.piggyBanks')); | ||||
|         View::share('mainTitleIcon', 'fa-sort-amount-asc'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Add money to piggy bank | ||||
|      * | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * @param PiggyBank                  $piggyBank | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function add(AccountRepositoryInterface $repository, PiggyBank $piggyBank) | ||||
|     { | ||||
|         $date          = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|         $leftOnAccount = $repository->leftOnAccount($piggyBank->account, $date); | ||||
|         $savedSoFar    = $piggyBank->currentRelevantRep()->currentamount; | ||||
|         $leftToSave    = $piggyBank->targetamount - $savedSoFar; | ||||
|         $maxAmount     = min($leftOnAccount, $leftToSave); | ||||
|  | ||||
|         return view('piggy-banks.add', compact('piggyBank', 'maxAmount')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function create(AccountRepositoryInterface $repository) | ||||
|     { | ||||
|  | ||||
|         $periods      = Config::get('firefly.piggy_bank_periods'); | ||||
|         $accounts     = ExpandedForm::makeSelectList($repository->getAccounts(['Default account', 'Asset account'])); | ||||
|         $subTitle     = trans('firefly.create_new_piggybank'); | ||||
|         $subTitleIcon = 'fa-plus'; | ||||
|  | ||||
|         // put previous url in session if not redirect from store (not "create another"). | ||||
|         if (Session::get('piggy-banks.create.fromStore') !== true) { | ||||
|             Session::put('piggy-banks.create.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('piggy-banks.create.fromStore'); | ||||
|         Session::flash('gaEventCategory', 'piggy-banks'); | ||||
|         Session::flash('gaEventAction', 'create'); | ||||
|  | ||||
|         return view('piggy-banks.create', compact('accounts', 'periods', 'subTitle', 'subTitleIcon')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function delete(PiggyBank $piggyBank) | ||||
|     { | ||||
|         $subTitle = trans('firefly.delete_piggy_bank', ['name' => $piggyBank->name]); | ||||
|  | ||||
|         // put previous url in session | ||||
|         Session::put('piggy-banks.delete.url', URL::previous()); | ||||
|         Session::flash('gaEventCategory', 'piggy-banks'); | ||||
|         Session::flash('gaEventAction', 'delete'); | ||||
|  | ||||
|         return view('piggy-banks.delete', compact('piggyBank', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBankRepositoryInterface $repository | ||||
|      * @param PiggyBank                    $piggyBank | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function destroy(PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank) | ||||
|     { | ||||
|  | ||||
|  | ||||
|         Session::flash('success', 'Piggy bank "' . e($piggyBank->name) . '" deleted.'); | ||||
|         Preferences::mark(); | ||||
|         $repository->destroy($piggyBank); | ||||
|  | ||||
|         return Redirect::to(Session::get('piggy-banks.delete.url')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * @param PiggyBank                  $piggyBank | ||||
|      * | ||||
|      * @return View | ||||
|      */ | ||||
|     public function edit(AccountRepositoryInterface $repository, PiggyBank $piggyBank) | ||||
|     { | ||||
|  | ||||
|         $periods      = Config::get('firefly.piggy_bank_periods'); | ||||
|         $accounts     = ExpandedForm::makeSelectList($repository->getAccounts(['Default account', 'Asset account'])); | ||||
|         $subTitle     = trans('firefly.update_piggy_title', ['name' => $piggyBank->name]); | ||||
|         $subTitleIcon = 'fa-pencil'; | ||||
|  | ||||
|         /* | ||||
|          * Flash some data to fill the form. | ||||
|          */ | ||||
|         if (is_null($piggyBank->targetdate) || $piggyBank->targetdate == '') { | ||||
|             $targetDate = null; | ||||
|         } else { | ||||
|             $targetDate = new Carbon($piggyBank->targetdate); | ||||
|             $targetDate = $targetDate->format('Y-m-d'); | ||||
|         } | ||||
|         $preFilled = ['name'         => $piggyBank->name, | ||||
|                       'account_id'   => $piggyBank->account_id, | ||||
|                       'targetamount' => $piggyBank->targetamount, | ||||
|                       'targetdate'   => $targetDate, | ||||
|                       'reminder'     => $piggyBank->reminder, | ||||
|                       'remind_me'    => intval($piggyBank->remind_me) == 1 && !is_null($piggyBank->reminder) ? true : false | ||||
|         ]; | ||||
|         Session::flash('preFilled', $preFilled); | ||||
|         Session::flash('gaEventCategory', 'piggy-banks'); | ||||
|         Session::flash('gaEventAction', 'edit'); | ||||
|  | ||||
|         // put previous url in session if not redirect from store (not "return_to_edit"). | ||||
|         if (Session::get('piggy-banks.edit.fromUpdate') !== true) { | ||||
|             Session::put('piggy-banks.edit.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('piggy-banks.edit.fromUpdate'); | ||||
|  | ||||
|         return view('piggy-banks.edit', compact('subTitle', 'subTitleIcon', 'piggyBank', 'accounts', 'periods', 'preFilled')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param AccountRepositoryInterface   $repository | ||||
|      * @param PiggyBankRepositoryInterface $piggyRepository | ||||
|      * | ||||
|      * @return View | ||||
|      */ | ||||
|     public function index(AccountRepositoryInterface $repository, PiggyBankRepositoryInterface $piggyRepository) | ||||
|     { | ||||
|         /** @var Collection $piggyBanks */ | ||||
|         $piggyBanks = $piggyRepository->getPiggyBanks(); | ||||
|         $end        = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|  | ||||
|         $accounts = []; | ||||
|         /** @var PiggyBank $piggyBank */ | ||||
|         foreach ($piggyBanks as $piggyBank) { | ||||
|             $piggyBank->savedSoFar = floatval($piggyBank->currentRelevantRep()->currentamount); | ||||
|             $piggyBank->percentage = $piggyBank->savedSoFar != 0 ? intval($piggyBank->savedSoFar / $piggyBank->targetamount * 100) : 0; | ||||
|             $piggyBank->leftToSave = $piggyBank->targetamount - $piggyBank->savedSoFar; | ||||
|  | ||||
|             /* | ||||
|              * Fill account information: | ||||
|              */ | ||||
|             $account = $piggyBank->account; | ||||
|             if (!isset($accounts[$account->id])) { | ||||
|                 $accounts[$account->id] = [ | ||||
|                     'name'              => $account->name, | ||||
|                     'balance'           => Steam::balance($account, $end, true), | ||||
|                     'leftForPiggyBanks' => $repository->leftOnAccount($account, $end), | ||||
|                     'sumOfSaved'        => $piggyBank->savedSoFar, | ||||
|                     'sumOfTargets'      => floatval($piggyBank->targetamount), | ||||
|                     'leftToSave'        => $piggyBank->leftToSave | ||||
|                 ]; | ||||
|             } else { | ||||
|                 $accounts[$account->id]['sumOfSaved'] += $piggyBank->savedSoFar; | ||||
|                 $accounts[$account->id]['sumOfTargets'] += floatval($piggyBank->targetamount); | ||||
|                 $accounts[$account->id]['leftToSave'] += $piggyBank->leftToSave; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return view('piggy-banks.index', compact('piggyBanks', 'accounts')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBankRepositoryInterface $repository | ||||
|      */ | ||||
|     public function order(PiggyBankRepositoryInterface $repository) | ||||
|     { | ||||
|         $data = Input::get('order'); | ||||
|  | ||||
|         // set all users piggy banks to zero: | ||||
|         $repository->reset(); | ||||
|  | ||||
|  | ||||
|         if (is_array($data)) { | ||||
|             foreach ($data as $order => $id) { | ||||
|                 $repository->setOrder(intval($id), (intval($order) + 1)); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBankRepositoryInterface $repository | ||||
|      * @param AccountRepositoryInterface   $accounts | ||||
|      * @param PiggyBank                    $piggyBank | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function postAdd(PiggyBankRepositoryInterface $repository, AccountRepositoryInterface $accounts, PiggyBank $piggyBank) | ||||
|     { | ||||
|         $amount        = round(floatval(Input::get('amount')), 2); | ||||
|         $date          = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|         $leftOnAccount = $accounts->leftOnAccount($piggyBank->account, $date); | ||||
|         $savedSoFar    = $piggyBank->currentRelevantRep()->currentamount; | ||||
|         $leftToSave    = $piggyBank->targetamount - $savedSoFar; | ||||
|         $maxAmount     = round(min($leftOnAccount, $leftToSave), 2); | ||||
|  | ||||
|         if ($amount <= $maxAmount) { | ||||
|             $repetition = $piggyBank->currentRelevantRep(); | ||||
|             $repetition->currentamount += $amount; | ||||
|             $repetition->save(); | ||||
|  | ||||
|             // create event | ||||
|             $repository->createEvent($piggyBank, $amount); | ||||
|  | ||||
|             Session::flash('success', 'Added ' . Amount::format($amount, false) . ' to "' . e($piggyBank->name) . '".'); | ||||
|             Preferences::mark(); | ||||
|         } else { | ||||
|             Session::flash('error', 'Could not add ' . Amount::format($amount, false) . ' to "' . e($piggyBank->name) . '".'); | ||||
|         } | ||||
|  | ||||
|         return Redirect::route('piggy-banks.index'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBankRepositoryInterface $repository | ||||
|      * @param PiggyBank                    $piggyBank | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function postRemove(PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank) | ||||
|     { | ||||
|         $amount = floatval(Input::get('amount')); | ||||
|  | ||||
|         $savedSoFar = $piggyBank->currentRelevantRep()->currentamount; | ||||
|  | ||||
|         if ($amount <= $savedSoFar) { | ||||
|             $repetition = $piggyBank->currentRelevantRep(); | ||||
|             $repetition->currentamount -= $amount; | ||||
|             $repetition->save(); | ||||
|  | ||||
|             // create event | ||||
|             $repository->createEvent($piggyBank, $amount * -1); | ||||
|  | ||||
|             Session::flash('success', 'Removed ' . Amount::format($amount, false) . ' from "' . e($piggyBank->name) . '".'); | ||||
|             Preferences::mark(); | ||||
|         } else { | ||||
|             Session::flash('error', 'Could not remove ' . Amount::format($amount, false) . ' from "' . e($piggyBank->name) . '".'); | ||||
|         } | ||||
|  | ||||
|         return Redirect::route('piggy-banks.index'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function remove(PiggyBank $piggyBank) | ||||
|     { | ||||
|         return view('piggy-banks.remove', compact('piggyBank')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBankRepositoryInterface $repository | ||||
|      * @param PiggyBank                    $piggyBank | ||||
|      * | ||||
|      * @return View | ||||
|      */ | ||||
|     public function show(PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank) | ||||
|     { | ||||
|         $events = $repository->getEvents($piggyBank); | ||||
|  | ||||
|         /* | ||||
|          * Number of reminders: | ||||
|          */ | ||||
|  | ||||
|         $subTitle = e($piggyBank->name); | ||||
|  | ||||
|         return view('piggy-banks.show', compact('piggyBank', 'events', 'subTitle')); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBankFormRequest         $request | ||||
|      * @param PiggyBankRepositoryInterface $repository | ||||
|      * | ||||
|      * @return $this|\Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function store(PiggyBankFormRequest $request, PiggyBankRepositoryInterface $repository) | ||||
|     { | ||||
|  | ||||
|         $piggyBankData = [ | ||||
|             'name'         => $request->get('name'), | ||||
|             'startdate'    => new Carbon, | ||||
|             'account_id'   => intval($request->get('account_id')), | ||||
|             'targetamount' => floatval($request->get('targetamount')), | ||||
|             'targetdate'   => strlen($request->get('targetdate')) > 0 ? new Carbon($request->get('targetdate')) : null, | ||||
|             'reminder'     => $request->get('reminder'), | ||||
|             'remind_me'    => $request->get('remind_me'), | ||||
|         ]; | ||||
|  | ||||
|         $piggyBank = $repository->store($piggyBankData); | ||||
|  | ||||
|         Session::flash('success', 'Stored piggy bank "' . e($piggyBank->name) . '".'); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         if (intval(Input::get('create_another')) === 1) { | ||||
|             Session::put('piggy-banks.create.fromStore', true); | ||||
|  | ||||
|             return Redirect::route('piggy-banks.create')->withInput(); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('piggy-banks.create.url')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBankRepositoryInterface $repository | ||||
|      * @param PiggyBankFormRequest         $request | ||||
|      * @param PiggyBank                    $piggyBank | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function update(PiggyBankRepositoryInterface $repository, PiggyBankFormRequest $request, PiggyBank $piggyBank) | ||||
|     { | ||||
|         $piggyBankData = [ | ||||
|             'name'         => $request->get('name'), | ||||
|             'startdate'    => is_null($piggyBank->startdate) ? $piggyBank->created_at : $piggyBank->startdate, | ||||
|             'account_id'   => intval($request->get('account_id')), | ||||
|             'targetamount' => floatval($request->get('targetamount')), | ||||
|             'targetdate'   => strlen($request->get('targetdate')) > 0 ? new Carbon($request->get('targetdate')) : null, | ||||
|             'reminder'     => $request->get('reminder'), | ||||
|             'remind_me'    => $request->get('remind_me') | ||||
|         ]; | ||||
|  | ||||
|         $piggyBank = $repository->update($piggyBank, $piggyBankData); | ||||
|  | ||||
|         Session::flash('success', 'Updated piggy bank "' . e($piggyBank->name) . '".'); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         if (intval(Input::get('return_to_edit')) === 1) { | ||||
|             Session::put('piggy-banks.edit.fromUpdate', true); | ||||
|  | ||||
|             return Redirect::route('piggy-banks.edit', [$piggyBank->id]); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('piggy-banks.edit.url')); | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										85
									
								
								app/Http/Controllers/PreferencesController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								app/Http/Controllers/PreferencesController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Config; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use Input; | ||||
| use Preferences; | ||||
| use Redirect; | ||||
| use Session; | ||||
| use View; | ||||
|  | ||||
| /** | ||||
|  * Class PreferencesController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers | ||||
|  */ | ||||
| class PreferencesController extends Controller | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         View::share('title', trans('firefly.preferences')); | ||||
|         View::share('mainTitleIcon', 'fa-gear'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * | ||||
|      * @return $this|\Illuminate\View\View | ||||
|      */ | ||||
|     public function index(AccountRepositoryInterface $repository) | ||||
|     { | ||||
|         $accounts          = $repository->getAccounts(['Default account', 'Asset account']); | ||||
|         $viewRangePref     = Preferences::get('viewRange', '1M'); | ||||
|         $viewRange         = $viewRangePref->data; | ||||
|         $frontPageAccounts = Preferences::get('frontPageAccounts', []); | ||||
|         $budgetMax         = Preferences::get('budgetMaximum', 1000); | ||||
|         $language          = Preferences::get('language', 'en')->data; | ||||
|         $budgetMaximum     = $budgetMax->data; | ||||
|  | ||||
|         return view('preferences.index', compact('budgetMaximum', 'language', 'accounts', 'frontPageAccounts', 'viewRange')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function postIndex() | ||||
|     { | ||||
|         // front page accounts | ||||
|         $frontPageAccounts = []; | ||||
|         if (is_array(Input::get('frontPageAccounts'))) { | ||||
|             foreach (Input::get('frontPageAccounts') as $id) { | ||||
|                 $frontPageAccounts[] = intval($id); | ||||
|             } | ||||
|             Preferences::set('frontPageAccounts', $frontPageAccounts); | ||||
|         } | ||||
|  | ||||
|         // view range: | ||||
|         Preferences::set('viewRange', Input::get('viewRange')); | ||||
|         // forget session values: | ||||
|         Session::forget('start'); | ||||
|         Session::forget('end'); | ||||
|         Session::forget('range'); | ||||
|  | ||||
|         // budget maximum: | ||||
|         $budgetMaximum = intval(Input::get('budgetMaximum')); | ||||
|         Preferences::set('budgetMaximum', $budgetMaximum); | ||||
|  | ||||
|         // language: | ||||
|         $lang = Input::get('language'); | ||||
|         if (in_array($lang, array_keys(Config::get('firefly.lang')))) { | ||||
|             Preferences::set('language', $lang); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         Session::flash('success', 'Preferences saved!'); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         return Redirect::route('preferences'); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										119
									
								
								app/Http/Controllers/ProfileController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								app/Http/Controllers/ProfileController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,119 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Http\Requests; | ||||
| use FireflyIII\Http\Requests\DeleteAccountFormRequest; | ||||
| use FireflyIII\Http\Requests\ProfileFormRequest; | ||||
| use Hash; | ||||
| use Redirect; | ||||
| use Session; | ||||
|  | ||||
| /** | ||||
|  * Class ProfileController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers | ||||
|  */ | ||||
| class ProfileController extends Controller | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function changePassword() | ||||
|     { | ||||
|         return view('profile.change-password')->with('title', Auth::user()->email)->with('subTitle', 'Change your password')->with( | ||||
|             'mainTitleIcon', 'fa-user' | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function deleteAccount() | ||||
|     { | ||||
|         return view('profile.delete-account')->with('title', Auth::user()->email)->with('subTitle', 'Delete account')->with( | ||||
|             'mainTitleIcon', 'fa-user' | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\View\View | ||||
|      * | ||||
|      */ | ||||
|     public function index() | ||||
|     { | ||||
|         return view('profile.index')->with('title', 'Profile')->with('subTitle', Auth::user()->email)->with('mainTitleIcon', 'fa-user'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param ProfileFormRequest $request | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View | ||||
|      */ | ||||
|     public function postChangePassword(ProfileFormRequest $request) | ||||
|     { | ||||
|         // old, new1, new2 | ||||
|         if (!Hash::check($request->get('current_password'), Auth::user()->password)) { | ||||
|             Session::flash('error', 'Invalid current password!'); | ||||
|  | ||||
|             return Redirect::route('profile.change-password'); | ||||
|         } | ||||
|         $result = $this->validatePassword($request->get('current_password'), $request->get('new_password')); | ||||
|         if (!($result === true)) { | ||||
|             Session::flash('error', $result); | ||||
|  | ||||
|             return Redirect::route('profile.change-password'); | ||||
|         } | ||||
|  | ||||
|         // update the user with the new password. | ||||
|         Auth::user()->password = $request->get('new_password'); | ||||
|         Auth::user()->save(); | ||||
|  | ||||
|         Session::flash('success', 'Password changed!'); | ||||
|  | ||||
|         return Redirect::route('profile'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * @param string $old | ||||
|      * @param string $new1 | ||||
|      * | ||||
|      * @return string|bool | ||||
|      */ | ||||
|     protected function validatePassword($old, $new1) | ||||
|     { | ||||
|         if ($new1 == $old) { | ||||
|             return 'The idea is to change your password.'; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param DeleteAccountFormRequest $request | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      * @throws \Exception | ||||
|      */ | ||||
|     public function postDeleteAccount(DeleteAccountFormRequest $request) | ||||
|     { | ||||
|         // old, new1, new2 | ||||
|         if (!Hash::check($request->get('password'), Auth::user()->password)) { | ||||
|             Session::flash('error', 'Invalid password!'); | ||||
|  | ||||
|             return Redirect::route('profile.delete-account'); | ||||
|         } | ||||
|  | ||||
|         // DELETE! | ||||
|         Auth::user()->delete(); | ||||
|         Session::flush(); | ||||
|         Session::flash('gaEventCategory', 'user'); | ||||
|         Session::flash('gaEventAction', 'delete-account'); | ||||
|  | ||||
|         return Redirect::route('index'); | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										92
									
								
								app/Http/Controllers/ReminderController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								app/Http/Controllers/ReminderController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use FireflyIII\Models\Reminder; | ||||
| use FireflyIII\Repositories\Reminder\ReminderRepositoryInterface; | ||||
| use Redirect; | ||||
| use Session; | ||||
| use URL; | ||||
|  | ||||
| /** | ||||
|  * Class ReminderController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers | ||||
|  */ | ||||
| class ReminderController extends Controller | ||||
| { | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @param Reminder $reminder | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function act(Reminder $reminder) | ||||
|     { | ||||
|         $data = [ | ||||
|             'description'   => 'Money for piggy bank "' . $reminder->remindersable->name . '"', | ||||
|             'amount'        => round($reminder->metadata->perReminder, 2), | ||||
|             'account_to_id' => $reminder->remindersable->account_id, | ||||
|             'piggy_bank_id' => $reminder->remindersable_id, | ||||
|             'reminder_id'   => $reminder->id, | ||||
|         ]; | ||||
|         Session::flash('_old_input', $data); | ||||
|  | ||||
|         return Redirect::route('transactions.create', ['transfer']); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Reminder $reminder | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function dismiss(Reminder $reminder) | ||||
|     { | ||||
|         $reminder->notnow = true; | ||||
|         $reminder->save(); | ||||
|  | ||||
|         return Redirect::to(URL::previous()); | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param ReminderRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function index(ReminderRepositoryInterface $repository) | ||||
|     { | ||||
|  | ||||
|  | ||||
|         $active    = $repository->getActiveReminders(); | ||||
|         $expired   = $repository->getExpiredReminders(); | ||||
|         $inactive  = $repository->getInactiveReminders(); | ||||
|         $dismissed = $repository->getDismissedReminders(); | ||||
|  | ||||
|         $title         = 'Reminders'; | ||||
|         $mainTitleIcon = 'fa-clock-o'; | ||||
|  | ||||
|         return view('reminders.index', compact('dismissed', 'expired', 'inactive', 'active', 'title', 'mainTitleIcon')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Reminder $reminder | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function show(Reminder $reminder) | ||||
|     { | ||||
|         $title         = trans('firefly.reminder'); | ||||
|         $mainTitleIcon = 'fa-clock-o'; | ||||
|         if ($reminder->notnow === true) { | ||||
|             $subTitle = trans('firefly.dismissed_reminder_for_piggy', ['name' => $reminder->remindersable->name]); | ||||
|         } else { | ||||
|             $subTitle = trans('firefly.reminder_for_piggy', ['name' => $reminder->remindersable->name]); | ||||
|         } | ||||
|  | ||||
|         return view('reminders.show', compact('reminder', 'title', 'subTitle', 'mainTitleIcon')); | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										151
									
								
								app/Http/Controllers/ReportController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								app/Http/Controllers/ReportController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,151 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Helpers\Report\ReportHelperInterface; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use Session; | ||||
| use View; | ||||
|  | ||||
| /** | ||||
|  * Class ReportController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers | ||||
|  */ | ||||
| class ReportController extends Controller | ||||
| { | ||||
|  | ||||
|     /** @var ReportHelperInterface */ | ||||
|     protected $helper; | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @param ReportHelperInterface $helper | ||||
|      */ | ||||
|     public function __construct(ReportHelperInterface $helper) | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->helper = $helper; | ||||
|  | ||||
|         View::share('title', trans('firefly.reports')); | ||||
|         View::share('mainTitleIcon', 'fa-line-chart'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * | ||||
|      * @return View | ||||
|      * @internal param ReportHelperInterface $helper | ||||
|      */ | ||||
|     public function index(AccountRepositoryInterface $repository) | ||||
|     { | ||||
|         $start  = Session::get('first'); | ||||
|         $months = $this->helper->listOfMonths($start); | ||||
|  | ||||
|         // does the user have shared accounts? | ||||
|         $accounts  = $repository->getAccounts(['Default account', 'Asset account']); | ||||
|         $hasShared = false; | ||||
|  | ||||
|         /** @var Account $account */ | ||||
|         foreach ($accounts as $account) { | ||||
|             if ($account->getMeta('accountRole') == 'sharedAsset') { | ||||
|                 $hasShared = true; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|         return view('reports.index', compact('months', 'hasShared')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $year | ||||
|      * @param string $month | ||||
|      * | ||||
|      * @param bool   $shared | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function month($year = '2014', $month = '1', $shared = false) | ||||
|     { | ||||
|         $start            = new Carbon($year . '-' . $month . '-01'); | ||||
|         $subTitle         = trans('firefly.reportForMonth', ['month' => $start->formatLocalized($this->monthFormat)]); | ||||
|         $subTitleIcon     = 'fa-calendar'; | ||||
|         $end              = clone $start; | ||||
|         $incomeTopLength  = 8; | ||||
|         $expenseTopLength = 8; | ||||
|         if ($shared == 'shared') { | ||||
|             $shared   = true; | ||||
|             $subTitle = trans('firefly.reportForMonthShared', ['month' => $start->formatLocalized($this->monthFormat)]); | ||||
|         } | ||||
|  | ||||
|         $end->endOfMonth(); | ||||
|  | ||||
|         $accounts   = $this->helper->getAccountReport($start, $end, $shared); | ||||
|         $incomes    = $this->helper->getIncomeReport($start, $end, $shared); | ||||
|         $expenses   = $this->helper->getExpenseReport($start, $end, $shared); | ||||
|         $budgets    = $this->helper->getBudgetReport($start, $end, $shared); | ||||
|         $categories = $this->helper->getCategoryReport($start, $end, $shared); | ||||
|         $balance    = $this->helper->getBalanceReport($start, $end, $shared); | ||||
|         $bills      = $this->helper->getBillReport($start, $end, $shared); | ||||
|  | ||||
|         Session::flash('gaEventCategory', 'report'); | ||||
|         Session::flash('gaEventAction', 'month'); | ||||
|         Session::flash('gaEventLabel', $start->format('F Y')); | ||||
|  | ||||
|  | ||||
|         return view( | ||||
|             'reports.month', | ||||
|             compact( | ||||
|                 'start', 'shared', | ||||
|                 'subTitle', 'subTitleIcon', | ||||
|                 'accounts', | ||||
|                 'incomes', 'incomeTopLength', | ||||
|                 'expenses', 'expenseTopLength', | ||||
|                 'budgets', 'balance', | ||||
|                 'categories', | ||||
|                 'bills' | ||||
|             ) | ||||
|         ); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param      $year | ||||
|      * | ||||
|      * @param bool $shared | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function year($year, $shared = false) | ||||
|     { | ||||
|         $start            = new Carbon('01-01-' . $year); | ||||
|         $end              = clone $start; | ||||
|         $subTitle         = trans('firefly.reportForYear', ['year' => $year]); | ||||
|         $subTitleIcon     = 'fa-bar-chart'; | ||||
|         $incomeTopLength  = 8; | ||||
|         $expenseTopLength = 8; | ||||
|  | ||||
|         if ($shared == 'shared') { | ||||
|             $shared   = true; | ||||
|             $subTitle = trans('firefly.reportForYearShared', ['year' => $year]); | ||||
|         } | ||||
|         $end->endOfYear(); | ||||
|  | ||||
|         $accounts = $this->helper->getAccountReport($start, $end, $shared); | ||||
|         $incomes  = $this->helper->getIncomeReport($start, $end, $shared); | ||||
|         $expenses = $this->helper->getExpenseReport($start, $end, $shared); | ||||
|  | ||||
|         Session::flash('gaEventCategory', 'report'); | ||||
|         Session::flash('gaEventAction', 'year'); | ||||
|         Session::flash('gaEventLabel', $start->format('Y')); | ||||
|  | ||||
|         return view( | ||||
|             'reports.year', | ||||
|             compact('start', 'shared', 'accounts', 'incomes', 'expenses', 'subTitle', 'subTitleIcon', 'incomeTopLength', 'expenseTopLength') | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										45
									
								
								app/Http/Controllers/SearchController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								app/Http/Controllers/SearchController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use FireflyIII\Support\Search\SearchInterface; | ||||
| use Input; | ||||
|  | ||||
| /** | ||||
|  * Class SearchController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers | ||||
|  */ | ||||
| class SearchController extends Controller | ||||
| { | ||||
|     /** | ||||
|      * Results always come in the form of an array [results, count, fullCount] | ||||
|      * | ||||
|      * @param SearchInterface $searcher | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function index(SearchInterface $searcher) | ||||
|     { | ||||
|  | ||||
|         $subTitle = null; | ||||
|         $rawQuery = null; | ||||
|         $result   = []; | ||||
|         if (!is_null(Input::get('q')) && strlen(Input::get('q')) > 0) { | ||||
|             $rawQuery = trim(Input::get('q')); | ||||
|             $words    = explode(' ', $rawQuery); | ||||
|             $subTitle = trans('firefly.search_results_for', ['query' => $rawQuery]); | ||||
|  | ||||
|             $transactions = $searcher->searchTransactions($words); | ||||
|             $accounts     = $searcher->searchAccounts($words); | ||||
|             $categories   = $searcher->searchCategories($words); | ||||
|             $budgets      = $searcher->searchBudgets($words); | ||||
|             $tags         = $searcher->searchTags($words); | ||||
|             $result       = ['transactions' => $transactions, 'accounts' => $accounts, 'categories' => $categories, 'budgets' => $budgets, 'tags' => $tags]; | ||||
|  | ||||
|         } | ||||
|  | ||||
|         return view('search.index')->with('title', 'Search')->with('subTitle', $subTitle)->with( | ||||
|             'mainTitleIcon', 'fa-search' | ||||
|         )->with('query', $rawQuery)->with('result', $result); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										304
									
								
								app/Http/Controllers/TagController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										304
									
								
								app/Http/Controllers/TagController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,304 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Http\Requests\TagFormRequest; | ||||
| use FireflyIII\Models\Preference; | ||||
| use FireflyIII\Models\Tag; | ||||
| use FireflyIII\Repositories\Tag\TagRepositoryInterface; | ||||
| use Input; | ||||
| use Preferences; | ||||
| use Redirect; | ||||
| use Response; | ||||
| use Session; | ||||
| use URL; | ||||
| use View; | ||||
|  | ||||
| /** | ||||
|  * Class TagController | ||||
|  * | ||||
|  * Remember: a balancingAct takes at most one expense and one transfer. | ||||
|  *           an advancePayment takes at most one expense, infinite deposits and NO transfers. | ||||
|  * | ||||
|  *  transaction can only have one advancePayment OR balancingAct. | ||||
|  *  Other attempts to put in such a tag are blocked. | ||||
|  *  also show an error when editing a tag and it becomes either | ||||
|  *  of these two types. Or rather, block editing of the tag. | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers | ||||
|  */ | ||||
| class TagController extends Controller | ||||
| { | ||||
|  | ||||
|     public $tagOptions = []; | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         View::share('title', 'Tags'); | ||||
|         View::share('mainTitleIcon', 'fa-tags'); | ||||
|         View::share('hideTags', true); | ||||
|         $this->tagOptions = [ | ||||
|             'nothing'        => 'Just a regular tag.', | ||||
|             'balancingAct'   => 'The tag takes at most two transactions; an expense and a transfer. They\'ll balance each other out.', | ||||
|             'advancePayment' => 'The tag accepts one expense and any number of deposits aimed to repay the original expense.', | ||||
|         ]; | ||||
|         View::share('tagOptions', $this->tagOptions); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function create() | ||||
|     { | ||||
|         $subTitle     = trans('firefly.new_tag'); | ||||
|         $subTitleIcon = 'fa-tag'; | ||||
|  | ||||
|         $preFilled = [ | ||||
|             'tagMode' => 'nothing' | ||||
|         ]; | ||||
|         if (!Input::old('tagMode')) { | ||||
|             Session::flash('preFilled', $preFilled); | ||||
|         } | ||||
|         // put previous url in session if not redirect from store (not "create another"). | ||||
|         if (Session::get('tags.create.fromStore') !== true) { | ||||
|             Session::put('tags.create.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('tags.create.fromStore'); | ||||
|         Session::flash('gaEventCategory', 'tags'); | ||||
|         Session::flash('gaEventAction', 'create'); | ||||
|  | ||||
|         return view('tags.create', compact('subTitle', 'subTitleIcon')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Tag $tag | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function delete(Tag $tag) | ||||
|     { | ||||
|         $subTitle = trans('firefly.delete_tag', ['name' => $tag->tag]); | ||||
|  | ||||
|         // put previous url in session | ||||
|         Session::put('tags.delete.url', URL::previous()); | ||||
|         Session::flash('gaEventCategory', 'tags'); | ||||
|         Session::flash('gaEventAction', 'delete'); | ||||
|  | ||||
|         return view('tags.delete', compact('tag', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TagRepositoryInterface $repository | ||||
|      * @param Tag                    $tag | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function destroy(TagRepositoryInterface $repository, Tag $tag) | ||||
|     { | ||||
|  | ||||
|         $tagName = $tag->tag; | ||||
|         $repository->destroy($tag); | ||||
|  | ||||
|         Session::flash('success', 'Tag "' . e($tagName) . '" was deleted.'); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         return Redirect::to(route('tags.index')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Tag                    $tag | ||||
|      * | ||||
|      * @param TagRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function edit(Tag $tag, TagRepositoryInterface $repository) | ||||
|     { | ||||
|         $subTitle     = trans('firefly.edit_tag', ['tag' => $tag->tag]); | ||||
|         $subTitleIcon = 'fa-tag'; | ||||
|  | ||||
|         /* | ||||
|          * Default tag options (again) | ||||
|          */ | ||||
|         $tagOptions = $this->tagOptions; | ||||
|  | ||||
|         /* | ||||
|          * Can this tag become another type? | ||||
|          */ | ||||
|         $allowAdvance        = $repository->tagAllowAdvance($tag); | ||||
|         $allowToBalancingAct = $repository->tagAllowBalancing($tag); | ||||
|  | ||||
|         // edit tag options: | ||||
|         if ($allowAdvance === false) { | ||||
|             unset($tagOptions['advancePayment']); | ||||
|         } | ||||
|         if ($allowToBalancingAct === false) { | ||||
|             unset($tagOptions['balancingAct']); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         // put previous url in session if not redirect from store (not "return_to_edit"). | ||||
|         if (Session::get('tags.edit.fromUpdate') !== true) { | ||||
|             Session::put('tags.edit.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('tags.edit.fromUpdate'); | ||||
|         Session::flash('gaEventCategory', 'tags'); | ||||
|         Session::flash('gaEventAction', 'edit'); | ||||
|  | ||||
|         return view('tags.edit', compact('tag', 'subTitle', 'subTitleIcon', 'tagOptions')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $state | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function hideTagHelp($state) | ||||
|     { | ||||
|  | ||||
|         $state = $state == 'true' ? true : false; | ||||
|         Preferences::set('hideTagHelp', $state); | ||||
|  | ||||
|         return Response::json([true]); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function index() | ||||
|     { | ||||
|         /** @var Preference $helpHiddenPref */ | ||||
|         $helpHiddenPref = Preferences::get('hideTagHelp', false); | ||||
|         $title          = 'Tags'; | ||||
|         $mainTitleIcon  = 'fa-tags'; | ||||
|         $helpHidden     = $helpHiddenPref->data; | ||||
|  | ||||
|         // group years. | ||||
|         $types = ['nothing','balancingAct', 'advancePayment']; | ||||
|  | ||||
|         // loop each types and get the tags, group them by year. | ||||
|         $collection = []; | ||||
|         foreach ($types as $type) { | ||||
|             $tags = Auth::user()->tags()->where('tagMode', $type)->orderBy('date','ASC')->get(); | ||||
|             /** @var Tag $tag */ | ||||
|             foreach ($tags as $tag) { | ||||
|                 $year                               = is_null($tag->date) ? trans('firefly.no_year') : $tag->date->year; | ||||
|                 $month                              = is_null($tag->date) ? trans('firefly.no_month') : $tag->date->formatLocalized($this->monthFormat); | ||||
|                 $collection[$type][$year][$month][] = $tag; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|         return view('tags.index', compact('title', 'mainTitleIcon','types', 'helpHidden', 'collection')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Tag $tag | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function show(Tag $tag) | ||||
|     { | ||||
|         $subTitle     = $tag->tag; | ||||
|         $subTitleIcon = 'fa-tag'; | ||||
|  | ||||
|         return view('tags.show', compact('tag', 'subTitle','types', 'subTitleIcon')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TagFormRequest         $request | ||||
|      * | ||||
|      * @param TagRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function store(TagFormRequest $request, TagRepositoryInterface $repository) | ||||
|     { | ||||
|         if (Input::get('setTag') == 'true') { | ||||
|             $latitude  = strlen($request->get('latitude')) > 0 ? $request->get('latitude') : null; | ||||
|             $longitude = strlen($request->get('longitude')) > 0 ? $request->get('longitude') : null; | ||||
|             $zoomLevel = strlen($request->get('zoomLevel')) > 0 ? $request->get('zoomLevel') : null; | ||||
|         } else { | ||||
|             $latitude  = null; | ||||
|             $longitude = null; | ||||
|             $zoomLevel = null; | ||||
|         } | ||||
|  | ||||
|         $data = [ | ||||
|             'tag'         => $request->get('tag'), | ||||
|             'date'        => strlen($request->get('date')) > 0 ? new Carbon($request->get('date')) : null, | ||||
|             'description' => strlen($request->get('description')) > 0 ? $request->get('description') : '', | ||||
|             'latitude'    => $latitude, | ||||
|             'longitude'   => $longitude, | ||||
|             'zoomLevel'   => $zoomLevel, | ||||
|             'tagMode'     => $request->get('tagMode'), | ||||
|         ]; | ||||
|         $repository->store($data); | ||||
|  | ||||
|         Session::flash('success', 'The tag has been created!'); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         if (intval(Input::get('create_another')) === 1) { | ||||
|             // set value so create routine will not overwrite URL: | ||||
|             Session::put('tags.create.fromStore', true); | ||||
|  | ||||
|             return Redirect::route('tags.create')->withInput(); | ||||
|         } | ||||
|  | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('tags.create.url')); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TagFormRequest         $request | ||||
|      * @param TagRepositoryInterface $repository | ||||
|      * @param Tag                    $tag | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function update(TagFormRequest $request, TagRepositoryInterface $repository, Tag $tag) | ||||
|     { | ||||
|         if (Input::get('setTag') == 'true') { | ||||
|             $latitude  = $request->get('latitude'); | ||||
|             $longitude = $request->get('longitude'); | ||||
|             $zoomLevel = $request->get('zoomLevel'); | ||||
|         } else { | ||||
|             $latitude  = null; | ||||
|             $longitude = null; | ||||
|             $zoomLevel = null; | ||||
|         } | ||||
|  | ||||
|         $data = [ | ||||
|             'tag'         => $request->get('tag'), | ||||
|             'date'        => strlen($request->get('date')) > 0 ? new Carbon($request->get('date')) : null, | ||||
|             'description' => strlen($request->get('description')) > 0 ? $request->get('description') : '', | ||||
|             'latitude'    => $latitude, | ||||
|             'longitude'   => $longitude, | ||||
|             'zoomLevel'   => $zoomLevel, | ||||
|             'tagMode'     => $request->get('tagMode'), | ||||
|         ]; | ||||
|  | ||||
|  | ||||
|         $repository->update($tag, $data); | ||||
|  | ||||
|         Session::flash('success', 'Tag "' . e($data['tag']) . '" updated.'); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         if (intval(Input::get('return_to_edit')) === 1) { | ||||
|             // set value so edit routine will not overwrite URL: | ||||
|             Session::put('tags.edit.fromUpdate', true); | ||||
|  | ||||
|             return Redirect::route('tags.edit', [$tag->id])->withInput(['return_to_edit' => 1]); | ||||
|         } | ||||
|  | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('tags.edit.url')); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										348
									
								
								app/Http/Controllers/TransactionController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										348
									
								
								app/Http/Controllers/TransactionController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,348 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use ExpandedForm; | ||||
| use FireflyIII\Events\JournalCreated; | ||||
| use FireflyIII\Events\JournalSaved; | ||||
| use FireflyIII\Http\Requests\JournalFormRequest; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Repositories\Journal\JournalRepositoryInterface; | ||||
| use Input; | ||||
| use Preferences; | ||||
| use Redirect; | ||||
| use Response; | ||||
| use Session; | ||||
| use URL; | ||||
| use View; | ||||
|  | ||||
| /** | ||||
|  * Class TransactionController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers | ||||
|  */ | ||||
| class TransactionController extends Controller | ||||
| { | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         View::share('title', trans('firefly.transactions')); | ||||
|         View::share('mainTitleIcon', 'fa-repeat'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * @param string                     $what | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function create(AccountRepositoryInterface $repository, $what = 'deposit') | ||||
|     { | ||||
|         $accounts   = ExpandedForm::makeSelectList($repository->getAccounts(['Default account', 'Asset account'])); | ||||
|         $budgets    = ExpandedForm::makeSelectList(Auth::user()->budgets()->get()); | ||||
|         $budgets[0] = trans('form.noBudget'); | ||||
|         $piggies    = ExpandedForm::makeSelectList(Auth::user()->piggyBanks()->get()); | ||||
|         $piggies[0] = trans('form.noPiggybank'); | ||||
|         $preFilled  = Session::has('preFilled') ? Session::get('preFilled') : []; | ||||
|         $respondTo  = ['account_id', 'account_from_id']; | ||||
|         $subTitle   = trans('form.add_new_' . $what); | ||||
|  | ||||
|         foreach ($respondTo as $r) { | ||||
|             $preFilled[$r] = Input::get($r); | ||||
|         } | ||||
|         Session::put('preFilled', $preFilled); | ||||
|  | ||||
|         // put previous url in session if not redirect from store (not "create another"). | ||||
|         if (Session::get('transactions.create.fromStore') !== true) { | ||||
|             Session::put('transactions.create.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('transactions.create.fromStore'); | ||||
|         Session::flash('gaEventCategory', 'transactions'); | ||||
|         Session::flash('gaEventAction', 'create-' . $what); | ||||
|  | ||||
|         asort($piggies); | ||||
|  | ||||
|  | ||||
|         return view('transactions.create', compact('accounts', 'budgets', 'what', 'piggies', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Shows the form that allows a user to delete a transaction journal. | ||||
|      * | ||||
|      * @param TransactionJournal $journal | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function delete(TransactionJournal $journal) | ||||
|     { | ||||
|         $what     = strtolower($journal->transactionType->type); | ||||
|         $subTitle = trans('firefly.delete_' . $what, ['description' => $journal->description]); | ||||
|  | ||||
|         // put previous url in session | ||||
|         Session::put('transactions.delete.url', URL::previous()); | ||||
|         Session::flash('gaEventCategory', 'transactions'); | ||||
|         Session::flash('gaEventAction', 'delete-' . $what); | ||||
|  | ||||
|         return view('transactions.delete', compact('journal', 'subTitle', 'what')); | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param JournalRepositoryInterface $repository | ||||
|      * @param TransactionJournal         $transactionJournal | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function destroy(JournalRepositoryInterface $repository, TransactionJournal $transactionJournal) | ||||
|     { | ||||
|         Session::flash('success', 'Transaction "' . e($transactionJournal->description) . '" destroyed.'); | ||||
|  | ||||
|         $repository->delete($transactionJournal); | ||||
|  | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         // redirect to previous URL: | ||||
|         return Redirect::to(Session::get('transactions.delete.url')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Shows the view to edit a transaction. | ||||
|      * | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * @param TransactionJournal         $journal | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function edit(AccountRepositoryInterface $repository, TransactionJournal $journal) | ||||
|     { | ||||
|         $what       = strtolower($journal->transactionType->type); | ||||
|         $accounts   = ExpandedForm::makeSelectList($repository->getAccounts(['Default account', 'Asset account'])); | ||||
|         $budgets    = ExpandedForm::makeSelectList(Auth::user()->budgets()->get()); | ||||
|         $budgets[0] = trans('form.noBudget'); | ||||
|         $piggies    = ExpandedForm::makeSelectList(Auth::user()->piggyBanks()->get()); | ||||
|         $piggies[0] = trans('form.noPiggybank'); | ||||
|         $subTitle   = trans('breadcrumbs.edit_journal', ['description' => $journal->description]); | ||||
|         $preFilled  = [ | ||||
|             'date'          => $journal->date->format('Y-m-d'), | ||||
|             'category'      => '', | ||||
|             'budget_id'     => 0, | ||||
|             'piggy_bank_id' => 0 | ||||
|         ]; | ||||
|         // get tags: | ||||
|         $tags = []; | ||||
|         foreach ($journal->tags as $tag) { | ||||
|             $tags[] = $tag->tag; | ||||
|         } | ||||
|         $preFilled['tags'] = join(',', $tags); | ||||
|  | ||||
|         $category = $journal->categories()->first(); | ||||
|         if (!is_null($category)) { | ||||
|             $preFilled['category'] = $category->name; | ||||
|         } | ||||
|  | ||||
|         $budget = $journal->budgets()->first(); | ||||
|         if (!is_null($budget)) { | ||||
|             $preFilled['budget_id'] = $budget->id; | ||||
|         } | ||||
|  | ||||
|         if ($journal->piggyBankEvents()->count() > 0) { | ||||
|             $preFilled['piggy_bank_id'] = $journal->piggyBankEvents()->orderBy('date', 'DESC')->first()->piggy_bank_id; | ||||
|         } | ||||
|  | ||||
|         $preFilled['amount'] = $journal->actual_amount; | ||||
|  | ||||
|         if ($journal->transactionType->type == 'Withdrawal') { | ||||
|             $preFilled['account_id']      = $journal->source_account->id; | ||||
|             $preFilled['expense_account'] = $journal->destination_account->name; | ||||
|         } else { | ||||
|             $preFilled['account_id']      = $journal->destination_account->id; | ||||
|             $preFilled['revenue_account'] = $journal->source_account->name; | ||||
|         } | ||||
|  | ||||
|         if ($journal->destination_account->accountType->type == 'Cash account') { | ||||
|             $preFilled['expense_account'] = ''; | ||||
|         } | ||||
|         if ($journal->source_account->accountType->type == 'Cash account') { | ||||
|             $preFilled['revenue_account'] = ''; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         $preFilled['account_from_id'] = $journal->source_account->id; | ||||
|         $preFilled['account_to_id']   = $journal->destination_account->id; | ||||
|  | ||||
|         Session::flash('preFilled', $preFilled); | ||||
|         Session::flash('gaEventCategory', 'transactions'); | ||||
|         Session::flash('gaEventAction', 'edit-' . $what); | ||||
|  | ||||
|         // put previous url in session if not redirect from store (not "return_to_edit"). | ||||
|         if (Session::get('transactions.edit.fromUpdate') !== true) { | ||||
|             Session::put('transactions.edit.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('transactions.edit.fromUpdate'); | ||||
|  | ||||
|  | ||||
|         return View::make('transactions.edit', compact('journal', 'accounts', 'what', 'budgets', 'piggies', 'subTitle'))->with('data', $preFilled); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param JournalRepositoryInterface $repository | ||||
|      * @param                            $what | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function index(JournalRepositoryInterface $repository, $what) | ||||
|     { | ||||
|         $types = []; | ||||
|         switch ($what) { | ||||
|             case 'expenses': | ||||
|             case 'withdrawal': | ||||
|                 $subTitleIcon = 'fa-long-arrow-left'; | ||||
|                 $subTitle     = trans('firefly.expenses'); | ||||
|                 $types        = ['Withdrawal']; | ||||
|                 break; | ||||
|             case 'revenue': | ||||
|             case 'deposit': | ||||
|                 $subTitleIcon = 'fa-long-arrow-right'; | ||||
|                 $subTitle     = trans('firefly.income'); | ||||
|                 $types        = ['Deposit']; | ||||
|                 break; | ||||
|             case 'transfer': | ||||
|             case 'transfers': | ||||
|                 $subTitleIcon = 'fa-exchange'; | ||||
|                 $subTitle     = trans('firefly.transfers'); | ||||
|                 $types        = ['Transfer']; | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         $page     = intval(Input::get('page')); | ||||
|         $offset   = $page > 0 ? ($page - 1) * 50 : 0; | ||||
|         $journals = $repository->getJournalsOfTypes($types, $offset, $page); | ||||
|  | ||||
|         $journals->setPath('transactions/' . $what); | ||||
|  | ||||
|         return view('transactions.index', compact('subTitle', 'what', 'subTitleIcon', 'journals')); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param JournalRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function reorder(JournalRepositoryInterface $repository) | ||||
|     { | ||||
|         $ids  = Input::get('items'); | ||||
|         $date = new Carbon(Input::get('date')); | ||||
|         if (count($ids) > 0) { | ||||
|             $order = 0; | ||||
|             foreach ($ids as $id) { | ||||
|  | ||||
|                 $journal = $repository->getWithDate($id, $date); | ||||
|                 if ($journal) { | ||||
|                     $journal->order = $order; | ||||
|                     $order++; | ||||
|                     $journal->save(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         return Response::json([true]); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param JournalRepositoryInterface $repository | ||||
|      * @param TransactionJournal         $journal | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function show(JournalRepositoryInterface $repository, TransactionJournal $journal) | ||||
|     { | ||||
|         $journal->transactions->each( | ||||
|             function (Transaction $t) use ($journal, $repository) { | ||||
|                 $t->before = $repository->getAmountBefore($journal, $t); | ||||
|                 $t->after  = $t->before + $t->amount; | ||||
|             } | ||||
|         ); | ||||
|         $what     = strtolower($journal->transactionType->type); | ||||
|         $subTitle = trans('firefly.' . $journal->transactionType->type) . ' "' . e($journal->description) . '"'; | ||||
|  | ||||
|         return view('transactions.show', compact('journal', 'subTitle', 'what')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param JournalFormRequest         $request | ||||
|      * @param JournalRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function store(JournalFormRequest $request, JournalRepositoryInterface $repository) | ||||
|     { | ||||
|  | ||||
|         $journalData = $request->getJournalData(); | ||||
|         $journal     = $repository->store($journalData); | ||||
|  | ||||
|         // rescan journal, UpdateJournalConnection | ||||
|         event(new JournalSaved($journal)); | ||||
|         // ConnectJournalToPiggyBank | ||||
|         if ($journal->transactionType->type == 'Transfer' && intval($request->get('piggy_bank_id')) > 0) { | ||||
|             event(new JournalCreated($journal, intval($request->get('piggy_bank_id')))); | ||||
|         } | ||||
|  | ||||
|         $repository->deactivateReminder($request->get('reminder_id')); | ||||
|  | ||||
|         Session::flash('success', 'New transaction "' . $journal->description . '" stored!'); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         if (intval(Input::get('create_another')) === 1) { | ||||
|             // set value so create routine will not overwrite URL: | ||||
|             Session::put('transactions.create.fromStore', true); | ||||
|  | ||||
|             return Redirect::route('transactions.create', [$request->input('what')])->withInput(); | ||||
|         } | ||||
|  | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('transactions.create.url')); | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @param JournalFormRequest         $request | ||||
|      * @param JournalRepositoryInterface $repository | ||||
|      * @param TransactionJournal         $journal | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function update(JournalFormRequest $request, JournalRepositoryInterface $repository, TransactionJournal $journal) | ||||
|     { | ||||
|  | ||||
|         $journalData = $request->getJournalData(); | ||||
|         $repository->update($journal, $journalData); | ||||
|  | ||||
|         event(new JournalSaved($journal)); | ||||
|         // update, get events by date and sort DESC | ||||
|  | ||||
|         Session::flash('success', 'Transaction "' . e($journalData['description']) . '" updated.'); | ||||
|         Preferences::mark(); | ||||
|  | ||||
|         if (intval(Input::get('return_to_edit')) === 1) { | ||||
|             // set value so edit routine will not overwrite URL: | ||||
|             Session::put('transactions.edit.fromUpdate', true); | ||||
|  | ||||
|             return Redirect::route('transactions.edit', [$journal->id])->withInput(['return_to_edit' => 1]); | ||||
|         } | ||||
|  | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('transactions.edit.url')); | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										44
									
								
								app/Http/Kernel.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								app/Http/Kernel.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| <?php namespace FireflyIII\Http; | ||||
|  | ||||
| use Illuminate\Foundation\Http\Kernel as HttpKernel; | ||||
|  | ||||
| /** | ||||
|  * Class Kernel | ||||
|  * | ||||
|  * @package FireflyIII\Http | ||||
|  */ | ||||
| class Kernel extends HttpKernel | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * The application's global HTTP middleware stack. | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $middleware | ||||
|         = [ | ||||
|             'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode', | ||||
|             'Illuminate\Cookie\Middleware\EncryptCookies', | ||||
|             'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse', | ||||
|             'Illuminate\Session\Middleware\StartSession', | ||||
|             'Illuminate\View\Middleware\ShareErrorsFromSession', | ||||
|             'FireflyIII\Http\Middleware\ReplaceTestVars', | ||||
|             'FireflyIII\Http\Middleware\VerifyCsrfToken', | ||||
|         ]; | ||||
|  | ||||
|     /** | ||||
|      * The application's route middleware. | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $routeMiddleware | ||||
|         = [ | ||||
|             'auth'       => 'FireflyIII\Http\Middleware\Authenticate', | ||||
|             'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth', | ||||
|             'guest'      => 'FireflyIII\Http\Middleware\RedirectIfAuthenticated', | ||||
|             'range'      => 'FireflyIII\Http\Middleware\Range', | ||||
|             'reminders'  => 'FireflyIII\Http\Middleware\Reminders', | ||||
|  | ||||
|         ]; | ||||
|  | ||||
| } | ||||
							
								
								
									
										65
									
								
								app/Http/Middleware/Authenticate.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								app/Http/Middleware/Authenticate.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| <?php namespace FireflyIII\Http\Middleware; | ||||
|  | ||||
| use App; | ||||
| use Carbon\Carbon; | ||||
| use Closure; | ||||
| use Config; | ||||
| use Illuminate\Contracts\Auth\Guard; | ||||
| use Illuminate\Http\Request; | ||||
| use Preferences; | ||||
|  | ||||
| /** | ||||
|  * Class Authenticate | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Http\Middleware | ||||
|  */ | ||||
| class Authenticate | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * The Guard implementation. | ||||
|      * | ||||
|      * @var Guard | ||||
|      */ | ||||
|     protected $auth; | ||||
|  | ||||
|     /** | ||||
|      * Create a new filter instance. | ||||
|      * | ||||
|      * @param  Guard $auth | ||||
|      * | ||||
|      */ | ||||
|     public function __construct(Guard $auth) | ||||
|     { | ||||
|         $this->auth = $auth; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Handle an incoming request. | ||||
|      * | ||||
|      * @param  \Illuminate\Http\Request $request | ||||
|      * @param  \Closure                 $next | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function handle(Request $request, Closure $next) | ||||
|     { | ||||
|         if ($this->auth->guest()) { | ||||
|             if ($request->ajax()) { | ||||
|                 return response('Unauthorized.', 401); | ||||
|             } else { | ||||
|                 return redirect()->guest('auth/login'); | ||||
|             } | ||||
|         } | ||||
|         // if logged in, set user language: | ||||
|         $pref = Preferences::get('language', 'en'); | ||||
|         App::setLocale($pref->data); | ||||
|         Carbon::setLocale($pref->data); | ||||
|  | ||||
|         setlocale(LC_TIME, Config::get('firefly.locales.' . $pref->data)); | ||||
|  | ||||
|         return $next($request); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										88
									
								
								app/Http/Middleware/Range.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								app/Http/Middleware/Range.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | ||||
| <?php | ||||
|  | ||||
|  | ||||
| namespace FireflyIII\Http\Middleware; | ||||
|  | ||||
| use App; | ||||
| use Carbon\Carbon; | ||||
| use Closure; | ||||
| use Illuminate\Contracts\Auth\Guard; | ||||
| use Illuminate\Http\Request; | ||||
| use Navigation; | ||||
| use Preferences; | ||||
| use Session; | ||||
| use View; | ||||
|  | ||||
| /** | ||||
|  * Class SessionFilter | ||||
|  * | ||||
|  * @package FireflyIII\Http\Middleware | ||||
|  */ | ||||
| class Range | ||||
| { | ||||
|     /** | ||||
|      * The Guard implementation. | ||||
|      * | ||||
|      * @var Guard | ||||
|      */ | ||||
|     protected $auth; | ||||
|  | ||||
|     /** | ||||
|      * Create a new filter instance. | ||||
|      * | ||||
|      * @param  Guard $auth | ||||
|      * | ||||
|      */ | ||||
|     public function __construct(Guard $auth) | ||||
|     { | ||||
|         $this->auth = $auth; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Handle an incoming request. | ||||
|      * | ||||
|      * @param  \Illuminate\Http\Request $request | ||||
|      * @param  \Closure                 $theNext | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function handle(Request $request, Closure $theNext) | ||||
|     { | ||||
|         if ($this->auth->check()) { | ||||
|  | ||||
|             // ignore preference. set the range to be the current month: | ||||
|             if (!Session::has('start') && !Session::has('end')) { | ||||
|  | ||||
|                 /** @var \FireflyIII\Models\Preference $viewRange */ | ||||
|                 $viewRange = Preferences::get('viewRange', '1M')->data; | ||||
|                 $start     = new Carbon; | ||||
|                 $start     = Navigation::updateStartDate($viewRange, $start); | ||||
|                 $end       = Navigation::updateEndDate($viewRange, $start); | ||||
|  | ||||
|                 Session::put('start', $start); | ||||
|                 Session::put('end', $end); | ||||
|             } | ||||
|             if (!Session::has('first')) { | ||||
|                 /** @var \FireflyIII\Repositories\Journal\JournalRepositoryInterface $repository */ | ||||
|                 $repository = App::make('FireflyIII\Repositories\Journal\JournalRepositoryInterface'); | ||||
|                 $journal    = $repository->first(); | ||||
|                 if ($journal) { | ||||
|                     Session::put('first', $journal->date); | ||||
|                 } else { | ||||
|                     Session::put('first', Carbon::now()->startOfYear()); | ||||
|                 } | ||||
|             } | ||||
|             $current = Carbon::now()->formatLocalized('%B %Y'); | ||||
|             $next    = Carbon::now()->endOfMonth()->addDay()->formatLocalized('%B %Y'); | ||||
|             $prev    = Carbon::now()->startOfMonth()->subDay()->formatLocalized('%B %Y'); | ||||
|             View::share('currentMonthName', $current); | ||||
|             View::share('previousMonthName', $prev); | ||||
|             View::share('nextMonthName', $next); | ||||
|         } | ||||
|  | ||||
|         return $theNext($request); | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										52
									
								
								app/Http/Middleware/RedirectIfAuthenticated.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								app/Http/Middleware/RedirectIfAuthenticated.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| <?php namespace FireflyIII\Http\Middleware; | ||||
|  | ||||
| use Closure; | ||||
| use Illuminate\Contracts\Auth\Guard; | ||||
| use Illuminate\Http\RedirectResponse; | ||||
| use Illuminate\Http\Request; | ||||
|  | ||||
| /** | ||||
|  * Class RedirectIfAuthenticated | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Http\Middleware | ||||
|  */ | ||||
| class RedirectIfAuthenticated | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * The Guard implementation. | ||||
|      * | ||||
|      * @var Guard | ||||
|      */ | ||||
|     protected $auth; | ||||
|  | ||||
|     /** | ||||
|      * Create a new filter instance. | ||||
|      * | ||||
|      * @param  Guard $auth | ||||
|      * | ||||
|      */ | ||||
|     public function __construct(Guard $auth) | ||||
|     { | ||||
|         $this->auth = $auth; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Handle an incoming request. | ||||
|      * | ||||
|      * @param  \Illuminate\Http\Request $request | ||||
|      * @param  \Closure                 $next | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function handle(Request $request, Closure $next) | ||||
|     { | ||||
|         if ($this->auth->check()) { | ||||
|             return new RedirectResponse(url('/')); | ||||
|         } | ||||
|  | ||||
|         return $next($request); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										96
									
								
								app/Http/Middleware/Reminders.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								app/Http/Middleware/Reminders.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Http\Middleware; | ||||
|  | ||||
| use App; | ||||
| use Carbon\Carbon; | ||||
| use Closure; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Models\Reminder; | ||||
| use FireflyIII\Support\CacheProperties; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Contracts\Auth\Guard; | ||||
| use Illuminate\Http\Request; | ||||
| use View; | ||||
|  | ||||
| /** | ||||
|  * Class Reminders | ||||
|  * | ||||
|  * @package FireflyIII\Http\Middleware | ||||
|  */ | ||||
| class Reminders | ||||
| { | ||||
|     /** | ||||
|      * The Guard implementation. | ||||
|      * | ||||
|      * @var Guard | ||||
|      */ | ||||
|     protected $auth; | ||||
|  | ||||
|     /** | ||||
|      * Create a new filter instance. | ||||
|      * | ||||
|      * @param  Guard $auth | ||||
|      * | ||||
|      */ | ||||
|     public function __construct(Guard $auth) | ||||
|     { | ||||
|         $this->auth = $auth; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Handle an incoming request. | ||||
|      * | ||||
|      * @param  \Illuminate\Http\Request $request | ||||
|      * @param  \Closure                 $next | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function handle(Request $request, Closure $next) | ||||
|     { | ||||
|  | ||||
|  | ||||
|         $user = $this->auth->user(); | ||||
|         if ($this->auth->check() && !$request->isXmlHttpRequest() && $user instanceof User) { | ||||
|             // do reminders stuff. | ||||
|  | ||||
|             // abuse CacheProperties to find out if we need to do this: | ||||
|             $cache = new CacheProperties; | ||||
|  | ||||
|             $cache->addProperty('reminders'); | ||||
|             if ($cache->has()) { | ||||
|                 $reminders = $cache->get(); | ||||
|                 View::share('reminders', $reminders); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
|  | ||||
|             $piggyBanks = $user->piggyBanks()->where('remind_me', 1)->get(); | ||||
|  | ||||
|             /** @var \FireflyIII\Helpers\Reminders\ReminderHelperInterface $helper */ | ||||
|             $helper = App::make('FireflyIII\Helpers\Reminders\ReminderHelperInterface'); | ||||
|  | ||||
|             /** @var PiggyBank $piggyBank */ | ||||
|             foreach ($piggyBanks as $piggyBank) { | ||||
|                 $helper->createReminders($piggyBank, new Carbon); | ||||
|             } | ||||
|             // delete invalid reminders | ||||
|             // this is a construction SQLITE cannot handle :( | ||||
|             if (env('DB_CONNECTION') != 'sqlite') { | ||||
|                 Reminder::whereUserId($user->id)->leftJoin('piggy_banks', 'piggy_banks.id', '=', 'remindersable_id')->whereNull('piggy_banks.id')->delete(); | ||||
|             } | ||||
|  | ||||
|             // get and list active reminders: | ||||
|             $reminders = $user->reminders()->today()->get(); | ||||
|             $reminders->each( | ||||
|                 function (Reminder $reminder) use ($helper) { | ||||
|                     $reminder->description = $helper->getReminderText($reminder); | ||||
|                 } | ||||
|             ); | ||||
|             $cache->store($reminders); | ||||
|             View::share('reminders', $reminders); | ||||
|         } | ||||
|  | ||||
|         return $next($request); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										57
									
								
								app/Http/Middleware/ReplaceTestVars.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								app/Http/Middleware/ReplaceTestVars.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Http\Middleware; | ||||
|  | ||||
| use Closure; | ||||
| use Illuminate\Contracts\Foundation\Application; | ||||
| use Illuminate\Http\Request; | ||||
| use Log; | ||||
|  | ||||
| /** | ||||
|  * Class ReplaceTestVars | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Http\Middleware | ||||
|  */ | ||||
| class ReplaceTestVars | ||||
| { | ||||
|     /** | ||||
|      * The application implementation. | ||||
|      * | ||||
|      * @var Application | ||||
|      */ | ||||
|     protected $app; | ||||
|  | ||||
|     /** | ||||
|      * Create a new filter instance. | ||||
|      * | ||||
|      * @param Application $app | ||||
|      * | ||||
|      */ | ||||
|     public function __construct(Application $app) | ||||
|     { | ||||
|         $this->app = $app; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Handle an incoming request. | ||||
|      * | ||||
|      * @param \Illuminate\Http\Request $request | ||||
|      * @param \Closure                 $next | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function handle(Request $request, Closure $next) | ||||
|     { | ||||
|         if ('testing' === $this->app->environment() && $request->has('_token')) { | ||||
|             $input           = $request->all(); | ||||
|             $input['_token'] = $request->session()->token(); | ||||
|             // we need to update _token value to make sure we get the POST / PUT tests passed. | ||||
|             Log::debug('Input token replaced (' . $input['_token'] . ').'); | ||||
|             $request->replace($input); | ||||
|         } | ||||
|  | ||||
|         return $next($request); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										28
									
								
								app/Http/Middleware/VerifyCsrfToken.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								app/Http/Middleware/VerifyCsrfToken.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| <?php namespace FireflyIII\Http\Middleware; | ||||
|  | ||||
| use Closure; | ||||
| use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier; | ||||
|  | ||||
| /** | ||||
|  * Class VerifyCsrfToken | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Http\Middleware | ||||
|  */ | ||||
| class VerifyCsrfToken extends BaseVerifier | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * Handle an incoming request. | ||||
|      * | ||||
|      * @param  \Illuminate\Http\Request $request | ||||
|      * @param  \Closure                 $next | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function handle($request, Closure $next) | ||||
|     { | ||||
|         return parent::handle($request, $next); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										57
									
								
								app/Http/Requests/AccountFormRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								app/Http/Requests/AccountFormRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Http\Requests; | ||||
|  | ||||
| use Auth; | ||||
| use Config; | ||||
| use FireflyIII\Models\Account; | ||||
| use Input; | ||||
|  | ||||
| /** | ||||
|  * Class AccountFormRequest | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Http\Requests | ||||
|  */ | ||||
| class AccountFormRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize() | ||||
|     { | ||||
|         // Only allow logged in users | ||||
|         return Auth::check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules() | ||||
|     { | ||||
|         $accountRoles   = join(',', array_keys(Config::get('firefly.accountRoles'))); | ||||
|         $types          = join(',', array_keys(Config::get('firefly.subTitlesByIdentifier'))); | ||||
|         $ccPaymentTypes = join(',', array_keys(Config::get('firefly.ccTypes'))); | ||||
|  | ||||
|         $nameRule = 'required|min:1|uniqueAccountForUser'; | ||||
|         $idRule   = ''; | ||||
|         if (Account::find(Input::get('id'))) { | ||||
|             $idRule   = 'belongsToUser:accounts'; | ||||
|             $nameRule = 'required|min:1|uniqueAccountForUser:' . Input::get('id'); | ||||
|         } | ||||
|  | ||||
|         return [ | ||||
|             'id'                   => $idRule, | ||||
|             'name'                 => $nameRule, | ||||
|             'openingBalance'       => 'numeric', | ||||
|             'virtualBalance'       => 'numeric', | ||||
|             'openingBalanceDate'   => 'date', | ||||
|             'accountRole'          => 'in:' . $accountRoles, | ||||
|             'active'               => 'boolean', | ||||
|             'ccType'               => 'in:' . $ccPaymentTypes, | ||||
|             'ccMonthlyPaymentDate' => 'date', | ||||
|             'balance_currency_id'  => 'exists:transaction_currencies,id', | ||||
|             'what'                 => 'in:' . $types | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										73
									
								
								app/Http/Requests/BillFormRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								app/Http/Requests/BillFormRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Http\Requests; | ||||
|  | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use Input; | ||||
|  | ||||
| /** | ||||
|  * Class BillFormRequest | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Http\Requests | ||||
|  */ | ||||
| class BillFormRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize() | ||||
|     { | ||||
|         // Only allow logged in users | ||||
|         return Auth::check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getBillData() | ||||
|     { | ||||
|         return [ | ||||
|             'name'               => $this->get('name'), | ||||
|             'match'              => $this->get('match'), | ||||
|             'amount_min'         => floatval($this->get('amount_min')), | ||||
|             'amount_currency_id' => floatval($this->get('amount_currency_id')), | ||||
|             'amount_max'         => floatval($this->get('amount_max')), | ||||
|             'date'               => new Carbon($this->get('date')), | ||||
|             'user'               => Auth::user()->id, | ||||
|             'repeat_freq'        => $this->get('repeat_freq'), | ||||
|             'skip'               => intval($this->get('skip')), | ||||
|             'automatch'          => intval($this->get('automatch')) === 1, | ||||
|             'active'             => intval($this->get('active')) === 1, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules() | ||||
|     { | ||||
|         $nameRule  = 'required|between:1,255|uniqueObjectForUser:bills,name'; | ||||
|         $matchRule = 'required|between:1,255|uniqueObjectForUser:bills,match'; | ||||
|         if (intval(Input::get('id')) > 0) { | ||||
|             $nameRule .= ',' . intval(Input::get('id')); | ||||
|             $matchRule .= ',' . intval(Input::get('id')); | ||||
|         } | ||||
|  | ||||
|         $rules = [ | ||||
|             'name'               => $nameRule, | ||||
|             'match'              => $matchRule, | ||||
|             'amount_min'         => 'required|numeric|min:0.01', | ||||
|             'amount_max'         => 'required|numeric|min:0.01', | ||||
|             'amount_currency_id' => 'required|exists:transaction_currencies,id', | ||||
|             'date'               => 'required|date', | ||||
|             'repeat_freq'        => 'required|in:weekly,monthly,quarterly,half-year,yearly', | ||||
|             'skip'               => 'required|between:0,31', | ||||
|             'automatch'          => 'in:1', | ||||
|             'active'             => 'in:1', | ||||
|         ]; | ||||
|  | ||||
|         return $rules; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										42
									
								
								app/Http/Requests/BudgetFormRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								app/Http/Requests/BudgetFormRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Http\Requests; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Budget; | ||||
| use Input; | ||||
|  | ||||
| /** | ||||
|  * Class BudgetFormRequest | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Http\Requests | ||||
|  */ | ||||
| class BudgetFormRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize() | ||||
|     { | ||||
|         // Only allow logged in users | ||||
|         return Auth::check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules() | ||||
|     { | ||||
|  | ||||
|         $nameRule = 'required|between:1,100|uniqueObjectForUser:budgets,name'; | ||||
|         if (Budget::find(Input::get('id'))) { | ||||
|             $nameRule = 'required|between:1,100|uniqueObjectForUser:budgets,name,' . intval(Input::get('id')); | ||||
|         } | ||||
|  | ||||
|         return [ | ||||
|             'name'   => $nameRule, | ||||
|             'active' => 'numeric|between:0,1' | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										41
									
								
								app/Http/Requests/CategoryFormRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								app/Http/Requests/CategoryFormRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Http\Requests; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Category; | ||||
| use Input; | ||||
|  | ||||
| /** | ||||
|  * Class CategoryFormRequest | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Http\Requests | ||||
|  */ | ||||
| class CategoryFormRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize() | ||||
|     { | ||||
|         // Only allow logged in users | ||||
|         return Auth::check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules() | ||||
|     { | ||||
|  | ||||
|         $nameRule = 'required|between:1,100|uniqueObjectForUser:categories,name'; | ||||
|         if (Category::find(Input::get('id'))) { | ||||
|             $nameRule = 'required|between:1,100|uniqueObjectForUser:categories,name,' . intval(Input::get('id')); | ||||
|         } | ||||
|  | ||||
|         return [ | ||||
|             'name' => $nameRule, | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										58
									
								
								app/Http/Requests/CurrencyFormRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								app/Http/Requests/CurrencyFormRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Http\Requests; | ||||
|  | ||||
| use Auth; | ||||
| use Input; | ||||
|  | ||||
| /** | ||||
|  * Class BillFormRequest | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Http\Requests | ||||
|  */ | ||||
| class CurrencyFormRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize() | ||||
|     { | ||||
|         // Only allow logged in users | ||||
|         return Auth::check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getCurrencyData() | ||||
|     { | ||||
|         return [ | ||||
|             'name'   => $this->get('name'), | ||||
|             'code'   => $this->get('code'), | ||||
|             'symbol' => $this->get('symbol'), | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules() | ||||
|     { | ||||
|  | ||||
|         $rules = [ | ||||
|             'code'   => 'required|min:3|max:3|unique:transaction_currencies,code', | ||||
|             'name'   => 'required|max:48|min:1|unique:transaction_currencies,name', | ||||
|             'symbol' => 'required|min:1|max:8|unique:transaction_currencies,symbol', | ||||
|         ]; | ||||
|         if (intval(Input::get('id')) > 0) { | ||||
|             $rules = [ | ||||
|                 'code'   => 'required|min:3|max:3', | ||||
|                 'name'   => 'required|max:48|min:1', | ||||
|                 'symbol' => 'required|min:1|max:8', | ||||
|             ]; | ||||
|         } | ||||
|  | ||||
|         return $rules; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										33
									
								
								app/Http/Requests/DeleteAccountFormRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								app/Http/Requests/DeleteAccountFormRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Http\Requests; | ||||
|  | ||||
| use Auth; | ||||
|  | ||||
| /** | ||||
|  * Class DeleteAccountFormRequest | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Http\Requests | ||||
|  */ | ||||
| class DeleteAccountFormRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize() | ||||
|     { | ||||
|         // Only allow logged in users | ||||
|         return Auth::check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules() | ||||
|     { | ||||
|         return [ | ||||
|             'password' => 'required', | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										95
									
								
								app/Http/Requests/JournalFormRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								app/Http/Requests/JournalFormRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Http\Requests; | ||||
|  | ||||
| use App; | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use Exception; | ||||
| use Input; | ||||
|  | ||||
| /** | ||||
|  * Class JournalFormRequest | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Http\Requests | ||||
|  */ | ||||
| class JournalFormRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize() | ||||
|     { | ||||
|         // Only allow logged in users | ||||
|         return Auth::check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getJournalData() | ||||
|     { | ||||
|         return [ | ||||
|             'what'               => $this->get('what'), | ||||
|             'description'        => $this->get('description'), | ||||
|             'account_id'         => intval($this->get('account_id')), | ||||
|             'account_from_id'    => intval($this->get('account_from_id')), | ||||
|             'account_to_id'      => intval($this->get('account_to_id')), | ||||
|             'expense_account'    => $this->get('expense_account'), | ||||
|             'revenue_account'    => $this->get('revenue_account'), | ||||
|             'amount'             => floatval($this->get('amount')), | ||||
|             'user'               => Auth::user()->id, | ||||
|             'amount_currency_id' => intval($this->get('amount_currency_id')), | ||||
|             'date'               => new Carbon($this->get('date')), | ||||
|             'budget_id'          => intval($this->get('budget_id')), | ||||
|             'category'           => $this->get('category'), | ||||
|             'tags'               => explode(',', $this->get('tags')), | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      * @throws Exception | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      */ | ||||
|     public function rules() | ||||
|     { | ||||
|         $what  = Input::get('what'); | ||||
|         $rules = [ | ||||
|             'description'        => 'required|min:1,max:255', | ||||
|             'what'               => 'required|in:withdrawal,deposit,transfer', | ||||
|             'amount'             => 'numeric|required|min:0.01', | ||||
|             'date'               => 'required|date', | ||||
|             'reminder_id'        => 'numeric|exists:reminders,id', | ||||
|             'amount_currency_id' => 'required|exists:transaction_currencies,id', | ||||
|  | ||||
|         ]; | ||||
|  | ||||
|         switch ($what) { | ||||
|             case 'withdrawal': | ||||
|                 $rules['account_id']      = 'required|exists:accounts,id|belongsToUser:accounts'; | ||||
|                 $rules['expense_account'] = 'between:1,255'; | ||||
|                 $rules['category']        = 'between:1,255'; | ||||
|                 if (intval(Input::get('budget_id')) != 0) { | ||||
|                     $rules['budget_id'] = 'exists:budgets,id|belongsToUser:budgets'; | ||||
|                 } | ||||
|                 break; | ||||
|             case 'deposit': | ||||
|                 $rules['category']        = 'between:1,255'; | ||||
|                 $rules['account_id']      = 'required|exists:accounts,id|belongsToUser:accounts'; | ||||
|                 $rules['revenue_account'] = 'between:1,255'; | ||||
|                 break; | ||||
|             case 'transfer': | ||||
|                 $rules['account_from_id'] = 'required|exists:accounts,id|belongsToUser:accounts|different:account_to_id'; | ||||
|                 $rules['account_to_id']   = 'required|exists:accounts,id|belongsToUser:accounts|different:account_from_id'; | ||||
|                 $rules['category']        = 'between:1,255'; | ||||
|                 break; | ||||
|             default: | ||||
|                 App::abort(500, 'Cannot handle ' . $what); | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         return $rules; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										37
									
								
								app/Http/Requests/NewUserFormRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								app/Http/Requests/NewUserFormRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Http\Requests; | ||||
|  | ||||
| use Auth; | ||||
|  | ||||
| /** | ||||
|  * Class NewUserFormRequest | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Http\Requests | ||||
|  */ | ||||
| class NewUserFormRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize() | ||||
|     { | ||||
|         // Only allow logged in users | ||||
|         return Auth::check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules() | ||||
|     { | ||||
|         return [ | ||||
|             'bank_name'           => 'required|between:1,200', | ||||
|             'bank_balance'        => 'required|numeric', | ||||
|             'savings_balance'     => 'numeric', | ||||
|             'credit_card_limit'   => 'numeric', | ||||
|             'balance_currency_id' => 'exists:transaction_currencies,id', | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										54
									
								
								app/Http/Requests/PiggyBankFormRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								app/Http/Requests/PiggyBankFormRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Http\Requests; | ||||
|  | ||||
| use Auth; | ||||
| use Input; | ||||
|  | ||||
| /** | ||||
|  * Class PiggyBankFormRequest | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Http\Requests | ||||
|  */ | ||||
| class PiggyBankFormRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize() | ||||
|     { | ||||
|         // Only allow logged in users | ||||
|         return Auth::check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules() | ||||
|     { | ||||
|  | ||||
|         $nameRule       = 'required|between:1,255|uniquePiggyBankForUser'; | ||||
|         $targetDateRule = 'date'; | ||||
|         if (intval(Input::get('id'))) { | ||||
|             $nameRule = 'required|between:1,255|uniquePiggyBankForUser:' . intval(Input::get('id')); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         $rules = [ | ||||
|             'name'               => $nameRule, | ||||
|             'account_id'         => 'required|belongsToUser:accounts', | ||||
|             'targetamount'       => 'required|min:0.01', | ||||
|             'amount_currency_id' => 'exists:transaction_currencies,id', | ||||
|             'startdate'          => 'date', | ||||
|             'targetdate'         => $targetDateRule, | ||||
|             'reminder'           => 'in:day,week,quarter,month,year', | ||||
|             'reminder_skip'      => 'integer|min:0|max:99', | ||||
|             'remind_me'          => 'boolean|piggyBankReminder', | ||||
|             'order'              => 'integer|min:1', | ||||
|  | ||||
|         ]; | ||||
|  | ||||
|         return $rules; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										35
									
								
								app/Http/Requests/ProfileFormRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								app/Http/Requests/ProfileFormRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Http\Requests; | ||||
|  | ||||
| use Auth; | ||||
|  | ||||
| /** | ||||
|  * Class ProfileFormRequest | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Http\Requests | ||||
|  */ | ||||
| class ProfileFormRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize() | ||||
|     { | ||||
|         // Only allow logged in users | ||||
|         return Auth::check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules() | ||||
|     { | ||||
|         return [ | ||||
|             'current_password'          => 'required', | ||||
|             'new_password'              => 'required|confirmed', | ||||
|             'new_password_confirmation' => 'required', | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										16
									
								
								app/Http/Requests/Request.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								app/Http/Requests/Request.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| <?php namespace FireflyIII\Http\Requests; | ||||
|  | ||||
| use Illuminate\Foundation\Http\FormRequest; | ||||
|  | ||||
| /** | ||||
|  * Class Request | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Http\Requests | ||||
|  */ | ||||
| abstract class Request extends FormRequest | ||||
| { | ||||
|  | ||||
|     // | ||||
|  | ||||
| } | ||||
							
								
								
									
										48
									
								
								app/Http/Requests/TagFormRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								app/Http/Requests/TagFormRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| <?php | ||||
| namespace FireflyIII\Http\Requests; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Tag; | ||||
| use Input; | ||||
|  | ||||
| /** | ||||
|  * Class TagFormRequest | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @package FireflyIII\Http\Requests | ||||
|  */ | ||||
| class TagFormRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize() | ||||
|     { | ||||
|         // Only allow logged in users | ||||
|         return Auth::check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules() | ||||
|     { | ||||
|         $idRule  = ''; | ||||
|         $tagRule = 'required|min:1|uniqueObjectForUser:tags,tag'; | ||||
|         if (Tag::find(Input::get('id'))) { | ||||
|             $idRule  = 'belongsToUser:tags'; | ||||
|             $tagRule = 'required|min:1|uniqueObjectForUser:tags,tag,' . Input::get('id'); | ||||
|         } | ||||
|  | ||||
|         return [ | ||||
|             'tag'         => $tagRule, | ||||
|             'id'          => $idRule, | ||||
|             'description' => 'min:1', | ||||
|             'date'        => 'date', | ||||
|             'latitude'    => 'numeric|min:-90|max:90', | ||||
|             'longitude'   => 'numeric|min:-90|max:90', | ||||
|             'zoomLevel'   => 'numeric|min:0|max:80', | ||||
|             'tagMode'     => 'required|in:nothing,balancingAct,advancePayment' | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										423
									
								
								app/Http/breadcrumbs.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										423
									
								
								app/Http/breadcrumbs.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,423 @@ | ||||
| <?php | ||||
| use Carbon\Carbon; | ||||
| use DaveJamesMiller\Breadcrumbs\Generator; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Models\Budget; | ||||
| use FireflyIII\Models\Category; | ||||
| use FireflyIII\Models\LimitRepetition; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Models\Reminder; | ||||
| use FireflyIII\Models\Tag; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
|  | ||||
| /* | ||||
|  * Back home. | ||||
|  */ | ||||
| Breadcrumbs::register( | ||||
|     'home', | ||||
|     function (Generator $breadcrumbs) { | ||||
|  | ||||
|         $breadcrumbs->push(trans('breadcrumbs.home'), route('index')); | ||||
|     } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'index', | ||||
|     function (Generator $breadcrumbs) { | ||||
|  | ||||
|         $breadcrumbs->push(trans('breadcrumbs.home'), route('index')); | ||||
|     } | ||||
| ); | ||||
| //trans('breadcrumbs.') | ||||
|  | ||||
| // accounts | ||||
| Breadcrumbs::register( | ||||
|     'accounts.index', function (Generator $breadcrumbs, $what) { | ||||
|     $breadcrumbs->parent('home'); | ||||
|     $breadcrumbs->push(trans('firefly.' . strtolower(e($what)) . '_accounts'), route('accounts.index', [$what])); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'accounts.create', function (Generator $breadcrumbs, $what) { | ||||
|     $breadcrumbs->parent('accounts.index', $what); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.new_' . strtolower(e($what)) . '_account'), route('accounts.create', [$what])); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'accounts.show', function (Generator $breadcrumbs, Account $account) { | ||||
|  | ||||
|     $what = Config::get('firefly.shortNamesByFullName.' . $account->accountType->type); | ||||
|  | ||||
|  | ||||
|     $breadcrumbs->parent('accounts.index', $what); | ||||
|     $breadcrumbs->push(e($account->name), route('accounts.show', [$account->id])); | ||||
| } | ||||
| ); | ||||
| Breadcrumbs::register( | ||||
|     'accounts.delete', function (Generator $breadcrumbs, Account $account) { | ||||
|     $breadcrumbs->parent('accounts.show', $account); | ||||
|     $breadcrumbs->push(trans('firefly.delete_account', ['name' => e($account->name)]), route('accounts.delete', [$account->id])); | ||||
| } | ||||
| ); | ||||
|  | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'accounts.edit', function (Generator $breadcrumbs, Account $account) { | ||||
|     $breadcrumbs->parent('accounts.show', $account); | ||||
|     $what = Config::get('firefly.shortNamesByFullName.' . $account->accountType->type); | ||||
|  | ||||
|     $breadcrumbs->push(trans('firefly.edit_' . $what . '_account', ['name' => e($account->name)]), route('accounts.edit', [$account->id])); | ||||
| } | ||||
| ); | ||||
|  | ||||
| // budgets. | ||||
| Breadcrumbs::register( | ||||
|     'budgets.index', function (Generator $breadcrumbs) { | ||||
|     $breadcrumbs->parent('home'); | ||||
|     $breadcrumbs->push(trans('firefly.budgets'), route('budgets.index')); | ||||
| } | ||||
| ); | ||||
| Breadcrumbs::register( | ||||
|     'budgets.create', function (Generator $breadcrumbs) { | ||||
|     $breadcrumbs->parent('budgets.index'); | ||||
|     $breadcrumbs->push(trans('firefly.create_new_budget'), route('budgets.create')); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'budgets.edit', function (Generator $breadcrumbs, Budget $budget) { | ||||
|     $breadcrumbs->parent('budgets.show', $budget); | ||||
|     $breadcrumbs->push(trans('firefly.edit_budget', ['name' => e($budget->name)]), route('budgets.edit', [$budget->id])); | ||||
| } | ||||
| ); | ||||
| Breadcrumbs::register( | ||||
|     'budgets.delete', function (Generator $breadcrumbs, Budget $budget) { | ||||
|     $breadcrumbs->parent('budgets.show', $budget); | ||||
|     $breadcrumbs->push(trans('firefly.delete_budget', ['name' => e($budget->name)]), route('budgets.delete', [$budget->id])); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'budgets.noBudget', function (Generator $breadcrumbs, $subTitle) { | ||||
|     $breadcrumbs->parent('budgets.index'); | ||||
|     $breadcrumbs->push($subTitle, route('budgets.noBudget')); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'budgets.show', function (Generator $breadcrumbs, Budget $budget, LimitRepetition $repetition = null) { | ||||
|     $breadcrumbs->parent('budgets.index'); | ||||
|     $breadcrumbs->push(e($budget->name), route('budgets.show', [$budget->id])); | ||||
|     if (!is_null($repetition) && !is_null($repetition->id)) { | ||||
|         $breadcrumbs->push( | ||||
|             Navigation::periodShow($repetition->startdate, $repetition->budgetLimit->repeat_freq), route('budgets.show', [$budget->id, $repetition->id]) | ||||
|         ); | ||||
|     } | ||||
| } | ||||
| ); | ||||
|  | ||||
| // categories | ||||
| Breadcrumbs::register( | ||||
|     'categories.index', function (Generator $breadcrumbs) { | ||||
|     $breadcrumbs->parent('home'); | ||||
|     $breadcrumbs->push(trans('firefly.categories'), route('categories.index')); | ||||
| } | ||||
| ); | ||||
| Breadcrumbs::register( | ||||
|     'categories.create', function (Generator $breadcrumbs) { | ||||
|     $breadcrumbs->parent('categories.index'); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.newCategory'), route('categories.create')); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'categories.edit', function (Generator $breadcrumbs, Category $category) { | ||||
|     $breadcrumbs->parent('categories.show', $category); | ||||
|     $breadcrumbs->push(trans('firefly.edit_category', ['name' => e($category->name)]), route('categories.edit', [$category->id])); | ||||
| } | ||||
| ); | ||||
| Breadcrumbs::register( | ||||
|     'categories.delete', function (Generator $breadcrumbs, Category $category) { | ||||
|     $breadcrumbs->parent('categories.show', $category); | ||||
|     $breadcrumbs->push(trans('firefly.delete_category', ['name' => e($category->name)]), route('categories.delete', [$category->id])); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'categories.show', function (Generator $breadcrumbs, Category $category) { | ||||
|     $breadcrumbs->parent('categories.index'); | ||||
|     $breadcrumbs->push(e($category->name), route('categories.show', [$category->id])); | ||||
|  | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'categories.noCategory', function (Generator $breadcrumbs, $subTitle) { | ||||
|     $breadcrumbs->parent('categories.index'); | ||||
|     $breadcrumbs->push($subTitle, route('categories.noCategory')); | ||||
| } | ||||
| ); | ||||
|  | ||||
| // currencies. | ||||
| Breadcrumbs::register( | ||||
|     'currency.index', function (Generator $breadcrumbs) { | ||||
|     $breadcrumbs->parent('home'); | ||||
|     $breadcrumbs->push(trans('firefly.currencies'), route('currency.index')); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'currency.create', function (Generator $breadcrumbs) { | ||||
|     $breadcrumbs->parent('currency.index'); | ||||
|     $breadcrumbs->push(trans('firefly.create_currency'), route('currency.create')); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'currency.edit', function (Generator $breadcrumbs, TransactionCurrency $currency) { | ||||
|     $breadcrumbs->parent('currency.index'); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.edit_currency', ['name' => e($currency->name)]), route('currency.edit', [$currency->id])); | ||||
| } | ||||
| ); | ||||
| Breadcrumbs::register( | ||||
|     'currency.delete', function (Generator $breadcrumbs, TransactionCurrency $currency) { | ||||
|     $breadcrumbs->parent('currency.index'); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.delete_currency', ['name' => e($currency->name)]), route('currency.delete', [$currency->id])); | ||||
| } | ||||
| ); | ||||
|  | ||||
|  | ||||
| // piggy banks | ||||
| Breadcrumbs::register( | ||||
|     'piggy-banks.index', function (Generator $breadcrumbs) { | ||||
|     $breadcrumbs->parent('home'); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.piggyBanks'), route('piggy-banks.index')); | ||||
| } | ||||
| ); | ||||
| Breadcrumbs::register( | ||||
|     'piggy-banks.create', function (Generator $breadcrumbs) { | ||||
|     $breadcrumbs->parent('piggy-banks.index'); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.newPiggyBank'), route('piggy-banks.create')); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'piggy-banks.edit', function (Generator $breadcrumbs, PiggyBank $piggyBank) { | ||||
|     $breadcrumbs->parent('piggy-banks.show', $piggyBank); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.edit_piggyBank', ['name' => e($piggyBank->name)]), route('piggy-banks.edit', [$piggyBank->id])); | ||||
| } | ||||
| ); | ||||
| Breadcrumbs::register( | ||||
|     'piggy-banks.delete', function (Generator $breadcrumbs, PiggyBank $piggyBank) { | ||||
|     $breadcrumbs->parent('piggy-banks.show', $piggyBank); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.delete_piggyBank', ['name' => e($piggyBank->name)]), route('piggy-banks.delete', [$piggyBank->id])); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'piggy-banks.show', function (Generator $breadcrumbs, PiggyBank $piggyBank) { | ||||
|     $breadcrumbs->parent('piggy-banks.index'); | ||||
|     $breadcrumbs->push(e($piggyBank->name), route('piggy-banks.show', [$piggyBank->id])); | ||||
|  | ||||
| } | ||||
| ); | ||||
|  | ||||
| // preferences | ||||
| Breadcrumbs::register( | ||||
|     'preferences', function (Generator $breadcrumbs) { | ||||
|     $breadcrumbs->parent('home'); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.preferences'), route('preferences')); | ||||
|  | ||||
| } | ||||
| ); | ||||
|  | ||||
| // profile | ||||
| Breadcrumbs::register( | ||||
|     'profile', function (Generator $breadcrumbs) { | ||||
|     $breadcrumbs->parent('home'); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.profile'), route('profile')); | ||||
|  | ||||
| } | ||||
| ); | ||||
| Breadcrumbs::register( | ||||
|     'change-password', function (Generator $breadcrumbs) { | ||||
|     $breadcrumbs->parent('profile'); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.changePassword'), route('change-password')); | ||||
|  | ||||
| } | ||||
| ); | ||||
|  | ||||
| // bills | ||||
| Breadcrumbs::register( | ||||
|     'bills.index', function (Generator $breadcrumbs) { | ||||
|     $breadcrumbs->parent('home'); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.bills'), route('bills.index')); | ||||
| } | ||||
| ); | ||||
| Breadcrumbs::register( | ||||
|     'bills.create', function (Generator $breadcrumbs) { | ||||
|     $breadcrumbs->parent('bills.index'); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.newBill'), route('bills.create')); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'bills.edit', function (Generator $breadcrumbs, Bill $bill) { | ||||
|     $breadcrumbs->parent('bills.show', $bill); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.edit_bill', ['name' => e($bill->name)]), route('bills.edit', [$bill->id])); | ||||
| } | ||||
| ); | ||||
| Breadcrumbs::register( | ||||
|     'bills.delete', function (Generator $breadcrumbs, Bill $bill) { | ||||
|     $breadcrumbs->parent('bills.show', $bill); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.delete_bill', ['name' => e($bill->name)]), route('bills.delete', [$bill->id])); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'bills.show', function (Generator $breadcrumbs, Bill $bill) { | ||||
|     $breadcrumbs->parent('bills.index'); | ||||
|     $breadcrumbs->push(e($bill->name), route('bills.show', [$bill->id])); | ||||
|  | ||||
| } | ||||
| ); | ||||
|  | ||||
| // reminders | ||||
| Breadcrumbs::register( | ||||
|     'reminders.index', function (Generator $breadcrumbs) { | ||||
|     $breadcrumbs->parent('home'); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.reminders'), route('reminders.index')); | ||||
|  | ||||
| } | ||||
| ); | ||||
|  | ||||
| // reminders | ||||
| Breadcrumbs::register( | ||||
|     'reminders.show', function (Generator $breadcrumbs, Reminder $reminder) { | ||||
|     $breadcrumbs->parent('reminders.index'); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.reminder', ['id' => e($reminder->id)]), route('reminders.show', [$reminder->id])); | ||||
|  | ||||
| } | ||||
| ); | ||||
|  | ||||
|  | ||||
| // reports | ||||
| Breadcrumbs::register( | ||||
|     'reports.index', function (Generator $breadcrumbs) { | ||||
|     $breadcrumbs->parent('home'); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.reports'), route('reports.index')); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'reports.year', function (Generator $breadcrumbs, Carbon $date, $shared) { | ||||
|     $breadcrumbs->parent('reports.index'); | ||||
|     if ($shared) { | ||||
|         $title = trans('breadcrumbs.yearly_report_shared', ['date' => $date->year]); | ||||
|     } else { | ||||
|         $title = trans('breadcrumbs.yearly_report', ['date' => $date->year]); | ||||
|     } | ||||
|     $breadcrumbs->push($title, route('reports.year', [$date->year])); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'reports.month', function (Generator $breadcrumbs, Carbon $date, $shared) { | ||||
|     $breadcrumbs->parent('reports.year', $date, $shared); | ||||
|     $language = Preferences::get('language', 'en')->data; | ||||
|     $format   = Config::get('firefly.month.' . $language); | ||||
|  | ||||
|     if ($shared) { | ||||
|         $title = trans('breadcrumbs.monthly_report_shared', ['date' => $date->formatLocalized($format)]); | ||||
|     } else { | ||||
|         $title = trans('breadcrumbs.monthly_report', ['date' => $date->formatLocalized($format)]); | ||||
|     } | ||||
|  | ||||
|     $breadcrumbs->push($title, route('reports.month', [$date->year, $date->month])); | ||||
| } | ||||
| ); | ||||
|  | ||||
| // search | ||||
| Breadcrumbs::register( | ||||
|     'search', function (Generator $breadcrumbs, $query) { | ||||
|     $breadcrumbs->parent('home'); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.searchResult', ['query' => e($query)]), route('search')); | ||||
| } | ||||
| ); | ||||
|  | ||||
| // transactions | ||||
| Breadcrumbs::register( | ||||
|     'transactions.index', function (Generator $breadcrumbs, $what) { | ||||
|     $breadcrumbs->parent('home'); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.' . $what . '_list'), route('transactions.index', [$what])); | ||||
| } | ||||
| ); | ||||
| Breadcrumbs::register( | ||||
|     'transactions.create', function (Generator $breadcrumbs, $what) { | ||||
|     $breadcrumbs->parent('transactions.index', $what); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.create_' . e($what)), route('transactions.create', [$what])); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'transactions.edit', function (Generator $breadcrumbs, TransactionJournal $journal) { | ||||
|     $breadcrumbs->parent('transactions.show', $journal); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.edit_journal', ['description' => $journal->description]), route('transactions.edit', [$journal->id])); | ||||
| } | ||||
| ); | ||||
| Breadcrumbs::register( | ||||
|     'transactions.delete', function (Generator $breadcrumbs, TransactionJournal $journal) { | ||||
|     $breadcrumbs->parent('transactions.show', $journal); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.delete_journal', ['description' => e($journal->description)]), route('transactions.delete', [$journal->id])); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'transactions.show', function (Generator $breadcrumbs, TransactionJournal $journal) { | ||||
|  | ||||
|     $breadcrumbs->parent('transactions.index', strtolower($journal->transactionType->type)); | ||||
|     $breadcrumbs->push($journal->description, route('transactions.show', [$journal->id])); | ||||
|  | ||||
| } | ||||
| ); | ||||
|  | ||||
| // tags | ||||
| Breadcrumbs::register( | ||||
|     'tags.index', function (Generator $breadcrumbs) { | ||||
|     $breadcrumbs->parent('home'); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.tags'), route('tags.index')); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'tags.create', function (Generator $breadcrumbs) { | ||||
|     $breadcrumbs->parent('tags.index'); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.createTag'), route('tags.create')); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'tags.edit', function (Generator $breadcrumbs, Tag $tag) { | ||||
|     $breadcrumbs->parent('tags.show', $tag); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.edit_tag', ['tag' => e($tag->tag)]), route('tags.edit', [$tag->id])); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'tags.delete', function (Generator $breadcrumbs, Tag $tag) { | ||||
|     $breadcrumbs->parent('tags.show', $tag); | ||||
|     $breadcrumbs->push(trans('breadcrumbs.delete_tag', ['tag' => e($tag->tag)]), route('tags.delete', [$tag->id])); | ||||
| } | ||||
| ); | ||||
|  | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'tags.show', function (Generator $breadcrumbs, Tag $tag) { | ||||
|     $breadcrumbs->parent('tags.index'); | ||||
|     $breadcrumbs->push(e($tag->tag), route('tags.show', [$tag->id])); | ||||
| } | ||||
| ); | ||||
							
								
								
									
										426
									
								
								app/Http/routes.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										426
									
								
								app/Http/routes.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,426 @@ | ||||
| <?php | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Models\Budget; | ||||
| use FireflyIII\Models\Category; | ||||
| use FireflyIII\Models\LimitRepetition; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Models\Reminder; | ||||
| use FireflyIII\Models\Tag; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | ||||
|  | ||||
|  | ||||
| // models | ||||
| Route::bind( | ||||
|     'account', | ||||
|     function ($value) { | ||||
|         if (Auth::check()) { | ||||
|             $object = Account::leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') | ||||
|                              ->where('account_types.editable', 1) | ||||
|                              ->where('accounts.id', $value) | ||||
|                              ->where('user_id', Auth::user()->id) | ||||
|                              ->first(['accounts.*']); | ||||
|             if ($object) { | ||||
|                 return $object; | ||||
|             } | ||||
|         } | ||||
|         throw new NotFoundHttpException; | ||||
|     } | ||||
| ); | ||||
|  | ||||
| Route::bind( | ||||
|     'tj', function ($value) { | ||||
|     if (Auth::check()) { | ||||
|         $object = TransactionJournal::where('id', $value)->where('user_id', Auth::user()->id)->first(); | ||||
|         if ($object) { | ||||
|             return $object; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     throw new NotFoundHttpException; | ||||
| } | ||||
| ); | ||||
|  | ||||
| Route::bind( | ||||
|     'currency', function ($value) { | ||||
|     if (Auth::check()) { | ||||
|         $object = TransactionCurrency::find($value); | ||||
|         if ($object) { | ||||
|             return $object; | ||||
|         } | ||||
|     } | ||||
|     throw new NotFoundHttpException; | ||||
| } | ||||
| ); | ||||
|  | ||||
| Route::bind( | ||||
|     'bill', function ($value) { | ||||
|     if (Auth::check()) { | ||||
|         $object = Bill::where('id', $value)->where('user_id', Auth::user()->id)->first(); | ||||
|         if ($object) { | ||||
|             return $object; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     throw new NotFoundHttpException; | ||||
| } | ||||
| ); | ||||
|  | ||||
| Route::bind( | ||||
|     'budget', function ($value) { | ||||
|     if (Auth::check()) { | ||||
|         $object = Budget::where('id', $value)->where('user_id', Auth::user()->id)->first(); | ||||
|         if ($object) { | ||||
|             return $object; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     throw new NotFoundHttpException; | ||||
| } | ||||
| ); | ||||
|  | ||||
| Route::bind( | ||||
|     'reminder', function ($value) { | ||||
|     if (Auth::check()) { | ||||
|         $object = Reminder::where('id', $value)->where('user_id', Auth::user()->id)->first(); | ||||
|         if ($object) { | ||||
|             return $object; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     throw new NotFoundHttpException; | ||||
| } | ||||
| ); | ||||
|  | ||||
| Route::bind( | ||||
|     'limitrepetition', function ($value) { | ||||
|     if (Auth::check()) { | ||||
|         $object = LimitRepetition::where('limit_repetitions.id', $value) | ||||
|                                  ->leftjoin('budget_limits', 'budget_limits.id', '=', 'limit_repetitions.budget_limit_id') | ||||
|                                  ->leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id') | ||||
|                                  ->where('budgets.user_id', Auth::user()->id) | ||||
|                                  ->first(['limit_repetitions.*']); | ||||
|         if ($object) { | ||||
|             return $object; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     throw new NotFoundHttpException; | ||||
| } | ||||
| ); | ||||
|  | ||||
| Route::bind( | ||||
|     'piggyBank', function ($value) { | ||||
|     if (Auth::check()) { | ||||
|         $object = PiggyBank::where('piggy_banks.id', $value) | ||||
|                            ->leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id') | ||||
|                            ->where('accounts.user_id', Auth::user()->id) | ||||
|                            ->first(['piggy_banks.*']); | ||||
|         if ($object) { | ||||
|             return $object; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     throw new NotFoundHttpException; | ||||
| } | ||||
| ); | ||||
|  | ||||
| Route::bind( | ||||
|     'category', function ($value) { | ||||
|     if (Auth::check()) { | ||||
|         $object = Category::where('id', $value)->where('user_id', Auth::user()->id)->first(); | ||||
|         if ($object) { | ||||
|             return $object; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     throw new NotFoundHttpException; | ||||
| } | ||||
| ); | ||||
|  | ||||
| /** @noinspection PhpUnusedParameterInspection */ | ||||
| Route::bind( | ||||
|     'reminder', function ($value) { | ||||
|     if (Auth::check()) { | ||||
|         /** @var \FireflyIII\Models\Reminder $object */ | ||||
|         $object = Reminder::find($value); | ||||
|         if ($object) { | ||||
|             if ($object->remindersable->account->user_id == Auth::user()->id) { | ||||
|                 return $object; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     throw new NotFoundHttpException; | ||||
| } | ||||
| ); | ||||
|  | ||||
| Route::bind( | ||||
|     'tag', function ($value) { | ||||
|     if (Auth::check()) { | ||||
|         $object = Tag::where('id', $value)->where('user_id', Auth::user()->id)->first(); | ||||
|         if ($object) { | ||||
|             return $object; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     throw new NotFoundHttpException; | ||||
| } | ||||
| ); | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Auth\AuthController | ||||
|  */ | ||||
| Route::get('/register', ['uses' => 'Auth\AuthController@getRegister', 'as' => 'register']); | ||||
|  | ||||
| Route::controllers( | ||||
|     [ | ||||
|         'auth'     => 'Auth\AuthController', | ||||
|         'password' => 'Auth\PasswordController', | ||||
|     ] | ||||
| ); | ||||
|  | ||||
|  | ||||
| Route::group( | ||||
|     ['middleware' => ['auth', 'range', 'reminders']], function () { | ||||
|  | ||||
|     /** | ||||
|      * Home Controller | ||||
|      */ | ||||
|     Route::get('/', ['uses' => 'HomeController@index', 'as' => 'index']); | ||||
|     Route::get('/home', ['uses' => 'HomeController@index', 'as' => 'home']); | ||||
|     Route::post('/daterange', ['uses' => 'HomeController@dateRange', 'as' => 'daterange']); | ||||
|     Route::get('/flush', ['uses' => 'HomeController@flush', 'as' => 'flush']); | ||||
|     /** | ||||
|      * Account Controller | ||||
|      */ | ||||
|     Route::get('/accounts/{what}', ['uses' => 'AccountController@index', 'as' => 'accounts.index'])->where('what', 'revenue|asset|expense'); | ||||
|     Route::get('/accounts/create/{what}', ['uses' => 'AccountController@create', 'as' => 'accounts.create'])->where('what', 'revenue|asset|expense'); | ||||
|     Route::get('/accounts/edit/{account}', ['uses' => 'AccountController@edit', 'as' => 'accounts.edit']); | ||||
|     Route::get('/accounts/delete/{account}', ['uses' => 'AccountController@delete', 'as' => 'accounts.delete']); | ||||
|     Route::get('/accounts/show/{account}/{view?}', ['uses' => 'AccountController@show', 'as' => 'accounts.show']); | ||||
|  | ||||
|     Route::post('/accounts/store', ['uses' => 'AccountController@store', 'as' => 'accounts.store']); | ||||
|     Route::post('/accounts/update/{account}', ['uses' => 'AccountController@update', 'as' => 'accounts.update']); | ||||
|     Route::post('/accounts/destroy/{account}', ['uses' => 'AccountController@destroy', 'as' => 'accounts.destroy']); | ||||
|  | ||||
|     /** | ||||
|      * Bills Controller | ||||
|      */ | ||||
|     Route::get('/bills', ['uses' => 'BillController@index', 'as' => 'bills.index']); | ||||
|     Route::get('/bills/rescan/{bill}', ['uses' => 'BillController@rescan', 'as' => 'bills.rescan']); # rescan for matching. | ||||
|     Route::get('/bills/create', ['uses' => 'BillController@create', 'as' => 'bills.create']); | ||||
|     Route::get('/bills/edit/{bill}', ['uses' => 'BillController@edit', 'as' => 'bills.edit']); | ||||
|     Route::get('/bills/delete/{bill}', ['uses' => 'BillController@delete', 'as' => 'bills.delete']); | ||||
|     Route::get('/bills/show/{bill}', ['uses' => 'BillController@show', 'as' => 'bills.show']); | ||||
|     Route::post('/bills/store', ['uses' => 'BillController@store', 'as' => 'bills.store']); | ||||
|     Route::post('/bills/update/{bill}', ['uses' => 'BillController@update', 'as' => 'bills.update']); | ||||
|     Route::post('/bills/destroy/{bill}', ['uses' => 'BillController@destroy', 'as' => 'bills.destroy']); | ||||
|  | ||||
|     /** | ||||
|      * Budget Controller | ||||
|      */ | ||||
|     Route::get('/budgets', ['uses' => 'BudgetController@index', 'as' => 'budgets.index']); | ||||
|     Route::get('/budgets/income', ['uses' => 'BudgetController@updateIncome', 'as' => 'budgets.income']); # extra. | ||||
|     Route::get('/budgets/create', ['uses' => 'BudgetController@create', 'as' => 'budgets.create']); | ||||
|     Route::get('/budgets/edit/{budget}', ['uses' => 'BudgetController@edit', 'as' => 'budgets.edit']); | ||||
|     Route::get('/budgets/delete/{budget}', ['uses' => 'BudgetController@delete', 'as' => 'budgets.delete']); | ||||
|     Route::get('/budgets/show/{budget}/{limitrepetition?}', ['uses' => 'BudgetController@show', 'as' => 'budgets.show']); | ||||
|     Route::get('/budgets/list/noBudget', ['uses' => 'BudgetController@noBudget', 'as' => 'budgets.noBudget']); | ||||
|     Route::post('/budgets/income', ['uses' => 'BudgetController@postUpdateIncome', 'as' => 'budgets.postIncome']); | ||||
|     Route::post('/budgets/store', ['uses' => 'BudgetController@store', 'as' => 'budgets.store']); | ||||
|     Route::post('/budgets/update/{budget}', ['uses' => 'BudgetController@update', 'as' => 'budgets.update']); | ||||
|     Route::post('/budgets/destroy/{budget}', ['uses' => 'BudgetController@destroy', 'as' => 'budgets.destroy']); | ||||
|     Route::post('budgets/amount/{budget}', ['uses' => 'BudgetController@amount']); | ||||
|  | ||||
|     /** | ||||
|      * Category Controller | ||||
|      */ | ||||
|     Route::get('/categories', ['uses' => 'CategoryController@index', 'as' => 'categories.index']); | ||||
|     Route::get('/categories/create', ['uses' => 'CategoryController@create', 'as' => 'categories.create']); | ||||
|     Route::get('/categories/edit/{category}', ['uses' => 'CategoryController@edit', 'as' => 'categories.edit']); | ||||
|     Route::get('/categories/delete/{category}', ['uses' => 'CategoryController@delete', 'as' => 'categories.delete']); | ||||
|     Route::get('/categories/show/{category}', ['uses' => 'CategoryController@show', 'as' => 'categories.show']); | ||||
|     Route::get('/categories/list/noCategory', ['uses' => 'CategoryController@noCategory', 'as' => 'categories.noCategory']); | ||||
|     Route::post('/categories/store', ['uses' => 'CategoryController@store', 'as' => 'categories.store']); | ||||
|     Route::post('/categories/update/{category}', ['uses' => 'CategoryController@update', 'as' => 'categories.update']); | ||||
|     Route::post('/categories/destroy/{category}', ['uses' => 'CategoryController@destroy', 'as' => 'categories.destroy']); | ||||
|  | ||||
|     /** | ||||
|      * Currency Controller | ||||
|      */ | ||||
|     Route::get('/currency', ['uses' => 'CurrencyController@index', 'as' => 'currency.index']); | ||||
|     Route::get('/currency/create', ['uses' => 'CurrencyController@create', 'as' => 'currency.create']); | ||||
|     Route::get('/currency/edit/{currency}', ['uses' => 'CurrencyController@edit', 'as' => 'currency.edit']); | ||||
|     Route::get('/currency/delete/{currency}', ['uses' => 'CurrencyController@delete', 'as' => 'currency.delete']); | ||||
|     Route::get('/currency/default/{currency}', ['uses' => 'CurrencyController@defaultCurrency', 'as' => 'currency.default']); | ||||
|     Route::post('/currency/store', ['uses' => 'CurrencyController@store', 'as' => 'currency.store']); | ||||
|     Route::post('/currency/update/{currency}', ['uses' => 'CurrencyController@update', 'as' => 'currency.update']); | ||||
|     Route::post('/currency/destroy/{currency}', ['uses' => 'CurrencyController@destroy', 'as' => 'currency.destroy']); | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * ALL CHART Controllers | ||||
|      */ | ||||
|     // accounts: | ||||
|     Route::get('/chart/account/frontpage', ['uses' => 'Chart\AccountController@frontpage']); | ||||
|     Route::get('/chart/account/month/{year}/{month}/{shared?}', ['uses' => 'Chart\AccountController@all'])->where( | ||||
|         ['year' => '[0-9]{4}', 'month' => '[0-9]{1,2}', 'shared' => 'shared'] | ||||
|     ); | ||||
|     Route::get('/chart/account/{account}', ['uses' => 'Chart\AccountController@single']); | ||||
|  | ||||
|  | ||||
|     // bills: | ||||
|     Route::get('/chart/bill/frontpage', ['uses' => 'Chart\BillController@frontpage']); | ||||
|     Route::get('/chart/bill/{bill}', ['uses' => 'Chart\BillController@single']); | ||||
|  | ||||
|     // budgets: | ||||
|     Route::get('/chart/budget/frontpage', ['uses' => 'Chart\BudgetController@frontpage']); | ||||
|     Route::get('/chart/budget/year/{year}/{shared?}', ['uses' => 'Chart\BudgetController@year'])->where(['year' => '[0-9]{4}', 'shared' => 'shared']); | ||||
|     Route::get('/chart/budget/{budget}/{limitrepetition}', ['uses' => 'Chart\BudgetController@budgetLimit']); | ||||
|     Route::get('/chart/budget/{budget}', ['uses' => 'Chart\BudgetController@budget']); | ||||
|  | ||||
|     // categories: | ||||
|     Route::get('/chart/category/frontpage', ['uses' => 'Chart\CategoryController@frontpage']); | ||||
|     Route::get('/chart/category/year/{year}/{shared?}', ['uses' => 'Chart\CategoryController@year'])->where(['year' => '[0-9]{4}', 'shared' => 'shared']); | ||||
|     Route::get('/chart/category/{category}/month', ['uses' => 'Chart\CategoryController@month']); // should be period. | ||||
|     Route::get('/chart/category/{category}/all', ['uses' => 'Chart\CategoryController@all']); | ||||
|  | ||||
|     // piggy banks: | ||||
|     Route::get('/chart/piggyBank/{piggyBank}', ['uses' => 'Chart\PiggyBankController@history']); | ||||
|  | ||||
|     // reports: | ||||
|     Route::get('/chart/report/in-out/{year}/{shared?}', ['uses' => 'Chart\ReportController@yearInOut'])->where(['year' => '[0-9]{4}', 'shared' => 'shared']); | ||||
|     Route::get('/chart/report/in-out-sum/{year}/{shared?}', ['uses' => 'Chart\ReportController@yearInOutSummarized'])->where( | ||||
|         ['year' => '[0-9]{4}', 'shared' => 'shared'] | ||||
|     ); | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Help Controller | ||||
|      */ | ||||
|     Route::get('/help/{route}', ['uses' => 'HelpController@show', 'as' => 'help.show']); | ||||
|  | ||||
|     /** | ||||
|      * JSON Controller | ||||
|      */ | ||||
|     Route::get('/json/expense-accounts', ['uses' => 'JsonController@expenseAccounts', 'as' => 'json.expense-accounts']); | ||||
|     Route::get('/json/revenue-accounts', ['uses' => 'JsonController@revenueAccounts', 'as' => 'json.revenue-accounts']); | ||||
|     Route::get('/json/categories', ['uses' => 'JsonController@categories', 'as' => 'json.categories']); | ||||
|     Route::get('/json/tags', ['uses' => 'JsonController@tags', 'as' => 'json.tags']); | ||||
|     Route::get('/json/box/in', ['uses' => 'JsonController@boxIn', 'as' => 'json.box.in']); | ||||
|     Route::get('/json/box/out', ['uses' => 'JsonController@boxOut', 'as' => 'json.box.out']); | ||||
|     Route::get('/json/box/bills-unpaid', ['uses' => 'JsonController@boxBillsUnpaid', 'as' => 'json.box.paid']); | ||||
|     Route::get('/json/box/bills-paid', ['uses' => 'JsonController@boxBillsPaid', 'as' => 'json.box.unpaid']); | ||||
|     Route::get('/json/transaction-journals/{what}', 'JsonController@transactionJournals'); | ||||
|  | ||||
|     /** | ||||
|      * New user Controller | ||||
|      */ | ||||
|     Route::get('/new-user', ['uses' => 'NewUserController@index', 'as' => 'new-user.index']); | ||||
|     Route::post('/new-user/submit', ['uses' => 'NewUserController@submit', 'as' => 'new-user.submit']); | ||||
|  | ||||
|     /** | ||||
|      * Piggy Bank Controller | ||||
|      */ | ||||
|     Route::get('/piggy-banks', ['uses' => 'PiggyBankController@index', 'as' => 'piggy-banks.index']); | ||||
|     Route::get('/piggy-banks/add/{piggyBank}', ['uses' => 'PiggyBankController@add', 'as' => 'piggy-banks.addMoney']); # add money | ||||
|     Route::get('/piggy-banks/remove/{piggyBank}', ['uses' => 'PiggyBankController@remove', 'as' => 'piggy-banks.removeMoney']); #remove money | ||||
|     Route::get('/piggy-banks/create', ['uses' => 'PiggyBankController@create', 'as' => 'piggy-banks.create']); | ||||
|     Route::get('/piggy-banks/edit/{piggyBank}', ['uses' => 'PiggyBankController@edit', 'as' => 'piggy-banks.edit']); | ||||
|     Route::get('/piggy-banks/delete/{piggyBank}', ['uses' => 'PiggyBankController@delete', 'as' => 'piggy-banks.delete']); | ||||
|     Route::get('/piggy-banks/show/{piggyBank}', ['uses' => 'PiggyBankController@show', 'as' => 'piggy-banks.show']); | ||||
|     Route::post('/piggy-banks/store', ['uses' => 'PiggyBankController@store', 'as' => 'piggy-banks.store']); | ||||
|     Route::post('/piggy-banks/update/{piggyBank}', ['uses' => 'PiggyBankController@update', 'as' => 'piggy-banks.update']); | ||||
|     Route::post('/piggy-banks/destroy/{piggyBank}', ['uses' => 'PiggyBankController@destroy', 'as' => 'piggy-banks.destroy']); | ||||
|     Route::post('/piggy-banks/add/{piggyBank}', ['uses' => 'PiggyBankController@postAdd', 'as' => 'piggy-banks.add']); # add money | ||||
|     Route::post('/piggy-banks/remove/{piggyBank}', ['uses' => 'PiggyBankController@postRemove', 'as' => 'piggy-banks.remove']); # remove money. | ||||
|     Route::post('/piggy-banks/sort', ['uses' => 'PiggyBankController@order', 'as' => 'piggy-banks.order']); | ||||
|  | ||||
|     /** | ||||
|      * Preferences Controller | ||||
|      */ | ||||
|     Route::get('/preferences', ['uses' => 'PreferencesController@index', 'as' => 'preferences']); | ||||
|     Route::post('/preferences', ['uses' => 'PreferencesController@postIndex']); | ||||
|  | ||||
|     /** | ||||
|      * Profile Controller | ||||
|      */ | ||||
|     Route::get('/profile', ['uses' => 'ProfileController@index', 'as' => 'profile']); | ||||
|     Route::get('/profile/change-password', ['uses' => 'ProfileController@changePassword', 'as' => 'profile.change-password']); | ||||
|     Route::get('/profile/delete-account', ['uses' => 'ProfileController@deleteAccount', 'as' => 'profile.delete-account']); | ||||
|     Route::post('/profile/delete-account', ['uses' => 'ProfileController@postDeleteAccount', 'as' => 'delete-account-post']); | ||||
|     Route::post('/profile/change-password', ['uses' => 'ProfileController@postChangePassword', 'as' => 'change-password-post']); | ||||
|  | ||||
|     /** | ||||
|      * Reminder Controller | ||||
|      */ | ||||
|     Route::get('/reminders', ['uses' => 'ReminderController@index', 'as' => 'reminders.index']); | ||||
|     Route::get('/reminder/dismiss/{reminder}', ['uses' => 'ReminderController@dismiss', 'as' => 'reminders.dismiss']); | ||||
|     Route::get('/reminder/act/{reminder}', ['uses' => 'ReminderController@act', 'as' => 'reminders.act']); | ||||
|     Route::get('/reminder/{reminder}', ['uses' => 'ReminderController@show', 'as' => 'reminders.show']); | ||||
|  | ||||
|     /** | ||||
|      * Report Controller | ||||
|      */ | ||||
|     Route::get('/reports', ['uses' => 'ReportController@index', 'as' => 'reports.index']); | ||||
|     Route::get('/reports/{year}/{shared?}', ['uses' => 'ReportController@year', 'as' => 'reports.year'])->where(['year' => '[0-9]{4}', 'shared' => 'shared']); | ||||
|     Route::get('/reports/{year}/{month}/{shared?}', ['uses' => 'ReportController@month', 'as' => 'reports.month'])->where( | ||||
|         ['year' => '[0-9]{4}', 'month' => '[0-9]{1,2}', 'shared' => 'shared'] | ||||
|     ); | ||||
|  | ||||
|     // pop ups for budget report: | ||||
|  | ||||
|     /** | ||||
|      * Search Controller | ||||
|      */ | ||||
|     Route::get('/search', ['uses' => 'SearchController@index', 'as' => 'search']); | ||||
|  | ||||
|     /** | ||||
|      * Tag Controller | ||||
|      */ | ||||
|     Route::get('/tags', ['uses' => 'TagController@index', 'as' => 'tags.index']); | ||||
|     Route::get('/tags/create', ['uses' => 'TagController@create', 'as' => 'tags.create']); | ||||
|     Route::get('/tags/show/{tag}', ['uses' => 'TagController@show', 'as' => 'tags.show']); | ||||
|     Route::get('/tags/edit/{tag}', ['uses' => 'TagController@edit', 'as' => 'tags.edit']); | ||||
|     Route::get('/tags/delete/{tag}', ['uses' => 'TagController@delete', 'as' => 'tags.delete']); | ||||
|  | ||||
|     Route::post('/tags/store', ['uses' => 'TagController@store', 'as' => 'tags.store']); | ||||
|     Route::post('/tags/update/{tag}', ['uses' => 'TagController@update', 'as' => 'tags.update']); | ||||
|     Route::post('/tags/destroy/{tag}', ['uses' => 'TagController@destroy', 'as' => 'tags.destroy']); | ||||
|  | ||||
|     Route::post('/tags/hideTagHelp/{state}', ['uses' => 'TagController@hideTagHelp', 'as' => 'tags.hideTagHelp']); | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Transaction Controller | ||||
|      */ | ||||
|     Route::get('/transactions/{what}', ['uses' => 'TransactionController@index', 'as' => 'transactions.index'])->where( | ||||
|         ['what' => 'expenses|revenue|withdrawal|deposit|transfer|transfers'] | ||||
|     ); | ||||
|     Route::get('/transactions/create/{what}', ['uses' => 'TransactionController@create', 'as' => 'transactions.create'])->where( | ||||
|         ['what' => 'expenses|revenue|withdrawal|deposit|transfer|transfers'] | ||||
|     ); | ||||
|     Route::get('/transaction/edit/{tj}', ['uses' => 'TransactionController@edit', 'as' => 'transactions.edit']); | ||||
|     Route::get('/transaction/delete/{tj}', ['uses' => 'TransactionController@delete', 'as' => 'transactions.delete']); | ||||
|     Route::get('/transaction/show/{tj}', ['uses' => 'TransactionController@show', 'as' => 'transactions.show']); | ||||
|     // transaction controller: | ||||
|     Route::post('/transactions/store/{what}', ['uses' => 'TransactionController@store', 'as' => 'transactions.store'])->where( | ||||
|         ['what' => 'expenses|revenue|withdrawal|deposit|transfer|transfers'] | ||||
|     ); | ||||
|     Route::post('/transaction/update/{tj}', ['uses' => 'TransactionController@update', 'as' => 'transactions.update']); | ||||
|     Route::post('/transaction/destroy/{tj}', ['uses' => 'TransactionController@destroy', 'as' => 'transactions.destroy']); | ||||
|     Route::post('/transaction/reorder', ['uses' => 'TransactionController@reorder', 'as' => 'transactions.reorder']); | ||||
|  | ||||
|     /** | ||||
|      * Auth\Auth Controller | ||||
|      */ | ||||
|     Route::get('/logout', ['uses' => 'Auth\AuthController@getLogout', 'as' => 'logout']); | ||||
|  | ||||
|  | ||||
| } | ||||
| ); | ||||
|  | ||||
							
								
								
									
										264
									
								
								app/Models/Account.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										264
									
								
								app/Models/Account.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,264 @@ | ||||
| <?php namespace FireflyIII\Models; | ||||
|  | ||||
| use Crypt; | ||||
| use Illuminate\Database\Eloquent\Builder as EloquentBuilder; | ||||
| use Illuminate\Database\Eloquent\Model; | ||||
| use Illuminate\Database\Eloquent\SoftDeletes; | ||||
| use Illuminate\Database\Query\JoinClause; | ||||
| use Watson\Validating\ValidatingTrait; | ||||
|  | ||||
| /** | ||||
|  * Class Account | ||||
|  * | ||||
|  * @package FireflyIII\Models | ||||
|  * @property integer                                                                        $id | ||||
|  * @property \Carbon\Carbon                                                                 $created_at | ||||
|  * @property \Carbon\Carbon                                                                 $updated_at | ||||
|  * @property \Carbon\Carbon                                                                 $deleted_at | ||||
|  * @property integer                                                                        $user_id | ||||
|  * @property integer                                                                        $account_type_id | ||||
|  * @property string                                                                         $name | ||||
|  * @property boolean                                                                        $active | ||||
|  * @property boolean                                                                        $encrypted | ||||
|  * @property float                                                                          $virtual_balance | ||||
|  * @property string                                                                         $virtual_balance_encrypted | ||||
|  * @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\AccountMeta[] $accountMeta | ||||
|  * @property-read \FireflyIII\Models\AccountType                                            $accountType | ||||
|  * @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\PiggyBank[]   $piggyBanks | ||||
|  * @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Transaction[] $transactions | ||||
|  * @property-read \FireflyIII\User                                                          $user | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account whereId($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account whereCreatedAt($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account whereUpdatedAt($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account whereDeletedAt($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account whereUserId($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account whereAccountTypeId($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account whereName($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account whereActive($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account whereEncrypted($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account whereVirtualBalance($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Account whereVirtualBalanceEncrypted($value) | ||||
|  * @method static \FireflyIII\Models\Account accountTypeIn($types) | ||||
|  * @method static \FireflyIII\Models\Account hasMetaValue($name, $value) | ||||
|  * @property boolean                                                                        joinedAccountTypes | ||||
|  * @property mixed                                                                          startBalance | ||||
|  * @property mixed                                                                          endBalance | ||||
|  * @property mixed                                                                          lastActivityDate | ||||
|  * @property mixed                                                                          piggyBalance | ||||
|  * @property mixed                                                                          difference | ||||
|  * @property mixed                                                                          percentage | ||||
|  */ | ||||
| class Account extends Model | ||||
| { | ||||
|     use SoftDeletes, ValidatingTrait; | ||||
|  | ||||
|     protected $fillable = ['user_id', 'account_type_id', 'name', 'active', 'virtual_balance']; | ||||
|     protected $hidden   = ['virtual_balance_encrypted', 'encrypted']; | ||||
|     protected $rules | ||||
|                         = [ | ||||
|             'user_id'         => 'required|exists:users,id', | ||||
|             'account_type_id' => 'required|exists:account_types,id', | ||||
|             'name'            => 'required|between:1,1024|uniqueAccountForUser', | ||||
|             'active'          => 'required|boolean' | ||||
|         ]; | ||||
|  | ||||
|     /** | ||||
|      * @param array $fields | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * | ||||
|      * @return Account|null | ||||
|      */ | ||||
|     public static function firstOrCreateEncrypted(array $fields) | ||||
|     { | ||||
|         // everything but the name: | ||||
|         $query = Account::orderBy('id'); | ||||
|         foreach ($fields as $name => $value) { | ||||
|             if ($name != 'name') { | ||||
|                 $query->where($name, $value); | ||||
|             } | ||||
|         } | ||||
|         $set = $query->get(['accounts.*']); | ||||
|         /** @var Account $account */ | ||||
|         foreach ($set as $account) { | ||||
|             if ($account->name == $fields['name']) { | ||||
|                 return $account; | ||||
|             } | ||||
|         } | ||||
|         // create it! | ||||
|         $account = Account::create($fields); | ||||
|  | ||||
|         return $account; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $fields | ||||
|      * | ||||
|      * @return Account|null | ||||
|      */ | ||||
|     public static function firstOrNullEncrypted(array $fields) | ||||
|     { | ||||
|         // everything but the name: | ||||
|         $query = Account::orderBy('id'); | ||||
|         foreach ($fields as $name => $value) { | ||||
|             if ($name != 'name') { | ||||
|                 $query->where($name, $value); | ||||
|             } | ||||
|         } | ||||
|         $set = $query->get(['accounts.*']); | ||||
|         /** @var Account $account */ | ||||
|         foreach ($set as $account) { | ||||
|             if ($account->name == $fields['name']) { | ||||
|                 return $account; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\HasMany | ||||
|      */ | ||||
|     public function accountMeta() | ||||
|     { | ||||
|         return $this->hasMany('FireflyIII\Models\AccountMeta'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||||
|      */ | ||||
|     public function accountType() | ||||
|     { | ||||
|         return $this->belongsTo('FireflyIII\Models\AccountType'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * @return string[] | ||||
|      */ | ||||
|     public function getDates() | ||||
|     { | ||||
|         return ['created_at', 'updated_at', 'deleted_at']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * @param string $fieldName | ||||
|      * | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @return string|null | ||||
|      */ | ||||
|     public function getMeta($fieldName) | ||||
|     { | ||||
|         foreach ($this->accountMeta as $meta) { | ||||
|             if ($meta->name == $fieldName) { | ||||
|                 return $meta->data; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @param $value | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getNameAttribute($value) | ||||
|     { | ||||
|  | ||||
|         if (intval($this->encrypted) == 1) { | ||||
|             return Crypt::decrypt($value); | ||||
|         } | ||||
|  | ||||
|         return $value; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\HasMany | ||||
|      */ | ||||
|     public function piggyBanks() | ||||
|     { | ||||
|         return $this->hasMany('FireflyIII\Models\PiggyBank'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @param EloquentBuilder $query | ||||
|      * @param array           $types | ||||
|      */ | ||||
|     public function scopeAccountTypeIn(EloquentBuilder $query, array $types) | ||||
|     { | ||||
|         if (is_null($this->joinedAccountTypes)) { | ||||
|             $query->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id'); | ||||
|             $this->joinedAccountTypes = true; | ||||
|         } | ||||
|         $query->whereIn('account_types.type', $types); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @param EloquentBuilder $query | ||||
|      * @param string          $name | ||||
|      * @param string          $value | ||||
|      */ | ||||
|     public function scopeHasMetaValue(EloquentBuilder $query, $name, $value) | ||||
|     { | ||||
|         $joinName = str_replace('.', '_', $name); | ||||
|         $query->leftJoin( | ||||
|             'account_meta as ' . $joinName, function (JoinClause $join) use ($joinName, $name) { | ||||
|             $join->on($joinName . '.account_id', '=', 'accounts.id')->where($joinName . '.name', '=', $name); | ||||
|         } | ||||
|         ); | ||||
|         $query->where($joinName . '.data', json_encode($value)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @param $value | ||||
|      */ | ||||
|     public function setNameAttribute($value) | ||||
|     { | ||||
|         $this->attributes['name']      = Crypt::encrypt($value); | ||||
|         $this->attributes['encrypted'] = true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      * | ||||
|      * @codeCoverageIgnore | ||||
|      */ | ||||
|     public function setVirtualBalanceAttribute($value) | ||||
|     { | ||||
|         $this->attributes['virtual_balance'] = strval(round($value, 2)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\HasMany | ||||
|      */ | ||||
|     public function transactions() | ||||
|     { | ||||
|         return $this->hasMany('FireflyIII\Models\Transaction'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||||
|      */ | ||||
|     public function user() | ||||
|     { | ||||
|         return $this->belongsTo('FireflyIII\User'); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										74
									
								
								app/Models/AccountMeta.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								app/Models/AccountMeta.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| <?php namespace FireflyIII\Models; | ||||
|  | ||||
| use Illuminate\Database\Eloquent\Model; | ||||
| use Watson\Validating\ValidatingTrait; | ||||
|  | ||||
| /** | ||||
|  * Class AccountMeta | ||||
|  * | ||||
|  * @codeCoverageIgnore  | ||||
|  * @package FireflyIII\Models | ||||
|  * @property integer                         $id | ||||
|  * @property \Carbon\Carbon                  $created_at | ||||
|  * @property \Carbon\Carbon                  $updated_at | ||||
|  * @property integer                         $account_id | ||||
|  * @property string                          $name | ||||
|  * @property string                          $data | ||||
|  * @property-read \FireflyIII\Models\Account $account | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountMeta whereId($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountMeta whereCreatedAt($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountMeta whereUpdatedAt($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountMeta whereAccountId($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountMeta whereName($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountMeta whereData($value) | ||||
|  */ | ||||
| class AccountMeta extends Model | ||||
| { | ||||
|  | ||||
|     use ValidatingTrait; | ||||
|     protected $fillable = ['account_id', 'name', 'data']; | ||||
|     protected $rules | ||||
|                         = [ | ||||
|             'account_id' => 'required|exists:accounts,id', | ||||
|             'name'       => 'required|between:1,100', | ||||
|             'data'       => 'required' | ||||
|         ]; | ||||
|     protected $table    = 'account_meta'; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||||
|      */ | ||||
|     public function account() | ||||
|     { | ||||
|         return $this->belongsTo('FireflyIII\Models\Account'); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function getDataAttribute($value) | ||||
|     { | ||||
|         return json_decode($value); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getDates() | ||||
|     { | ||||
|         return ['created_at', 'updated_at']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      */ | ||||
|     public function setDataAttribute($value) | ||||
|     { | ||||
|         $this->attributes['data'] = json_encode($value); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										41
									
								
								app/Models/AccountType.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								app/Models/AccountType.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| <?php namespace FireflyIII\Models; | ||||
|  | ||||
| use Illuminate\Database\Eloquent\Model; | ||||
|  | ||||
| /** | ||||
|  * Class AccountType | ||||
|  * | ||||
|  * @codeCoverageIgnore  | ||||
|  * @package FireflyIII\Models | ||||
|  * @property integer                                                                    $id | ||||
|  * @property \Carbon\Carbon                                                             $created_at | ||||
|  * @property \Carbon\Carbon                                                             $updated_at | ||||
|  * @property string                                                                     $type | ||||
|  * @property boolean                                                                    $editable | ||||
|  * @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Account[] $accounts | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountType whereId($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountType whereCreatedAt($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountType whereUpdatedAt($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountType whereType($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountType whereEditable($value) | ||||
|  */ | ||||
| class AccountType extends Model | ||||
| { | ||||
|  | ||||
|     // | ||||
|     /** | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\HasMany | ||||
|      */ | ||||
|     public function accounts() | ||||
|     { | ||||
|         return $this->hasMany('FireflyIII\Models\Account'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getDates() | ||||
|     { | ||||
|         return ['created_at', 'updated_at']; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										148
									
								
								app/Models/Bill.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								app/Models/Bill.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,148 @@ | ||||
| <?php namespace FireflyIII\Models; | ||||
|  | ||||
| use Crypt; | ||||
| use Illuminate\Database\Eloquent\Model; | ||||
|  | ||||
| /** | ||||
|  * FireflyIII\Models\Bill | ||||
|  * | ||||
|  * @codeCoverageIgnore Class Bill | ||||
|  * @package FireflyIII\Models | ||||
|  * @property integer                                                                               $id | ||||
|  * @property \Carbon\Carbon                                                                        $created_at | ||||
|  * @property \Carbon\Carbon                                                                        $updated_at | ||||
|  * @property integer                                                                               $user_id | ||||
|  * @property string                                                                                $name | ||||
|  * @property string                                                                                $match | ||||
|  * @property float                                                                                 $amount_min | ||||
|  * @property string                                                                                $amount_min_encrypted | ||||
|  * @property float                                                                                 $amount_max | ||||
|  * @property string                                                                                $amount_max_encrypted | ||||
|  * @property \Carbon\Carbon                                                                        $date | ||||
|  * @property boolean                                                                               $active | ||||
|  * @property boolean                                                                               $automatch | ||||
|  * @property string                                                                                $repeat_freq | ||||
|  * @property integer                                                                               $skip | ||||
|  * @property boolean                                                                               $name_encrypted | ||||
|  * @property boolean                                                                               $match_encrypted | ||||
|  * @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\TransactionJournal[] $transactionjournals | ||||
|  * @property-read \FireflyIII\User                                                                 $user | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereId($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereCreatedAt($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereUpdatedAt($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereUserId($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereName($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereMatch($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereAmountMin($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereAmountMinEncrypted($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereAmountMax($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereAmountMaxEncrypted($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereDate($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereActive($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereAutomatch($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereRepeatFreq($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereSkip($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereNameEncrypted($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereMatchEncrypted($value) | ||||
|  * @property mixed                                                                                 nextExpectedMatch | ||||
|  * @property mixed                                                                                 lastFoundMatch | ||||
|  */ | ||||
| class Bill extends Model | ||||
| { | ||||
|  | ||||
|     protected $fillable | ||||
|         = ['name', 'match', 'amount_min', 'match_encrypted', 'name_encrypted', 'user_id', 'amount_max', 'date', 'repeat_freq', 'skip', 'automatch', 'active',]; | ||||
|  | ||||
|     protected $hidden = ['amount_min_encrypted', 'amount_max_encrypted', 'name_encrypted', 'match_encrypted']; | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getDates() | ||||
|     { | ||||
|         return ['created_at', 'updated_at', 'date']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getMatchAttribute($value) | ||||
|     { | ||||
|  | ||||
|         if (intval($this->match_encrypted) == 1) { | ||||
|             return Crypt::decrypt($value); | ||||
|         } | ||||
|  | ||||
|         return $value; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getNameAttribute($value) | ||||
|     { | ||||
|  | ||||
|         if (intval($this->name_encrypted) == 1) { | ||||
|             return Crypt::decrypt($value); | ||||
|         } | ||||
|  | ||||
|         return $value; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      */ | ||||
|     public function setAmountMaxAttribute($value) | ||||
|     { | ||||
|         $this->attributes['amount_max'] = strval(round($value, 2)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      */ | ||||
|     public function setAmountMinAttribute($value) | ||||
|     { | ||||
|         $this->attributes['amount_min'] = strval(round($value, 2)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      */ | ||||
|     public function setMatchAttribute($value) | ||||
|     { | ||||
|         $this->attributes['match']           = Crypt::encrypt($value); | ||||
|         $this->attributes['match_encrypted'] = true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      */ | ||||
|     public function setNameAttribute($value) | ||||
|     { | ||||
|         $this->attributes['name']           = Crypt::encrypt($value); | ||||
|         $this->attributes['name_encrypted'] = true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\HasMany | ||||
|      */ | ||||
|     public function transactionjournals() | ||||
|     { | ||||
|         return $this->hasMany('FireflyIII\Models\TransactionJournal'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||||
|      */ | ||||
|     public function user() | ||||
|     { | ||||
|         return $this->belongsTo('FireflyIII\User'); | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										106
									
								
								app/Models/Budget.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								app/Models/Budget.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | ||||
| <?php namespace FireflyIII\Models; | ||||
|  | ||||
| use Crypt; | ||||
| use Illuminate\Database\Eloquent\Model; | ||||
| use Illuminate\Database\Eloquent\SoftDeletes; | ||||
|  | ||||
| /** | ||||
|  * Class Budget | ||||
|  * | ||||
|  * @codeCoverageIgnore  | ||||
|  * @package FireflyIII\Models | ||||
|  * @property integer                                                                               $id | ||||
|  * @property \Carbon\Carbon                                                                        $created_at | ||||
|  * @property \Carbon\Carbon                                                                        $updated_at | ||||
|  * @property \Carbon\Carbon                                                                        $deleted_at | ||||
|  * @property string                                                                                $name | ||||
|  * @property integer                                                                               $user_id | ||||
|  * @property boolean                                                                               $active | ||||
|  * @property boolean                                                                               $encrypted | ||||
|  * @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\BudgetLimit[]        $budgetlimits | ||||
|  * @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\TransactionJournal[] $transactionjournals | ||||
|  * @property-read \FireflyIII\User                                                                 $user | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Budget whereId($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Budget whereCreatedAt($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Budget whereUpdatedAt($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Budget whereDeletedAt($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Budget whereName($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Budget whereUserId($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Budget whereActive($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Budget whereEncrypted($value) | ||||
|  */ | ||||
| class Budget extends Model | ||||
| { | ||||
|  | ||||
|     use SoftDeletes; | ||||
|  | ||||
|     protected $fillable = ['user_id', 'name', 'active']; | ||||
|     protected $hidden   = ['encrypted']; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\HasMany | ||||
|      */ | ||||
|     public function budgetlimits() | ||||
|     { | ||||
|         return $this->hasMany('FireflyIII\Models\BudgetLimit'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getDates() | ||||
|     { | ||||
|         return ['created_at', 'updated_at', 'deleted_at']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getNameAttribute($value) | ||||
|     { | ||||
|  | ||||
|         if (intval($this->encrypted) == 1) { | ||||
|             return Crypt::decrypt($value); | ||||
|         } | ||||
|  | ||||
|         return $value; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\HasManyThrough | ||||
|      */ | ||||
|     public function limitrepetitions() | ||||
|     { | ||||
|         return $this->hasManyThrough('FireflyIII\Models\LimitRepetition', 'FireflyIII\Models\BudgetLimit', 'budget_id'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      */ | ||||
|     public function setNameAttribute($value) | ||||
|     { | ||||
|         $this->attributes['name']      = Crypt::encrypt($value); | ||||
|         $this->attributes['encrypted'] = true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany | ||||
|      */ | ||||
|     public function transactionjournals() | ||||
|     { | ||||
|         return $this->belongsToMany('FireflyIII\Models\TransactionJournal', 'budget_transaction_journal', 'budget_id'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||||
|      */ | ||||
|     public function user() | ||||
|     { | ||||
|         return $this->belongsTo('FireflyIII\User'); | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										68
									
								
								app/Models/BudgetLimit.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								app/Models/BudgetLimit.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| <?php namespace FireflyIII\Models; | ||||
|  | ||||
| use Illuminate\Database\Eloquent\Model; | ||||
|  | ||||
| /** | ||||
|  * Class BudgetLimit | ||||
|  * | ||||
|  * @codeCoverageIgnore  | ||||
|  * @package FireflyIII\Models | ||||
|  * @property integer                                                                            $id | ||||
|  * @property \Carbon\Carbon                                                                     $created_at | ||||
|  * @property \Carbon\Carbon                                                                     $updated_at | ||||
|  * @property integer                                                                            $budget_id | ||||
|  * @property \Carbon\Carbon                                                                     $startdate | ||||
|  * @property float                                                                              $amount | ||||
|  * @property string                                                                             $amount_encrypted | ||||
|  * @property boolean                                                                            $repeats | ||||
|  * @property string                                                                             $repeat_freq | ||||
|  * @property-read \FireflyIII\Models\Budget                                                     $budget | ||||
|  * @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\LimitRepetition[] $limitrepetitions | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\BudgetLimit whereId($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\BudgetLimit whereCreatedAt($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\BudgetLimit whereUpdatedAt($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\BudgetLimit whereBudgetId($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\BudgetLimit whereStartdate($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\BudgetLimit whereAmount($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\BudgetLimit whereAmountEncrypted($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\BudgetLimit whereRepeats($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\BudgetLimit whereRepeatFreq($value) | ||||
|  */ | ||||
| class BudgetLimit extends Model | ||||
| { | ||||
|  | ||||
|     protected $hidden = ['amount_encrypted']; | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||||
|      */ | ||||
|     public function budget() | ||||
|     { | ||||
|         return $this->belongsTo('FireflyIII\Models\Budget'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getDates() | ||||
|     { | ||||
|         return ['created_at', 'updated_at', 'startdate']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\HasMany | ||||
|      */ | ||||
|     public function limitrepetitions() | ||||
|     { | ||||
|         return $this->hasMany('FireflyIII\Models\LimitRepetition'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      */ | ||||
|     public function setAmountAttribute($value) | ||||
|     { | ||||
|         $this->attributes['amount'] = strval(round($value, 2)); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										121
									
								
								app/Models/Category.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								app/Models/Category.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,121 @@ | ||||
| <?php namespace FireflyIII\Models; | ||||
|  | ||||
| use Crypt; | ||||
| use Illuminate\Database\Eloquent\Model; | ||||
| use Illuminate\Database\Eloquent\SoftDeletes; | ||||
|  | ||||
| /** | ||||
|  * Class Category | ||||
|  * | ||||
|  * @package FireflyIII\Models | ||||
|  * @property integer                                                                               $id | ||||
|  * @property \Carbon\Carbon                                                                        $created_at | ||||
|  * @property \Carbon\Carbon                                                                        $updated_at | ||||
|  * @property \Carbon\Carbon                                                                        $deleted_at | ||||
|  * @property string                                                                                $name | ||||
|  * @property integer                                                                               $user_id | ||||
|  * @property boolean                                                                               $encrypted | ||||
|  * @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\TransactionJournal[] $transactionjournals | ||||
|  * @property-read \FireflyIII\User                                                                 $user | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Category whereId($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Category whereCreatedAt($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Category whereUpdatedAt($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Category whereDeletedAt($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Category whereName($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Category whereUserId($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Category whereEncrypted($value) | ||||
|  * @property mixed                                                                                 spent | ||||
|  * @property mixed                                                                                 lastActivity | ||||
|  */ | ||||
| class Category extends Model | ||||
| { | ||||
|     use SoftDeletes; | ||||
|  | ||||
|     protected $fillable = ['user_id', 'name']; | ||||
|     protected $hidden   = ['encrypted']; | ||||
|  | ||||
|     /** | ||||
|      * @param array $fields | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * | ||||
|      * @return Category | ||||
|      */ | ||||
|     public static function firstOrCreateEncrypted(array $fields) | ||||
|     { | ||||
|         // everything but the name: | ||||
|         $query = Category::orderBy('id'); | ||||
|         foreach ($fields as $name => $value) { | ||||
|             if ($name != 'name') { | ||||
|                 $query->where($name, $value); | ||||
|             } | ||||
|         } | ||||
|         $set = $query->get(['categories.*']); | ||||
|         /** @var Category $category */ | ||||
|         foreach ($set as $category) { | ||||
|             if ($category->name == $fields['name']) { | ||||
|                 return $category; | ||||
|             } | ||||
|         } | ||||
|         // create it! | ||||
|         $category = Category::create($fields); | ||||
|  | ||||
|         return $category; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * @return string[] | ||||
|      */ | ||||
|     public function getDates() | ||||
|     { | ||||
|         return ['created_at', 'updated_at', 'deleted_at']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @param $value | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getNameAttribute($value) | ||||
|     { | ||||
|  | ||||
|         if (intval($this->encrypted) == 1) { | ||||
|             return Crypt::decrypt($value); | ||||
|         } | ||||
|  | ||||
|         return $value; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * | ||||
|      * @param $value | ||||
|      */ | ||||
|     public function setNameAttribute($value) | ||||
|     { | ||||
|         $this->attributes['name']      = Crypt::encrypt($value); | ||||
|         $this->attributes['encrypted'] = true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany | ||||
|      */ | ||||
|     public function transactionjournals() | ||||
|     { | ||||
|         return $this->belongsToMany('FireflyIII\Models\TransactionJournal', 'category_transaction_journal', 'category_id'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @codeCoverageIgnore | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||||
|      */ | ||||
|     public function user() | ||||
|     { | ||||
|         return $this->belongsTo('FireflyIII\User'); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										39
									
								
								app/Models/Component.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								app/Models/Component.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| <?php namespace FireflyIII\Models; | ||||
|  | ||||
| use Illuminate\Database\Eloquent\Model; | ||||
| use Illuminate\Database\Eloquent\SoftDeletes; | ||||
|  | ||||
| /** | ||||
|  * Class Component | ||||
|  * | ||||
|  * @codeCoverageIgnore  | ||||
|  * @package FireflyIII\Models | ||||
|  * @property integer        $id | ||||
|  * @property \Carbon\Carbon $created_at | ||||
|  * @property \Carbon\Carbon $updated_at | ||||
|  * @property \Carbon\Carbon $deleted_at | ||||
|  * @property string         $name | ||||
|  * @property integer        $user_id | ||||
|  * @property string         $class | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Component whereId($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Component whereCreatedAt($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Component whereUpdatedAt($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Component whereDeletedAt($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Component whereName($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Component whereUserId($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Component whereClass($value) | ||||
|  */ | ||||
| class Component extends Model | ||||
| { | ||||
|     use SoftDeletes; | ||||
|  | ||||
|     protected $fillable = ['user_id', 'name', 'class']; | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getDates() | ||||
|     { | ||||
|         return ['created_at', 'updated_at', 'deleted_at']; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										57
									
								
								app/Models/LimitRepetition.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								app/Models/LimitRepetition.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| <?php namespace FireflyIII\Models; | ||||
|  | ||||
| use Illuminate\Database\Eloquent\Model; | ||||
|  | ||||
| /** | ||||
|  * Class LimitRepetition | ||||
|  * | ||||
|  * @codeCoverageIgnore  | ||||
|  * @package FireflyIII\Models | ||||
|  * @property integer                             $id | ||||
|  * @property \Carbon\Carbon                      $created_at | ||||
|  * @property \Carbon\Carbon                      $updated_at | ||||
|  * @property integer                             $budget_limit_id | ||||
|  * @property \Carbon\Carbon                      $startdate | ||||
|  * @property \Carbon\Carbon                      $enddate | ||||
|  * @property float                               $amount | ||||
|  * @property string                              $amount_encrypted | ||||
|  * @property-read \FireflyIII\Models\BudgetLimit $budgetLimit | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\LimitRepetition whereId($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\LimitRepetition whereCreatedAt($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\LimitRepetition whereUpdatedAt($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\LimitRepetition whereBudgetLimitId($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\LimitRepetition whereStartdate($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\LimitRepetition whereEnddate($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\LimitRepetition whereAmount($value) | ||||
|  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\LimitRepetition whereAmountEncrypted($value) | ||||
|  */ | ||||
| class LimitRepetition extends Model | ||||
| { | ||||
|  | ||||
|     protected $hidden = ['amount_encrypted']; | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||||
|      */ | ||||
|     public function budgetLimit() | ||||
|     { | ||||
|         return $this->belongsTo('FireflyIII\Models\BudgetLimit'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getDates() | ||||
|     { | ||||
|         return ['created_at', 'updated_at', 'startdate', 'enddate']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      */ | ||||
|     public function setAmountAttribute($value) | ||||
|     { | ||||
|         $this->attributes['amount'] = strval(round($value, 2)); | ||||
|     } | ||||
|  | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user