mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-11-04 05:15:39 +00:00 
			
		
		
		
	Compare commits
	
		
			924 Commits
		
	
	
		
			v6.1.18
			...
			develop-20
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					422a23e700 | ||
| 
						 | 
					8c2672cdf8 | ||
| 
						 | 
					764e49985b | ||
| 
						 | 
					84251f8f10 | ||
| 
						 | 
					8b4740d28c | ||
| 
						 | 
					0845e265c2 | ||
| 
						 | 
					b4455a3802 | ||
| 
						 | 
					8d12d47691 | ||
| 
						 | 
					3dc01b0d5c | ||
| 
						 | 
					b442645280 | ||
| 
						 | 
					eda2b5f822 | ||
| 
						 | 
					d9593db5e2 | ||
| 
						 | 
					56bac9fc97 | ||
| 
						 | 
					b93cfc5de2 | ||
| 
						 | 
					d41f5b1090 | ||
| 
						 | 
					40322813c9 | ||
| 
						 | 
					4a98927e32 | ||
| 
						 | 
					193e529803 | ||
| 
						 | 
					fbf20ef2c2 | ||
| 
						 | 
					54de829c8a | ||
| 
						 | 
					131b987561 | ||
| 
						 | 
					dce6754c62 | ||
| 
						 | 
					f4bca90080 | ||
| 
						 | 
					b2960b1ed9 | ||
| 
						 | 
					33f87bce23 | ||
| 
						 | 
					23aa45609b | ||
| 
						 | 
					b098952f82 | ||
| 
						 | 
					68c3e14b0c | ||
| 
						 | 
					19d08137a5 | ||
| 
						 | 
					73776e7869 | ||
| 
						 | 
					bf04ca12c1 | ||
| 
						 | 
					a4637debe9 | ||
| 
						 | 
					48c1b525be | ||
| 
						 | 
					56470bfbba | ||
| 
						 | 
					0f732ca874 | ||
| 
						 | 
					e452ba938d | ||
| 
						 | 
					9921c5a925 | ||
| 
						 | 
					58fab75681 | ||
| 
						 | 
					54990308f6 | ||
| 
						 | 
					f95758ff47 | ||
| 
						 | 
					8d830e178f | ||
| 
						 | 
					334a521ca1 | ||
| 
						 | 
					12629a1955 | ||
| 
						 | 
					2e3669a32f | ||
| 
						 | 
					ea337607c4 | ||
| 
						 | 
					f7f317a3b2 | ||
| 
						 | 
					adbf6defe5 | ||
| 
						 | 
					e0709f2975 | ||
| 
						 | 
					30007b05cb | ||
| 
						 | 
					13fc7f0d8d | ||
| 
						 | 
					7c85138115 | ||
| 
						 | 
					2c25f65f7f | ||
| 
						 | 
					7eaba962e8 | ||
| 
						 | 
					7c38393cde | ||
| 
						 | 
					153fd2ae74 | ||
| 
						 | 
					c0204c810c | ||
| 
						 | 
					944c107e26 | ||
| 
						 | 
					18e05c06fd | ||
| 
						 | 
					fb79dbf17c | ||
| 
						 | 
					31a8163c61 | ||
| 
						 | 
					8bcd729250 | ||
| 
						 | 
					80c4e69528 | ||
| 
						 | 
					7f6d8fdb87 | ||
| 
						 | 
					c8e301326e | ||
| 
						 | 
					4820ef6580 | ||
| 
						 | 
					4cb775cf4b | ||
| 
						 | 
					c371662c51 | ||
| 
						 | 
					ffaa164aa5 | ||
| 
						 | 
					344bfbe059 | ||
| 
						 | 
					6c38b87ec5 | ||
| 
						 | 
					dfcd5d79be | ||
| 
						 | 
					07631eea28 | ||
| 
						 | 
					26c4fe36cc | ||
| 
						 | 
					90fc4b44f2 | ||
| 
						 | 
					f755dd2d48 | ||
| 
						 | 
					d2647f96e7 | ||
| 
						 | 
					9f94ec067a | ||
| 
						 | 
					a795755618 | ||
| 
						 | 
					8457a1c881 | ||
| 
						 | 
					fc9429bf3e | ||
| 
						 | 
					b6e8b66035 | ||
| 
						 | 
					7504b21c3e | ||
| 
						 | 
					b7dad8166d | ||
| 
						 | 
					2da1b43c37 | ||
| 
						 | 
					a606315884 | ||
| 
						 | 
					295feedd77 | ||
| 
						 | 
					d3b2748c8f | ||
| 
						 | 
					1b4655fd70 | ||
| 
						 | 
					05f67ef584 | ||
| 
						 | 
					04ab7ba07d | ||
| 
						 | 
					5806323970 | ||
| 
						 | 
					ee260a3df7 | ||
| 
						 | 
					7cb41fb333 | ||
| 
						 | 
					d38adbfdc2 | ||
| 
						 | 
					e6a6766ef1 | ||
| 
						 | 
					a1e596491c | ||
| 
						 | 
					9c920908a6 | ||
| 
						 | 
					0014bffeb8 | ||
| 
						 | 
					63c17f99b2 | ||
| 
						 | 
					ec1e0e2807 | ||
| 
						 | 
					2f16419a7b | ||
| 
						 | 
					02c13859e7 | ||
| 
						 | 
					57ec9b8e36 | ||
| 
						 | 
					41ad35880d | ||
| 
						 | 
					3aa946e028 | ||
| 
						 | 
					53e46895aa | ||
| 
						 | 
					c61389037d | ||
| 
						 | 
					6172d60e00 | ||
| 
						 | 
					f909f1d9ff | ||
| 
						 | 
					55018ca046 | ||
| 
						 | 
					19c746a865 | ||
| 
						 | 
					503d2aa786 | ||
| 
						 | 
					70d83ab501 | ||
| 
						 | 
					edab602bb7 | ||
| 
						 | 
					f9bcc4b1fa | ||
| 
						 | 
					f3fe86167c | ||
| 
						 | 
					2189fb46a2 | ||
| 
						 | 
					7ff4178c8b | ||
| 
						 | 
					fffd695ef8 | ||
| 
						 | 
					ee592de035 | ||
| 
						 | 
					7394e50ae2 | ||
| 
						 | 
					f42fcff04a | ||
| 
						 | 
					4eb3ce7c14 | ||
| 
						 | 
					a977c567ce | ||
| 
						 | 
					785bd7e905 | ||
| 
						 | 
					df19f699d4 | ||
| 
						 | 
					5e6e932e7e | ||
| 
						 | 
					5bc397f01a | ||
| 
						 | 
					42209e367f | ||
| 
						 | 
					d53b1670d3 | ||
| 
						 | 
					a6d450ba18 | ||
| 
						 | 
					e8c1a95128 | ||
| 
						 | 
					edb201f210 | ||
| 
						 | 
					fe57367a8c | ||
| 
						 | 
					134194a95b | ||
| 
						 | 
					41c0e6fe2d | ||
| 
						 | 
					c07914e733 | ||
| 
						 | 
					52e2302f4f | ||
| 
						 | 
					0a6b34b4f2 | ||
| 
						 | 
					1e06b4dd0b | ||
| 
						 | 
					5701f95e0b | ||
| 
						 | 
					60d3572d37 | ||
| 
						 | 
					ffa6e6a571 | ||
| 
						 | 
					d6453cd735 | ||
| 
						 | 
					fd79f9df44 | ||
| 
						 | 
					4587340293 | ||
| 
						 | 
					90bfdc7573 | ||
| 
						 | 
					eca12f661f | ||
| 
						 | 
					f85878b843 | ||
| 
						 | 
					6499b5eaab | ||
| 
						 | 
					7e4fece63d | ||
| 
						 | 
					512eddf8be | ||
| 
						 | 
					f0fa93a811 | ||
| 
						 | 
					3c8de21709 | ||
| 
						 | 
					81173e8340 | ||
| 
						 | 
					35a8fa5f02 | ||
| 
						 | 
					443036936d | ||
| 
						 | 
					ac88007593 | ||
| 
						 | 
					2297589dca | ||
| 
						 | 
					6ada5fa560 | ||
| 
						 | 
					8f6eefb5e7 | ||
| 
						 | 
					b36a50381b | ||
| 
						 | 
					51f84b3060 | ||
| 
						 | 
					72132a19b0 | ||
| 
						 | 
					065d165211 | ||
| 
						 | 
					cabedf39b2 | ||
| 
						 | 
					5d3806fcd4 | ||
| 
						 | 
					01695b3342 | ||
| 
						 | 
					71fb5fe077 | ||
| 
						 | 
					3bec106840 | ||
| 
						 | 
					fb01c36be1 | ||
| 
						 | 
					26d851e69e | ||
| 
						 | 
					28c18c046b | ||
| 
						 | 
					318cef7e3b | ||
| 
						 | 
					e8dc8f25be | ||
| 
						 | 
					10ccc30240 | ||
| 
						 | 
					5adc877d5e | ||
| 
						 | 
					30923afb2b | ||
| 
						 | 
					4eb6813b43 | ||
| 
						 | 
					7521a31619 | ||
| 
						 | 
					fc05beb452 | ||
| 
						 | 
					1103428a83 | ||
| 
						 | 
					d06d521bf0 | ||
| 
						 | 
					8f64f1c0eb | ||
| 
						 | 
					d11c232171 | ||
| 
						 | 
					93c73248de | ||
| 
						 | 
					5bed081ab9 | ||
| 
						 | 
					c5188c503e | ||
| 
						 | 
					98ffcac7b6 | ||
| 
						 | 
					df1e81d611 | ||
| 
						 | 
					9711170b08 | ||
| 
						 | 
					e43264bdce | ||
| 
						 | 
					e0643bed7a | ||
| 
						 | 
					7f0eb3b064 | ||
| 
						 | 
					f38e510526 | ||
| 
						 | 
					25f99b23b2 | ||
| 
						 | 
					44281fc8a0 | ||
| 
						 | 
					eed3902cb7 | ||
| 
						 | 
					94a3bb0443 | ||
| 
						 | 
					8dcc36880e | ||
| 
						 | 
					695bb31894 | ||
| 
						 | 
					f8ded66869 | ||
| 
						 | 
					8e4bdbc584 | ||
| 
						 | 
					f7b14b01bc | ||
| 
						 | 
					705b9bf0f2 | ||
| 
						 | 
					f0226dbc54 | ||
| 
						 | 
					1b1dfb0d7b | ||
| 
						 | 
					8ed5092a76 | ||
| 
						 | 
					d609821be6 | ||
| 
						 | 
					cd0201074c | ||
| 
						 | 
					1d8feec7bc | ||
| 
						 | 
					d941472c84 | ||
| 
						 | 
					674a118fac | ||
| 
						 | 
					1334d793f6 | ||
| 
						 | 
					60354c0202 | ||
| 
						 | 
					22081d3f0a | ||
| 
						 | 
					4b3f8fc78d | ||
| 
						 | 
					4bd1aab86d | ||
| 
						 | 
					60362cb60c | ||
| 
						 | 
					27f740bf98 | ||
| 
						 | 
					5e15747a5b | ||
| 
						 | 
					8a6eaad2bb | ||
| 
						 | 
					5ab52d9f66 | ||
| 
						 | 
					21a327bf08 | ||
| 
						 | 
					15dd175394 | ||
| 
						 | 
					3f35305beb | ||
| 
						 | 
					768d8b1515 | ||
| 
						 | 
					1c19428a12 | ||
| 
						 | 
					c204533195 | ||
| 
						 | 
					6d89485792 | ||
| 
						 | 
					949d818bad | ||
| 
						 | 
					a12e200a0a | ||
| 
						 | 
					b4039b1f13 | ||
| 
						 | 
					32921e15b1 | ||
| 
						 | 
					4f7cc7d53b | ||
| 
						 | 
					0986bfbc34 | ||
| 
						 | 
					663202bfc6 | ||
| 
						 | 
					6f63ddf5b0 | ||
| 
						 | 
					a9805b144a | ||
| 
						 | 
					e1b8b9b3ae | ||
| 
						 | 
					d57327fd11 | ||
| 
						 | 
					15ac69bfad | ||
| 
						 | 
					a5bd28f8d4 | ||
| 
						 | 
					b2516ca1b4 | ||
| 
						 | 
					053b46ae63 | ||
| 
						 | 
					6e836aceec | ||
| 
						 | 
					0e8bcd2e79 | ||
| 
						 | 
					bd1f8b2497 | ||
| 
						 | 
					19dfcf7139 | ||
| 
						 | 
					ef7a3287bb | ||
| 
						 | 
					2900049498 | ||
| 
						 | 
					04d1e8fd59 | ||
| 
						 | 
					9d2f57e40a | ||
| 
						 | 
					ae366341cc | ||
| 
						 | 
					3766128cb8 | ||
| 
						 | 
					950c60d55c | ||
| 
						 | 
					4b2807de48 | ||
| 
						 | 
					649736cb31 | ||
| 
						 | 
					6a121a8a78 | ||
| 
						 | 
					f69b9ac9da | ||
| 
						 | 
					23d70a2fac | ||
| 
						 | 
					d178ff9de0 | ||
| 
						 | 
					3ecad3457f | ||
| 
						 | 
					fa6c621968 | ||
| 
						 | 
					df863b6cff | ||
| 
						 | 
					9316ff3e51 | ||
| 
						 | 
					bfd91f8ee6 | ||
| 
						 | 
					13e5d25cfe | ||
| 
						 | 
					b13030420b | ||
| 
						 | 
					44d1e8181c | ||
| 
						 | 
					63b34c1853 | ||
| 
						 | 
					facd0144cb | ||
| 
						 | 
					115e3435af | ||
| 
						 | 
					d44cd50768 | ||
| 
						 | 
					1afcaea4c6 | ||
| 
						 | 
					2bd1b37717 | ||
| 
						 | 
					2d37177316 | ||
| 
						 | 
					abb25e2015 | ||
| 
						 | 
					d08d075e30 | ||
| 
						 | 
					b4c67c02a7 | ||
| 
						 | 
					04fb6a953e | ||
| 
						 | 
					5dce0bec8e | ||
| 
						 | 
					481bb3fb0a | ||
| 
						 | 
					b6960dc299 | ||
| 
						 | 
					73104aae1f | ||
| 
						 | 
					10a284848b | ||
| 
						 | 
					fd6560bdd0 | ||
| 
						 | 
					0810f617c7 | ||
| 
						 | 
					c3ffd39450 | ||
| 
						 | 
					0f69e0d672 | ||
| 
						 | 
					1aa8ebe57f | ||
| 
						 | 
					23178614d5 | ||
| 
						 | 
					d2b6829574 | ||
| 
						 | 
					5602715c96 | ||
| 
						 | 
					54d0433dd4 | ||
| 
						 | 
					f4bc313d0b | ||
| 
						 | 
					5617de3a79 | ||
| 
						 | 
					2d62f0ff06 | ||
| 
						 | 
					1c79f6b1b6 | ||
| 
						 | 
					bf01153c6b | ||
| 
						 | 
					c43b37baef | ||
| 
						 | 
					d4942efd8e | ||
| 
						 | 
					ea9f635b1a | ||
| 
						 | 
					7eaa0e16b3 | ||
| 
						 | 
					1b97d8fd48 | ||
| 
						 | 
					89a29b9b10 | ||
| 
						 | 
					2baac1a6d7 | ||
| 
						 | 
					cd296aa9ac | ||
| 
						 | 
					959d168352 | ||
| 
						 | 
					6cd60951ba | ||
| 
						 | 
					3898c0c0ef | ||
| 
						 | 
					fe4d139817 | ||
| 
						 | 
					d95f3ca59f | ||
| 
						 | 
					7f6c03ce17 | ||
| 
						 | 
					394d0eabef | ||
| 
						 | 
					a8ae496fda | ||
| 
						 | 
					1787f4421b | ||
| 
						 | 
					36351a5dd9 | ||
| 
						 | 
					d009ce31ca | ||
| 
						 | 
					44eafeeae5 | ||
| 
						 | 
					21165eb3e0 | ||
| 
						 | 
					2ef3a33fbf | ||
| 
						 | 
					f74be0402f | ||
| 
						 | 
					a60cb366b2 | ||
| 
						 | 
					58e2ef187d | ||
| 
						 | 
					ae80fd8578 | ||
| 
						 | 
					c17f2efca6 | ||
| 
						 | 
					4a185639b9 | ||
| 
						 | 
					dae7e7d507 | ||
| 
						 | 
					e33e3cc40f | ||
| 
						 | 
					36ec1daf3a | ||
| 
						 | 
					50aff9cfb6 | ||
| 
						 | 
					058a0f9fb2 | ||
| 
						 | 
					0c955efa8b | ||
| 
						 | 
					a62916a63d | ||
| 
						 | 
					af7a4b5d3d | ||
| 
						 | 
					2ae3929dd6 | ||
| 
						 | 
					ebd30f4861 | ||
| 
						 | 
					afc9ea08f3 | ||
| 
						 | 
					78f9f7e2dd | ||
| 
						 | 
					c44b827922 | ||
| 
						 | 
					fb30f7ec8f | ||
| 
						 | 
					e878d5ce07 | ||
| 
						 | 
					f727a38b69 | ||
| 
						 | 
					c11a5384da | ||
| 
						 | 
					ed92cbd4b8 | ||
| 
						 | 
					a9ea32772f | ||
| 
						 | 
					92f5cca65b | ||
| 
						 | 
					57b064f590 | ||
| 
						 | 
					9729434926 | ||
| 
						 | 
					9d9dffee74 | ||
| 
						 | 
					b3f374f4ea | ||
| 
						 | 
					50e07d422f | ||
| 
						 | 
					631ed4956a | ||
| 
						 | 
					0eca1c8d03 | ||
| 
						 | 
					e38e4574ad | ||
| 
						 | 
					be2d3f3637 | ||
| 
						 | 
					0e3d779e24 | ||
| 
						 | 
					4d25336d87 | ||
| 
						 | 
					74f76a2835 | ||
| 
						 | 
					84560a6f44 | ||
| 
						 | 
					6fde693e7a | ||
| 
						 | 
					2e46d9ba33 | ||
| 
						 | 
					e36f8deb08 | ||
| 
						 | 
					1631b422f1 | ||
| 
						 | 
					b58d809063 | ||
| 
						 | 
					9e34314dbc | ||
| 
						 | 
					e4aa218b5f | ||
| 
						 | 
					31722477d4 | ||
| 
						 | 
					ec82105433 | ||
| 
						 | 
					146e164f04 | ||
| 
						 | 
					7d37c93988 | ||
| 
						 | 
					73dffacd9a | ||
| 
						 | 
					d37304fa68 | ||
| 
						 | 
					62f4da6063 | ||
| 
						 | 
					760da08ab7 | ||
| 
						 | 
					e68c4d4408 | ||
| 
						 | 
					46a200aa1f | ||
| 
						 | 
					c422039335 | ||
| 
						 | 
					0579c8565d | ||
| 
						 | 
					9f25880a59 | ||
| 
						 | 
					05f1819f7d | ||
| 
						 | 
					fa2149f957 | ||
| 
						 | 
					c21a79e029 | ||
| 
						 | 
					03e31ebb5e | ||
| 
						 | 
					3c20e5f3af | ||
| 
						 | 
					9a9dd9e075 | ||
| 
						 | 
					7189986c03 | ||
| 
						 | 
					b407d8d315 | ||
| 
						 | 
					41fa2a6208 | ||
| 
						 | 
					fe00c4c373 | ||
| 
						 | 
					7248a76c63 | ||
| 
						 | 
					ee3c618797 | ||
| 
						 | 
					a1241ebedb | ||
| 
						 | 
					af78d998db | ||
| 
						 | 
					d96c235ffe | ||
| 
						 | 
					79ca1b5f4e | ||
| 
						 | 
					0f68735e1c | ||
| 
						 | 
					82abee37de | ||
| 
						 | 
					507040f1fd | ||
| 
						 | 
					42dc8486e9 | ||
| 
						 | 
					6c655634bc | ||
| 
						 | 
					f2166b97b8 | ||
| 
						 | 
					da88e02be0 | ||
| 
						 | 
					0d56b7d251 | ||
| 
						 | 
					0a089efcac | ||
| 
						 | 
					89ab360391 | ||
| 
						 | 
					2bd97d9a99 | ||
| 
						 | 
					103b9056e4 | ||
| 
						 | 
					23c4352c18 | ||
| 
						 | 
					2dddaa36d5 | ||
| 
						 | 
					8ab7cf2388 | ||
| 
						 | 
					f191086adb | ||
| 
						 | 
					68b446db18 | ||
| 
						 | 
					3d49d81856 | ||
| 
						 | 
					96493425d1 | ||
| 
						 | 
					419975285c | ||
| 
						 | 
					aa5bde122e | ||
| 
						 | 
					0fa3c2bd8d | ||
| 
						 | 
					b9249a4d96 | ||
| 
						 | 
					6638ca270f | ||
| 
						 | 
					9bfef892f8 | ||
| 
						 | 
					32e5efec7c | ||
| 
						 | 
					36457455ca | ||
| 
						 | 
					062c148e43 | ||
| 
						 | 
					2314ce8004 | ||
| 
						 | 
					a3ff73903a | ||
| 
						 | 
					7c8445707e | ||
| 
						 | 
					291e73da4b | ||
| 
						 | 
					286a29ca3e | ||
| 
						 | 
					71cf6c6a5e | ||
| 
						 | 
					1e8f0adaf8 | ||
| 
						 | 
					33531244aa | ||
| 
						 | 
					06049a9a28 | ||
| 
						 | 
					d313f5fdf5 | ||
| 
						 | 
					f4868126c1 | ||
| 
						 | 
					00147e98dd | ||
| 
						 | 
					6d22663ca2 | ||
| 
						 | 
					756bb9cf5e | ||
| 
						 | 
					399d7968f5 | ||
| 
						 | 
					966b68f42e | ||
| 
						 | 
					134c551c12 | ||
| 
						 | 
					9aeca15355 | ||
| 
						 | 
					6c6d31830b | ||
| 
						 | 
					e8cc321898 | ||
| 
						 | 
					e73fe06f7e | ||
| 
						 | 
					98b579c042 | ||
| 
						 | 
					7b3a5c1afd | ||
| 
						 | 
					7e2e49e129 | ||
| 
						 | 
					e8ef630424 | ||
| 
						 | 
					8805bcf6f6 | ||
| 
						 | 
					ff5c9a3aa0 | ||
| 
						 | 
					3a274dcaa7 | ||
| 
						 | 
					ddfededf02 | ||
| 
						 | 
					e1785898ba | ||
| 
						 | 
					ae09200f42 | ||
| 
						 | 
					847984f678 | ||
| 
						 | 
					5971d155ef | ||
| 
						 | 
					42305672ac | ||
| 
						 | 
					25a56d9f72 | ||
| 
						 | 
					cea52c0ac7 | ||
| 
						 | 
					1b33ff9c25 | ||
| 
						 | 
					8f9f08b96f | ||
| 
						 | 
					594ba205bb | ||
| 
						 | 
					3c65b46aa5 | ||
| 
						 | 
					1cf9c76329 | ||
| 
						 | 
					495f5c71c3 | ||
| 
						 | 
					7e80f607b7 | ||
| 
						 | 
					d93732e451 | ||
| 
						 | 
					1b57bc7889 | ||
| 
						 | 
					c0499df4ec | ||
| 
						 | 
					d90ac519f7 | ||
| 
						 | 
					a0e92b6969 | ||
| 
						 | 
					df49dd23e2 | ||
| 
						 | 
					d4525da6bc | ||
| 
						 | 
					25b11bd20b | ||
| 
						 | 
					9e373a9b0d | ||
| 
						 | 
					705aac419a | ||
| 
						 | 
					4fb61646b4 | ||
| 
						 | 
					f6e642f72e | ||
| 
						 | 
					565bd87959 | ||
| 
						 | 
					5751f7e5a3 | ||
| 
						 | 
					f5a755d4fc | ||
| 
						 | 
					a500de8ab1 | ||
| 
						 | 
					303548a5fe | ||
| 
						 | 
					68de905698 | ||
| 
						 | 
					9240b9868b | ||
| 
						 | 
					0e2e155cc6 | ||
| 
						 | 
					bffa0088b4 | ||
| 
						 | 
					2e993857e8 | ||
| 
						 | 
					117a376fc3 | ||
| 
						 | 
					1daffedde0 | ||
| 
						 | 
					0e8fdd76a6 | ||
| 
						 | 
					7ff4f29bcb | ||
| 
						 | 
					9e4cff2b23 | ||
| 
						 | 
					4aaea89f2c | ||
| 
						 | 
					4fbf7b38fb | ||
| 
						 | 
					76075401f9 | ||
| 
						 | 
					e2a20dd63d | ||
| 
						 | 
					b52a1f3eb1 | ||
| 
						 | 
					7fd5a88122 | ||
| 
						 | 
					1a1baa5cda | ||
| 
						 | 
					577d671a0c | ||
| 
						 | 
					380029ffd8 | ||
| 
						 | 
					e2f1fc307f | ||
| 
						 | 
					76cc27a267 | ||
| 
						 | 
					e8a6f30e4e | ||
| 
						 | 
					fe6021a3d6 | ||
| 
						 | 
					563c54702b | ||
| 
						 | 
					4d67d27ba0 | ||
| 
						 | 
					edf3876a57 | ||
| 
						 | 
					2d10f255c2 | ||
| 
						 | 
					ee76cc6761 | ||
| 
						 | 
					f197e6623b | ||
| 
						 | 
					42a9809450 | ||
| 
						 | 
					444f80a933 | ||
| 
						 | 
					4b985c818a | ||
| 
						 | 
					2e62fe7b72 | ||
| 
						 | 
					ccd182aed9 | ||
| 
						 | 
					615eef3fdd | ||
| 
						 | 
					d4e4907363 | ||
| 
						 | 
					c205e93876 | ||
| 
						 | 
					3b24bb99bb | ||
| 
						 | 
					2814cd1b2a | ||
| 
						 | 
					5285e1ac14 | ||
| 
						 | 
					48a999cf91 | ||
| 
						 | 
					3117c8846e | ||
| 
						 | 
					6bb297e76f | ||
| 
						 | 
					bc698f67ea | ||
| 
						 | 
					f1c859aaa3 | ||
| 
						 | 
					2d0aa207d4 | ||
| 
						 | 
					4a75e9c262 | ||
| 
						 | 
					ee7c4b8863 | ||
| 
						 | 
					f782979d6c | ||
| 
						 | 
					53cce6510c | ||
| 
						 | 
					53252b84fd | ||
| 
						 | 
					8f3cf38f77 | ||
| 
						 | 
					f33766a062 | ||
| 
						 | 
					ac5e62c65d | ||
| 
						 | 
					e2289ce1e6 | ||
| 
						 | 
					f0e2913802 | ||
| 
						 | 
					1fa928b98f | ||
| 
						 | 
					1c691cca33 | ||
| 
						 | 
					69e1eb3eff | ||
| 
						 | 
					90794cb515 | ||
| 
						 | 
					28d7e24d30 | ||
| 
						 | 
					6a62f781e9 | ||
| 
						 | 
					fb6c67fa04 | ||
| 
						 | 
					03e9e3dbdb | ||
| 
						 | 
					5520992861 | ||
| 
						 | 
					5f1502eea7 | ||
| 
						 | 
					b3560ff525 | ||
| 
						 | 
					8030167ffc | ||
| 
						 | 
					fd2c1615cf | ||
| 
						 | 
					b976239580 | ||
| 
						 | 
					7d8d773f8f | ||
| 
						 | 
					b930ad4da7 | ||
| 
						 | 
					abad7cdf16 | ||
| 
						 | 
					0e5eb036b0 | ||
| 
						 | 
					d995bfc081 | ||
| 
						 | 
					c920070ce2 | ||
| 
						 | 
					277f5e538f | ||
| 
						 | 
					89f197b9d4 | ||
| 
						 | 
					c35ff3174a | ||
| 
						 | 
					94085ee940 | ||
| 
						 | 
					c841fa3620 | ||
| 
						 | 
					69b2c1f4d2 | ||
| 
						 | 
					2f7a1c941e | ||
| 
						 | 
					c06fb8daf6 | ||
| 
						 | 
					26948a058a | ||
| 
						 | 
					1220564f30 | ||
| 
						 | 
					ea4be9dd0c | ||
| 
						 | 
					1ccda0b598 | ||
| 
						 | 
					eb3b67ffd6 | ||
| 
						 | 
					4819b5ac5d | ||
| 
						 | 
					591b795aa3 | ||
| 
						 | 
					ac21ed7d18 | ||
| 
						 | 
					d9c66a2db0 | ||
| 
						 | 
					d740814f88 | ||
| 
						 | 
					cdf1ebf3f7 | ||
| 
						 | 
					f2fab5d4ee | ||
| 
						 | 
					21a6927279 | ||
| 
						 | 
					92190bbc54 | ||
| 
						 | 
					9ad005e31f | ||
| 
						 | 
					f5c56e02da | ||
| 
						 | 
					6f02eff020 | ||
| 
						 | 
					c25c0d37c5 | ||
| 
						 | 
					4ba1c5bcfc | ||
| 
						 | 
					64aefe5848 | ||
| 
						 | 
					73f2f71b03 | ||
| 
						 | 
					12ee37d700 | ||
| 
						 | 
					9679c22a27 | ||
| 
						 | 
					1395c95353 | ||
| 
						 | 
					4d1fd43c8c | ||
| 
						 | 
					71c208c4fb | ||
| 
						 | 
					91a2a1afc3 | ||
| 
						 | 
					25c1ca2f5d | ||
| 
						 | 
					6f0bb82f59 | ||
| 
						 | 
					22a5184ebe | ||
| 
						 | 
					17b0b1f43f | ||
| 
						 | 
					b61df5ec19 | ||
| 
						 | 
					1ac7275f83 | ||
| 
						 | 
					cd10d04907 | ||
| 
						 | 
					f9b76fcb8b | ||
| 
						 | 
					093fa067e6 | ||
| 
						 | 
					fa655f065b | ||
| 
						 | 
					c8f2244912 | ||
| 
						 | 
					f3a20e14a6 | ||
| 
						 | 
					33ad47b115 | ||
| 
						 | 
					775424d3b7 | ||
| 
						 | 
					c9c86bbd1d | ||
| 
						 | 
					f76a6ad85c | ||
| 
						 | 
					2138b14d89 | ||
| 
						 | 
					1bf61f57f5 | ||
| 
						 | 
					07b55bd71f | ||
| 
						 | 
					8d2d3d4002 | ||
| 
						 | 
					d182b4b4a6 | ||
| 
						 | 
					60f6a91fe4 | ||
| 
						 | 
					ec89a2f956 | ||
| 
						 | 
					87113d7181 | ||
| 
						 | 
					59fae290e5 | ||
| 
						 | 
					1a8ba2ce53 | ||
| 
						 | 
					dddaa25d86 | ||
| 
						 | 
					f28341587a | ||
| 
						 | 
					5593bf3e08 | ||
| 
						 | 
					92574a7a9d | ||
| 
						 | 
					e049266f5d | ||
| 
						 | 
					5b3e6fcb07 | ||
| 
						 | 
					b0bfb556db | ||
| 
						 | 
					484acbcb45 | ||
| 
						 | 
					cdc802cfb8 | ||
| 
						 | 
					582671ca84 | ||
| 
						 | 
					22498b5804 | ||
| 
						 | 
					87f277a482 | ||
| 
						 | 
					ae0d74f57a | ||
| 
						 | 
					0ae5593dde | ||
| 
						 | 
					0d11769590 | ||
| 
						 | 
					b7d8daf013 | ||
| 
						 | 
					a9c0126b05 | ||
| 
						 | 
					6bc5a57d10 | ||
| 
						 | 
					2714ee96f1 | ||
| 
						 | 
					524d382b7a | ||
| 
						 | 
					2723e05d2a | ||
| 
						 | 
					6dd9bda6b4 | ||
| 
						 | 
					44449bc716 | ||
| 
						 | 
					b17d8edb50 | ||
| 
						 | 
					578072238a | ||
| 
						 | 
					b4edd3dcc4 | ||
| 
						 | 
					068094caac | ||
| 
						 | 
					deb58e617d | ||
| 
						 | 
					baca0c1120 | ||
| 
						 | 
					02543438a4 | ||
| 
						 | 
					d507e59038 | ||
| 
						 | 
					9d0fd7ef1b | ||
| 
						 | 
					dbef5e2143 | ||
| 
						 | 
					04eca755d2 | ||
| 
						 | 
					7883692196 | ||
| 
						 | 
					8f64977cb9 | ||
| 
						 | 
					f94fdc4979 | ||
| 
						 | 
					a0a0e28447 | ||
| 
						 | 
					f6f7783b94 | ||
| 
						 | 
					d233cc1de8 | ||
| 
						 | 
					37671499c8 | ||
| 
						 | 
					c83b79998d | ||
| 
						 | 
					ed842c2b42 | ||
| 
						 | 
					8c5f114339 | ||
| 
						 | 
					8b2f1d0b4f | ||
| 
						 | 
					591a1b3050 | ||
| 
						 | 
					42ec3fe02b | ||
| 
						 | 
					370a398b5e | ||
| 
						 | 
					554d89b6e9 | ||
| 
						 | 
					cb049f5dda | ||
| 
						 | 
					0728668d41 | ||
| 
						 | 
					dfc187874e | ||
| 
						 | 
					225588f3e7 | ||
| 
						 | 
					06cc6c29aa | ||
| 
						 | 
					b2d4469908 | ||
| 
						 | 
					c398383905 | ||
| 
						 | 
					7af9dce33b | ||
| 
						 | 
					038790a5d6 | ||
| 
						 | 
					fb3295bde1 | ||
| 
						 | 
					43a4fd2ecb | ||
| 
						 | 
					899c72d068 | ||
| 
						 | 
					d118c0d886 | ||
| 
						 | 
					6d4004d1ed | ||
| 
						 | 
					ae60cd5b28 | ||
| 
						 | 
					ab31a72199 | ||
| 
						 | 
					2c1b9534f3 | ||
| 
						 | 
					7028cb1546 | ||
| 
						 | 
					dc1ecf6a42 | ||
| 
						 | 
					3a27f9d02c | ||
| 
						 | 
					4b27ab38f8 | ||
| 
						 | 
					40de147611 | ||
| 
						 | 
					df5756dc86 | ||
| 
						 | 
					bb4f90d730 | ||
| 
						 | 
					d89d46aaec | ||
| 
						 | 
					304d720c4c | ||
| 
						 | 
					7eff160190 | ||
| 
						 | 
					8b2e18ed9d | ||
| 
						 | 
					7001051833 | ||
| 
						 | 
					b4b9752c05 | ||
| 
						 | 
					acadc89eaa | ||
| 
						 | 
					6ff84b8e90 | ||
| 
						 | 
					7f3e3fc3bf | ||
| 
						 | 
					02233fd7a4 | ||
| 
						 | 
					50d3db0643 | ||
| 
						 | 
					3751831779 | ||
| 
						 | 
					14a24e47fb | ||
| 
						 | 
					b7e78cb0e6 | ||
| 
						 | 
					a8f65f42fc | ||
| 
						 | 
					d3385a116d | ||
| 
						 | 
					e0c446dd13 | ||
| 
						 | 
					33d11b4780 | ||
| 
						 | 
					07c49d1d04 | ||
| 
						 | 
					9463285ac9 | ||
| 
						 | 
					b41fc43e64 | ||
| 
						 | 
					562763c938 | ||
| 
						 | 
					ec60194110 | ||
| 
						 | 
					1e472ee095 | ||
| 
						 | 
					5597327448 | ||
| 
						 | 
					cdd5baf5be | ||
| 
						 | 
					7b5978059b | ||
| 
						 | 
					da0b41e45c | ||
| 
						 | 
					d0be2afba5 | ||
| 
						 | 
					d99851231a | ||
| 
						 | 
					7e02c141f9 | ||
| 
						 | 
					d03960e379 | ||
| 
						 | 
					16d3984ffc | ||
| 
						 | 
					856a194988 | ||
| 
						 | 
					1bff966bfe | ||
| 
						 | 
					1948b6118b | ||
| 
						 | 
					20c25d3ca2 | ||
| 
						 | 
					a153735ac3 | ||
| 
						 | 
					62509f7c18 | ||
| 
						 | 
					9b48b67158 | ||
| 
						 | 
					cbd50634a4 | ||
| 
						 | 
					f475393bc1 | ||
| 
						 | 
					abcddb09bf | ||
| 
						 | 
					cf71a0fc55 | ||
| 
						 | 
					78253f9e1e | ||
| 
						 | 
					ebd0848c7f | ||
| 
						 | 
					c8461eb0b5 | ||
| 
						 | 
					a4cbdeaeac | ||
| 
						 | 
					3e1ce69d52 | ||
| 
						 | 
					08a26b976e | ||
| 
						 | 
					5fc55381a2 | ||
| 
						 | 
					dbf3d24ae7 | ||
| 
						 | 
					cc7c6e02c5 | ||
| 
						 | 
					b45aa85853 | ||
| 
						 | 
					e7526ac5e3 | ||
| 
						 | 
					441ada70b8 | ||
| 
						 | 
					dedc06a46b | ||
| 
						 | 
					b0adf1b277 | ||
| 
						 | 
					28f65e9f44 | ||
| 
						 | 
					a013af5f0d | ||
| 
						 | 
					9552701662 | ||
| 
						 | 
					ef52f0aad1 | ||
| 
						 | 
					0b6f04905a | ||
| 
						 | 
					cdb36357d4 | ||
| 
						 | 
					8938622bd9 | ||
| 
						 | 
					b210294aa9 | ||
| 
						 | 
					5b02f20775 | ||
| 
						 | 
					fac382a5df | ||
| 
						 | 
					88d88bebc9 | ||
| 
						 | 
					755fb9c29b | ||
| 
						 | 
					51a835ab51 | ||
| 
						 | 
					c9895ab182 | ||
| 
						 | 
					e71d46a4e5 | ||
| 
						 | 
					8d1d5f37c1 | ||
| 
						 | 
					525a68682d | ||
| 
						 | 
					715648d0d8 | ||
| 
						 | 
					9452e93f22 | ||
| 
						 | 
					a6aa145471 | ||
| 
						 | 
					25aa6dcb59 | ||
| 
						 | 
					bb2270b274 | ||
| 
						 | 
					d7f6b4143e | ||
| 
						 | 
					0cf0e26fa8 | ||
| 
						 | 
					cc23197d60 | ||
| 
						 | 
					bc1721d95e | ||
| 
						 | 
					0d19173da6 | ||
| 
						 | 
					1983f07d3c | ||
| 
						 | 
					aad1b91cc2 | ||
| 
						 | 
					8cb1057a33 | ||
| 
						 | 
					b178032985 | ||
| 
						 | 
					561213e95d | ||
| 
						 | 
					44fa7c4306 | ||
| 
						 | 
					e2169563e2 | ||
| 
						 | 
					845344e003 | ||
| 
						 | 
					cdb48453e8 | ||
| 
						 | 
					9669cef518 | ||
| 
						 | 
					f962f71ed7 | ||
| 
						 | 
					94ed4021fb | ||
| 
						 | 
					1765855c57 | ||
| 
						 | 
					55cf3e7d44 | ||
| 
						 | 
					9f1840dc05 | ||
| 
						 | 
					78dab2e5f9 | ||
| 
						 | 
					103b9d5005 | ||
| 
						 | 
					1b75b778d8 | ||
| 
						 | 
					7e665dbdfc | ||
| 
						 | 
					b6897ec3a9 | ||
| 
						 | 
					660260174a | ||
| 
						 | 
					78d32865b5 | ||
| 
						 | 
					edfa92c1aa | ||
| 
						 | 
					63012f269c | ||
| 
						 | 
					7d0e7f779f | ||
| 
						 | 
					b8e18f80f4 | ||
| 
						 | 
					481b01e4f7 | ||
| 
						 | 
					edf2030251 | ||
| 
						 | 
					bd1cfffb61 | ||
| 
						 | 
					629f70d27d | ||
| 
						 | 
					57f5ebc0f9 | ||
| 
						 | 
					b4f51e7b47 | ||
| 
						 | 
					d78d254e86 | ||
| 
						 | 
					eb0c113699 | ||
| 
						 | 
					23045ebd59 | ||
| 
						 | 
					2e5931f304 | ||
| 
						 | 
					a620b07c00 | ||
| 
						 | 
					cb724145f2 | ||
| 
						 | 
					8ef17f6686 | ||
| 
						 | 
					debfd9160c | ||
| 
						 | 
					f2482e4ace | ||
| 
						 | 
					d98d757f8b | ||
| 
						 | 
					0c9a41a929 | ||
| 
						 | 
					e26f78bf50 | ||
| 
						 | 
					ed265f68ba | ||
| 
						 | 
					d2e9b64bf5 | ||
| 
						 | 
					3811aff206 | ||
| 
						 | 
					762d898fee | ||
| 
						 | 
					5e6034fc86 | ||
| 
						 | 
					9da10459d6 | ||
| 
						 | 
					ff80cedd6b | ||
| 
						 | 
					b213148ae8 | ||
| 
						 | 
					c8646e20cb | ||
| 
						 | 
					76a41fec50 | ||
| 
						 | 
					0e705bd038 | ||
| 
						 | 
					f33ffb98ff | ||
| 
						 | 
					faa0d59340 | ||
| 
						 | 
					5af0219884 | ||
| 
						 | 
					dafd99f155 | ||
| 
						 | 
					3560f0388c | ||
| 
						 | 
					b2954658d8 | ||
| 
						 | 
					44581d9983 | ||
| 
						 | 
					02dcfeb227 | ||
| 
						 | 
					d8bafb349d | ||
| 
						 | 
					889598a4c8 | ||
| 
						 | 
					7e37d10016 | ||
| 
						 | 
					ebaebb09d1 | ||
| 
						 | 
					531a3a4b6c | ||
| 
						 | 
					b3e313821b | ||
| 
						 | 
					51958af422 | ||
| 
						 | 
					e3b21ccdba | ||
| 
						 | 
					31bb208835 | ||
| 
						 | 
					8c97e805a2 | ||
| 
						 | 
					ac8a43bb37 | ||
| 
						 | 
					2df4b40a28 | ||
| 
						 | 
					e06736c254 | ||
| 
						 | 
					ec367e94ce | ||
| 
						 | 
					1515dea9fa | ||
| 
						 | 
					adedf9c17d | ||
| 
						 | 
					0b52fb84f1 | ||
| 
						 | 
					16e742ae73 | ||
| 
						 | 
					1b4471dfae | ||
| 
						 | 
					ae152ce0a4 | ||
| 
						 | 
					2aa023f140 | ||
| 
						 | 
					6e2e4c6f08 | ||
| 
						 | 
					1c8c038735 | ||
| 
						 | 
					4d339a6da8 | ||
| 
						 | 
					b7edd4407a | ||
| 
						 | 
					a679a1e94a | ||
| 
						 | 
					180451d32f | ||
| 
						 | 
					7396f22bca | ||
| 
						 | 
					058019aa84 | ||
| 
						 | 
					695f83d1d8 | ||
| 
						 | 
					ac4dfb3baf | ||
| 
						 | 
					427001b223 | ||
| 
						 | 
					3117d8b30d | ||
| 
						 | 
					d19dd2a8b2 | ||
| 
						 | 
					de3dcc3fc2 | ||
| 
						 | 
					077f3e095b | ||
| 
						 | 
					ad3b0bb320 | ||
| 
						 | 
					8538741341 | ||
| 
						 | 
					a0aef5d579 | ||
| 
						 | 
					fdd93427aa | ||
| 
						 | 
					ac3f6557de | ||
| 
						 | 
					b0a909150c | ||
| 
						 | 
					913f163fe4 | ||
| 
						 | 
					3126b07b33 | ||
| 
						 | 
					08ca90cf75 | ||
| 
						 | 
					540ac2a277 | ||
| 
						 | 
					ed80bed066 | ||
| 
						 | 
					41d2541c6a | ||
| 
						 | 
					5dedf63498 | ||
| 
						 | 
					09bc4f41d2 | ||
| 
						 | 
					cebf0b5c57 | ||
| 
						 | 
					1632a57e3e | ||
| 
						 | 
					744c4be7d1 | ||
| 
						 | 
					bd99ef3eff | ||
| 
						 | 
					8a86f13a5d | ||
| 
						 | 
					7418b2f0ee | ||
| 
						 | 
					a0e9de9312 | ||
| 
						 | 
					7e23a6f5e8 | ||
| 
						 | 
					44589f8744 | ||
| 
						 | 
					d24531030f | ||
| 
						 | 
					25bdab1346 | ||
| 
						 | 
					41af1c863a | ||
| 
						 | 
					76b3b18cfb | ||
| 
						 | 
					e6fb2958a9 | ||
| 
						 | 
					15b75b322f | ||
| 
						 | 
					86149d1032 | ||
| 
						 | 
					ded142cd9e | ||
| 
						 | 
					7923eb9ec9 | ||
| 
						 | 
					132553c108 | ||
| 
						 | 
					c2269fc9a4 | ||
| 
						 | 
					aed30d1499 | ||
| 
						 | 
					84a1a876e1 | ||
| 
						 | 
					dc675707f9 | ||
| 
						 | 
					d5667c7ef6 | ||
| 
						 | 
					cba1213dd1 | ||
| 
						 | 
					7219c90957 | ||
| 
						 | 
					af13bd991e | ||
| 
						 | 
					48e548eb52 | ||
| 
						 | 
					1a19e27f0e | ||
| 
						 | 
					0cbd22426d | ||
| 
						 | 
					d5e52e99e0 | 
@@ -29,7 +29,7 @@ $paths = [
 | 
			
		||||
    $current . '/../../database',
 | 
			
		||||
    $current . '/../../routes',
 | 
			
		||||
    $current . '/../../tests',
 | 
			
		||||
    $current . '/../../resources/lang',
 | 
			
		||||
    $current . '/../../resources/lang/en_US',
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
$finder = PhpCsFixer\Finder::create()
 | 
			
		||||
@@ -61,6 +61,7 @@ return $config->setRules(
 | 
			
		||||
        'comment_to_phpdoc'             => false, // breaks phpstan lines in combination with PHPStorm.
 | 
			
		||||
        'type_declaration_spaces'       => false,
 | 
			
		||||
        'cast_spaces'                   => false,
 | 
			
		||||
        'phpdoc_to_comment' => false, // do not overrule single line comment style, breaks phpstan.
 | 
			
		||||
 | 
			
		||||
        // complex rules
 | 
			
		||||
        'array_syntax'                  => ['syntax' => 'short'],
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										460
									
								
								.ci/php-cs-fixer/composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										460
									
								
								.ci/php-cs-fixer/composer.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -26,10 +26,9 @@ SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
 | 
			
		||||
cd $SCRIPT_DIR/php-cs-fixer
 | 
			
		||||
composer update --quiet
 | 
			
		||||
rm -f .php-cs-fixer.cache
 | 
			
		||||
PHP_CS_FIXER_IGNORE_ENV=true
 | 
			
		||||
./vendor/bin/php-cs-fixer fix \
 | 
			
		||||
PHP_CS_FIXER_IGNORE_ENV=true ./vendor/bin/php-cs-fixer fix \
 | 
			
		||||
    --config $SCRIPT_DIR/php-cs-fixer/.php-cs-fixer.php \
 | 
			
		||||
    --format=txt \
 | 
			
		||||
    --format=txt -v \
 | 
			
		||||
    --allow-risky=yes
 | 
			
		||||
 | 
			
		||||
EXIT_CODE=$?
 | 
			
		||||
 
 | 
			
		||||
@@ -1,59 +1,36 @@
 | 
			
		||||
parameters:
 | 
			
		||||
  universalObjectCratesClasses:
 | 
			
		||||
    - Illuminate\Database\Eloquent\Model
 | 
			
		||||
  # TODO: slowly remove these parameters and fix the issues found.
 | 
			
		||||
  reportUnmatchedIgnoredErrors: false
 | 
			
		||||
  checkGenericClassInNonGenericObjectType: false  # remove this rule when all other issues are solved.
 | 
			
		||||
  ignoreErrors:
 | 
			
		||||
  # TODO: slowly remove these exceptions and fix the issues found.
 | 
			
		||||
    - '#Dynamic call to static method#' # all the Laravel ORM things depend on this.
 | 
			
		||||
    - '#Control structures using switch should not be used.#' # switch is fine in some cases.
 | 
			
		||||
    - '#with no value type specified in iterable type array#' # remove this rule when all other issues are solved.
 | 
			
		||||
    - '#has no value type specified in iterable type array#' # remove this rule when all other issues are solved.
 | 
			
		||||
    - '#is not allowed to extend#'
 | 
			
		||||
    - '#switch is forbidden to use#'
 | 
			
		||||
    - '#is neither abstract nor final#'
 | 
			
		||||
    - '#on left side of \?\?\= always exists and is not nullable#'
 | 
			
		||||
    - '#has a nullable return type declaration#' # perhaps throw errors instead?
 | 
			
		||||
    - '#with a nullable type declaration#' # decide what action should be if param is null.
 | 
			
		||||
    - '#with null as default value#'
 | 
			
		||||
    -
 | 
			
		||||
        message: '#Constructor in [a-zA-Z0-9\\_]+ has parameter \$[a-zA-Z0-9\\_]+ with default value#'
 | 
			
		||||
        paths:
 | 
			
		||||
            - ../app/Exceptions/IntervalException.php
 | 
			
		||||
            - ../app/Support/Navigation.php
 | 
			
		||||
    -
 | 
			
		||||
        message: '#but containers should not be injected#'
 | 
			
		||||
        paths:
 | 
			
		||||
            - ../app/Support/Authentication/RemoteUserGuard.php
 | 
			
		||||
    -
 | 
			
		||||
        message: '#Function compact\(\) should not be used#' # too useful in template rendering.
 | 
			
		||||
        paths:
 | 
			
		||||
            - ../app/Generator/Report/Account/MonthReportGenerator.php
 | 
			
		||||
            - ../app/Generator/Report/Audit/MonthReportGenerator.php
 | 
			
		||||
            - ../app/Generator/Report/Budget/MonthReportGenerator.php
 | 
			
		||||
            - ../app/Generator/Report/Category/MonthReportGenerator.php
 | 
			
		||||
            - ../app/Generator/Report/Standard/MonthReportGenerator.php
 | 
			
		||||
            - ../app/Generator/Report/Standard/MultiYearReportGenerator.php
 | 
			
		||||
            - ../app/Generator/Report/Standard/YearReportGenerator.php
 | 
			
		||||
            - ../app/Generator/Report/Tag/MonthReportGenerator.php
 | 
			
		||||
            - ../app/Http/Controllers/Account/*.php
 | 
			
		||||
            - ../app/Http/Controllers/Admin/*.php
 | 
			
		||||
            - ../app/Http/Controllers/*.php
 | 
			
		||||
            - ../app/Support/ExpandedForm.php
 | 
			
		||||
            - ../app/Support/Form/AccountForm.php
 | 
			
		||||
            - ../app/Support/Form/CurrencyForm.php
 | 
			
		||||
            - ../app/Support/Form/FormSupport.php
 | 
			
		||||
    -
 | 
			
		||||
        message: '#Either catch a more specific exception#'
 | 
			
		||||
        paths:
 | 
			
		||||
            - ../app/Support/Form/FormSupport.php
 | 
			
		||||
  scanFiles:
 | 
			
		||||
    - ../_ide_helper
 | 
			
		||||
  paths:
 | 
			
		||||
    - ../app
 | 
			
		||||
    - ../database
 | 
			
		||||
    - ../routes
 | 
			
		||||
    - ../config
 | 
			
		||||
    - ../bootstrap/app.php
 | 
			
		||||
  universalObjectCratesClasses:
 | 
			
		||||
    - Illuminate\Database\Eloquent\Model
 | 
			
		||||
  # TODO: slowly remove these parameters and fix the issues found.
 | 
			
		||||
  reportUnmatchedIgnoredErrors: true
 | 
			
		||||
  ignoreErrors:
 | 
			
		||||
  # TODO: slowly remove these exceptions and fix the issues found.
 | 
			
		||||
    - '#Dynamic call to static method#' # all the Laravel ORM things depend on this.
 | 
			
		||||
    - identifier: varTag.nativeType
 | 
			
		||||
    - identifier: varTag.type
 | 
			
		||||
    -
 | 
			
		||||
        identifier: larastan.noEnvCallsOutsideOfConfig
 | 
			
		||||
        path: ../app/Console/Commands/System/CreatesDatabase.php
 | 
			
		||||
    - identifier: missingType.iterableValue # not interesting enough to fix.
 | 
			
		||||
    - identifier: missingType.generics # not interesting enough to fix.
 | 
			
		||||
    - "#Parameter \\#[1-2] \\$num[1-2] of function bc[a-z]+ expects numeric-string, [a-z\\-|&]+ given#"
 | 
			
		||||
    - '#expects view-string, string given#'
 | 
			
		||||
    - '#expects view-string\|null, string given#'
 | 
			
		||||
 | 
			
		||||
    # phpstan can't handle this so we ignore them.
 | 
			
		||||
    - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::before#'
 | 
			
		||||
    - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::after#'
 | 
			
		||||
    - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::withTrashed#'
 | 
			
		||||
    - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::accountTypeIn#'
 | 
			
		||||
    - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\BelongsTo::withTrashed#'
 | 
			
		||||
 | 
			
		||||
  # The level 8 is the highest level. original was 5
 | 
			
		||||
  # 7 is more than enough, higher just leaves NULL things.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								.env.example
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								.env.example
									
									
									
									
									
								
							@@ -19,7 +19,7 @@ SITE_OWNER=mail@example.com
 | 
			
		||||
APP_KEY=SomeRandomStringOf32CharsExactly
 | 
			
		||||
 | 
			
		||||
# Firefly III will launch using this language (for new users and unauthenticated visitors)
 | 
			
		||||
# For a list of available languages: https://github.com/firefly-iii/firefly-iii/tree/main/resources/lang
 | 
			
		||||
# For a list of available languages: https://github.com/firefly-iii/firefly-iii/blob/main/config/firefly.php#L123
 | 
			
		||||
#
 | 
			
		||||
# If text is still in English, remember that not everything may have been translated.
 | 
			
		||||
DEFAULT_LANGUAGE=en_US
 | 
			
		||||
@@ -176,6 +176,7 @@ MAILGUN_ENDPOINT=api.mailgun.net
 | 
			
		||||
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
 | 
			
		||||
MANDRILL_SECRET=
 | 
			
		||||
SPARKPOST_SECRET=
 | 
			
		||||
MAILERSEND_API_KEY=
 | 
			
		||||
 | 
			
		||||
# Firefly III can send you the following messages.
 | 
			
		||||
SEND_ERROR_MESSAGE=true
 | 
			
		||||
@@ -188,7 +189,7 @@ SEND_REPORT_JOURNALS=true
 | 
			
		||||
ENABLE_EXTERNAL_MAP=false
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Enable or disable exchange rate conversion. This function isn't used yet by Firefly III
 | 
			
		||||
# Enable or disable exchange rate conversion.
 | 
			
		||||
#
 | 
			
		||||
ENABLE_EXCHANGE_RATES=false
 | 
			
		||||
 | 
			
		||||
@@ -312,12 +313,24 @@ PUSHER_ID=
 | 
			
		||||
DEMO_USERNAME=
 | 
			
		||||
DEMO_PASSWORD=
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Disable or enable the running balance column data
 | 
			
		||||
# Please disable this. It's a very experimental feature.
 | 
			
		||||
#
 | 
			
		||||
USE_RUNNING_BALANCE=false
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# The v2 layout is very experimental. If it breaks you get to keep both parts.
 | 
			
		||||
# Be wary of data loss.
 | 
			
		||||
#
 | 
			
		||||
FIREFLY_III_LAYOUT=v1
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Which Query Parser implementation to use for the search rngine and rules
 | 
			
		||||
# 'new' is experimental, 'legacy' is the classic one
 | 
			
		||||
#
 | 
			
		||||
QUERY_PARSER_IMPLEMENTATION=legacy
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Please make sure this URL matches the external URL of your Firefly III installation.
 | 
			
		||||
# It is used to validate specific requests and to generate URLs in emails.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
								
							@@ -4,6 +4,7 @@ updates:
 | 
			
		||||
  # Check for updates to GitHub Actions every week
 | 
			
		||||
  - package-ecosystem: "github-actions"
 | 
			
		||||
    directory: "/"
 | 
			
		||||
    labels: []
 | 
			
		||||
    schedule:
 | 
			
		||||
      interval: "weekly"
 | 
			
		||||
 | 
			
		||||
@@ -11,6 +12,7 @@ updates:
 | 
			
		||||
  - package-ecosystem: "composer"
 | 
			
		||||
    directory: "/" # Location of package manifests
 | 
			
		||||
    target-branch: develop
 | 
			
		||||
    labels: []
 | 
			
		||||
    versioning-strategy: increase
 | 
			
		||||
    schedule:
 | 
			
		||||
      interval: "weekly"
 | 
			
		||||
@@ -18,6 +20,7 @@ updates:
 | 
			
		||||
  # yarn / JS updates
 | 
			
		||||
  - package-ecosystem: "npm"
 | 
			
		||||
    directory: "/"
 | 
			
		||||
    labels: []
 | 
			
		||||
    target-branch: develop
 | 
			
		||||
    versioning-strategy: increase
 | 
			
		||||
    schedule:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										37
									
								
								.github/label-actions.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										37
									
								
								.github/label-actions.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,15 +1,29 @@
 | 
			
		||||
# Configuration for Label Actions - https://github.com/dessant/label-actions
 | 
			
		||||
 | 
			
		||||
# The `feature` label is added to issues
 | 
			
		||||
feature:
 | 
			
		||||
fixed:
 | 
			
		||||
  issues:
 | 
			
		||||
    # Post a comment, `{issue-author}` is an optional placeholder
 | 
			
		||||
    comment: |
 | 
			
		||||
      Hi there! 
 | 
			
		||||
      Hi there!
 | 
			
		||||
 | 
			
		||||
      This is an automatic reply. `Share and enjoy`
 | 
			
		||||
 | 
			
		||||
      This issue has been marked as a feature request. The requested (new) feature will become a part of Firefly III or the data importer in due course.
 | 
			
		||||
      This issue has been marked as fixed. Thanks for reporting! A new version will be released in due time. Unfortunately, [I cannot give an estimate](https://docs.firefly-iii.org/references/faq/firefly-iii/general/#when-will-you-release-version-the-next-version), but [the roadmap](https://roadmap.firefly-iii.org/) is available for your reading pleasure.
 | 
			
		||||
 | 
			
		||||
      There is no need to close the issue. It will be closed automatically.
 | 
			
		||||
 | 
			
		||||
      Thank you for your contributions.
 | 
			
		||||
feature:
 | 
			
		||||
  issues:
 | 
			
		||||
    # Post a comment, `{issue-author}` is an optional placeholder
 | 
			
		||||
    unlabel: feature
 | 
			
		||||
    comment: |
 | 
			
		||||
      Hi there!
 | 
			
		||||
 | 
			
		||||
      This is an automatic reply. `Share and enjoy`
 | 
			
		||||
 | 
			
		||||
      This issue has been marked as a feature request.
 | 
			
		||||
 | 
			
		||||
      If you come across this issue, please be aware there is NO need to reply with "+1" or "me too" or "I need this too" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted. You can subscribe to this issue to get updates.
 | 
			
		||||
 | 
			
		||||
@@ -19,27 +33,28 @@ epic:
 | 
			
		||||
  issues:
 | 
			
		||||
    # Post a comment, `{issue-author}` is an optional placeholder
 | 
			
		||||
    comment: |
 | 
			
		||||
      Hi there! 
 | 
			
		||||
      Hi there!
 | 
			
		||||
 | 
			
		||||
      This is an automatic reply. `Share and enjoy`
 | 
			
		||||
 | 
			
		||||
      This issue has been marked as an epic. In epics, large amounts of works are collected that will be part of a major new feature. If you have more ideas that could be a part of this epic, feel free to reply.
 | 
			
		||||
 | 
			
		||||
      *However*, please be aware there is NO need to reply with "+1" or "me too" or "I need this too" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted. 
 | 
			
		||||
      *However*, please be aware there is NO need to reply with "+1" or "me too" or "I need this too" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted.
 | 
			
		||||
 | 
			
		||||
      If you are merely interested in this epic's progress, you can subscribe to this issue to get updates.
 | 
			
		||||
 | 
			
		||||
      Thank you for your contributions.
 | 
			
		||||
 | 
			
		||||
enhancement:
 | 
			
		||||
  unlabel: enhancement
 | 
			
		||||
  issues:
 | 
			
		||||
    # Post a comment, `{issue-author}` is an optional placeholder
 | 
			
		||||
    comment: |
 | 
			
		||||
      Hi there! 
 | 
			
		||||
      Hi there!
 | 
			
		||||
 | 
			
		||||
      This is an automatic reply. `Share and enjoy`
 | 
			
		||||
 | 
			
		||||
      This issue has been marked as an enhancement. The requested enhancement to an existing feature will become a part of Firefly III or the data importer in due course.
 | 
			
		||||
      This issue has been marked as an enhancement.
 | 
			
		||||
 | 
			
		||||
      If you come across this issue, please be aware there is NO need to reply with "+1" or "me too" or "I need this too" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted. You can subscribe to this issue to get updates.
 | 
			
		||||
 | 
			
		||||
@@ -49,7 +64,7 @@ triage:
 | 
			
		||||
  issues:
 | 
			
		||||
    # Post a comment, `{issue-author}` is an optional placeholder
 | 
			
		||||
    comment: |
 | 
			
		||||
      Hi there! 
 | 
			
		||||
      Hi there!
 | 
			
		||||
 | 
			
		||||
      This is an automatic reply. `Share and enjoy`
 | 
			
		||||
 | 
			
		||||
@@ -60,7 +75,7 @@ triage:
 | 
			
		||||
needs-moar-debug:
 | 
			
		||||
  issues:
 | 
			
		||||
    comment: |
 | 
			
		||||
      Hi there! 
 | 
			
		||||
      Hi there!
 | 
			
		||||
 | 
			
		||||
      This is an automatic reply. `Share and enjoy`
 | 
			
		||||
 | 
			
		||||
@@ -78,7 +93,7 @@ needs-moar-debug:
 | 
			
		||||
needs-moar-logs:
 | 
			
		||||
  issues:
 | 
			
		||||
    comment: |
 | 
			
		||||
      Hi there! 
 | 
			
		||||
      Hi there!
 | 
			
		||||
 | 
			
		||||
      This is an automatic reply. `Share and enjoy`
 | 
			
		||||
 | 
			
		||||
@@ -94,7 +109,7 @@ needs-moar-logs:
 | 
			
		||||
v2-layout-issue:
 | 
			
		||||
  issues:
 | 
			
		||||
    comment: |
 | 
			
		||||
      Hi there! 
 | 
			
		||||
      Hi there!
 | 
			
		||||
 | 
			
		||||
      This is an automatic reply. `Share and enjoy`
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										53
									
								
								.github/mergify.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										53
									
								
								.github/mergify.yml
									
									
									
									
										vendored
									
									
								
							@@ -8,56 +8,3 @@ pull_request_rules:
 | 
			
		||||
      close:
 | 
			
		||||
        message: Please do not open PR's on the `main` branch, but on the `develop`
 | 
			
		||||
          branch only. Thank you!
 | 
			
		||||
  - name: No translations
 | 
			
		||||
    conditions:
 | 
			
		||||
      - -author~=^dependabot(|-preview)\[bot\]$
 | 
			
		||||
      - base=develop
 | 
			
		||||
      - or:
 | 
			
		||||
          - files~=^resources/lang/bg_BG
 | 
			
		||||
          - files~=^resources/lang/ca_ES
 | 
			
		||||
          - files~=^resources/lang/cs_CZ
 | 
			
		||||
          - files~=^resources/lang/da_DK
 | 
			
		||||
          - files~=^resources/lang/de_DE
 | 
			
		||||
          - files~=^resources/lang/el_GR
 | 
			
		||||
          - files~=^resources/lang/en_GB
 | 
			
		||||
          - files~=^resources/lang/es_ES
 | 
			
		||||
          - files~=^resources/lang/et_EE
 | 
			
		||||
          - files~=^resources/lang/fa_IR
 | 
			
		||||
          - files~=^resources/lang/fi_FI
 | 
			
		||||
          - files~=^resources/lang/fr_FR
 | 
			
		||||
          - files~=^resources/lang/he_IL
 | 
			
		||||
          - files~=^resources/lang/hu_HU
 | 
			
		||||
          - files~=^resources/lang/id_ID
 | 
			
		||||
          - files~=^resources/lang/is_IS
 | 
			
		||||
          - files~=^resources/lang/it_IT
 | 
			
		||||
          - files~=^resources/lang/ja_JP
 | 
			
		||||
          - files~=^resources/lang/ko_KR
 | 
			
		||||
          - files~=^resources/lang/lt_LT
 | 
			
		||||
          - files~=^resources/lang/nb_NO
 | 
			
		||||
          - files~=^resources/lang/nl_NL
 | 
			
		||||
          - files~=^resources/lang/pl_PL
 | 
			
		||||
          - files~=^resources/lang/pt_BR
 | 
			
		||||
          - files~=^resources/lang/pt_PT
 | 
			
		||||
          - files~=^resources/lang/ro_RO
 | 
			
		||||
          - files~=^resources/lang/ru_RU
 | 
			
		||||
          - files~=^resources/lang/si_LK
 | 
			
		||||
          - files~=^resources/lang/sk_SK
 | 
			
		||||
          - files~=^resources/lang/sl_SI
 | 
			
		||||
          - files~=^resources/lang/sr_CS
 | 
			
		||||
          - files~=^resources/lang/sv_SE
 | 
			
		||||
          - files~=^resources/lang/th_TH
 | 
			
		||||
          - files~=^resources/lang/tlh_AA
 | 
			
		||||
          - files~=^resources/lang/tr_TR
 | 
			
		||||
          - files~=^resources/lang/uk_UA
 | 
			
		||||
          - files~=^resources/lang/vi_VN
 | 
			
		||||
          - files~=^resources/lang/zh_CN
 | 
			
		||||
          - files~=^resources/lang/zh_TW
 | 
			
		||||
    actions:
 | 
			
		||||
      comment:
 | 
			
		||||
        message: >
 | 
			
		||||
          Please do not submit translated strings in your PR. If you need new
 | 
			
		||||
          sentences to be translated, add them to the `en_US` language strings.
 | 
			
		||||
          New or changed translations for other languages can be submitted at
 | 
			
		||||
          https://crowdin.com/project/firefly-iii
 | 
			
		||||
 | 
			
		||||
          Thank you!
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								.github/pull_request_template.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/pull_request_template.md
									
									
									
									
										vendored
									
									
								
							@@ -6,6 +6,7 @@ Thank you for submitting new code to Firefly III, or any of the related projects
 | 
			
		||||
- Please do not open PRs to "discuss" possible solutions or to "get feedback" on your code. I simply don't have time for that.
 | 
			
		||||
- Pull requests for the MAIN branch will be closed.
 | 
			
		||||
- DO NOT include translated strings in your PR.
 | 
			
		||||
- PRs (or parts thereof) that only fix issues inside code comments will not be accepted.
 | 
			
		||||
 | 
			
		||||
If it feels necessary to open an issue first, please do so, before you open a PR.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/close-duplicates.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/close-duplicates.yml
									
									
									
									
										vendored
									
									
								
							@@ -13,7 +13,7 @@ jobs:
 | 
			
		||||
  close_duplicates:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: github/command@v1.2.0
 | 
			
		||||
      - uses: github/command@v1.3.0
 | 
			
		||||
        id: command
 | 
			
		||||
        with:
 | 
			
		||||
          allowed_contexts: "issue"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/closed-issues.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/closed-issues.yml
									
									
									
									
										vendored
									
									
								
							@@ -8,7 +8,7 @@ jobs:
 | 
			
		||||
  command_and_close:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: aws-actions/closed-issue-message@v1
 | 
			
		||||
      - uses: aws-actions/closed-issue-message@v2
 | 
			
		||||
        with:
 | 
			
		||||
          message: |
 | 
			
		||||
            Hi there! This is an automatic reply. `Share and enjoy`
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										175
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										175
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							@@ -4,9 +4,13 @@ on:
 | 
			
		||||
  workflow_dispatch:
 | 
			
		||||
    inputs:
 | 
			
		||||
      version:
 | 
			
		||||
        description: 'Release "v1.2.3" or "develop"'
 | 
			
		||||
        description: 'Release "v1.2.3" or "develop" or "branch-abc"'
 | 
			
		||||
        required: true
 | 
			
		||||
        default: 'develop'
 | 
			
		||||
      phpversion:
 | 
			
		||||
        description: 'PHP version'
 | 
			
		||||
        required: true
 | 
			
		||||
        default: '8.4'
 | 
			
		||||
  schedule:
 | 
			
		||||
    - cron: '0 3 * * MON'
 | 
			
		||||
 | 
			
		||||
@@ -23,6 +27,11 @@ jobs:
 | 
			
		||||
          if [[ "develop" == "$version" ]]; then
 | 
			
		||||
            git checkout --track origin/develop
 | 
			
		||||
            git pull
 | 
			
		||||
          elif [[ "$version" == branch* ]]; then
 | 
			
		||||
            PULLBRANCH=${version:7}
 | 
			
		||||
            echo "The branch is '$PULLBRANCH' ($version)"
 | 
			
		||||
            git checkout --track origin/$PULLBRANCH
 | 
			
		||||
            git pull
 | 
			
		||||
          else
 | 
			
		||||
            git config user.name github-actions
 | 
			
		||||
            git config user.email 41898282+github-actions[bot]@users.noreply.github.com
 | 
			
		||||
@@ -36,7 +45,7 @@ jobs:
 | 
			
		||||
      - name: Setup PHP
 | 
			
		||||
        uses: shivammathur/setup-php@v2
 | 
			
		||||
        with:
 | 
			
		||||
          php-version: '8.3'
 | 
			
		||||
          php-version: ${{ github.event.inputs.phpversion }}
 | 
			
		||||
          extensions: mbstring, intl, zip, bcmath
 | 
			
		||||
      - name: crowdin action
 | 
			
		||||
        uses: crowdin/github-action@v2
 | 
			
		||||
@@ -49,15 +58,6 @@ jobs:
 | 
			
		||||
          GITHUB_TOKEN: ${{ github.token }}
 | 
			
		||||
          CROWDIN_PROJECT_NR: ${{ secrets.CROWDIN_PROJECT_NR }}
 | 
			
		||||
          CROWDIN_TOKEN: ${{ secrets.CROWDIN_TOKEN }}
 | 
			
		||||
      - name: Cleanup translations
 | 
			
		||||
        id: cleanup-transactions
 | 
			
		||||
        uses: JC5/firefly-iii-dev@main
 | 
			
		||||
        with:
 | 
			
		||||
          action: 'ff3:crowdin-warning'
 | 
			
		||||
          output: ''
 | 
			
		||||
        env:
 | 
			
		||||
          FIREFLY_III_ROOT: /github/workspace
 | 
			
		||||
          GH_TOKEN: ''
 | 
			
		||||
      - name: Cleanup changelog
 | 
			
		||||
        id: cleanup-changelog
 | 
			
		||||
        uses: JC5/firefly-iii-dev@main
 | 
			
		||||
@@ -133,7 +133,7 @@ jobs:
 | 
			
		||||
          rm -rf vendor composer.lock
 | 
			
		||||
          composer update --no-dev --no-scripts --no-plugins -q
 | 
			
		||||
          sudo chown -R runner:docker resources/lang
 | 
			
		||||
          .ci/phpcs.sh
 | 
			
		||||
          .ci/phpcs.sh || true
 | 
			
		||||
      - name: Import GPG key
 | 
			
		||||
        uses: crazy-max/ghaction-import-gpg@v6
 | 
			
		||||
        with:
 | 
			
		||||
@@ -159,13 +159,23 @@ jobs:
 | 
			
		||||
 | 
			
		||||
          # if this is a develop build, slightly different variable names.
 | 
			
		||||
          if [[ "develop" == "$version" ]]; then
 | 
			
		||||
            [[ -z $(git status --untracked-files=normal --porcelain) ]] && echo "this branch is clean, no need to push..." && exit 0;
 | 
			
		||||
            #[[ -z $(git status --untracked-files=normal --porcelain) ]] && echo "this branch is clean, no need to push..." && exit 0;
 | 
			
		||||
            releaseName=$version-$(date +'%Y%m%d')
 | 
			
		||||
            originalName=$releaseName
 | 
			
		||||
            zipName=FireflyIII-develop.zip
 | 
			
		||||
            tarName=FireflyIII-develop.tar.gz
 | 
			
		||||
          fi
 | 
			
		||||
 | 
			
		||||
          # if this is a branch build, also slightly different variable names.
 | 
			
		||||
          if [[ "$version" == branch* ]]; then
 | 
			
		||||
            #[[ -z $(git status --untracked-files=normal --porcelain) ]] && echo "this branch is clean, no need to push..." && exit 0;
 | 
			
		||||
            # branch builds overrule develop
 | 
			
		||||
            releaseName=$version-$(date +'%Y%m%d')
 | 
			
		||||
            originalName=$releaseName
 | 
			
		||||
            zipName=FireflyIII-$version.zip
 | 
			
		||||
            tarName=FireflyIII-$version.tar.gz
 | 
			
		||||
          fi
 | 
			
		||||
 | 
			
		||||
          # in both cases, if the release or tag already exists, add ".1" until it no longer exists.
 | 
			
		||||
          tagFound=true
 | 
			
		||||
          tagCount=1
 | 
			
		||||
@@ -194,9 +204,9 @@ jobs:
 | 
			
		||||
 | 
			
		||||
          # zip and tar everything
 | 
			
		||||
          echo 'Zip and tar...'
 | 
			
		||||
          zip -rq $zipName . -x "*.git*" "*.ci*" "*.github*" "*node_modules*" "*output.txt*"
 | 
			
		||||
          zip -rq $zipName . -x "*.git*" "*.ci*" "*.github*" "*node_modules*" "*output.txt*" "*Procfile*" "*crowdin.yml*" "*sonar-project.properties*"
 | 
			
		||||
          touch $tarName
 | 
			
		||||
          tar --exclude=$tarName --exclude=$zipName --exclude='./.git' --exclude='./.ci' --exclude='./.github' --exclude='./node_modules' --exclude='./output.txt' -czf $tarName .
 | 
			
		||||
          tar --exclude=$tarName --exclude=$zipName --exclude='./.git' --exclude='./.ci' --exclude='./.github' --exclude='./node_modules' --exclude='./output.txt' --exclude='./Procfile' --exclude='../crowdin.yml' --exclude='./sonar-project.properties' -czf $tarName .
 | 
			
		||||
 | 
			
		||||
          # add sha256 sum
 | 
			
		||||
          echo 'Sha sum ...'
 | 
			
		||||
@@ -207,28 +217,114 @@ jobs:
 | 
			
		||||
          gpg --armor --detach-sign $zipName
 | 
			
		||||
          gpg --armor --detach-sign $tarName
 | 
			
		||||
 | 
			
		||||
          # create a development (nightly) release:
 | 
			
		||||
          # describe the development release.
 | 
			
		||||
          if [[ "develop" == "$version" ]]; then
 | 
			
		||||
            echo 'Develop release.'
 | 
			
		||||
            # add text to output.txt (instructions)
 | 
			
		||||
            rm output.txt
 | 
			
		||||
            echo "Bi-weekly development release of Firefly III with the latest fixes, translations and features. Docker users can find this release under the \`develop\` tag." >> output.txt
 | 
			
		||||
            rm -f output.txt
 | 
			
		||||
            touch output.txt
 | 
			
		||||
            sudo chown -R runner:docker output.txt
 | 
			
		||||
            echo "Weekly development release of Firefly III with the latest fixes, translations and features. Docker users can find this release under the \`develop\` tag." >> output.txt
 | 
			
		||||
            echo "" >> output.txt
 | 
			
		||||
            echo "This release was created on **$(date +'%Y-%m-%d')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
 | 
			
		||||
            echo "This release was created on **$(date +'%Y-%m-%d %H:%M')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
 | 
			
		||||
            echo "" >> output.txt
 | 
			
		||||
            echo "* Please read the installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
 | 
			
		||||
            echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
 | 
			
		||||
            echo "" >> output.txt
 | 
			
		||||
            echo ":warning: Please be careful with this pre-release, as it may not work as expected." >> output.txt
 | 
			
		||||
          fi
 | 
			
		||||
          # describe a branch release
 | 
			
		||||
          if [[ "$version" == branch* ]]; then
 | 
			
		||||
            echo 'Branch release.'
 | 
			
		||||
            rm -f output.txt
 | 
			
		||||
            touch output.txt
 | 
			
		||||
            sudo chown -R runner:docker output.txt
 | 
			
		||||
            echo "Irregular BRANCH release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt
 | 
			
		||||
            echo "" >> output.txt
 | 
			
		||||
            echo "This release was created on **$(date +'%Y-%m-%d %H:%M')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
 | 
			
		||||
            echo "" >> output.txt
 | 
			
		||||
            echo "* Please read the installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
 | 
			
		||||
            echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
 | 
			
		||||
            echo "" >> output.txt
 | 
			
		||||
            echo ":warning: Please be careful with this branch pre-release, as it may not work as expected." >> output.txt
 | 
			
		||||
          fi
 | 
			
		||||
          # describe the main release
 | 
			
		||||
          if [[ "develop" != "$version" ]] && [[ "$version" != branch* ]] && [[ "$version" != *alpha* ]] && [[ "$version" != *beta* ]]; then
 | 
			
		||||
            echo 'Main release.'
 | 
			
		||||
            sudo chown -R runner:docker output.txt
 | 
			
		||||
            echo '' >> output.txt
 | 
			
		||||
            echo '### Instructions' >> output.txt
 | 
			
		||||
            echo '' >> output.txt
 | 
			
		||||
            echo "* Installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
 | 
			
		||||
            echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
 | 
			
		||||
            echo "* The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
 | 
			
		||||
 | 
			
		||||
          fi
 | 
			
		||||
 | 
			
		||||
          # describe alpha release
 | 
			
		||||
          if [[ "$version" == *alpha* ]]; then
 | 
			
		||||
            echo 'ALPHA release.'
 | 
			
		||||
            rm -f output.txt
 | 
			
		||||
            touch output.txt
 | 
			
		||||
            sudo chown -R runner:docker output.txt
 | 
			
		||||
            echo "Very early ALPHA release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt
 | 
			
		||||
            echo '' >> output.txt
 | 
			
		||||
            echo "This release was created on **$(date +'%Y-%m-%d %H:%M')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
 | 
			
		||||
            echo '' >> output.txt
 | 
			
		||||
            echo '### Instructions' >> output.txt
 | 
			
		||||
            echo '' >> output.txt
 | 
			
		||||
            echo "* Installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
 | 
			
		||||
            echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
 | 
			
		||||
            echo "* The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
 | 
			
		||||
 | 
			
		||||
          fi
 | 
			
		||||
 | 
			
		||||
          # describe beta release
 | 
			
		||||
          if [[ "$version" == *beta* ]]; then
 | 
			
		||||
            echo 'BETA release.'
 | 
			
		||||
            rm -f output.txt
 | 
			
		||||
            touch output.txt
 | 
			
		||||
            sudo chown -R runner:docker output.txt
 | 
			
		||||
            echo "Very early BETA release of Firefly III. This release contains specific features or changes. Docker users can find this release under the \`$version\` tag." >> output.txt
 | 
			
		||||
            echo '' >> output.txt
 | 
			
		||||
            echo "This release was created on **$(date +'%Y-%m-%d %H:%M')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
 | 
			
		||||
            echo '' >> output.txt
 | 
			
		||||
            echo '### Instructions' >> output.txt
 | 
			
		||||
            echo '' >> output.txt
 | 
			
		||||
            echo "* Installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
 | 
			
		||||
            echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
 | 
			
		||||
            echo "* The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
 | 
			
		||||
 | 
			
		||||
          fi
 | 
			
		||||
 | 
			
		||||
          # create a development release:
 | 
			
		||||
          if [[ "develop" == "$version" ]]; then
 | 
			
		||||
            # create the release:
 | 
			
		||||
            echo "Create nightly release."
 | 
			
		||||
            git tag -a $releaseName -m "Nightly development release '$version' on $(date +'%Y-%m-%d')"
 | 
			
		||||
            echo "Create develop release."
 | 
			
		||||
            git tag -a $releaseName -m "Development release '$version' on $(date +'%Y-%m-%d')"
 | 
			
		||||
 | 
			
		||||
            git push origin $releaseName
 | 
			
		||||
            gh release create $releaseName -p --verify-tag \
 | 
			
		||||
              -t "Development release for $(date +'%Y-%m-%d')" \
 | 
			
		||||
              --latest=false \
 | 
			
		||||
              -F output.txt
 | 
			
		||||
          fi
 | 
			
		||||
 | 
			
		||||
          # create a branch release:
 | 
			
		||||
          if [[ "$version" == branch* ]]; then
 | 
			
		||||
 | 
			
		||||
            # create the release:
 | 
			
		||||
            echo "Create branch release."
 | 
			
		||||
            git tag -a $releaseName -m "Branch release '$version' on $(date +'%Y-%m-%d')"
 | 
			
		||||
 | 
			
		||||
            git push origin $releaseName
 | 
			
		||||
            gh release create $releaseName -p --verify-tag \
 | 
			
		||||
              -t "Branch release for $(date +'%Y-%m-%d')" \
 | 
			
		||||
              --latest=false \
 | 
			
		||||
              -F output.txt
 | 
			
		||||
          fi
 | 
			
		||||
 | 
			
		||||
          # create a development (nightly) release:
 | 
			
		||||
          if [[ "develop" == "$version" ]] || [[ "$version" == branch* ]]; then
 | 
			
		||||
            # add zip file to release.
 | 
			
		||||
            gh release upload $releaseName $zipName
 | 
			
		||||
            gh release upload $releaseName $tarName
 | 
			
		||||
@@ -247,19 +343,20 @@ jobs:
 | 
			
		||||
            gh release upload $releaseName HEAD.txt
 | 
			
		||||
          else
 | 
			
		||||
            echo 'MAIN (real) release'
 | 
			
		||||
            sudo chown -R runner:docker output.txt
 | 
			
		||||
            # add text to output.txt (more instructions)
 | 
			
		||||
            echo '' >> output.txt
 | 
			
		||||
            echo '### Instructions' >> output.txt
 | 
			
		||||
            echo '' >> output.txt
 | 
			
		||||
            echo "* Installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
 | 
			
		||||
            echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
 | 
			
		||||
            echo "* The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
 | 
			
		||||
 | 
			
		||||
            echo "Create default release."
 | 
			
		||||
            git tag -a $releaseName -m "Here be changelog"
 | 
			
		||||
            git push origin $releaseName
 | 
			
		||||
            gh release create $releaseName -F output.txt -t "$releaseName" --verify-tag
 | 
			
		||||
 | 
			
		||||
            # do not tag as latest when alpha or beta.
 | 
			
		||||
            if [[ "$version" == *alpha* ]] || [[ "$version" == *beta* ]]; then
 | 
			
		||||
              echo 'Mark alpha or beta as NOT the latest.'
 | 
			
		||||
              gh release create $releaseName -F output.txt -t "$releaseName" --verify-tag --latest=false
 | 
			
		||||
            fi
 | 
			
		||||
 | 
			
		||||
            # tag as latest when NOT alpha or beta.
 | 
			
		||||
            if [[ "$version" != *alpha* ]] && [[ "$version" != *beta* ]]; then
 | 
			
		||||
              echo 'Mark prod as the latest.'
 | 
			
		||||
              gh release create $releaseName -F output.txt -t "$releaseName" --verify-tag
 | 
			
		||||
            fi
 | 
			
		||||
 | 
			
		||||
            # add archive files to release
 | 
			
		||||
            gh release upload $releaseName $zipName
 | 
			
		||||
@@ -279,12 +376,12 @@ jobs:
 | 
			
		||||
            gh release upload $releaseName HEAD.txt
 | 
			
		||||
 | 
			
		||||
            # remove all temporary files
 | 
			
		||||
            rm output.txt
 | 
			
		||||
            rm HEAD.txt
 | 
			
		||||
            rm $zipName
 | 
			
		||||
            rm $zipName.sha256
 | 
			
		||||
            rm $tarName
 | 
			
		||||
            rm $tarName.sha256
 | 
			
		||||
            rm -f output.txt
 | 
			
		||||
            rm -f HEAD.txt
 | 
			
		||||
            rm -f $zipName
 | 
			
		||||
            rm -f $zipName.sha256
 | 
			
		||||
            rm -f $tarName
 | 
			
		||||
            rm -f $tarName.sha256
 | 
			
		||||
 | 
			
		||||
            # merge main back into develop
 | 
			
		||||
            git checkout develop
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								.github/workflows/sonarcloud.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/sonarcloud.yml
									
									
									
									
										vendored
									
									
								
							@@ -8,7 +8,7 @@ on:
 | 
			
		||||
      - develop
 | 
			
		||||
env:
 | 
			
		||||
  DB_CONNECTION: sqlite
 | 
			
		||||
  APP_KEY: UfpBqqeXx7zpNodsC6yjYQcRfDdm4Bxh
 | 
			
		||||
  APP_KEY: TestTestTestTestTestTestTestTest
 | 
			
		||||
jobs:
 | 
			
		||||
  sonarcloud:
 | 
			
		||||
    name: SonarCloud
 | 
			
		||||
@@ -19,7 +19,7 @@ jobs:
 | 
			
		||||
      - name: Setup PHP with Xdebug
 | 
			
		||||
        uses: shivammathur/setup-php@v2
 | 
			
		||||
        with:
 | 
			
		||||
          php-version: '8.3'
 | 
			
		||||
          php-version: '8.4'
 | 
			
		||||
          coverage: xdebug
 | 
			
		||||
          extensions: >-
 | 
			
		||||
            bcmath
 | 
			
		||||
@@ -46,7 +46,9 @@ jobs:
 | 
			
		||||
        run: composer install --prefer-dist --no-interaction --no-progress --no-scripts
 | 
			
		||||
 | 
			
		||||
      - name: "Create database file"
 | 
			
		||||
        run: touch storage/database/database.sqlite
 | 
			
		||||
        run: |
 | 
			
		||||
          touch storage/database/database.sqlite
 | 
			
		||||
          wget -q https://github.com/firefly-iii/test-fixtures/raw/refs/heads/main/test-database.sqlite -O storage/database/database.sqlite
 | 
			
		||||
 | 
			
		||||
      - name: "Upgrades the database to the latest version"
 | 
			
		||||
        run: php artisan firefly-iii:upgrade-database
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								.github/workflows/stale.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/stale.yml
									
									
									
									
										vendored
									
									
								
							@@ -12,6 +12,7 @@ jobs:
 | 
			
		||||
    permissions:
 | 
			
		||||
      issues: write  # for actions/stale to close stale issues
 | 
			
		||||
      pull-requests: write  # for actions/stale to close stale PRs
 | 
			
		||||
      actions: write
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/stale@v9
 | 
			
		||||
@@ -35,4 +36,5 @@ jobs:
 | 
			
		||||
            Thank you for your contributions.
 | 
			
		||||
          days-before-stale: 14
 | 
			
		||||
          days-before-close: 7
 | 
			
		||||
          exempt-issue-labels: 'enhancement,feature,bug,announcement,epic,triage'
 | 
			
		||||
          exempt-all-milestones: true
 | 
			
		||||
          exempt-issue-labels: 'triage'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -14,7 +14,16 @@ public/build
 | 
			
		||||
# ignore v1 build files
 | 
			
		||||
resources/assets/v1/node_modules
 | 
			
		||||
resources/assets/v1/build
 | 
			
		||||
public/v1/js/app.js*
 | 
			
		||||
public/v1/js/app_vue.js*
 | 
			
		||||
public/v1/js/create*
 | 
			
		||||
public/v1/js/edit*
 | 
			
		||||
public/v1/js/profile*
 | 
			
		||||
public/v1/js/administrations
 | 
			
		||||
public/v1/js/exchange-rates
 | 
			
		||||
public/v1/js/webhooks
 | 
			
		||||
 | 
			
		||||
# ignore v2 build files
 | 
			
		||||
resources/assets/v2/node_modules
 | 
			
		||||
resources/assets/v2/build
 | 
			
		||||
public/v2/i18n
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								THANKS.md
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								THANKS.md
									
									
									
									
									
								
							@@ -3,7 +3,20 @@
 | 
			
		||||
Over time, many people have contributed to Firefly III. Their efforts are not always visible, but always remembered and appreciated.
 | 
			
		||||
Please find below all the people who contributed to the Firefly III code. Their names are mentioned in the year of their first contribution.
 | 
			
		||||
 | 
			
		||||
## 2025
 | 
			
		||||
- Lompi
 | 
			
		||||
- Jose Diaz-Gonzalez
 | 
			
		||||
- SoftBrix
 | 
			
		||||
 | 
			
		||||
## 2024
 | 
			
		||||
- Sobuno
 | 
			
		||||
- TasneemTantawy
 | 
			
		||||
- Antônio Franco
 | 
			
		||||
- yparitcher
 | 
			
		||||
- Jhon Pedroza
 | 
			
		||||
- mzhubail
 | 
			
		||||
- tasnim
 | 
			
		||||
- withbest
 | 
			
		||||
- Steve Wasiura
 | 
			
		||||
- imlonghao
 | 
			
		||||
- Rahman Yusuf
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * AccountController.php
 | 
			
		||||
 * Copyright (c) 2020 james@firefly-iii.org
 | 
			
		||||
@@ -25,13 +26,15 @@ namespace FireflyIII\Api\V1\Controllers\Autocomplete;
 | 
			
		||||
 | 
			
		||||
use FireflyIII\Api\V1\Controllers\Controller;
 | 
			
		||||
use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteRequest;
 | 
			
		||||
use FireflyIII\Enums\AccountTypeEnum;
 | 
			
		||||
use FireflyIII\Exceptions\FireflyException;
 | 
			
		||||
use FireflyIII\Models\Account;
 | 
			
		||||
use FireflyIII\Models\AccountType;
 | 
			
		||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
 | 
			
		||||
use FireflyIII\Support\Facades\Steam;
 | 
			
		||||
use FireflyIII\Support\Http\Api\AccountFilter;
 | 
			
		||||
use FireflyIII\User;
 | 
			
		||||
use Illuminate\Http\JsonResponse;
 | 
			
		||||
use Illuminate\Support\Facades\Log;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class AccountController
 | 
			
		||||
@@ -39,6 +42,8 @@ use Illuminate\Http\JsonResponse;
 | 
			
		||||
class AccountController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    use AccountFilter;
 | 
			
		||||
    // this array only exists to test if the constructor will use it properly.
 | 
			
		||||
    protected array $accepts = ['application/json', 'application/vnd.api+json'];
 | 
			
		||||
 | 
			
		||||
    /** @var array<int, string> */
 | 
			
		||||
    private array                      $balanceTypes;
 | 
			
		||||
@@ -60,7 +65,7 @@ class AccountController extends Controller
 | 
			
		||||
                return $next($request);
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
        $this->balanceTypes = [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE];
 | 
			
		||||
        $this->balanceTypes = [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -72,40 +77,50 @@ class AccountController extends Controller
 | 
			
		||||
     */
 | 
			
		||||
    public function accounts(AutocompleteRequest $request): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
        $data            = $request->getData();
 | 
			
		||||
        $types           = $data['types'];
 | 
			
		||||
        $query           = $data['query'];
 | 
			
		||||
        $date            = $data['date'] ?? today(config('app.timezone'));
 | 
			
		||||
        $return          = [];
 | 
			
		||||
        $result          = $this->repository->searchAccount((string)$query, $types, $this->parameters->get('limit'));
 | 
			
		||||
        $data   = $request->getData();
 | 
			
		||||
        $types  = $data['types'];
 | 
			
		||||
        $query  = $data['query'];
 | 
			
		||||
        $date   = $data['date'] ?? today(config('app.timezone'));
 | 
			
		||||
        $return = [];
 | 
			
		||||
        $result = $this->repository->searchAccount((string) $query, $types, $this->parameters->get('limit'));
 | 
			
		||||
 | 
			
		||||
        // TODO this code is duplicated in the V2 Autocomplete controller, which means this code is due to be deprecated.
 | 
			
		||||
        $defaultCurrency = app('amount')->getDefaultCurrency();
 | 
			
		||||
        // set date to subday + end-of-day for account balance. so it is at $date 23:59:59
 | 
			
		||||
        $date->endOfDay();
 | 
			
		||||
 | 
			
		||||
        /** @var Account $account */
 | 
			
		||||
        foreach ($result as $account) {
 | 
			
		||||
            $nameWithBalance = $account->name;
 | 
			
		||||
            $currency        = $this->repository->getAccountCurrency($account) ?? $defaultCurrency;
 | 
			
		||||
 | 
			
		||||
            $currency        = $this->repository->getAccountCurrency($account) ?? $this->nativeCurrency;
 | 
			
		||||
            $useCurrency     = $currency;
 | 
			
		||||
            if (in_array($account->accountType->type, $this->balanceTypes, true)) {
 | 
			
		||||
                $balance         = app('steam')->balance($account, $date);
 | 
			
		||||
                // this one is correct.
 | 
			
		||||
                Log::debug(sprintf('accounts: Call finalAccountBalance with date/time "%s"', $date->toIso8601String()));
 | 
			
		||||
                $balance         = Steam::finalAccountBalance($account, $date);
 | 
			
		||||
                $key             = $this->convertToNative && $currency->id !== $this->nativeCurrency->id ? 'native_balance' : 'balance';
 | 
			
		||||
                $useCurrency     = $this->convertToNative && $currency->id !== $this->nativeCurrency->id ? $this->nativeCurrency : $currency;
 | 
			
		||||
                $amount          = $balance[$key] ?? '0';
 | 
			
		||||
                $nameWithBalance = sprintf(
 | 
			
		||||
                    '%s (%s)',
 | 
			
		||||
                    $account->name,
 | 
			
		||||
                    app('amount')->formatAnything($currency, $balance, false)
 | 
			
		||||
                    app('amount')->formatAnything($useCurrency, $amount, false)
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $return[]        = [
 | 
			
		||||
                'id'                      => (string)$account->id,
 | 
			
		||||
                'name'                    => $account->name,
 | 
			
		||||
                'name_with_balance'       => $nameWithBalance,
 | 
			
		||||
                'type'                    => $account->accountType->type,
 | 
			
		||||
                'currency_id'             => (string)$currency->id,
 | 
			
		||||
                'currency_name'           => $currency->name,
 | 
			
		||||
                'currency_code'           => $currency->code,
 | 
			
		||||
                'currency_symbol'         => $currency->symbol,
 | 
			
		||||
                'currency_decimal_places' => $currency->decimal_places,
 | 
			
		||||
                'id'                              => (string) $account->id,
 | 
			
		||||
                'name'                            => $account->name,
 | 
			
		||||
                'name_with_balance'               => $nameWithBalance,
 | 
			
		||||
                'type'                            => $account->accountType->type,
 | 
			
		||||
                'currency_id'                     => (string) $useCurrency->id,
 | 
			
		||||
                'currency_name'                   => $useCurrency->name,
 | 
			
		||||
                'currency_code'                   => $useCurrency->code,
 | 
			
		||||
                'currency_symbol'                 => $useCurrency->symbol,
 | 
			
		||||
                'currency_decimal_places'         => $useCurrency->decimal_places,
 | 
			
		||||
                'account_currency_id'             => (string) $currency->id,
 | 
			
		||||
                'account_currency_name'           => $currency->name,
 | 
			
		||||
                'account_currency_code'           => $currency->code,
 | 
			
		||||
                'account_currency_symbol'         => $currency->symbol,
 | 
			
		||||
                'account_currency_decimal_places' => $currency->decimal_places,
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -113,14 +128,14 @@ class AccountController extends Controller
 | 
			
		||||
        usort(
 | 
			
		||||
            $return,
 | 
			
		||||
            static function (array $left, array $right) {
 | 
			
		||||
                $order = [AccountType::ASSET, AccountType::REVENUE, AccountType::EXPENSE];
 | 
			
		||||
                $posA  = (int)array_search($left['type'], $order, true);
 | 
			
		||||
                $posB  = (int)array_search($right['type'], $order, true);
 | 
			
		||||
                $order = [AccountTypeEnum::ASSET->value, AccountTypeEnum::REVENUE->value, AccountTypeEnum::EXPENSE->value];
 | 
			
		||||
                $posA  = (int) array_search($left['type'], $order, true);
 | 
			
		||||
                $posB  = (int) array_search($right['type'], $order, true);
 | 
			
		||||
 | 
			
		||||
                return $posA - $posB;
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        return response()->json($return);
 | 
			
		||||
        return response()->api($return);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * BillController.php
 | 
			
		||||
 * Copyright (c) 2020 james@firefly-iii.org
 | 
			
		||||
@@ -66,13 +67,13 @@ class BillController extends Controller
 | 
			
		||||
        $filtered = $result->map(
 | 
			
		||||
            static function (Bill $item) {
 | 
			
		||||
                return [
 | 
			
		||||
                    'id'     => (string)$item->id,
 | 
			
		||||
                    'id'     => (string) $item->id,
 | 
			
		||||
                    'name'   => $item->name,
 | 
			
		||||
                    'active' => $item->active,
 | 
			
		||||
                ];
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        return response()->json($filtered->toArray());
 | 
			
		||||
        return response()->api($filtered->toArray());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * BudgetController.php
 | 
			
		||||
 * Copyright (c) 2020 james@firefly-iii.org
 | 
			
		||||
@@ -66,12 +67,12 @@ class BudgetController extends Controller
 | 
			
		||||
        $filtered = $result->map(
 | 
			
		||||
            static function (Budget $item) {
 | 
			
		||||
                return [
 | 
			
		||||
                    'id'   => (string)$item->id,
 | 
			
		||||
                    'id'   => (string) $item->id,
 | 
			
		||||
                    'name' => $item->name,
 | 
			
		||||
                ];
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        return response()->json($filtered);
 | 
			
		||||
        return response()->api($filtered->toArray());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * CategoryController.php
 | 
			
		||||
 * Copyright (c) 2020 james@firefly-iii.org
 | 
			
		||||
@@ -66,12 +67,12 @@ class CategoryController extends Controller
 | 
			
		||||
        $filtered = $result->map(
 | 
			
		||||
            static function (Category $item) {
 | 
			
		||||
                return [
 | 
			
		||||
                    'id'   => (string)$item->id,
 | 
			
		||||
                    'id'   => (string) $item->id,
 | 
			
		||||
                    'name' => $item->name,
 | 
			
		||||
                ];
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        return response()->json($filtered);
 | 
			
		||||
        return response()->api($filtered->toArray());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * CurrencyController.php
 | 
			
		||||
 * Copyright (c) 2020 james@firefly-iii.org
 | 
			
		||||
@@ -68,7 +69,7 @@ class CurrencyController extends Controller
 | 
			
		||||
        /** @var TransactionCurrency $currency */
 | 
			
		||||
        foreach ($collection as $currency) {
 | 
			
		||||
            $result[] = [
 | 
			
		||||
                'id'             => (string)$currency->id,
 | 
			
		||||
                'id'             => (string) $currency->id,
 | 
			
		||||
                'name'           => $currency->name,
 | 
			
		||||
                'code'           => $currency->code,
 | 
			
		||||
                'symbol'         => $currency->symbol,
 | 
			
		||||
@@ -76,7 +77,7 @@ class CurrencyController extends Controller
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response()->json($result);
 | 
			
		||||
        return response()->api($result);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -94,7 +95,7 @@ class CurrencyController extends Controller
 | 
			
		||||
        /** @var TransactionCurrency $currency */
 | 
			
		||||
        foreach ($collection as $currency) {
 | 
			
		||||
            $result[] = [
 | 
			
		||||
                'id'             => (string)$currency->id,
 | 
			
		||||
                'id'             => (string) $currency->id,
 | 
			
		||||
                'name'           => sprintf('%s (%s)', $currency->name, $currency->code),
 | 
			
		||||
                'code'           => $currency->code,
 | 
			
		||||
                'symbol'         => $currency->symbol,
 | 
			
		||||
@@ -102,6 +103,6 @@ class CurrencyController extends Controller
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response()->json($result);
 | 
			
		||||
        return response()->api($result);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ObjectGroupController.php
 | 
			
		||||
 * Copyright (c) 2020 james@firefly-iii.org
 | 
			
		||||
@@ -68,12 +69,12 @@ class ObjectGroupController extends Controller
 | 
			
		||||
        /** @var ObjectGroup $objectGroup */
 | 
			
		||||
        foreach ($result as $objectGroup) {
 | 
			
		||||
            $return[] = [
 | 
			
		||||
                'id'    => (string)$objectGroup->id,
 | 
			
		||||
                'id'    => (string) $objectGroup->id,
 | 
			
		||||
                'name'  => $objectGroup->title,
 | 
			
		||||
                'title' => $objectGroup->title,
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response()->json($return);
 | 
			
		||||
        return response()->api($return);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * PiggyBankController.php
 | 
			
		||||
 * Copyright (c) 2020 james@firefly-iii.org
 | 
			
		||||
@@ -65,29 +66,28 @@ class PiggyBankController extends Controller
 | 
			
		||||
     */
 | 
			
		||||
    public function piggyBanks(AutocompleteRequest $request): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
        $data            = $request->getData();
 | 
			
		||||
        $piggies         = $this->piggyRepository->searchPiggyBank($data['query'], $this->parameters->get('limit'));
 | 
			
		||||
        $defaultCurrency = app('amount')->getDefaultCurrency();
 | 
			
		||||
        $response        = [];
 | 
			
		||||
        $data     = $request->getData();
 | 
			
		||||
        $piggies  = $this->piggyRepository->searchPiggyBank($data['query'], $this->parameters->get('limit'));
 | 
			
		||||
        $response = [];
 | 
			
		||||
 | 
			
		||||
        /** @var PiggyBank $piggy */
 | 
			
		||||
        foreach ($piggies as $piggy) {
 | 
			
		||||
            $currency    = $this->accountRepository->getAccountCurrency($piggy->account) ?? $defaultCurrency;
 | 
			
		||||
            $currency    = $piggy->transactionCurrency;
 | 
			
		||||
            $objectGroup = $piggy->objectGroups()->first();
 | 
			
		||||
            $response[]  = [
 | 
			
		||||
                'id'                      => (string)$piggy->id,
 | 
			
		||||
                'id'                      => (string) $piggy->id,
 | 
			
		||||
                'name'                    => $piggy->name,
 | 
			
		||||
                'currency_id'             => (string)$currency->id,
 | 
			
		||||
                'currency_id'             => (string) $currency->id,
 | 
			
		||||
                'currency_name'           => $currency->name,
 | 
			
		||||
                'currency_code'           => $currency->code,
 | 
			
		||||
                'currency_symbol'         => $currency->symbol,
 | 
			
		||||
                'currency_decimal_places' => $currency->decimal_places,
 | 
			
		||||
                'object_group_id'         => null === $objectGroup ? null : (string)$objectGroup->id,
 | 
			
		||||
                'object_group_id'         => null === $objectGroup ? null : (string) $objectGroup->id,
 | 
			
		||||
                'object_group_title'      => $objectGroup?->title,
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response()->json($response);
 | 
			
		||||
        return response()->api($response);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -96,35 +96,34 @@ class PiggyBankController extends Controller
 | 
			
		||||
     */
 | 
			
		||||
    public function piggyBanksWithBalance(AutocompleteRequest $request): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
        $data            = $request->getData();
 | 
			
		||||
        $piggies         = $this->piggyRepository->searchPiggyBank($data['query'], $this->parameters->get('limit'));
 | 
			
		||||
        $defaultCurrency = app('amount')->getDefaultCurrency();
 | 
			
		||||
        $response        = [];
 | 
			
		||||
        $data     = $request->getData();
 | 
			
		||||
        $piggies  = $this->piggyRepository->searchPiggyBank($data['query'], $this->parameters->get('limit'));
 | 
			
		||||
        $response = [];
 | 
			
		||||
 | 
			
		||||
        /** @var PiggyBank $piggy */
 | 
			
		||||
        foreach ($piggies as $piggy) {
 | 
			
		||||
            $currency      = $this->accountRepository->getAccountCurrency($piggy->account) ?? $defaultCurrency;
 | 
			
		||||
            $currentAmount = $this->piggyRepository->getRepetition($piggy)->currentamount ?? '0';
 | 
			
		||||
            $currency      = $piggy->transactionCurrency;
 | 
			
		||||
            $currentAmount = $this->piggyRepository->getCurrentAmount($piggy);
 | 
			
		||||
            $objectGroup   = $piggy->objectGroups()->first();
 | 
			
		||||
            $response[]    = [
 | 
			
		||||
                'id'                      => (string)$piggy->id,
 | 
			
		||||
                'id'                      => (string) $piggy->id,
 | 
			
		||||
                'name'                    => $piggy->name,
 | 
			
		||||
                'name_with_balance'       => sprintf(
 | 
			
		||||
                    '%s (%s / %s)',
 | 
			
		||||
                    $piggy->name,
 | 
			
		||||
                    app('amount')->formatAnything($currency, $currentAmount, false),
 | 
			
		||||
                    app('amount')->formatAnything($currency, $piggy->targetamount, false),
 | 
			
		||||
                    app('amount')->formatAnything($currency, $piggy->target_amount, false),
 | 
			
		||||
                ),
 | 
			
		||||
                'currency_id'             => (string)$currency->id,
 | 
			
		||||
                'currency_id'             => (string) $currency->id,
 | 
			
		||||
                'currency_name'           => $currency->name,
 | 
			
		||||
                'currency_code'           => $currency->code,
 | 
			
		||||
                'currency_symbol'         => $currency->symbol,
 | 
			
		||||
                'currency_decimal_places' => $currency->decimal_places,
 | 
			
		||||
                'object_group_id'         => null === $objectGroup ? null : (string)$objectGroup->id,
 | 
			
		||||
                'object_group_id'         => null === $objectGroup ? null : (string) $objectGroup->id,
 | 
			
		||||
                'object_group_title'      => $objectGroup?->title,
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response()->json($response);
 | 
			
		||||
        return response()->api($response);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * RecurrenceController.php
 | 
			
		||||
 * Copyright (c) 2020 james@firefly-iii.org
 | 
			
		||||
@@ -66,12 +67,12 @@ class RecurrenceController extends Controller
 | 
			
		||||
        /** @var Recurrence $recurrence */
 | 
			
		||||
        foreach ($recurrences as $recurrence) {
 | 
			
		||||
            $response[] = [
 | 
			
		||||
                'id'          => (string)$recurrence->id,
 | 
			
		||||
                'id'          => (string) $recurrence->id,
 | 
			
		||||
                'name'        => $recurrence->title,
 | 
			
		||||
                'description' => $recurrence->description,
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response()->json($response);
 | 
			
		||||
        return response()->api($response);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * RuleController.php
 | 
			
		||||
 * Copyright (c) 2020 james@firefly-iii.org
 | 
			
		||||
@@ -65,12 +66,12 @@ class RuleController extends Controller
 | 
			
		||||
        /** @var Rule $rule */
 | 
			
		||||
        foreach ($rules as $rule) {
 | 
			
		||||
            $response[] = [
 | 
			
		||||
                'id'          => (string)$rule->id,
 | 
			
		||||
                'id'          => (string) $rule->id,
 | 
			
		||||
                'name'        => $rule->title,
 | 
			
		||||
                'description' => $rule->description,
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response()->json($response);
 | 
			
		||||
        return response()->api($response);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * RuleGroupController.php
 | 
			
		||||
 * Copyright (c) 2020 james@firefly-iii.org
 | 
			
		||||
@@ -65,12 +66,12 @@ class RuleGroupController extends Controller
 | 
			
		||||
        /** @var RuleGroup $group */
 | 
			
		||||
        foreach ($groups as $group) {
 | 
			
		||||
            $response[] = [
 | 
			
		||||
                'id'          => (string)$group->id,
 | 
			
		||||
                'id'          => (string) $group->id,
 | 
			
		||||
                'name'        => $group->title,
 | 
			
		||||
                'description' => $group->description,
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response()->json($response);
 | 
			
		||||
        return response()->api($response);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * TagController.php
 | 
			
		||||
 * Copyright (c) 2020 james@firefly-iii.org
 | 
			
		||||
@@ -68,12 +69,12 @@ class TagController extends Controller
 | 
			
		||||
        /** @var Tag $tag */
 | 
			
		||||
        foreach ($result as $tag) {
 | 
			
		||||
            $array[] = [
 | 
			
		||||
                'id'   => (string)$tag->id,
 | 
			
		||||
                'id'   => (string) $tag->id,
 | 
			
		||||
                'name' => $tag->tag,
 | 
			
		||||
                'tag'  => $tag->tag,
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response()->json($array);
 | 
			
		||||
        return response()->api($array);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * TransactionController.php
 | 
			
		||||
 * Copyright (c) 2020 james@firefly-iii.org
 | 
			
		||||
@@ -25,6 +26,7 @@ namespace FireflyIII\Api\V1\Controllers\Autocomplete;
 | 
			
		||||
 | 
			
		||||
use FireflyIII\Api\V1\Controllers\Controller;
 | 
			
		||||
use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteRequest;
 | 
			
		||||
use FireflyIII\Enums\UserRoleEnum;
 | 
			
		||||
use FireflyIII\Models\TransactionJournal;
 | 
			
		||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
 | 
			
		||||
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface;
 | 
			
		||||
@@ -40,6 +42,8 @@ class TransactionController extends Controller
 | 
			
		||||
    private TransactionGroupRepositoryInterface $groupRepository;
 | 
			
		||||
    private JournalRepositoryInterface          $repository;
 | 
			
		||||
 | 
			
		||||
    protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * TransactionController constructor.
 | 
			
		||||
     */
 | 
			
		||||
@@ -50,10 +54,12 @@ class TransactionController extends Controller
 | 
			
		||||
            function ($request, $next) {
 | 
			
		||||
                /** @var User $user */
 | 
			
		||||
                $user                  = auth()->user();
 | 
			
		||||
                $userGroup             = $this->validateUserGroup($request);
 | 
			
		||||
                $this->repository      = app(JournalRepositoryInterface::class);
 | 
			
		||||
                $this->groupRepository = app(TransactionGroupRepositoryInterface::class);
 | 
			
		||||
                $this->repository->setUser($user);
 | 
			
		||||
                $this->groupRepository->setUser($user);
 | 
			
		||||
                $this->groupRepository->setUserGroup($userGroup);
 | 
			
		||||
 | 
			
		||||
                return $next($request);
 | 
			
		||||
            }
 | 
			
		||||
@@ -76,14 +82,14 @@ class TransactionController extends Controller
 | 
			
		||||
        /** @var TransactionJournal $journal */
 | 
			
		||||
        foreach ($filtered as $journal) {
 | 
			
		||||
            $array[] = [
 | 
			
		||||
                'id'                   => (string)$journal->id,
 | 
			
		||||
                'transaction_group_id' => (string)$journal->transaction_group_id,
 | 
			
		||||
                'id'                   => (string) $journal->id,
 | 
			
		||||
                'transaction_group_id' => (string) $journal->transaction_group_id,
 | 
			
		||||
                'name'                 => $journal->description,
 | 
			
		||||
                'description'          => $journal->description,
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response()->json($array);
 | 
			
		||||
        return response()->api($array);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -96,7 +102,7 @@ class TransactionController extends Controller
 | 
			
		||||
        $result = new Collection();
 | 
			
		||||
        if (is_numeric($data['query'])) {
 | 
			
		||||
            // search for group, not journal.
 | 
			
		||||
            $firstResult = $this->groupRepository->find((int)$data['query']);
 | 
			
		||||
            $firstResult = $this->groupRepository->find((int) $data['query']);
 | 
			
		||||
            if (null !== $firstResult) {
 | 
			
		||||
                // group may contain multiple journals, each a result:
 | 
			
		||||
                foreach ($firstResult->transactionJournals as $journal) {
 | 
			
		||||
@@ -114,13 +120,13 @@ class TransactionController extends Controller
 | 
			
		||||
        /** @var TransactionJournal $journal */
 | 
			
		||||
        foreach ($result as $journal) {
 | 
			
		||||
            $array[] = [
 | 
			
		||||
                'id'                   => (string)$journal->id,
 | 
			
		||||
                'transaction_group_id' => (string)$journal->transaction_group_id,
 | 
			
		||||
                'id'                   => (string) $journal->id,
 | 
			
		||||
                'transaction_group_id' => (string) $journal->transaction_group_id,
 | 
			
		||||
                'name'                 => sprintf('#%d: %s', $journal->transaction_group_id, $journal->description),
 | 
			
		||||
                'description'          => sprintf('#%d: %s', $journal->transaction_group_id, $journal->description),
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response()->json($array);
 | 
			
		||||
        return response()->api($array);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * TransactionTypeController.php
 | 
			
		||||
 * Copyright (c) 2020 james@firefly-iii.org
 | 
			
		||||
@@ -65,12 +66,12 @@ class TransactionTypeController extends Controller
 | 
			
		||||
        foreach ($types as $type) {
 | 
			
		||||
            // different key for consistency.
 | 
			
		||||
            $array[] = [
 | 
			
		||||
                'id'   => (string)$type->id,
 | 
			
		||||
                'id'   => (string) $type->id,
 | 
			
		||||
                'name' => $type->type,
 | 
			
		||||
                'type' => $type->type,
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response()->json($array);
 | 
			
		||||
        return response()->api($array);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -27,11 +27,12 @@ namespace FireflyIII\Api\V1\Controllers\Chart;
 | 
			
		||||
use Carbon\Carbon;
 | 
			
		||||
use FireflyIII\Api\V1\Controllers\Controller;
 | 
			
		||||
use FireflyIII\Api\V1\Requests\Data\DateRequest;
 | 
			
		||||
use FireflyIII\Enums\AccountTypeEnum;
 | 
			
		||||
use FireflyIII\Exceptions\FireflyException;
 | 
			
		||||
use FireflyIII\Models\Account;
 | 
			
		||||
use FireflyIII\Models\AccountType;
 | 
			
		||||
use FireflyIII\Models\Preference;
 | 
			
		||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
 | 
			
		||||
use FireflyIII\Support\Facades\Steam;
 | 
			
		||||
use FireflyIII\Support\Http\Api\ApiSupport;
 | 
			
		||||
use FireflyIII\User;
 | 
			
		||||
use Illuminate\Http\JsonResponse;
 | 
			
		||||
@@ -80,12 +81,15 @@ class AccountController extends Controller
 | 
			
		||||
        /** @var Carbon $end */
 | 
			
		||||
        $end        = $dates['end'];
 | 
			
		||||
 | 
			
		||||
        // set dates to end of day + start of day:
 | 
			
		||||
        $start->startOfDay();
 | 
			
		||||
        $end->endOfDay();
 | 
			
		||||
 | 
			
		||||
        // user's preferences
 | 
			
		||||
        $defaultSet = $this->repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray();
 | 
			
		||||
        $defaultSet = $this->repository->getAccountsByType([AccountTypeEnum::ASSET->value])->pluck('id')->toArray();
 | 
			
		||||
 | 
			
		||||
        /** @var Preference $frontpage */
 | 
			
		||||
        $frontpage  = app('preferences')->get('frontpageAccounts', $defaultSet);
 | 
			
		||||
        $default    = app('amount')->getDefaultCurrency();
 | 
			
		||||
 | 
			
		||||
        if (!(is_array($frontpage->data) && count($frontpage->data) > 0)) {
 | 
			
		||||
            $frontpage->data = $defaultSet;
 | 
			
		||||
@@ -98,13 +102,11 @@ class AccountController extends Controller
 | 
			
		||||
 | 
			
		||||
        /** @var Account $account */
 | 
			
		||||
        foreach ($accounts as $account) {
 | 
			
		||||
            $currency     = $this->repository->getAccountCurrency($account);
 | 
			
		||||
            if (null === $currency) {
 | 
			
		||||
                $currency = $default;
 | 
			
		||||
            }
 | 
			
		||||
            $currency     = $this->repository->getAccountCurrency($account) ?? $this->nativeCurrency;
 | 
			
		||||
            $field        = $this->convertToNative && $currency->id !== $this->nativeCurrency->id ? 'native_balance' : 'balance';
 | 
			
		||||
            $currentSet   = [
 | 
			
		||||
                'label'                   => $account->name,
 | 
			
		||||
                'currency_id'             => (string)$currency->id,
 | 
			
		||||
                'currency_id'             => (string) $currency->id,
 | 
			
		||||
                'currency_code'           => $currency->code,
 | 
			
		||||
                'currency_symbol'         => $currency->symbol,
 | 
			
		||||
                'currency_decimal_places' => $currency->decimal_places,
 | 
			
		||||
@@ -116,13 +118,12 @@ class AccountController extends Controller
 | 
			
		||||
            ];
 | 
			
		||||
            // TODO this code is also present in the V2 chart account controller so this method is due to be deprecated.
 | 
			
		||||
            $currentStart = clone $start;
 | 
			
		||||
            $range        = app('steam')->balanceInRange($account, $start, clone $end);
 | 
			
		||||
            // 2022-10-11 this method no longer converts to float.
 | 
			
		||||
            $previous     = array_values($range)[0];
 | 
			
		||||
            $range        = Steam::finalAccountBalanceInRange($account, $start, clone $end, $this->convertToNative);
 | 
			
		||||
            $previous     = array_values($range)[0][$field];
 | 
			
		||||
            while ($currentStart <= $end) {
 | 
			
		||||
                $format                        = $currentStart->format('Y-m-d');
 | 
			
		||||
                $label                         = $currentStart->toAtomString();
 | 
			
		||||
                $balance                       = array_key_exists($format, $range) ? $range[$format] : $previous;
 | 
			
		||||
                $balance                       = array_key_exists($format, $range) ? $range[$format][$field] : $previous;
 | 
			
		||||
                $previous                      = $balance;
 | 
			
		||||
                $currentStart->addDay();
 | 
			
		||||
                $currentSet['entries'][$label] = $balance;
 | 
			
		||||
 
 | 
			
		||||
@@ -25,15 +25,26 @@ declare(strict_types=1);
 | 
			
		||||
namespace FireflyIII\Api\V1\Controllers;
 | 
			
		||||
 | 
			
		||||
use Carbon\Carbon;
 | 
			
		||||
use Carbon\Exceptions\InvalidDateException;
 | 
			
		||||
use Carbon\Exceptions\InvalidFormatException;
 | 
			
		||||
use FireflyIII\Exceptions\BadHttpHeaderException;
 | 
			
		||||
use FireflyIII\Models\Preference;
 | 
			
		||||
use FireflyIII\Models\TransactionCurrency;
 | 
			
		||||
use FireflyIII\Support\Facades\Amount;
 | 
			
		||||
use FireflyIII\Support\Facades\Steam;
 | 
			
		||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
 | 
			
		||||
use FireflyIII\Transformers\V2\AbstractTransformer;
 | 
			
		||||
use FireflyIII\User;
 | 
			
		||||
use Illuminate\Database\Eloquent\Model;
 | 
			
		||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
 | 
			
		||||
use Illuminate\Foundation\Bus\DispatchesJobs;
 | 
			
		||||
use Illuminate\Foundation\Validation\ValidatesRequests;
 | 
			
		||||
use Illuminate\Pagination\LengthAwarePaginator;
 | 
			
		||||
use Illuminate\Routing\Controller as BaseController;
 | 
			
		||||
use Illuminate\Support\Collection;
 | 
			
		||||
use League\Fractal\Manager;
 | 
			
		||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
 | 
			
		||||
use League\Fractal\Resource\Collection as FractalCollection;
 | 
			
		||||
use League\Fractal\Resource\Item;
 | 
			
		||||
use League\Fractal\Serializer\JsonApiSerializer;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
 | 
			
		||||
use Symfony\Component\HttpFoundation\ParameterBag;
 | 
			
		||||
@@ -41,20 +52,25 @@ use Symfony\Component\HttpFoundation\ParameterBag;
 | 
			
		||||
/**
 | 
			
		||||
 * Class Controller.
 | 
			
		||||
 *
 | 
			
		||||
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 | 
			
		||||
 * @SuppressWarnings(PHPMD.NumberOfChildren)
 | 
			
		||||
 * @SuppressWarnings("PHPMD.CouplingBetweenObjects")
 | 
			
		||||
 * @SuppressWarnings("PHPMD.NumberOfChildren")
 | 
			
		||||
 */
 | 
			
		||||
abstract class Controller extends BaseController
 | 
			
		||||
{
 | 
			
		||||
    use AuthorizesRequests;
 | 
			
		||||
    use DispatchesJobs;
 | 
			
		||||
    use ValidatesRequests;
 | 
			
		||||
    use ValidatesUserGroupTrait;
 | 
			
		||||
 | 
			
		||||
    protected const string CONTENT_TYPE = 'application/vnd.api+json';
 | 
			
		||||
    protected const string CONTENT_TYPE      = 'application/vnd.api+json';
 | 
			
		||||
    protected const string JSON_CONTENT_TYPE = 'application/json';
 | 
			
		||||
 | 
			
		||||
    /** @var array<int, string> */
 | 
			
		||||
    protected array        $allowedSort;
 | 
			
		||||
    protected ParameterBag $parameters;
 | 
			
		||||
    protected bool        $convertToNative   = false;
 | 
			
		||||
    protected array $accepts                 = ['application/json', 'application/vnd.api+json'];
 | 
			
		||||
    protected TransactionCurrency $nativeCurrency;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Controller constructor.
 | 
			
		||||
@@ -67,10 +83,19 @@ abstract class Controller extends BaseController
 | 
			
		||||
            function ($request, $next) {
 | 
			
		||||
                $this->parameters = $this->getParameters();
 | 
			
		||||
                if (auth()->check()) {
 | 
			
		||||
                    $language = app('steam')->getLanguage();
 | 
			
		||||
                    $language              = Steam::getLanguage();
 | 
			
		||||
                    $this->convertToNative = Amount::convertToNative();
 | 
			
		||||
                    $this->nativeCurrency  = Amount::getNativeCurrency();
 | 
			
		||||
                    app()->setLocale($language);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                // filter down what this endpoint accepts.
 | 
			
		||||
                if (!$request->accepts($this->accepts)) {
 | 
			
		||||
                    throw new BadHttpHeaderException(sprintf('Sorry, Accept header "%s" is not something this endpoint can provide.', $request->header('Accept')));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                return $next($request);
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
@@ -82,7 +107,7 @@ abstract class Controller extends BaseController
 | 
			
		||||
    private function getParameters(): ParameterBag
 | 
			
		||||
    {
 | 
			
		||||
        $bag      = new ParameterBag();
 | 
			
		||||
        $page     = (int)request()->get('page');
 | 
			
		||||
        $page     = (int) request()->get('page');
 | 
			
		||||
        if ($page < 1) {
 | 
			
		||||
            $page = 1;
 | 
			
		||||
        }
 | 
			
		||||
@@ -107,13 +132,13 @@ abstract class Controller extends BaseController
 | 
			
		||||
            $obj  = null;
 | 
			
		||||
            if (null !== $date) {
 | 
			
		||||
                try {
 | 
			
		||||
                    $obj = Carbon::parse((string)$date);
 | 
			
		||||
                } catch (InvalidDateException|InvalidFormatException $e) {
 | 
			
		||||
                    $obj = Carbon::parse((string) $date);
 | 
			
		||||
                } catch (InvalidFormatException $e) {
 | 
			
		||||
                    // don't care
 | 
			
		||||
                    app('log')->warning(
 | 
			
		||||
                        sprintf(
 | 
			
		||||
                            'Ignored invalid date "%s" in API controller parameter check: %s',
 | 
			
		||||
                            substr((string)$date, 0, 20),
 | 
			
		||||
                            substr((string) $date, 0, 20),
 | 
			
		||||
                            $e->getMessage()
 | 
			
		||||
                        )
 | 
			
		||||
                    );
 | 
			
		||||
@@ -134,7 +159,15 @@ abstract class Controller extends BaseController
 | 
			
		||||
                $value = null;
 | 
			
		||||
            }
 | 
			
		||||
            if (null !== $value) {
 | 
			
		||||
                $bag->set($integer, (int)$value);
 | 
			
		||||
                $value = (int) $value;
 | 
			
		||||
                if ($value < 1) {
 | 
			
		||||
                    $value = 1;
 | 
			
		||||
                }
 | 
			
		||||
                if ($value > 2 ** 16) {
 | 
			
		||||
                    $value = 2 ** 16;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                $bag->set($integer, $value);
 | 
			
		||||
            }
 | 
			
		||||
            if (null === $value
 | 
			
		||||
                && 'limit' === $integer // @phpstan-ignore-line
 | 
			
		||||
@@ -144,7 +177,7 @@ abstract class Controller extends BaseController
 | 
			
		||||
                $user     = auth()->user();
 | 
			
		||||
 | 
			
		||||
                /** @var Preference $pageSize */
 | 
			
		||||
                $pageSize = (int)app('preferences')->getForUser($user, 'listPageSize', 50)->data;
 | 
			
		||||
                $pageSize = (int) app('preferences')->getForUser($user, 'listPageSize', 50)->data;
 | 
			
		||||
                $bag->set($integer, $pageSize);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -158,7 +191,7 @@ abstract class Controller extends BaseController
 | 
			
		||||
        $sortParameters = [];
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            $param = (string)request()->query->get('sort');
 | 
			
		||||
            $param = (string) request()->query->get('sort');
 | 
			
		||||
        } catch (BadRequestException $e) {
 | 
			
		||||
            app('log')->error('Request field "sort" contains a non-scalar value. Value set to NULL.');
 | 
			
		||||
            app('log')->error($e->getMessage());
 | 
			
		||||
@@ -216,4 +249,45 @@ abstract class Controller extends BaseController
 | 
			
		||||
 | 
			
		||||
        return $manager;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    final protected function jsonApiList(string $key, LengthAwarePaginator $paginator, AbstractTransformer $transformer): array
 | 
			
		||||
    {
 | 
			
		||||
        $manager  = new Manager();
 | 
			
		||||
        $baseUrl  = sprintf('%s/api/v1/', request()->getSchemeAndHttpHost());
 | 
			
		||||
 | 
			
		||||
        // TODO add stuff to path?
 | 
			
		||||
 | 
			
		||||
        $manager->setSerializer(new JsonApiSerializer($baseUrl));
 | 
			
		||||
 | 
			
		||||
        $objects  = $paginator->getCollection();
 | 
			
		||||
 | 
			
		||||
        // the transformer, at this point, needs to collect information that ALL items in the collection
 | 
			
		||||
        // require, like meta-data and stuff like that, and save it for later.
 | 
			
		||||
        $objects  = $transformer->collectMetaData($objects);
 | 
			
		||||
        $paginator->setCollection($objects);
 | 
			
		||||
 | 
			
		||||
        $resource = new FractalCollection($objects, $transformer, $key);
 | 
			
		||||
        $resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
 | 
			
		||||
 | 
			
		||||
        return $manager->createData($resource)->toArray();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns a JSON API object and returns it.
 | 
			
		||||
     *
 | 
			
		||||
     * @param array<int, mixed>|Model $object
 | 
			
		||||
     */
 | 
			
		||||
    final protected function jsonApiObject(string $key, array|Model $object, AbstractTransformer $transformer): array
 | 
			
		||||
    {
 | 
			
		||||
        // create some objects:
 | 
			
		||||
        $manager  = new Manager();
 | 
			
		||||
        $baseUrl  = sprintf('%s/api/v1', request()->getSchemeAndHttpHost());
 | 
			
		||||
        $manager->setSerializer(new JsonApiSerializer($baseUrl));
 | 
			
		||||
 | 
			
		||||
        $transformer->collectMetaData(new Collection([$object]));
 | 
			
		||||
 | 
			
		||||
        $resource = new Item($object, $transformer, $key);
 | 
			
		||||
 | 
			
		||||
        return $manager->createData($resource)->toArray();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -70,8 +70,8 @@ class TransactionController extends Controller
 | 
			
		||||
        // to respond to what is in the $query.
 | 
			
		||||
        // this is OK because only one thing can be in the query at the moment.
 | 
			
		||||
        if ($this->isUpdateTransactionAccount($params)) {
 | 
			
		||||
            $original    = $this->repository->find((int)$params['where']['account_id']);
 | 
			
		||||
            $destination = $this->repository->find((int)$params['update']['account_id']);
 | 
			
		||||
            $original    = $this->repository->find((int) $params['where']['account_id']);
 | 
			
		||||
            $destination = $this->repository->find((int) $params['update']['account_id']);
 | 
			
		||||
 | 
			
		||||
            /** @var AccountDestroyService $service */
 | 
			
		||||
            $service     = app(AccountDestroyService::class);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * DestroyController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
@@ -25,11 +26,11 @@ namespace FireflyIII\Api\V1\Controllers\Data;
 | 
			
		||||
 | 
			
		||||
use FireflyIII\Api\V1\Controllers\Controller;
 | 
			
		||||
use FireflyIII\Api\V1\Requests\Data\DestroyRequest;
 | 
			
		||||
use FireflyIII\Enums\AccountTypeEnum;
 | 
			
		||||
use FireflyIII\Enums\TransactionTypeEnum;
 | 
			
		||||
use FireflyIII\Exceptions\FireflyException;
 | 
			
		||||
use FireflyIII\Models\Account;
 | 
			
		||||
use FireflyIII\Models\AccountType;
 | 
			
		||||
use FireflyIII\Models\TransactionJournal;
 | 
			
		||||
use FireflyIII\Models\TransactionType;
 | 
			
		||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
 | 
			
		||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
 | 
			
		||||
use FireflyIII\Repositories\Budget\AvailableBudgetRepositoryInterface;
 | 
			
		||||
@@ -65,10 +66,10 @@ class DestroyController extends Controller
 | 
			
		||||
        $objects         = $request->getObjects();
 | 
			
		||||
        $this->unused    = $request->boolean('unused', false);
 | 
			
		||||
 | 
			
		||||
        $allExceptAssets = [AccountType::BENEFICIARY, AccountType::CASH, AccountType::CREDITCARD, AccountType::DEFAULT, AccountType::EXPENSE, AccountType::IMPORT, AccountType::INITIAL_BALANCE, AccountType::LIABILITY_CREDIT, AccountType::RECONCILIATION, AccountType::REVENUE];
 | 
			
		||||
        $all             = [AccountType::ASSET, AccountType::BENEFICIARY, AccountType::CASH, AccountType::CREDITCARD, AccountType::DEBT, AccountType::DEFAULT, AccountType::EXPENSE, AccountType::IMPORT, AccountType::INITIAL_BALANCE, AccountType::LIABILITY_CREDIT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::RECONCILIATION];
 | 
			
		||||
        $liabilities     = [AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::CREDITCARD];
 | 
			
		||||
        $transactions    = [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER, TransactionType::RECONCILIATION];
 | 
			
		||||
        $allExceptAssets = [AccountTypeEnum::BENEFICIARY->value, AccountTypeEnum::CASH->value, AccountTypeEnum::CREDITCARD->value, AccountTypeEnum::DEFAULT->value, AccountTypeEnum::EXPENSE->value, AccountTypeEnum::IMPORT->value, AccountTypeEnum::INITIAL_BALANCE->value, AccountTypeEnum::LIABILITY_CREDIT->value, AccountTypeEnum::RECONCILIATION->value, AccountTypeEnum::REVENUE->value];
 | 
			
		||||
        $all             = [AccountTypeEnum::ASSET->value, AccountTypeEnum::BENEFICIARY->value, AccountTypeEnum::CASH->value, AccountTypeEnum::CREDITCARD->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::DEFAULT->value, AccountTypeEnum::EXPENSE->value, AccountTypeEnum::IMPORT->value, AccountTypeEnum::INITIAL_BALANCE->value, AccountTypeEnum::LIABILITY_CREDIT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::RECONCILIATION->value];
 | 
			
		||||
        $liabilities     = [AccountTypeEnum::DEBT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::CREDITCARD->value];
 | 
			
		||||
        $transactions    = [TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::DEPOSIT->value, TransactionTypeEnum::TRANSFER->value, TransactionTypeEnum::RECONCILIATION->value];
 | 
			
		||||
 | 
			
		||||
        match ($objects) {
 | 
			
		||||
            'budgets'                => $this->destroyBudgets(),
 | 
			
		||||
@@ -81,14 +82,14 @@ class DestroyController extends Controller
 | 
			
		||||
            'object_groups'          => $this->destroyObjectGroups(),
 | 
			
		||||
            'not_assets_liabilities' => $this->destroyAccounts($allExceptAssets),
 | 
			
		||||
            'accounts'               => $this->destroyAccounts($all),
 | 
			
		||||
            'asset_accounts'         => $this->destroyAccounts([AccountType::ASSET, AccountType::DEFAULT]),
 | 
			
		||||
            'expense_accounts'       => $this->destroyAccounts([AccountType::BENEFICIARY, AccountType::EXPENSE]),
 | 
			
		||||
            'revenue_accounts'       => $this->destroyAccounts([AccountType::REVENUE]),
 | 
			
		||||
            'asset_accounts'         => $this->destroyAccounts([AccountTypeEnum::ASSET->value, AccountTypeEnum::DEFAULT->value]),
 | 
			
		||||
            'expense_accounts'       => $this->destroyAccounts([AccountTypeEnum::BENEFICIARY->value, AccountTypeEnum::EXPENSE->value]),
 | 
			
		||||
            'revenue_accounts'       => $this->destroyAccounts([AccountTypeEnum::REVENUE->value]),
 | 
			
		||||
            'liabilities'            => $this->destroyAccounts($liabilities),
 | 
			
		||||
            'transactions'           => $this->destroyTransactions($transactions),
 | 
			
		||||
            'withdrawals'            => $this->destroyTransactions([TransactionType::WITHDRAWAL]),
 | 
			
		||||
            'deposits'               => $this->destroyTransactions([TransactionType::DEPOSIT]),
 | 
			
		||||
            'transfers'              => $this->destroyTransactions([TransactionType::TRANSFER]),
 | 
			
		||||
            'withdrawals'            => $this->destroyTransactions([TransactionTypeEnum::WITHDRAWAL->value]),
 | 
			
		||||
            'deposits'               => $this->destroyTransactions([TransactionTypeEnum::DEPOSIT->value]),
 | 
			
		||||
            'transfers'              => $this->destroyTransactions([TransactionTypeEnum::TRANSFER->value]),
 | 
			
		||||
            default                  => throw new FireflyException(sprintf('200033: This endpoint can\'t handle object "%s"', $objects)),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -59,7 +59,7 @@ class ExportController extends Controller
 | 
			
		||||
     *
 | 
			
		||||
     * @throws FireflyException
 | 
			
		||||
     *
 | 
			
		||||
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 | 
			
		||||
     * @SuppressWarnings("PHPMD.UnusedFormalParameter")
 | 
			
		||||
     */
 | 
			
		||||
    public function accounts(ExportRequest $request): LaravelResponse
 | 
			
		||||
    {
 | 
			
		||||
@@ -88,7 +88,7 @@ class ExportController extends Controller
 | 
			
		||||
            ->header('Expires', '0')
 | 
			
		||||
            ->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
 | 
			
		||||
            ->header('Pragma', 'public')
 | 
			
		||||
            ->header('Content-Length', (string)strlen($data[$key]))
 | 
			
		||||
            ->header('Content-Length', (string) strlen($data[$key]))
 | 
			
		||||
        ;
 | 
			
		||||
 | 
			
		||||
        return $response;
 | 
			
		||||
@@ -100,7 +100,7 @@ class ExportController extends Controller
 | 
			
		||||
     *
 | 
			
		||||
     * @throws FireflyException
 | 
			
		||||
     *
 | 
			
		||||
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 | 
			
		||||
     * @SuppressWarnings("PHPMD.UnusedFormalParameter")
 | 
			
		||||
     */
 | 
			
		||||
    public function bills(ExportRequest $request): LaravelResponse
 | 
			
		||||
    {
 | 
			
		||||
@@ -115,7 +115,7 @@ class ExportController extends Controller
 | 
			
		||||
     *
 | 
			
		||||
     * @throws FireflyException
 | 
			
		||||
     *
 | 
			
		||||
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 | 
			
		||||
     * @SuppressWarnings("PHPMD.UnusedFormalParameter")
 | 
			
		||||
     */
 | 
			
		||||
    public function budgets(ExportRequest $request): LaravelResponse
 | 
			
		||||
    {
 | 
			
		||||
@@ -130,7 +130,7 @@ class ExportController extends Controller
 | 
			
		||||
     *
 | 
			
		||||
     * @throws FireflyException
 | 
			
		||||
     *
 | 
			
		||||
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 | 
			
		||||
     * @SuppressWarnings("PHPMD.UnusedFormalParameter")
 | 
			
		||||
     */
 | 
			
		||||
    public function categories(ExportRequest $request): LaravelResponse
 | 
			
		||||
    {
 | 
			
		||||
@@ -145,7 +145,7 @@ class ExportController extends Controller
 | 
			
		||||
     *
 | 
			
		||||
     * @throws FireflyException
 | 
			
		||||
     *
 | 
			
		||||
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 | 
			
		||||
     * @SuppressWarnings("PHPMD.UnusedFormalParameter")
 | 
			
		||||
     */
 | 
			
		||||
    public function piggyBanks(ExportRequest $request): LaravelResponse
 | 
			
		||||
    {
 | 
			
		||||
@@ -160,7 +160,7 @@ class ExportController extends Controller
 | 
			
		||||
     *
 | 
			
		||||
     * @throws FireflyException
 | 
			
		||||
     *
 | 
			
		||||
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 | 
			
		||||
     * @SuppressWarnings("PHPMD.UnusedFormalParameter")
 | 
			
		||||
     */
 | 
			
		||||
    public function recurring(ExportRequest $request): LaravelResponse
 | 
			
		||||
    {
 | 
			
		||||
@@ -175,7 +175,7 @@ class ExportController extends Controller
 | 
			
		||||
     *
 | 
			
		||||
     * @throws FireflyException
 | 
			
		||||
     *
 | 
			
		||||
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 | 
			
		||||
     * @SuppressWarnings("PHPMD.UnusedFormalParameter")
 | 
			
		||||
     */
 | 
			
		||||
    public function rules(ExportRequest $request): LaravelResponse
 | 
			
		||||
    {
 | 
			
		||||
@@ -190,7 +190,7 @@ class ExportController extends Controller
 | 
			
		||||
     *
 | 
			
		||||
     * @throws FireflyException
 | 
			
		||||
     *
 | 
			
		||||
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 | 
			
		||||
     * @SuppressWarnings("PHPMD.UnusedFormalParameter")
 | 
			
		||||
     */
 | 
			
		||||
    public function tags(ExportRequest $request): LaravelResponse
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * PurgeController.php
 | 
			
		||||
 * Copyright (c) 2022 james@firefly-iii.org
 | 
			
		||||
@@ -28,13 +29,13 @@ use FireflyIII\Models\Account;
 | 
			
		||||
use FireflyIII\Models\Bill;
 | 
			
		||||
use FireflyIII\Models\Budget;
 | 
			
		||||
use FireflyIII\Models\Category;
 | 
			
		||||
use FireflyIII\Models\PiggyBank;
 | 
			
		||||
use FireflyIII\Models\Recurrence;
 | 
			
		||||
use FireflyIII\Models\Rule;
 | 
			
		||||
use FireflyIII\Models\RuleGroup;
 | 
			
		||||
use FireflyIII\Models\Tag;
 | 
			
		||||
use FireflyIII\Models\TransactionGroup;
 | 
			
		||||
use FireflyIII\Models\TransactionJournal;
 | 
			
		||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
 | 
			
		||||
use FireflyIII\User;
 | 
			
		||||
use Illuminate\Http\JsonResponse;
 | 
			
		||||
 | 
			
		||||
@@ -51,7 +52,7 @@ class PurgeController extends Controller
 | 
			
		||||
    public function purge(): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
        /** @var User $user */
 | 
			
		||||
        $user = auth()->user();
 | 
			
		||||
        $user       = auth()->user();
 | 
			
		||||
 | 
			
		||||
        // some manual code, too lazy to call all repositories.
 | 
			
		||||
 | 
			
		||||
@@ -62,14 +63,17 @@ class PurgeController extends Controller
 | 
			
		||||
        Bill::whereUserId($user->id)->onlyTrashed()->forceDelete();
 | 
			
		||||
 | 
			
		||||
        // piggies
 | 
			
		||||
        $set  = PiggyBank::leftJoin('accounts', 'accounts.id', 'piggy_banks.account_id')
 | 
			
		||||
            ->where('accounts.user_id', $user->id)->onlyTrashed()->get(['piggy_banks.*'])
 | 
			
		||||
        ;
 | 
			
		||||
 | 
			
		||||
        /** @var PiggyBank $piggy */
 | 
			
		||||
        foreach ($set as $piggy) {
 | 
			
		||||
            $piggy->forceDelete();
 | 
			
		||||
        }
 | 
			
		||||
        $repository = app(PiggyBankRepositoryInterface::class);
 | 
			
		||||
        $repository->setUser($user);
 | 
			
		||||
        $repository->purgeAll();
 | 
			
		||||
        //        $set  = PiggyBank::leftJoin('accounts', 'accounts.id', 'piggy_banks.account_id')
 | 
			
		||||
        //            ->where('accounts.user_id', $user->id)->onlyTrashed()->get(['piggy_banks.*'])
 | 
			
		||||
        //        ;
 | 
			
		||||
        //
 | 
			
		||||
        //        /** @var PiggyBank $piggy */
 | 
			
		||||
        //        foreach ($set as $piggy) {
 | 
			
		||||
        //            $piggy->forceDelete();
 | 
			
		||||
        //        }
 | 
			
		||||
 | 
			
		||||
        // rule group
 | 
			
		||||
        RuleGroup::whereUserId($user->id)->onlyTrashed()->forceDelete();
 | 
			
		||||
 
 | 
			
		||||
@@ -79,11 +79,11 @@ class AccountController extends Controller
 | 
			
		||||
        /** @var array $expense */
 | 
			
		||||
        foreach ($expenses as $expense) {
 | 
			
		||||
            $result[] = [
 | 
			
		||||
                'id'               => (string)$expense['id'],
 | 
			
		||||
                'id'               => (string) $expense['id'],
 | 
			
		||||
                'name'             => $expense['name'],
 | 
			
		||||
                'difference'       => $expense['sum'],
 | 
			
		||||
                'difference_float' => (float)$expense['sum'], // intentional float
 | 
			
		||||
                'currency_id'      => (string)$expense['currency_id'],
 | 
			
		||||
                'difference_float' => (float) $expense['sum'], // intentional float
 | 
			
		||||
                'currency_id'      => (string) $expense['currency_id'],
 | 
			
		||||
                'currency_code'    => $expense['currency_code'],
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
@@ -107,11 +107,11 @@ class AccountController extends Controller
 | 
			
		||||
        /** @var array $expense */
 | 
			
		||||
        foreach ($expenses as $expense) {
 | 
			
		||||
            $result[] = [
 | 
			
		||||
                'id'               => (string)$expense['id'],
 | 
			
		||||
                'id'               => (string) $expense['id'],
 | 
			
		||||
                'name'             => $expense['name'],
 | 
			
		||||
                'difference'       => $expense['sum'],
 | 
			
		||||
                'difference_float' => (float)$expense['sum'], // intentional float
 | 
			
		||||
                'currency_id'      => (string)$expense['currency_id'],
 | 
			
		||||
                'difference_float' => (float) $expense['sum'], // intentional float
 | 
			
		||||
                'currency_id'      => (string) $expense['currency_id'],
 | 
			
		||||
                'currency_code'    => $expense['currency_code'],
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -26,10 +26,12 @@ namespace FireflyIII\Api\V1\Controllers\Insight\Expense;
 | 
			
		||||
 | 
			
		||||
use FireflyIII\Api\V1\Controllers\Controller;
 | 
			
		||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
 | 
			
		||||
use FireflyIII\Enums\TransactionTypeEnum;
 | 
			
		||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
 | 
			
		||||
use FireflyIII\Models\TransactionType;
 | 
			
		||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
 | 
			
		||||
use FireflyIII\Support\Facades\Amount;
 | 
			
		||||
use Illuminate\Http\JsonResponse;
 | 
			
		||||
use Illuminate\Support\Facades\Log;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class BillController
 | 
			
		||||
@@ -63,11 +65,13 @@ class BillController extends Controller
 | 
			
		||||
     */
 | 
			
		||||
    public function bill(GenericRequest $request): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
        $accounts   = $request->getAssetAccounts();
 | 
			
		||||
        $bills      = $request->getBills();
 | 
			
		||||
        $start      = $request->getStart();
 | 
			
		||||
        $end        = $request->getEnd();
 | 
			
		||||
        $response   = [];
 | 
			
		||||
        $accounts        = $request->getAssetAccounts();
 | 
			
		||||
        $bills           = $request->getBills();
 | 
			
		||||
        $start           = $request->getStart();
 | 
			
		||||
        $end             = $request->getEnd();
 | 
			
		||||
        $convertToNative = Amount::convertToNative();
 | 
			
		||||
        $default         = Amount::getNativeCurrency();
 | 
			
		||||
        $response        = [];
 | 
			
		||||
 | 
			
		||||
        // get all bills:
 | 
			
		||||
        if (0 === $bills->count()) {
 | 
			
		||||
@@ -75,39 +79,42 @@ class BillController extends Controller
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // collect all expenses in this period (regardless of type) by the given bills and accounts.
 | 
			
		||||
        $collector  = app(GroupCollectorInterface::class);
 | 
			
		||||
        $collector->setTypes([TransactionType::WITHDRAWAL])->setRange($start, $end)->setSourceAccounts($accounts);
 | 
			
		||||
        $collector       = app(GroupCollectorInterface::class);
 | 
			
		||||
        $collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setRange($start, $end)->setSourceAccounts($accounts);
 | 
			
		||||
        $collector->setBills($bills);
 | 
			
		||||
 | 
			
		||||
        $genericSet = $collector->getExtractedJournals();
 | 
			
		||||
        $genericSet      = $collector->getExtractedJournals();
 | 
			
		||||
        foreach ($genericSet as $journal) {
 | 
			
		||||
            $billId            = (int)$journal['bill_id'];
 | 
			
		||||
            $currencyId        = (int)$journal['currency_id'];
 | 
			
		||||
            $foreignCurrencyId = (int)$journal['foreign_currency_id'];
 | 
			
		||||
            $key               = sprintf('%d-%d', $billId, $currencyId);
 | 
			
		||||
            $foreignKey        = sprintf('%d-%d', $billId, $foreignCurrencyId);
 | 
			
		||||
            $billId       = (int) $journal['bill_id'];
 | 
			
		||||
            $currencyId   = (int) $journal['currency_id'];
 | 
			
		||||
            $currencyCode = $journal['currency_code'];
 | 
			
		||||
            $field        = 'amount';
 | 
			
		||||
 | 
			
		||||
            // use the native amount if the user wants to convert to native currency
 | 
			
		||||
            if ($convertToNative && $currencyId !== $default->id) {
 | 
			
		||||
                $currencyId   = $default->id;
 | 
			
		||||
                $currencyCode = $default->code;
 | 
			
		||||
                $field        = 'native_amount';
 | 
			
		||||
            }
 | 
			
		||||
            // use foreign amount when the foreign currency IS the default currency.
 | 
			
		||||
            if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) {
 | 
			
		||||
                $field = 'foreign_amount';
 | 
			
		||||
            }
 | 
			
		||||
            Log::debug(sprintf('Journal #%d in bill #%d will use %s (%s %s)', $journal['transaction_group_id'], $billId, $field, $currencyCode, $journal[$field] ?? '0'));
 | 
			
		||||
 | 
			
		||||
            $key          = sprintf('%d-%d', $billId, $currencyId);
 | 
			
		||||
 | 
			
		||||
            if (0 !== $currencyId) {
 | 
			
		||||
                $response[$key] ??= [
 | 
			
		||||
                    'id'               => (string)$billId,
 | 
			
		||||
                    'id'               => (string) $billId,
 | 
			
		||||
                    'name'             => $journal['bill_name'],
 | 
			
		||||
                    'difference'       => '0',
 | 
			
		||||
                    'difference_float' => 0,
 | 
			
		||||
                    'currency_id'      => (string)$currencyId,
 | 
			
		||||
                    'currency_code'    => $journal['currency_code'],
 | 
			
		||||
                    'currency_id'      => (string) $currencyId,
 | 
			
		||||
                    'currency_code'    => $currencyCode,
 | 
			
		||||
                ];
 | 
			
		||||
                $response[$key]['difference']       = bcadd($response[$key]['difference'], $journal['amount']);
 | 
			
		||||
                $response[$key]['difference_float'] = (float)$response[$key]['difference']; // intentional float
 | 
			
		||||
            }
 | 
			
		||||
            if (0 !== $foreignCurrencyId) {
 | 
			
		||||
                $response[$foreignKey] ??= [
 | 
			
		||||
                    'difference'       => '0',
 | 
			
		||||
                    'difference_float' => 0,
 | 
			
		||||
                    'currency_id'      => (string)$foreignCurrencyId,
 | 
			
		||||
                    'currency_code'    => $journal['foreign_currency_code'],
 | 
			
		||||
                ];
 | 
			
		||||
                $response[$foreignKey]['difference']       = bcadd($response[$foreignKey]['difference'], $journal['foreign_amount']);
 | 
			
		||||
                $response[$foreignKey]['difference_float'] = (float)$response[$foreignKey]['difference']; // intentional float
 | 
			
		||||
                $response[$key]['difference']       = bcadd($response[$key]['difference'], (string) ($journal[$field] ?? '0'));
 | 
			
		||||
                $response[$key]['difference_float'] = (float) $response[$key]['difference']; // intentional float
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -122,41 +129,46 @@ class BillController extends Controller
 | 
			
		||||
     */
 | 
			
		||||
    public function noBill(GenericRequest $request): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
        $accounts   = $request->getAssetAccounts();
 | 
			
		||||
        $start      = $request->getStart();
 | 
			
		||||
        $end        = $request->getEnd();
 | 
			
		||||
        $response   = [];
 | 
			
		||||
        $accounts        = $request->getAssetAccounts();
 | 
			
		||||
        $start           = $request->getStart();
 | 
			
		||||
        $end             = $request->getEnd();
 | 
			
		||||
        $convertToNative = Amount::convertToNative();
 | 
			
		||||
        $default         = Amount::getNativeCurrency();
 | 
			
		||||
        $response        = [];
 | 
			
		||||
 | 
			
		||||
        // collect all expenses in this period (regardless of type) by the given bills and accounts.
 | 
			
		||||
        $collector  = app(GroupCollectorInterface::class);
 | 
			
		||||
        $collector->setTypes([TransactionType::WITHDRAWAL])->setRange($start, $end)->setSourceAccounts($accounts);
 | 
			
		||||
        $collector       = app(GroupCollectorInterface::class);
 | 
			
		||||
        $collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setRange($start, $end)->setSourceAccounts($accounts);
 | 
			
		||||
        $collector->withoutBill();
 | 
			
		||||
 | 
			
		||||
        $genericSet = $collector->getExtractedJournals();
 | 
			
		||||
        $genericSet      = $collector->getExtractedJournals();
 | 
			
		||||
 | 
			
		||||
        foreach ($genericSet as $journal) {
 | 
			
		||||
            $currencyId        = (int)$journal['currency_id'];
 | 
			
		||||
            $foreignCurrencyId = (int)$journal['foreign_currency_id'];
 | 
			
		||||
            $currencyId   = (int) $journal['currency_id'];
 | 
			
		||||
            $currencyCode = $journal['currency_code'];
 | 
			
		||||
            $field        = 'amount';
 | 
			
		||||
 | 
			
		||||
            // use the native amount if the user wants to convert to native currency
 | 
			
		||||
            if ($convertToNative && $currencyId !== $default->id) {
 | 
			
		||||
                $currencyId   = $default->id;
 | 
			
		||||
                $currencyCode = $default->code;
 | 
			
		||||
                $field        = 'native_amount';
 | 
			
		||||
            }
 | 
			
		||||
            // use foreign amount when the foreign currency IS the default currency.
 | 
			
		||||
            if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) {
 | 
			
		||||
                $field = 'foreign_amount';
 | 
			
		||||
            }
 | 
			
		||||
            Log::debug(sprintf('Journal #%d will use %s (%s %s)', $journal['transaction_group_id'], $field, $currencyCode, $journal[$field] ?? '0'));
 | 
			
		||||
 | 
			
		||||
            if (0 !== $currencyId) {
 | 
			
		||||
                $response[$currencyId] ??= [
 | 
			
		||||
                    'difference'       => '0',
 | 
			
		||||
                    'difference_float' => 0,
 | 
			
		||||
                    'currency_id'      => (string)$currencyId,
 | 
			
		||||
                    'currency_code'    => $journal['currency_code'],
 | 
			
		||||
                    'currency_id'      => (string) $currencyId,
 | 
			
		||||
                    'currency_code'    => $currencyCode,
 | 
			
		||||
                ];
 | 
			
		||||
                $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], $journal['amount']);
 | 
			
		||||
                $response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference']; // intentional float
 | 
			
		||||
            }
 | 
			
		||||
            if (0 !== $foreignCurrencyId) {
 | 
			
		||||
                $response[$foreignCurrencyId] ??= [
 | 
			
		||||
                    'difference'       => '0',
 | 
			
		||||
                    'difference_float' => 0,
 | 
			
		||||
                    'currency_id'      => (string)$foreignCurrencyId,
 | 
			
		||||
                    'currency_code'    => $journal['foreign_currency_code'],
 | 
			
		||||
                ];
 | 
			
		||||
                $response[$foreignCurrencyId]['difference']       = bcadd($response[$foreignCurrencyId]['difference'], $journal['foreign_amount']);
 | 
			
		||||
                $response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference']; // intentional float
 | 
			
		||||
                $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], (string) ($journal[$field] ?? '0'));
 | 
			
		||||
                $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // intentional float
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * BudgetController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
@@ -84,11 +85,11 @@ class BudgetController extends Controller
 | 
			
		||||
            /** @var array $expense */
 | 
			
		||||
            foreach ($expenses as $expense) {
 | 
			
		||||
                $result[] = [
 | 
			
		||||
                    'id'               => (string)$budget->id,
 | 
			
		||||
                    'id'               => (string) $budget->id,
 | 
			
		||||
                    'name'             => $budget->name,
 | 
			
		||||
                    'difference'       => $expense['sum'],
 | 
			
		||||
                    'difference_float' => (float)$expense['sum'], // intentional float
 | 
			
		||||
                    'currency_id'      => (string)$expense['currency_id'],
 | 
			
		||||
                    'difference_float' => (float) $expense['sum'], // intentional float
 | 
			
		||||
                    'currency_id'      => (string) $expense['currency_id'],
 | 
			
		||||
                    'currency_code'    => $expense['currency_code'],
 | 
			
		||||
                ];
 | 
			
		||||
            }
 | 
			
		||||
@@ -113,8 +114,8 @@ class BudgetController extends Controller
 | 
			
		||||
        foreach ($expenses as $expense) {
 | 
			
		||||
            $result[] = [
 | 
			
		||||
                'difference'       => $expense['sum'],
 | 
			
		||||
                'difference_float' => (float)$expense['sum'], // intentional float
 | 
			
		||||
                'currency_id'      => (string)$expense['currency_id'],
 | 
			
		||||
                'difference_float' => (float) $expense['sum'], // intentional float
 | 
			
		||||
                'currency_id'      => (string) $expense['currency_id'],
 | 
			
		||||
                'currency_code'    => $expense['currency_code'],
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -85,11 +85,11 @@ class CategoryController extends Controller
 | 
			
		||||
            /** @var array $expense */
 | 
			
		||||
            foreach ($expenses as $expense) {
 | 
			
		||||
                $result[] = [
 | 
			
		||||
                    'id'               => (string)$category->id,
 | 
			
		||||
                    'id'               => (string) $category->id,
 | 
			
		||||
                    'name'             => $category->name,
 | 
			
		||||
                    'difference'       => $expense['sum'],
 | 
			
		||||
                    'difference_float' => (float)$expense['sum'], // intentional float
 | 
			
		||||
                    'currency_id'      => (string)$expense['currency_id'],
 | 
			
		||||
                    'difference_float' => (float) $expense['sum'], // intentional float
 | 
			
		||||
                    'currency_id'      => (string) $expense['currency_id'],
 | 
			
		||||
                    'currency_code'    => $expense['currency_code'],
 | 
			
		||||
                ];
 | 
			
		||||
            }
 | 
			
		||||
@@ -114,8 +114,8 @@ class CategoryController extends Controller
 | 
			
		||||
        foreach ($expenses as $expense) {
 | 
			
		||||
            $result[] = [
 | 
			
		||||
                'difference'       => $expense['sum'],
 | 
			
		||||
                'difference_float' => (float)$expense['sum'], // intentional float
 | 
			
		||||
                'currency_id'      => (string)$expense['currency_id'],
 | 
			
		||||
                'difference_float' => (float) $expense['sum'], // intentional float
 | 
			
		||||
                'currency_id'      => (string) $expense['currency_id'],
 | 
			
		||||
                'currency_code'    => $expense['currency_code'],
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * PeriodController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
@@ -25,9 +26,11 @@ namespace FireflyIII\Api\V1\Controllers\Insight\Expense;
 | 
			
		||||
 | 
			
		||||
use FireflyIII\Api\V1\Controllers\Controller;
 | 
			
		||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
 | 
			
		||||
use FireflyIII\Enums\TransactionTypeEnum;
 | 
			
		||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
 | 
			
		||||
use FireflyIII\Models\TransactionType;
 | 
			
		||||
use FireflyIII\Support\Facades\Amount;
 | 
			
		||||
use Illuminate\Http\JsonResponse;
 | 
			
		||||
use Illuminate\Support\Facades\Log;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class PeriodController
 | 
			
		||||
@@ -40,39 +43,49 @@ class PeriodController extends Controller
 | 
			
		||||
     */
 | 
			
		||||
    public function total(GenericRequest $request): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
        $accounts   = $request->getAssetAccounts();
 | 
			
		||||
        $start      = $request->getStart();
 | 
			
		||||
        $end        = $request->getEnd();
 | 
			
		||||
        $response   = [];
 | 
			
		||||
        $accounts        = $request->getAssetAccounts();
 | 
			
		||||
        $start           = $request->getStart();
 | 
			
		||||
        $end             = $request->getEnd();
 | 
			
		||||
        $response        = [];
 | 
			
		||||
        $convertToNative = Amount::convertToNative();
 | 
			
		||||
        $default         = Amount::getNativeCurrency();
 | 
			
		||||
 | 
			
		||||
        // collect all expenses in this period (regardless of type)
 | 
			
		||||
        $collector  = app(GroupCollectorInterface::class);
 | 
			
		||||
        $collector->setTypes([TransactionType::WITHDRAWAL])->setRange($start, $end)->setSourceAccounts($accounts);
 | 
			
		||||
        $genericSet = $collector->getExtractedJournals();
 | 
			
		||||
        $collector       = app(GroupCollectorInterface::class);
 | 
			
		||||
        $collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setRange($start, $end)->setSourceAccounts($accounts);
 | 
			
		||||
        $genericSet      = $collector->getExtractedJournals();
 | 
			
		||||
        foreach ($genericSet as $journal) {
 | 
			
		||||
            $currencyId        = (int)$journal['currency_id'];
 | 
			
		||||
            $foreignCurrencyId = (int)$journal['foreign_currency_id'];
 | 
			
		||||
            // same code as many other sumExpense methods. I think this needs some kind of generic method.
 | 
			
		||||
            $amount                                    = '0';
 | 
			
		||||
            $currencyId                                = (int) $journal['currency_id'];
 | 
			
		||||
            $currencyCode                              = $journal['currency_code'];
 | 
			
		||||
            if ($convertToNative) {
 | 
			
		||||
                $amount = Amount::getAmountFromJournal($journal);
 | 
			
		||||
                if ($default->id !== (int) $journal['currency_id'] && $default->id !== (int) $journal['foreign_currency_id']) {
 | 
			
		||||
                    $currencyId   = $default->id;
 | 
			
		||||
                    $currencyCode = $default->code;
 | 
			
		||||
                }
 | 
			
		||||
                if ($default->id !== (int) $journal['currency_id'] && $default->id === (int) $journal['foreign_currency_id']) {
 | 
			
		||||
                    $currencyId   = $journal['foreign_currency_id'];
 | 
			
		||||
                    $currencyCode = $journal['foreign_currency_code'];
 | 
			
		||||
                }
 | 
			
		||||
                Log::debug(sprintf('[a] Add amount %s %s', $currencyCode, $amount));
 | 
			
		||||
            }
 | 
			
		||||
            if (!$convertToNative) {
 | 
			
		||||
                // ignore the amount in foreign currency.
 | 
			
		||||
                Log::debug(sprintf('[b] Add amount %s %s', $currencyCode, $journal['amount']));
 | 
			
		||||
                $amount = $journal['amount'];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (0 !== $currencyId) {
 | 
			
		||||
                $response[$currencyId] ??= [
 | 
			
		||||
                    'difference'       => '0',
 | 
			
		||||
                    'difference_float' => 0,
 | 
			
		||||
                    'currency_id'      => (string)$currencyId,
 | 
			
		||||
                    'currency_code'    => $journal['currency_code'],
 | 
			
		||||
                ];
 | 
			
		||||
                $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], $journal['amount']);
 | 
			
		||||
                $response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference']; // intentional float
 | 
			
		||||
            }
 | 
			
		||||
            if (0 !== $foreignCurrencyId) {
 | 
			
		||||
                $response[$foreignCurrencyId] ??= [
 | 
			
		||||
                    'difference'       => '0',
 | 
			
		||||
                    'difference_float' => 0,
 | 
			
		||||
                    'currency_id'      => (string)$foreignCurrencyId,
 | 
			
		||||
                    'currency_code'    => $journal['foreign_currency_code'],
 | 
			
		||||
                ];
 | 
			
		||||
                $response[$foreignCurrencyId]['difference']       = bcadd($response[$foreignCurrencyId]['difference'], $journal['foreign_amount']);
 | 
			
		||||
                $response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference']; // intentional float
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $response[$currencyId] ??= [
 | 
			
		||||
                'difference'       => '0',
 | 
			
		||||
                'difference_float' => 0,
 | 
			
		||||
                'currency_id'      => (string) $currencyId,
 | 
			
		||||
                'currency_code'    => $currencyCode,
 | 
			
		||||
            ];
 | 
			
		||||
            $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], $amount);
 | 
			
		||||
            $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // intentional float
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response()->json(array_values($response));
 | 
			
		||||
 
 | 
			
		||||
@@ -26,10 +26,12 @@ namespace FireflyIII\Api\V1\Controllers\Insight\Expense;
 | 
			
		||||
 | 
			
		||||
use FireflyIII\Api\V1\Controllers\Controller;
 | 
			
		||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
 | 
			
		||||
use FireflyIII\Enums\TransactionTypeEnum;
 | 
			
		||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
 | 
			
		||||
use FireflyIII\Models\TransactionType;
 | 
			
		||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
 | 
			
		||||
use FireflyIII\Support\Facades\Amount;
 | 
			
		||||
use Illuminate\Http\JsonResponse;
 | 
			
		||||
use Illuminate\Support\Facades\Log;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class TagController
 | 
			
		||||
@@ -62,42 +64,51 @@ class TagController extends Controller
 | 
			
		||||
     */
 | 
			
		||||
    public function noTag(GenericRequest $request): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
        $accounts   = $request->getAssetAccounts();
 | 
			
		||||
        $start      = $request->getStart();
 | 
			
		||||
        $end        = $request->getEnd();
 | 
			
		||||
        $response   = [];
 | 
			
		||||
        $accounts        = $request->getAssetAccounts();
 | 
			
		||||
        $start           = $request->getStart();
 | 
			
		||||
        $end             = $request->getEnd();
 | 
			
		||||
        $response        = [];
 | 
			
		||||
        $convertToNative = Amount::convertToNative();
 | 
			
		||||
        $default         = Amount::getNativeCurrency();
 | 
			
		||||
 | 
			
		||||
        // collect all expenses in this period (regardless of type) by the given bills and accounts.
 | 
			
		||||
        $collector  = app(GroupCollectorInterface::class);
 | 
			
		||||
        $collector->setTypes([TransactionType::WITHDRAWAL])->setRange($start, $end)->setSourceAccounts($accounts);
 | 
			
		||||
        $collector       = app(GroupCollectorInterface::class);
 | 
			
		||||
        $collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setRange($start, $end)->setSourceAccounts($accounts);
 | 
			
		||||
        $collector->withoutTags();
 | 
			
		||||
 | 
			
		||||
        $genericSet = $collector->getExtractedJournals();
 | 
			
		||||
        $genericSet      = $collector->getExtractedJournals();
 | 
			
		||||
 | 
			
		||||
        foreach ($genericSet as $journal) {
 | 
			
		||||
            $currencyId        = (int)$journal['currency_id'];
 | 
			
		||||
            $foreignCurrencyId = (int)$journal['foreign_currency_id'];
 | 
			
		||||
            // same code as many other sumExpense methods. I think this needs some kind of generic method.
 | 
			
		||||
            $amount                                    = '0';
 | 
			
		||||
            $currencyId                                = (int) $journal['currency_id'];
 | 
			
		||||
            $currencyCode                              = $journal['currency_code'];
 | 
			
		||||
            if ($convertToNative) {
 | 
			
		||||
                $amount = Amount::getAmountFromJournal($journal);
 | 
			
		||||
                if ($default->id !== (int) $journal['currency_id'] && $default->id !== (int) $journal['foreign_currency_id']) {
 | 
			
		||||
                    $currencyId   = $default->id;
 | 
			
		||||
                    $currencyCode = $default->code;
 | 
			
		||||
                }
 | 
			
		||||
                if ($default->id !== (int) $journal['currency_id'] && $default->id === (int) $journal['foreign_currency_id']) {
 | 
			
		||||
                    $currencyId   = $journal['foreign_currency_id'];
 | 
			
		||||
                    $currencyCode = $journal['foreign_currency_code'];
 | 
			
		||||
                }
 | 
			
		||||
                Log::debug(sprintf('[a] Add amount %s %s', $currencyCode, $amount));
 | 
			
		||||
            }
 | 
			
		||||
            if (!$convertToNative) {
 | 
			
		||||
                // ignore the amount in foreign currency.
 | 
			
		||||
                Log::debug(sprintf('[b] Add amount %s %s', $currencyCode, $journal['amount']));
 | 
			
		||||
                $amount = $journal['amount'];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (0 !== $currencyId) {
 | 
			
		||||
                $response[$currencyId] ??= [
 | 
			
		||||
                    'difference'       => '0',
 | 
			
		||||
                    'difference_float' => 0,
 | 
			
		||||
                    'currency_id'      => (string)$currencyId,
 | 
			
		||||
                    'currency_code'    => $journal['currency_code'],
 | 
			
		||||
                ];
 | 
			
		||||
                $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], $journal['amount']);
 | 
			
		||||
                $response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference']; // float but on purpose.
 | 
			
		||||
            }
 | 
			
		||||
            if (0 !== $foreignCurrencyId) {
 | 
			
		||||
                $response[$foreignCurrencyId] ??= [
 | 
			
		||||
                    'difference'       => '0',
 | 
			
		||||
                    'difference_float' => 0,
 | 
			
		||||
                    'currency_id'      => (string)$foreignCurrencyId,
 | 
			
		||||
                    'currency_code'    => $journal['foreign_currency_code'],
 | 
			
		||||
                ];
 | 
			
		||||
                $response[$foreignCurrencyId]['difference']       = bcadd($response[$foreignCurrencyId]['difference'], $journal['foreign_amount']);
 | 
			
		||||
                $response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference']; // float but on purpose.
 | 
			
		||||
            }
 | 
			
		||||
            $response[$currencyId] ??= [
 | 
			
		||||
                'difference'       => '0',
 | 
			
		||||
                'difference_float' => 0,
 | 
			
		||||
                'currency_id'      => (string) $currencyId,
 | 
			
		||||
                'currency_code'    => $currencyCode,
 | 
			
		||||
            ];
 | 
			
		||||
            $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], $amount);
 | 
			
		||||
            $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose.
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response()->json(array_values($response));
 | 
			
		||||
@@ -124,14 +135,14 @@ class TagController extends Controller
 | 
			
		||||
 | 
			
		||||
        // collect all expenses in this period (regardless of type) by the given bills and accounts.
 | 
			
		||||
        $collector  = app(GroupCollectorInterface::class);
 | 
			
		||||
        $collector->setTypes([TransactionType::WITHDRAWAL])->setRange($start, $end)->setSourceAccounts($accounts);
 | 
			
		||||
        $collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setRange($start, $end)->setSourceAccounts($accounts);
 | 
			
		||||
        $collector->setTags($tags);
 | 
			
		||||
        $genericSet = $collector->getExtractedJournals();
 | 
			
		||||
 | 
			
		||||
        /** @var array $journal */
 | 
			
		||||
        foreach ($genericSet as $journal) {
 | 
			
		||||
            $currencyId        = (int)$journal['currency_id'];
 | 
			
		||||
            $foreignCurrencyId = (int)$journal['foreign_currency_id'];
 | 
			
		||||
            $currencyId        = (int) $journal['currency_id'];
 | 
			
		||||
            $foreignCurrencyId = (int) $journal['foreign_currency_id'];
 | 
			
		||||
 | 
			
		||||
            /** @var array $tag */
 | 
			
		||||
            foreach ($journal['tags'] as $tag) {
 | 
			
		||||
@@ -142,15 +153,15 @@ class TagController extends Controller
 | 
			
		||||
                // on currency ID
 | 
			
		||||
                if (0 !== $currencyId) {
 | 
			
		||||
                    $response[$key] ??= [
 | 
			
		||||
                        'id'               => (string)$tagId,
 | 
			
		||||
                        'id'               => (string) $tagId,
 | 
			
		||||
                        'name'             => $tag['name'],
 | 
			
		||||
                        'difference'       => '0',
 | 
			
		||||
                        'difference_float' => 0,
 | 
			
		||||
                        'currency_id'      => (string)$currencyId,
 | 
			
		||||
                        'currency_id'      => (string) $currencyId,
 | 
			
		||||
                        'currency_code'    => $journal['currency_code'],
 | 
			
		||||
                    ];
 | 
			
		||||
                    $response[$key]['difference']       = bcadd($response[$key]['difference'], $journal['amount']);
 | 
			
		||||
                    $response[$key]['difference_float'] = (float)$response[$key]['difference']; // float but on purpose.
 | 
			
		||||
                    $response[$key]['difference_float'] = (float) $response[$key]['difference']; // float but on purpose.
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // on foreign ID
 | 
			
		||||
@@ -158,11 +169,11 @@ class TagController extends Controller
 | 
			
		||||
                    $response[$foreignKey]                     = $journal[$foreignKey] ?? [
 | 
			
		||||
                        'difference'       => '0',
 | 
			
		||||
                        'difference_float' => 0,
 | 
			
		||||
                        'currency_id'      => (string)$foreignCurrencyId,
 | 
			
		||||
                        'currency_id'      => (string) $foreignCurrencyId,
 | 
			
		||||
                        'currency_code'    => $journal['foreign_currency_code'],
 | 
			
		||||
                    ];
 | 
			
		||||
                    $response[$foreignKey]['difference']       = bcadd($response[$foreignKey]['difference'], $journal['foreign_amount']);
 | 
			
		||||
                    $response[$foreignKey]['difference_float'] = (float)$response[$foreignKey]['difference']; // float but on purpose.
 | 
			
		||||
                    $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // float but on purpose.
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -73,17 +73,18 @@ class AccountController extends Controller
 | 
			
		||||
        $start         = $request->getStart();
 | 
			
		||||
        $end           = $request->getEnd();
 | 
			
		||||
        $assetAccounts = $request->getAssetAccounts();
 | 
			
		||||
 | 
			
		||||
        $income        = $this->opsRepository->sumIncomeByDestination($start, $end, $assetAccounts);
 | 
			
		||||
        $result        = [];
 | 
			
		||||
 | 
			
		||||
        /** @var array $entry */
 | 
			
		||||
        foreach ($income as $entry) {
 | 
			
		||||
            $result[] = [
 | 
			
		||||
                'id'               => (string)$entry['id'],
 | 
			
		||||
                'id'               => (string) $entry['id'],
 | 
			
		||||
                'name'             => $entry['name'],
 | 
			
		||||
                'difference'       => $entry['sum'],
 | 
			
		||||
                'difference_float' => (float)$entry['sum'], // float but on purpose.
 | 
			
		||||
                'currency_id'      => (string)$entry['currency_id'],
 | 
			
		||||
                'difference_float' => (float) $entry['sum'], // float but on purpose.
 | 
			
		||||
                'currency_id'      => (string) $entry['currency_id'],
 | 
			
		||||
                'currency_code'    => $entry['currency_code'],
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
@@ -107,11 +108,11 @@ class AccountController extends Controller
 | 
			
		||||
        /** @var array $entry */
 | 
			
		||||
        foreach ($income as $entry) {
 | 
			
		||||
            $result[] = [
 | 
			
		||||
                'id'               => (string)$entry['id'],
 | 
			
		||||
                'id'               => (string) $entry['id'],
 | 
			
		||||
                'name'             => $entry['name'],
 | 
			
		||||
                'difference'       => $entry['sum'],
 | 
			
		||||
                'difference_float' => (float)$entry['sum'], // float but on purpose.
 | 
			
		||||
                'currency_id'      => (string)$entry['currency_id'],
 | 
			
		||||
                'difference_float' => (float) $entry['sum'], // float but on purpose.
 | 
			
		||||
                'currency_id'      => (string) $entry['currency_id'],
 | 
			
		||||
                'currency_code'    => $entry['currency_code'],
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -85,11 +85,11 @@ class CategoryController extends Controller
 | 
			
		||||
            /** @var array $expense */
 | 
			
		||||
            foreach ($expenses as $expense) {
 | 
			
		||||
                $result[] = [
 | 
			
		||||
                    'id'               => (string)$category->id,
 | 
			
		||||
                    'id'               => (string) $category->id,
 | 
			
		||||
                    'name'             => $category->name,
 | 
			
		||||
                    'difference'       => $expense['sum'],
 | 
			
		||||
                    'difference_float' => (float)$expense['sum'], // float but on purpose.
 | 
			
		||||
                    'currency_id'      => (string)$expense['currency_id'],
 | 
			
		||||
                    'difference_float' => (float) $expense['sum'], // float but on purpose.
 | 
			
		||||
                    'currency_id'      => (string) $expense['currency_id'],
 | 
			
		||||
                    'currency_code'    => $expense['currency_code'],
 | 
			
		||||
                ];
 | 
			
		||||
            }
 | 
			
		||||
@@ -114,8 +114,8 @@ class CategoryController extends Controller
 | 
			
		||||
        foreach ($expenses as $expense) {
 | 
			
		||||
            $result[] = [
 | 
			
		||||
                'difference'       => $expense['sum'],
 | 
			
		||||
                'difference_float' => (float)$expense['sum'], // float but on purpose.
 | 
			
		||||
                'currency_id'      => (string)$expense['currency_id'],
 | 
			
		||||
                'difference_float' => (float) $expense['sum'], // float but on purpose.
 | 
			
		||||
                'currency_id'      => (string) $expense['currency_id'],
 | 
			
		||||
                'currency_code'    => $expense['currency_code'],
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * PeriodController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
@@ -25,8 +26,9 @@ namespace FireflyIII\Api\V1\Controllers\Insight\Income;
 | 
			
		||||
 | 
			
		||||
use FireflyIII\Api\V1\Controllers\Controller;
 | 
			
		||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
 | 
			
		||||
use FireflyIII\Enums\TransactionTypeEnum;
 | 
			
		||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
 | 
			
		||||
use FireflyIII\Models\TransactionType;
 | 
			
		||||
use FireflyIII\Support\Facades\Amount;
 | 
			
		||||
use Illuminate\Http\JsonResponse;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -40,42 +42,41 @@ class PeriodController extends Controller
 | 
			
		||||
     */
 | 
			
		||||
    public function total(GenericRequest $request): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
        $accounts   = $request->getAssetAccounts();
 | 
			
		||||
        $start      = $request->getStart();
 | 
			
		||||
        $end        = $request->getEnd();
 | 
			
		||||
        $response   = [];
 | 
			
		||||
        $accounts        = $request->getAssetAccounts();
 | 
			
		||||
        $start           = $request->getStart();
 | 
			
		||||
        $end             = $request->getEnd();
 | 
			
		||||
        $response        = [];
 | 
			
		||||
        $convertToNative = Amount::convertToNative();
 | 
			
		||||
        $default         = Amount::getNativeCurrency();
 | 
			
		||||
 | 
			
		||||
        // collect all expenses in this period (regardless of type)
 | 
			
		||||
        $collector  = app(GroupCollectorInterface::class);
 | 
			
		||||
        $collector->setTypes([TransactionType::DEPOSIT])->setRange($start, $end)->setDestinationAccounts($accounts);
 | 
			
		||||
        $genericSet = $collector->getExtractedJournals();
 | 
			
		||||
        $collector       = app(GroupCollectorInterface::class);
 | 
			
		||||
        $collector->setTypes([TransactionTypeEnum::DEPOSIT->value])->setRange($start, $end)->setDestinationAccounts($accounts);
 | 
			
		||||
        $genericSet      = $collector->getExtractedJournals();
 | 
			
		||||
        foreach ($genericSet as $journal) {
 | 
			
		||||
            $currencyId        = (int)$journal['currency_id'];
 | 
			
		||||
            $foreignCurrencyId = (int)$journal['foreign_currency_id'];
 | 
			
		||||
            // currency
 | 
			
		||||
            $currencyId                                = $journal['currency_id'];
 | 
			
		||||
            $currencyCode                              = $journal['currency_code'];
 | 
			
		||||
            $field                                     = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount';
 | 
			
		||||
 | 
			
		||||
            if (0 !== $currencyId) {
 | 
			
		||||
                $response[$currencyId] ??= [
 | 
			
		||||
                    'difference'       => '0',
 | 
			
		||||
                    'difference_float' => 0,
 | 
			
		||||
                    'currency_id'      => (string)$currencyId,
 | 
			
		||||
                    'currency_code'    => $journal['currency_code'],
 | 
			
		||||
                ];
 | 
			
		||||
                $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount']));
 | 
			
		||||
                $response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference']; // float but on purpose.
 | 
			
		||||
            // perhaps use default currency instead?
 | 
			
		||||
            if ($convertToNative && $journal['currency_id'] !== $default->id) {
 | 
			
		||||
                $currencyId   = $default->id;
 | 
			
		||||
                $currencyCode = $default->code;
 | 
			
		||||
            }
 | 
			
		||||
            if (0 !== $foreignCurrencyId) {
 | 
			
		||||
                $response[$foreignCurrencyId] ??= [
 | 
			
		||||
                    'difference'       => '0',
 | 
			
		||||
                    'difference_float' => 0,
 | 
			
		||||
                    'currency_id'      => (string)$foreignCurrencyId,
 | 
			
		||||
                    'currency_code'    => $journal['foreign_currency_code'],
 | 
			
		||||
                ];
 | 
			
		||||
                $response[$foreignCurrencyId]['difference']       = bcadd(
 | 
			
		||||
                    $response[$foreignCurrencyId]['difference'],
 | 
			
		||||
                    app('steam')->positive($journal['foreign_amount'])
 | 
			
		||||
                );
 | 
			
		||||
                $response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference']; // float but on purpose.
 | 
			
		||||
            // use foreign amount when the foreign currency IS the default currency.
 | 
			
		||||
            if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) {
 | 
			
		||||
                $field = 'foreign_amount';
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $response[$currencyId] ??= [
 | 
			
		||||
                'difference'       => '0',
 | 
			
		||||
                'difference_float' => 0,
 | 
			
		||||
                'currency_id'      => (string) $currencyId,
 | 
			
		||||
                'currency_code'    => $currencyCode,
 | 
			
		||||
            ];
 | 
			
		||||
            $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field]));
 | 
			
		||||
            $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose.
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response()->json(array_values($response));
 | 
			
		||||
 
 | 
			
		||||
@@ -26,9 +26,10 @@ namespace FireflyIII\Api\V1\Controllers\Insight\Income;
 | 
			
		||||
 | 
			
		||||
use FireflyIII\Api\V1\Controllers\Controller;
 | 
			
		||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
 | 
			
		||||
use FireflyIII\Enums\TransactionTypeEnum;
 | 
			
		||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
 | 
			
		||||
use FireflyIII\Models\TransactionType;
 | 
			
		||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
 | 
			
		||||
use FireflyIII\Support\Facades\Amount;
 | 
			
		||||
use Illuminate\Http\JsonResponse;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -63,45 +64,45 @@ class TagController extends Controller
 | 
			
		||||
     */
 | 
			
		||||
    public function noTag(GenericRequest $request): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
        $accounts   = $request->getAssetAccounts();
 | 
			
		||||
        $start      = $request->getStart();
 | 
			
		||||
        $end        = $request->getEnd();
 | 
			
		||||
        $response   = [];
 | 
			
		||||
        $accounts        = $request->getAssetAccounts();
 | 
			
		||||
        $start           = $request->getStart();
 | 
			
		||||
        $end             = $request->getEnd();
 | 
			
		||||
        $response        = [];
 | 
			
		||||
        $convertToNative = Amount::convertToNative();
 | 
			
		||||
        $default         = Amount::getNativeCurrency();
 | 
			
		||||
 | 
			
		||||
        // collect all expenses in this period (regardless of type) by the given bills and accounts.
 | 
			
		||||
        $collector  = app(GroupCollectorInterface::class);
 | 
			
		||||
        $collector->setTypes([TransactionType::DEPOSIT])->setRange($start, $end)->setDestinationAccounts($accounts);
 | 
			
		||||
        $collector       = app(GroupCollectorInterface::class);
 | 
			
		||||
        $collector->setTypes([TransactionTypeEnum::DEPOSIT->value])->setRange($start, $end)->setDestinationAccounts($accounts);
 | 
			
		||||
        $collector->withoutTags();
 | 
			
		||||
 | 
			
		||||
        $genericSet = $collector->getExtractedJournals();
 | 
			
		||||
        $genericSet      = $collector->getExtractedJournals();
 | 
			
		||||
 | 
			
		||||
        foreach ($genericSet as $journal) {
 | 
			
		||||
            $currencyId        = (int)$journal['currency_id'];
 | 
			
		||||
            $foreignCurrencyId = (int)$journal['foreign_currency_id'];
 | 
			
		||||
            // currency
 | 
			
		||||
            $currencyId                                = $journal['currency_id'];
 | 
			
		||||
            $currencyCode                              = $journal['currency_code'];
 | 
			
		||||
            $field                                     = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount';
 | 
			
		||||
 | 
			
		||||
            if (0 !== $currencyId) {
 | 
			
		||||
                $response[$currencyId] ??= [
 | 
			
		||||
                    'difference'       => '0',
 | 
			
		||||
                    'difference_float' => 0,
 | 
			
		||||
                    'currency_id'      => (string)$currencyId,
 | 
			
		||||
                    'currency_code'    => $journal['currency_code'],
 | 
			
		||||
                ];
 | 
			
		||||
                $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount']));
 | 
			
		||||
                $response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference'];
 | 
			
		||||
            // perhaps use default currency instead?
 | 
			
		||||
            if ($convertToNative && $journal['currency_id'] !== $default->id) {
 | 
			
		||||
                $currencyId   = $default->id;
 | 
			
		||||
                $currencyCode = $default->code;
 | 
			
		||||
            }
 | 
			
		||||
            if (0 !== $foreignCurrencyId) {
 | 
			
		||||
                $response[$foreignCurrencyId] ??= [
 | 
			
		||||
                    'difference'       => '0',
 | 
			
		||||
                    'difference_float' => 0,
 | 
			
		||||
                    'currency_id'      => (string)$foreignCurrencyId,
 | 
			
		||||
                    'currency_code'    => $journal['foreign_currency_code'],
 | 
			
		||||
                ];
 | 
			
		||||
                $response[$foreignCurrencyId]['difference']       = bcadd(
 | 
			
		||||
                    $response[$foreignCurrencyId]['difference'],
 | 
			
		||||
                    app('steam')->positive($journal['foreign_amount'])
 | 
			
		||||
                );
 | 
			
		||||
                $response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference'];
 | 
			
		||||
            // use foreign amount when the foreign currency IS the default currency.
 | 
			
		||||
            if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) {
 | 
			
		||||
                $field = 'foreign_amount';
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $response[$currencyId] ??= [
 | 
			
		||||
                'difference'       => '0',
 | 
			
		||||
                'difference_float' => 0,
 | 
			
		||||
                'currency_id'      => (string) $currencyId,
 | 
			
		||||
                'currency_code'    => $currencyCode,
 | 
			
		||||
            ];
 | 
			
		||||
            $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field]));
 | 
			
		||||
            $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response()->json(array_values($response));
 | 
			
		||||
@@ -128,14 +129,14 @@ class TagController extends Controller
 | 
			
		||||
 | 
			
		||||
        // collect all expenses in this period (regardless of type) by the given bills and accounts.
 | 
			
		||||
        $collector  = app(GroupCollectorInterface::class);
 | 
			
		||||
        $collector->setTypes([TransactionType::DEPOSIT])->setRange($start, $end)->setDestinationAccounts($accounts);
 | 
			
		||||
        $collector->setTypes([TransactionTypeEnum::DEPOSIT->value])->setRange($start, $end)->setDestinationAccounts($accounts);
 | 
			
		||||
        $collector->setTags($tags);
 | 
			
		||||
        $genericSet = $collector->getExtractedJournals();
 | 
			
		||||
 | 
			
		||||
        /** @var array $journal */
 | 
			
		||||
        foreach ($genericSet as $journal) {
 | 
			
		||||
            $currencyId        = (int)$journal['currency_id'];
 | 
			
		||||
            $foreignCurrencyId = (int)$journal['foreign_currency_id'];
 | 
			
		||||
            $currencyId        = (int) $journal['currency_id'];
 | 
			
		||||
            $foreignCurrencyId = (int) $journal['foreign_currency_id'];
 | 
			
		||||
 | 
			
		||||
            /** @var array $tag */
 | 
			
		||||
            foreach ($journal['tags'] as $tag) {
 | 
			
		||||
@@ -146,15 +147,15 @@ class TagController extends Controller
 | 
			
		||||
                // on currency ID
 | 
			
		||||
                if (0 !== $currencyId) {
 | 
			
		||||
                    $response[$key] ??= [
 | 
			
		||||
                        'id'               => (string)$tagId,
 | 
			
		||||
                        'id'               => (string) $tagId,
 | 
			
		||||
                        'name'             => $tag['name'],
 | 
			
		||||
                        'difference'       => '0',
 | 
			
		||||
                        'difference_float' => 0,
 | 
			
		||||
                        'currency_id'      => (string)$currencyId,
 | 
			
		||||
                        'currency_id'      => (string) $currencyId,
 | 
			
		||||
                        'currency_code'    => $journal['currency_code'],
 | 
			
		||||
                    ];
 | 
			
		||||
                    $response[$key]['difference']       = bcadd($response[$key]['difference'], app('steam')->positive($journal['amount']));
 | 
			
		||||
                    $response[$key]['difference_float'] = (float)$response[$key]['difference'];
 | 
			
		||||
                    $response[$key]['difference_float'] = (float) $response[$key]['difference'];
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // on foreign ID
 | 
			
		||||
@@ -162,14 +163,14 @@ class TagController extends Controller
 | 
			
		||||
                    $response[$foreignKey]                     = $journal[$foreignKey] ?? [
 | 
			
		||||
                        'difference'       => '0',
 | 
			
		||||
                        'difference_float' => 0,
 | 
			
		||||
                        'currency_id'      => (string)$foreignCurrencyId,
 | 
			
		||||
                        'currency_id'      => (string) $foreignCurrencyId,
 | 
			
		||||
                        'currency_code'    => $journal['foreign_currency_code'],
 | 
			
		||||
                    ];
 | 
			
		||||
                    $response[$foreignKey]['difference']       = bcadd(
 | 
			
		||||
                        $response[$foreignKey]['difference'],
 | 
			
		||||
                        app('steam')->positive($journal['foreign_amount'])
 | 
			
		||||
                    );
 | 
			
		||||
                    $response[$foreignKey]['difference_float'] = (float)$response[$foreignKey]['difference'];
 | 
			
		||||
                    $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference'];
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * AccountController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * CategoryController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
@@ -84,11 +85,11 @@ class CategoryController extends Controller
 | 
			
		||||
            /** @var array $expense */
 | 
			
		||||
            foreach ($expenses as $expense) {
 | 
			
		||||
                $result[] = [
 | 
			
		||||
                    'id'               => (string)$category->id,
 | 
			
		||||
                    'id'               => (string) $category->id,
 | 
			
		||||
                    'name'             => $category->name,
 | 
			
		||||
                    'difference'       => $expense['sum'],
 | 
			
		||||
                    'difference_float' => (float)$expense['sum'],
 | 
			
		||||
                    'currency_id'      => (string)$expense['currency_id'],
 | 
			
		||||
                    'difference_float' => (float) $expense['sum'],
 | 
			
		||||
                    'currency_id'      => (string) $expense['currency_id'],
 | 
			
		||||
                    'currency_code'    => $expense['currency_code'],
 | 
			
		||||
                ];
 | 
			
		||||
            }
 | 
			
		||||
@@ -113,8 +114,8 @@ class CategoryController extends Controller
 | 
			
		||||
        foreach ($expenses as $expense) {
 | 
			
		||||
            $result[] = [
 | 
			
		||||
                'difference'       => $expense['sum'],
 | 
			
		||||
                'difference_float' => (float)$expense['sum'],
 | 
			
		||||
                'currency_id'      => (string)$expense['currency_id'],
 | 
			
		||||
                'difference_float' => (float) $expense['sum'],
 | 
			
		||||
                'currency_id'      => (string) $expense['currency_id'],
 | 
			
		||||
                'currency_code'    => $expense['currency_code'],
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * PeriodController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
@@ -25,8 +26,9 @@ namespace FireflyIII\Api\V1\Controllers\Insight\Transfer;
 | 
			
		||||
 | 
			
		||||
use FireflyIII\Api\V1\Controllers\Controller;
 | 
			
		||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
 | 
			
		||||
use FireflyIII\Enums\TransactionTypeEnum;
 | 
			
		||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
 | 
			
		||||
use FireflyIII\Models\TransactionType;
 | 
			
		||||
use FireflyIII\Support\Facades\Amount;
 | 
			
		||||
use Illuminate\Http\JsonResponse;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -40,42 +42,42 @@ class PeriodController extends Controller
 | 
			
		||||
     */
 | 
			
		||||
    public function total(GenericRequest $request): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
        $accounts   = $request->getAssetAccounts();
 | 
			
		||||
        $start      = $request->getStart();
 | 
			
		||||
        $end        = $request->getEnd();
 | 
			
		||||
        $response   = [];
 | 
			
		||||
        $accounts        = $request->getAssetAccounts();
 | 
			
		||||
        $start           = $request->getStart();
 | 
			
		||||
        $end             = $request->getEnd();
 | 
			
		||||
        $response        = [];
 | 
			
		||||
        $convertToNative = Amount::convertToNative();
 | 
			
		||||
        $default         = Amount::getNativeCurrency();
 | 
			
		||||
 | 
			
		||||
        // collect all expenses in this period (regardless of type)
 | 
			
		||||
        $collector  = app(GroupCollectorInterface::class);
 | 
			
		||||
        $collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts);
 | 
			
		||||
        $genericSet = $collector->getExtractedJournals();
 | 
			
		||||
        $collector       = app(GroupCollectorInterface::class);
 | 
			
		||||
        $collector->setTypes([TransactionTypeEnum::TRANSFER->value])->setRange($start, $end)->setDestinationAccounts($accounts);
 | 
			
		||||
        $genericSet      = $collector->getExtractedJournals();
 | 
			
		||||
        foreach ($genericSet as $journal) {
 | 
			
		||||
            $currencyId        = (int)$journal['currency_id'];
 | 
			
		||||
            $foreignCurrencyId = (int)$journal['foreign_currency_id'];
 | 
			
		||||
            // currency
 | 
			
		||||
            $currencyId                                = $journal['currency_id'];
 | 
			
		||||
            $currencyCode                              = $journal['currency_code'];
 | 
			
		||||
            $field                                     = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount';
 | 
			
		||||
 | 
			
		||||
            if (0 !== $currencyId) {
 | 
			
		||||
                $response[$currencyId] ??= [
 | 
			
		||||
                    'difference'       => '0',
 | 
			
		||||
                    'difference_float' => 0,
 | 
			
		||||
                    'currency_id'      => (string)$currencyId,
 | 
			
		||||
                    'currency_code'    => $journal['currency_code'],
 | 
			
		||||
                ];
 | 
			
		||||
                $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount']));
 | 
			
		||||
                $response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference'];
 | 
			
		||||
            // perhaps use default currency instead?
 | 
			
		||||
            if ($convertToNative && $journal['currency_id'] !== $default->id) {
 | 
			
		||||
                $currencyId   = $default->id;
 | 
			
		||||
                $currencyCode = $default->code;
 | 
			
		||||
            }
 | 
			
		||||
            if (0 !== $foreignCurrencyId) {
 | 
			
		||||
                $response[$foreignCurrencyId] ??= [
 | 
			
		||||
                    'difference'       => '0',
 | 
			
		||||
                    'difference_float' => 0,
 | 
			
		||||
                    'currency_id'      => (string)$foreignCurrencyId,
 | 
			
		||||
                    'currency_code'    => $journal['foreign_currency_code'],
 | 
			
		||||
                ];
 | 
			
		||||
                $response[$foreignCurrencyId]['difference']       = bcadd(
 | 
			
		||||
                    $response[$foreignCurrencyId]['difference'],
 | 
			
		||||
                    app('steam')->positive($journal['foreign_amount'])
 | 
			
		||||
                );
 | 
			
		||||
                $response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference'];
 | 
			
		||||
            // use foreign amount when the foreign currency IS the default currency.
 | 
			
		||||
            if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) {
 | 
			
		||||
                $field = 'foreign_amount';
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $response[$currencyId] ??= [
 | 
			
		||||
                'difference'       => '0',
 | 
			
		||||
                'difference_float' => 0,
 | 
			
		||||
                'currency_id'      => (string) $currencyId,
 | 
			
		||||
                'currency_code'    => $currencyCode,
 | 
			
		||||
            ];
 | 
			
		||||
            $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field]));
 | 
			
		||||
            $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response()->json(array_values($response));
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * TagController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
@@ -25,9 +26,10 @@ namespace FireflyIII\Api\V1\Controllers\Insight\Transfer;
 | 
			
		||||
 | 
			
		||||
use FireflyIII\Api\V1\Controllers\Controller;
 | 
			
		||||
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
 | 
			
		||||
use FireflyIII\Enums\TransactionTypeEnum;
 | 
			
		||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
 | 
			
		||||
use FireflyIII\Models\TransactionType;
 | 
			
		||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
 | 
			
		||||
use FireflyIII\Support\Facades\Amount;
 | 
			
		||||
use Illuminate\Http\JsonResponse;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -60,45 +62,46 @@ class TagController extends Controller
 | 
			
		||||
     */
 | 
			
		||||
    public function noTag(GenericRequest $request): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
        $accounts   = $request->getAssetAccounts();
 | 
			
		||||
        $start      = $request->getStart();
 | 
			
		||||
        $end        = $request->getEnd();
 | 
			
		||||
        $response   = [];
 | 
			
		||||
        $accounts        = $request->getAssetAccounts();
 | 
			
		||||
        $start           = $request->getStart();
 | 
			
		||||
        $end             = $request->getEnd();
 | 
			
		||||
        $response        = [];
 | 
			
		||||
        $convertToNative = Amount::convertToNative();
 | 
			
		||||
        $default         = Amount::getNativeCurrency();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        // collect all expenses in this period (regardless of type) by the given bills and accounts.
 | 
			
		||||
        $collector  = app(GroupCollectorInterface::class);
 | 
			
		||||
        $collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts);
 | 
			
		||||
        $collector       = app(GroupCollectorInterface::class);
 | 
			
		||||
        $collector->setTypes([TransactionTypeEnum::TRANSFER->value])->setRange($start, $end)->setDestinationAccounts($accounts);
 | 
			
		||||
        $collector->withoutTags();
 | 
			
		||||
 | 
			
		||||
        $genericSet = $collector->getExtractedJournals();
 | 
			
		||||
        $genericSet      = $collector->getExtractedJournals();
 | 
			
		||||
 | 
			
		||||
        foreach ($genericSet as $journal) {
 | 
			
		||||
            $currencyId        = (int)$journal['currency_id'];
 | 
			
		||||
            $foreignCurrencyId = (int)$journal['foreign_currency_id'];
 | 
			
		||||
            // currency
 | 
			
		||||
            $currencyId                                = $journal['currency_id'];
 | 
			
		||||
            $currencyCode                              = $journal['currency_code'];
 | 
			
		||||
            $field                                     = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount';
 | 
			
		||||
 | 
			
		||||
            if (0 !== $currencyId) {
 | 
			
		||||
                $response[$currencyId] ??= [
 | 
			
		||||
                    'difference'       => '0',
 | 
			
		||||
                    'difference_float' => 0,
 | 
			
		||||
                    'currency_id'      => (string)$currencyId,
 | 
			
		||||
                    'currency_code'    => $journal['currency_code'],
 | 
			
		||||
                ];
 | 
			
		||||
                $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount']));
 | 
			
		||||
                $response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference'];
 | 
			
		||||
            // perhaps use default currency instead?
 | 
			
		||||
            if ($convertToNative && $journal['currency_id'] !== $default->id) {
 | 
			
		||||
                $currencyId   = $default->id;
 | 
			
		||||
                $currencyCode = $default->code;
 | 
			
		||||
            }
 | 
			
		||||
            if (0 !== $foreignCurrencyId) {
 | 
			
		||||
                $response[$foreignCurrencyId] ??= [
 | 
			
		||||
                    'difference'       => '0',
 | 
			
		||||
                    'difference_float' => 0,
 | 
			
		||||
                    'currency_id'      => (string)$foreignCurrencyId,
 | 
			
		||||
                    'currency_code'    => $journal['foreign_currency_code'],
 | 
			
		||||
                ];
 | 
			
		||||
                $response[$foreignCurrencyId]['difference']       = bcadd(
 | 
			
		||||
                    $response[$foreignCurrencyId]['difference'],
 | 
			
		||||
                    app('steam')->positive($journal['foreign_amount'])
 | 
			
		||||
                );
 | 
			
		||||
                $response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference'];
 | 
			
		||||
            // use foreign amount when the foreign currency IS the default currency.
 | 
			
		||||
            if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) {
 | 
			
		||||
                $field = 'foreign_amount';
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $response[$currencyId] ??= [
 | 
			
		||||
                'difference'       => '0',
 | 
			
		||||
                'difference_float' => 0,
 | 
			
		||||
                'currency_id'      => (string) $currencyId,
 | 
			
		||||
                'currency_code'    => $currencyCode,
 | 
			
		||||
            ];
 | 
			
		||||
            $response[$currencyId]['difference']       = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field]));
 | 
			
		||||
            $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response()->json(array_values($response));
 | 
			
		||||
@@ -125,14 +128,14 @@ class TagController extends Controller
 | 
			
		||||
 | 
			
		||||
        // collect all expenses in this period (regardless of type) by the given bills and accounts.
 | 
			
		||||
        $collector  = app(GroupCollectorInterface::class);
 | 
			
		||||
        $collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts);
 | 
			
		||||
        $collector->setTypes([TransactionTypeEnum::TRANSFER->value])->setRange($start, $end)->setDestinationAccounts($accounts);
 | 
			
		||||
        $collector->setTags($tags);
 | 
			
		||||
        $genericSet = $collector->getExtractedJournals();
 | 
			
		||||
 | 
			
		||||
        /** @var array $journal */
 | 
			
		||||
        foreach ($genericSet as $journal) {
 | 
			
		||||
            $currencyId        = (int)$journal['currency_id'];
 | 
			
		||||
            $foreignCurrencyId = (int)$journal['foreign_currency_id'];
 | 
			
		||||
            $currencyId        = (int) $journal['currency_id'];
 | 
			
		||||
            $foreignCurrencyId = (int) $journal['foreign_currency_id'];
 | 
			
		||||
 | 
			
		||||
            /** @var array $tag */
 | 
			
		||||
            foreach ($journal['tags'] as $tag) {
 | 
			
		||||
@@ -143,15 +146,15 @@ class TagController extends Controller
 | 
			
		||||
                // on currency ID
 | 
			
		||||
                if (0 !== $currencyId) {
 | 
			
		||||
                    $response[$key] ??= [
 | 
			
		||||
                        'id'               => (string)$tagId,
 | 
			
		||||
                        'id'               => (string) $tagId,
 | 
			
		||||
                        'name'             => $tag['name'],
 | 
			
		||||
                        'difference'       => '0',
 | 
			
		||||
                        'difference_float' => 0,
 | 
			
		||||
                        'currency_id'      => (string)$currencyId,
 | 
			
		||||
                        'currency_id'      => (string) $currencyId,
 | 
			
		||||
                        'currency_code'    => $journal['currency_code'],
 | 
			
		||||
                    ];
 | 
			
		||||
                    $response[$key]['difference']       = bcadd($response[$key]['difference'], app('steam')->positive($journal['amount']));
 | 
			
		||||
                    $response[$key]['difference_float'] = (float)$response[$key]['difference'];
 | 
			
		||||
                    $response[$key]['difference_float'] = (float) $response[$key]['difference'];
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // on foreign ID
 | 
			
		||||
@@ -159,14 +162,14 @@ class TagController extends Controller
 | 
			
		||||
                    $response[$foreignKey]                     = $journal[$foreignKey] ?? [
 | 
			
		||||
                        'difference'       => '0',
 | 
			
		||||
                        'difference_float' => 0,
 | 
			
		||||
                        'currency_id'      => (string)$foreignCurrencyId,
 | 
			
		||||
                        'currency_id'      => (string) $foreignCurrencyId,
 | 
			
		||||
                        'currency_code'    => $journal['foreign_currency_code'],
 | 
			
		||||
                    ];
 | 
			
		||||
                    $response[$foreignKey]['difference']       = bcadd(
 | 
			
		||||
                        $response[$foreignKey]['difference'],
 | 
			
		||||
                        app('steam')->positive($journal['foreign_amount'])
 | 
			
		||||
                    );
 | 
			
		||||
                    $response[$foreignKey]['difference_float'] = (float)$response[$foreignKey]['difference']; // intentional float
 | 
			
		||||
                    $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // intentional float
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * AccountController.php
 | 
			
		||||
 * Copyright (c) 2019 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * AccountController.php
 | 
			
		||||
 * Copyright (c) 2019 james@firefly-iii.org
 | 
			
		||||
@@ -29,6 +30,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface;
 | 
			
		||||
use FireflyIII\Models\Account;
 | 
			
		||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
 | 
			
		||||
use FireflyIII\Support\Http\Api\TransactionFilter;
 | 
			
		||||
use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment;
 | 
			
		||||
use FireflyIII\Transformers\AttachmentTransformer;
 | 
			
		||||
use FireflyIII\Transformers\PiggyBankTransformer;
 | 
			
		||||
use FireflyIII\Transformers\TransactionGroupTransformer;
 | 
			
		||||
@@ -110,7 +112,7 @@ class ListController extends Controller
 | 
			
		||||
        // types to get, page size:
 | 
			
		||||
        $pageSize    = $this->parameters->get('limit');
 | 
			
		||||
 | 
			
		||||
        // get list of budgets. Count it and split it.
 | 
			
		||||
        // get list of piggy banks. Count it and split it.
 | 
			
		||||
        $collection  = $this->repository->getPiggyBanks($account);
 | 
			
		||||
        $count       = $collection->count();
 | 
			
		||||
        $piggyBanks  = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
 | 
			
		||||
@@ -139,18 +141,18 @@ class ListController extends Controller
 | 
			
		||||
     */
 | 
			
		||||
    public function transactions(Request $request, Account $account): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
        $pageSize    = $this->parameters->get('limit');
 | 
			
		||||
        $type        = $request->get('type') ?? 'default';
 | 
			
		||||
        $pageSize     = $this->parameters->get('limit');
 | 
			
		||||
        $type         = $request->get('type') ?? 'default';
 | 
			
		||||
        $this->parameters->set('type', $type);
 | 
			
		||||
        $types       = $this->mapTransactionTypes($this->parameters->get('type'));
 | 
			
		||||
        $manager     = $this->getManager();
 | 
			
		||||
        $types        = $this->mapTransactionTypes($this->parameters->get('type'));
 | 
			
		||||
        $manager      = $this->getManager();
 | 
			
		||||
 | 
			
		||||
        /** @var User $admin */
 | 
			
		||||
        $admin       = auth()->user();
 | 
			
		||||
        $admin        = auth()->user();
 | 
			
		||||
 | 
			
		||||
        // use new group collector:
 | 
			
		||||
        /** @var GroupCollectorInterface $collector */
 | 
			
		||||
        $collector   = app(GroupCollectorInterface::class);
 | 
			
		||||
        $collector    = app(GroupCollectorInterface::class);
 | 
			
		||||
        $collector->setUser($admin)->setAccounts(new Collection([$account]))
 | 
			
		||||
            ->withAPIInformation()->setLimit($pageSize)->setPage($this->parameters->get('page'))->setTypes($types)
 | 
			
		||||
        ;
 | 
			
		||||
@@ -162,15 +164,19 @@ class ListController extends Controller
 | 
			
		||||
            $collector->setEnd($this->parameters->get('end'));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $paginator   = $collector->getPaginatedGroups();
 | 
			
		||||
        $paginator    = $collector->getPaginatedGroups();
 | 
			
		||||
        $paginator->setPath(route('api.v1.accounts.transactions', [$account->id]).$this->buildParams());
 | 
			
		||||
        $groups      = $paginator->getCollection();
 | 
			
		||||
 | 
			
		||||
        // enrich
 | 
			
		||||
        $enrichment   = new TransactionGroupEnrichment();
 | 
			
		||||
        $enrichment->setUser($admin);
 | 
			
		||||
        $transactions = $enrichment->enrich($paginator->getCollection());
 | 
			
		||||
 | 
			
		||||
        /** @var TransactionGroupTransformer $transformer */
 | 
			
		||||
        $transformer = app(TransactionGroupTransformer::class);
 | 
			
		||||
        $transformer  = app(TransactionGroupTransformer::class);
 | 
			
		||||
        $transformer->setParameters($this->parameters);
 | 
			
		||||
 | 
			
		||||
        $resource    = new FractalCollection($groups, $transformer, 'transactions');
 | 
			
		||||
        $resource     = new FractalCollection($transactions, $transformer, 'transactions');
 | 
			
		||||
        $resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
 | 
			
		||||
 | 
			
		||||
        return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ShowController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
@@ -28,7 +29,9 @@ use FireflyIII\Exceptions\FireflyException;
 | 
			
		||||
use FireflyIII\Models\Account;
 | 
			
		||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
 | 
			
		||||
use FireflyIII\Support\Http\Api\AccountFilter;
 | 
			
		||||
use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment;
 | 
			
		||||
use FireflyIII\Transformers\AccountTransformer;
 | 
			
		||||
use FireflyIII\User;
 | 
			
		||||
use Illuminate\Http\JsonResponse;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Pagination\LengthAwarePaginator;
 | 
			
		||||
@@ -87,9 +90,17 @@ class ShowController extends Controller
 | 
			
		||||
        $count       = $collection->count();
 | 
			
		||||
 | 
			
		||||
        // continue sort:
 | 
			
		||||
 | 
			
		||||
        $accounts    = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
 | 
			
		||||
 | 
			
		||||
        // enrich
 | 
			
		||||
        /** @var User $admin */
 | 
			
		||||
        $admin       = auth()->user();
 | 
			
		||||
        $enrichment  = new AccountEnrichment();
 | 
			
		||||
        $enrichment->setUser($admin);
 | 
			
		||||
        $enrichment->setConvertToNative($this->convertToNative);
 | 
			
		||||
        $enrichment->setNative($this->nativeCurrency);
 | 
			
		||||
        $accounts    = $enrichment->enrich($accounts);
 | 
			
		||||
 | 
			
		||||
        // make paginator:
 | 
			
		||||
        $paginator   = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page'));
 | 
			
		||||
        $paginator->setPath(route('api.v1.accounts.index').$this->buildParams());
 | 
			
		||||
@@ -117,6 +128,16 @@ class ShowController extends Controller
 | 
			
		||||
        $account->refresh();
 | 
			
		||||
        $manager     = $this->getManager();
 | 
			
		||||
 | 
			
		||||
        // enrich
 | 
			
		||||
        /** @var User $admin */
 | 
			
		||||
        $admin       = auth()->user();
 | 
			
		||||
        $enrichment  = new AccountEnrichment();
 | 
			
		||||
        $enrichment->setUser($admin);
 | 
			
		||||
        $enrichment->setConvertToNative($this->convertToNative);
 | 
			
		||||
        $enrichment->setNative($this->nativeCurrency);
 | 
			
		||||
        $account     = $enrichment->enrichSingle($account);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        /** @var AccountTransformer $transformer */
 | 
			
		||||
        $transformer = app(AccountTransformer::class);
 | 
			
		||||
        $transformer->setParameters($this->parameters);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * AccountController.php
 | 
			
		||||
 * Copyright (c) 2019 james@firefly-iii.org
 | 
			
		||||
@@ -26,7 +27,9 @@ namespace FireflyIII\Api\V1\Controllers\Models\Account;
 | 
			
		||||
use FireflyIII\Api\V1\Controllers\Controller;
 | 
			
		||||
use FireflyIII\Api\V1\Requests\Models\Account\StoreRequest;
 | 
			
		||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
 | 
			
		||||
use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment;
 | 
			
		||||
use FireflyIII\Transformers\AccountTransformer;
 | 
			
		||||
use FireflyIII\User;
 | 
			
		||||
use Illuminate\Http\JsonResponse;
 | 
			
		||||
use League\Fractal\Resource\Item;
 | 
			
		||||
 | 
			
		||||
@@ -68,6 +71,15 @@ class StoreController extends Controller
 | 
			
		||||
        $account     = $this->repository->store($data);
 | 
			
		||||
        $manager     = $this->getManager();
 | 
			
		||||
 | 
			
		||||
        // enrich
 | 
			
		||||
        /** @var User $admin */
 | 
			
		||||
        $admin       = auth()->user();
 | 
			
		||||
        $enrichment  = new AccountEnrichment();
 | 
			
		||||
        $enrichment->setUser($admin);
 | 
			
		||||
        $enrichment->setConvertToNative($this->convertToNative);
 | 
			
		||||
        $enrichment->setNative($this->nativeCurrency);
 | 
			
		||||
        $account     = $enrichment->enrichSingle($account);
 | 
			
		||||
 | 
			
		||||
        /** @var AccountTransformer $transformer */
 | 
			
		||||
        $transformer = app(AccountTransformer::class);
 | 
			
		||||
        $transformer->setParameters($this->parameters);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * AccountController.php
 | 
			
		||||
 * Copyright (c) 2019 james@firefly-iii.org
 | 
			
		||||
@@ -27,7 +28,9 @@ use FireflyIII\Api\V1\Controllers\Controller;
 | 
			
		||||
use FireflyIII\Api\V1\Requests\Models\Account\UpdateRequest;
 | 
			
		||||
use FireflyIII\Models\Account;
 | 
			
		||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
 | 
			
		||||
use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment;
 | 
			
		||||
use FireflyIII\Transformers\AccountTransformer;
 | 
			
		||||
use FireflyIII\User;
 | 
			
		||||
use Illuminate\Http\JsonResponse;
 | 
			
		||||
use League\Fractal\Resource\Item;
 | 
			
		||||
 | 
			
		||||
@@ -72,6 +75,15 @@ class UpdateController extends Controller
 | 
			
		||||
        $account->refresh();
 | 
			
		||||
        app('preferences')->mark();
 | 
			
		||||
 | 
			
		||||
        // enrich
 | 
			
		||||
        /** @var User $admin */
 | 
			
		||||
        $admin        = auth()->user();
 | 
			
		||||
        $enrichment   = new AccountEnrichment();
 | 
			
		||||
        $enrichment->setUser($admin);
 | 
			
		||||
        $enrichment->setConvertToNative($this->convertToNative);
 | 
			
		||||
        $enrichment->setNative($this->nativeCurrency);
 | 
			
		||||
        $account      = $enrichment->enrichSingle($account);
 | 
			
		||||
 | 
			
		||||
        /** @var AccountTransformer $transformer */
 | 
			
		||||
        $transformer  = app(AccountTransformer::class);
 | 
			
		||||
        $transformer->setParameters($this->parameters);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * DestroyController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ShowController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
@@ -104,7 +105,7 @@ class ShowController extends Controller
 | 
			
		||||
                ->header('Expires', '0')
 | 
			
		||||
                ->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
 | 
			
		||||
                ->header('Pragma', 'public')
 | 
			
		||||
                ->header('Content-Length', (string)strlen($content))
 | 
			
		||||
                ->header('Content-Length', (string) strlen($content))
 | 
			
		||||
            ;
 | 
			
		||||
 | 
			
		||||
            return $response;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * StoreController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
@@ -112,7 +113,12 @@ class StoreController extends Controller
 | 
			
		||||
 | 
			
		||||
            return response()->json([], 422);
 | 
			
		||||
        }
 | 
			
		||||
        $helper->saveAttachmentFromApi($attachment, $body);
 | 
			
		||||
        $result = $helper->saveAttachmentFromApi($attachment, $body);
 | 
			
		||||
        if (false === $result) {
 | 
			
		||||
            app('log')->error('Could not save attachment from API.');
 | 
			
		||||
 | 
			
		||||
            return response()->json([], 422);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response()->json([], 204);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * UpdateController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ShowController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * DestroyController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ListController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
@@ -29,6 +30,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface;
 | 
			
		||||
use FireflyIII\Models\Bill;
 | 
			
		||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
 | 
			
		||||
use FireflyIII\Support\Http\Api\TransactionFilter;
 | 
			
		||||
use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment;
 | 
			
		||||
use FireflyIII\Transformers\AttachmentTransformer;
 | 
			
		||||
use FireflyIII\Transformers\RuleTransformer;
 | 
			
		||||
use FireflyIII\Transformers\TransactionGroupTransformer;
 | 
			
		||||
@@ -175,7 +177,11 @@ class ListController extends Controller
 | 
			
		||||
        // get paginator.
 | 
			
		||||
        $paginator    = $collector->getPaginatedGroups();
 | 
			
		||||
        $paginator->setPath(route('api.v1.bills.transactions', [$bill->id]).$this->buildParams());
 | 
			
		||||
        $transactions = $paginator->getCollection();
 | 
			
		||||
 | 
			
		||||
        // enrich
 | 
			
		||||
        $enrichment   = new TransactionGroupEnrichment();
 | 
			
		||||
        $enrichment->setUser($admin);
 | 
			
		||||
        $transactions = $enrichment->enrich($paginator->getCollection());
 | 
			
		||||
 | 
			
		||||
        /** @var TransactionGroupTransformer $transformer */
 | 
			
		||||
        $transformer  = app(TransactionGroupTransformer::class);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ShowController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * StoreController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * UpdateController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * DestroyController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ListController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
@@ -24,12 +25,14 @@ declare(strict_types=1);
 | 
			
		||||
namespace FireflyIII\Api\V1\Controllers\Models\Budget;
 | 
			
		||||
 | 
			
		||||
use FireflyIII\Api\V1\Controllers\Controller;
 | 
			
		||||
use FireflyIII\Enums\TransactionTypeEnum;
 | 
			
		||||
use FireflyIII\Exceptions\FireflyException;
 | 
			
		||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
 | 
			
		||||
use FireflyIII\Models\Budget;
 | 
			
		||||
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
 | 
			
		||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
 | 
			
		||||
use FireflyIII\Support\Http\Api\TransactionFilter;
 | 
			
		||||
use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment;
 | 
			
		||||
use FireflyIII\Transformers\AttachmentTransformer;
 | 
			
		||||
use FireflyIII\Transformers\BudgetLimitTransformer;
 | 
			
		||||
use FireflyIII\Transformers\TransactionGroupTransformer;
 | 
			
		||||
@@ -170,7 +173,11 @@ class ListController extends Controller
 | 
			
		||||
 | 
			
		||||
        $paginator    = $collector->getPaginatedGroups();
 | 
			
		||||
        $paginator->setPath(route('api.v1.budgets.transactions', [$budget->id]).$this->buildParams());
 | 
			
		||||
        $transactions = $paginator->getCollection();
 | 
			
		||||
 | 
			
		||||
        // enrich
 | 
			
		||||
        $enrichment   = new TransactionGroupEnrichment();
 | 
			
		||||
        $enrichment->setUser($admin);
 | 
			
		||||
        $transactions = $enrichment->enrich($paginator->getCollection());
 | 
			
		||||
 | 
			
		||||
        /** @var TransactionGroupTransformer $transformer */
 | 
			
		||||
        $transformer  = app(TransactionGroupTransformer::class);
 | 
			
		||||
@@ -207,6 +214,8 @@ class ListController extends Controller
 | 
			
		||||
        $collector    = app(GroupCollectorInterface::class);
 | 
			
		||||
        $collector
 | 
			
		||||
            ->setUser($admin)
 | 
			
		||||
            // withdrawals only
 | 
			
		||||
            ->setTypes([TransactionTypeEnum::WITHDRAWAL->value])
 | 
			
		||||
            // filter on budget.
 | 
			
		||||
            ->withoutBudget()
 | 
			
		||||
            // all info needed for the API:
 | 
			
		||||
@@ -228,7 +237,11 @@ class ListController extends Controller
 | 
			
		||||
 | 
			
		||||
        $paginator    = $collector->getPaginatedGroups();
 | 
			
		||||
        $paginator->setPath(route('api.v1.budgets.without-budget').$this->buildParams());
 | 
			
		||||
        $transactions = $paginator->getCollection();
 | 
			
		||||
 | 
			
		||||
        // enrich
 | 
			
		||||
        $enrichment   = new TransactionGroupEnrichment();
 | 
			
		||||
        $enrichment->setUser($admin);
 | 
			
		||||
        $transactions = $enrichment->enrich($paginator->getCollection());
 | 
			
		||||
 | 
			
		||||
        /** @var TransactionGroupTransformer $transformer */
 | 
			
		||||
        $transformer  = app(TransactionGroupTransformer::class);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ShowController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * StoreController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * UpdateController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * DestroyController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ListController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
@@ -29,6 +30,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface;
 | 
			
		||||
use FireflyIII\Models\Budget;
 | 
			
		||||
use FireflyIII\Models\BudgetLimit;
 | 
			
		||||
use FireflyIII\Support\Http\Api\TransactionFilter;
 | 
			
		||||
use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment;
 | 
			
		||||
use FireflyIII\Transformers\TransactionGroupTransformer;
 | 
			
		||||
use FireflyIII\User;
 | 
			
		||||
use Illuminate\Http\JsonResponse;
 | 
			
		||||
@@ -83,7 +85,11 @@ class ListController extends Controller
 | 
			
		||||
        $collector->setTypes($types);
 | 
			
		||||
        $paginator    = $collector->getPaginatedGroups();
 | 
			
		||||
        $paginator->setPath(route('api.v1.budgets.limits.transactions', [$budget->id, $budgetLimit->id]).$this->buildParams());
 | 
			
		||||
        $transactions = $paginator->getCollection();
 | 
			
		||||
 | 
			
		||||
        // enrich
 | 
			
		||||
        $enrichment   = new TransactionGroupEnrichment();
 | 
			
		||||
        $enrichment->setUser($admin);
 | 
			
		||||
        $transactions = $enrichment->enrich($paginator->getCollection());
 | 
			
		||||
 | 
			
		||||
        /** @var TransactionGroupTransformer $transformer */
 | 
			
		||||
        $transformer  = app(TransactionGroupTransformer::class);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ShowController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
@@ -99,7 +100,7 @@ class ShowController extends Controller
 | 
			
		||||
     *
 | 
			
		||||
     * Display a listing of the budget limits for this budget.
 | 
			
		||||
     *
 | 
			
		||||
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 | 
			
		||||
     * @SuppressWarnings("PHPMD.UnusedFormalParameter")
 | 
			
		||||
     */
 | 
			
		||||
    public function indexAll(SameDateRequest $request): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * StoreController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
@@ -68,6 +69,7 @@ class StoreController extends Controller
 | 
			
		||||
        $data               = $request->getAll();
 | 
			
		||||
        $data['start_date'] = $data['start'];
 | 
			
		||||
        $data['end_date']   = $data['end'];
 | 
			
		||||
        $data['notes']      = $data['notes'];
 | 
			
		||||
        $data['budget_id']  = $budget->id;
 | 
			
		||||
 | 
			
		||||
        $budgetLimit        = $this->blRepository->store($data);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * UpdateController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * DestroyController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ListController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
@@ -29,6 +30,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface;
 | 
			
		||||
use FireflyIII\Models\Category;
 | 
			
		||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
 | 
			
		||||
use FireflyIII\Support\Http\Api\TransactionFilter;
 | 
			
		||||
use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment;
 | 
			
		||||
use FireflyIII\Transformers\AttachmentTransformer;
 | 
			
		||||
use FireflyIII\Transformers\TransactionGroupTransformer;
 | 
			
		||||
use FireflyIII\User;
 | 
			
		||||
@@ -138,7 +140,11 @@ class ListController extends Controller
 | 
			
		||||
 | 
			
		||||
        $paginator    = $collector->getPaginatedGroups();
 | 
			
		||||
        $paginator->setPath(route('api.v1.categories.transactions', [$category->id]).$this->buildParams());
 | 
			
		||||
        $transactions = $paginator->getCollection();
 | 
			
		||||
 | 
			
		||||
        // enrich
 | 
			
		||||
        $enrichment   = new TransactionGroupEnrichment();
 | 
			
		||||
        $enrichment->setUser($admin);
 | 
			
		||||
        $transactions = $enrichment->enrich($paginator->getCollection());
 | 
			
		||||
 | 
			
		||||
        /** @var TransactionGroupTransformer $transformer */
 | 
			
		||||
        $transformer  = app(TransactionGroupTransformer::class);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ShowController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * StoreController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * UpdateController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,82 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * DestroyController.php
 | 
			
		||||
 * Copyright (c) 2025 james@firefly-iii.org.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of Firefly III (https://github.com/firefly-iii).
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Affero General Public License as
 | 
			
		||||
 * published by the Free Software Foundation, either version 3 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see https://www.gnu.org/licenses/.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate;
 | 
			
		||||
 | 
			
		||||
use FireflyIII\Api\V1\Controllers\Controller;
 | 
			
		||||
use FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate\DestroyRequest;
 | 
			
		||||
use FireflyIII\Enums\UserRoleEnum;
 | 
			
		||||
use FireflyIII\Exceptions\ValidationException;
 | 
			
		||||
use FireflyIII\Models\CurrencyExchangeRate;
 | 
			
		||||
use FireflyIII\Models\TransactionCurrency;
 | 
			
		||||
use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface;
 | 
			
		||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
 | 
			
		||||
use Illuminate\Http\JsonResponse;
 | 
			
		||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 | 
			
		||||
 | 
			
		||||
class DestroyController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    use ValidatesUserGroupTrait;
 | 
			
		||||
 | 
			
		||||
    protected array $acceptedRoles   = [UserRoleEnum::OWNER];
 | 
			
		||||
 | 
			
		||||
    public const string RESOURCE_KEY = 'exchange-rates';
 | 
			
		||||
 | 
			
		||||
    private ExchangeRateRepositoryInterface $repository;
 | 
			
		||||
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct();
 | 
			
		||||
        $this->middleware(
 | 
			
		||||
            function ($request, $next) {
 | 
			
		||||
                $this->repository = app(ExchangeRateRepositoryInterface::class);
 | 
			
		||||
                $this->repository->setUserGroup($this->validateUserGroup($request));
 | 
			
		||||
 | 
			
		||||
                return $next($request);
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function destroy(DestroyRequest $request, TransactionCurrency $from, TransactionCurrency $to): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
        $date = $request->getDate();
 | 
			
		||||
        if (null === $date) {
 | 
			
		||||
            throw new ValidationException('Date is required');
 | 
			
		||||
        }
 | 
			
		||||
        $rate = $this->repository->getSpecificRateOnDate($from, $to, $date);
 | 
			
		||||
        if (null === $rate) {
 | 
			
		||||
            throw new NotFoundHttpException();
 | 
			
		||||
        }
 | 
			
		||||
        $this->repository->deleteRate($rate);
 | 
			
		||||
 | 
			
		||||
        return response()->json([], 204);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function destroySingle(CurrencyExchangeRate $exchangeRate): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
        $this->repository->deleteRate($exchangeRate);
 | 
			
		||||
 | 
			
		||||
        return response()->json([], 204);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,73 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * IndexController.php
 | 
			
		||||
 * Copyright (c) 2025 james@firefly-iii.org.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of Firefly III (https://github.com/firefly-iii).
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Affero General Public License as
 | 
			
		||||
 * published by the Free Software Foundation, either version 3 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see https://www.gnu.org/licenses/.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate;
 | 
			
		||||
 | 
			
		||||
use FireflyIII\Api\V2\Controllers\Controller;
 | 
			
		||||
use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface;
 | 
			
		||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
 | 
			
		||||
use FireflyIII\Transformers\V2\ExchangeRateTransformer;
 | 
			
		||||
use Illuminate\Http\JsonResponse;
 | 
			
		||||
use Illuminate\Pagination\LengthAwarePaginator;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class ShowController
 | 
			
		||||
 */
 | 
			
		||||
class IndexController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    use ValidatesUserGroupTrait;
 | 
			
		||||
 | 
			
		||||
    public const string RESOURCE_KEY = 'currency_exchange_rates';
 | 
			
		||||
 | 
			
		||||
    private ExchangeRateRepositoryInterface $repository;
 | 
			
		||||
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct();
 | 
			
		||||
        $this->middleware(
 | 
			
		||||
            function ($request, $next) {
 | 
			
		||||
                $this->repository = app(ExchangeRateRepositoryInterface::class);
 | 
			
		||||
                $this->repository->setUserGroup($this->validateUserGroup($request));
 | 
			
		||||
 | 
			
		||||
                return $next($request);
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function index(): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
        $entries     = $this->repository->getAll();
 | 
			
		||||
        $pageSize    = $this->parameters->get('limit');
 | 
			
		||||
        $count       = $entries->count();
 | 
			
		||||
        $entries     = $entries->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
 | 
			
		||||
        $paginator   = new LengthAwarePaginator($entries, $count, $pageSize, $this->parameters->get('page'));
 | 
			
		||||
        $transformer = new ExchangeRateTransformer();
 | 
			
		||||
        $transformer->setParameters($this->parameters); // give params to transformer
 | 
			
		||||
 | 
			
		||||
        return response()
 | 
			
		||||
            ->json($this->jsonApiList(self::RESOURCE_KEY, $paginator, $transformer))
 | 
			
		||||
            ->header('Content-Type', self::CONTENT_TYPE)
 | 
			
		||||
        ;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,88 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ShowController.php
 | 
			
		||||
 * Copyright (c) 2025 james@firefly-iii.org.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of Firefly III (https://github.com/firefly-iii).
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Affero General Public License as
 | 
			
		||||
 * published by the Free Software Foundation, either version 3 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see https://www.gnu.org/licenses/.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate;
 | 
			
		||||
 | 
			
		||||
use FireflyIII\Api\V2\Controllers\Controller;
 | 
			
		||||
use FireflyIII\Models\CurrencyExchangeRate;
 | 
			
		||||
use FireflyIII\Models\TransactionCurrency;
 | 
			
		||||
use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface;
 | 
			
		||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
 | 
			
		||||
use FireflyIII\Transformers\V2\ExchangeRateTransformer;
 | 
			
		||||
use Illuminate\Http\JsonResponse;
 | 
			
		||||
use Illuminate\Pagination\LengthAwarePaginator;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class ShowController
 | 
			
		||||
 */
 | 
			
		||||
class ShowController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    use ValidatesUserGroupTrait;
 | 
			
		||||
 | 
			
		||||
    public const string RESOURCE_KEY = 'exchange-rates';
 | 
			
		||||
 | 
			
		||||
    private ExchangeRateRepositoryInterface $repository;
 | 
			
		||||
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct();
 | 
			
		||||
        $this->middleware(
 | 
			
		||||
            function ($request, $next) {
 | 
			
		||||
                $this->repository = app(ExchangeRateRepositoryInterface::class);
 | 
			
		||||
                $this->repository->setUserGroup($this->validateUserGroup($request));
 | 
			
		||||
 | 
			
		||||
                return $next($request);
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function show(TransactionCurrency $from, TransactionCurrency $to): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
        $pageSize    = $this->parameters->get('limit');
 | 
			
		||||
        $page        = $this->parameters->get('page');
 | 
			
		||||
        $rates       = $this->repository->getRates($from, $to);
 | 
			
		||||
        $count       = $rates->count();
 | 
			
		||||
        $rates       = $rates->slice(($page - 1) * $pageSize, $pageSize);
 | 
			
		||||
        $paginator   = new LengthAwarePaginator($rates, $count, $pageSize, $page);
 | 
			
		||||
 | 
			
		||||
        $transformer = new ExchangeRateTransformer();
 | 
			
		||||
        $transformer->setParameters($this->parameters); // give params to transformer
 | 
			
		||||
 | 
			
		||||
        return response()
 | 
			
		||||
            ->json($this->jsonApiList(self::RESOURCE_KEY, $paginator, $transformer))
 | 
			
		||||
            ->header('Content-Type', self::CONTENT_TYPE)
 | 
			
		||||
        ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function showSingle(CurrencyExchangeRate $exchangeRate): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
        $transformer = new ExchangeRateTransformer();
 | 
			
		||||
        $transformer->setParameters($this->parameters);
 | 
			
		||||
 | 
			
		||||
        return response()
 | 
			
		||||
            ->api($this->jsonApiObject(self::RESOURCE_KEY, $exchangeRate, $transformer))
 | 
			
		||||
            ->header('Content-Type', self::CONTENT_TYPE)
 | 
			
		||||
        ;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,81 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * StoreController.php
 | 
			
		||||
 * Copyright (c) 2025 james@firefly-iii.org.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of Firefly III (https://github.com/firefly-iii).
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Affero General Public License as
 | 
			
		||||
 * published by the Free Software Foundation, either version 3 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see https://www.gnu.org/licenses/.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate;
 | 
			
		||||
 | 
			
		||||
use FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate\StoreRequest;
 | 
			
		||||
use FireflyIII\Api\V2\Controllers\Controller;
 | 
			
		||||
use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface;
 | 
			
		||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
 | 
			
		||||
use FireflyIII\Transformers\V2\ExchangeRateTransformer;
 | 
			
		||||
use Illuminate\Http\JsonResponse;
 | 
			
		||||
 | 
			
		||||
class StoreController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    use ValidatesUserGroupTrait;
 | 
			
		||||
 | 
			
		||||
    public const string RESOURCE_KEY = 'exchange-rates';
 | 
			
		||||
 | 
			
		||||
    private ExchangeRateRepositoryInterface $repository;
 | 
			
		||||
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct();
 | 
			
		||||
        $this->middleware(
 | 
			
		||||
            function ($request, $next) {
 | 
			
		||||
                $this->repository = app(ExchangeRateRepositoryInterface::class);
 | 
			
		||||
                $this->repository->setUserGroup($this->validateUserGroup($request));
 | 
			
		||||
 | 
			
		||||
                return $next($request);
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function store(StoreRequest $request): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
        $date        = $request->getDate();
 | 
			
		||||
        $rate        = $request->getRate();
 | 
			
		||||
        $from        = $request->getFromCurrency();
 | 
			
		||||
        $to          = $request->getToCurrency();
 | 
			
		||||
 | 
			
		||||
        // already has rate?
 | 
			
		||||
        $object      = $this->repository->getSpecificRateOnDate($from, $to, $date);
 | 
			
		||||
        if (null !== $object) {
 | 
			
		||||
            // just update it, no matter.
 | 
			
		||||
            $rate = $this->repository->updateExchangeRate($object, $rate, $date);
 | 
			
		||||
        }
 | 
			
		||||
        if (null === $object) {
 | 
			
		||||
            // store new
 | 
			
		||||
            $rate = $this->repository->storeExchangeRate($from, $to, $rate, $date);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $transformer = new ExchangeRateTransformer();
 | 
			
		||||
        $transformer->setParameters($this->parameters);
 | 
			
		||||
 | 
			
		||||
        return response()
 | 
			
		||||
            ->api($this->jsonApiObject(self::RESOURCE_KEY, $rate, $transformer))
 | 
			
		||||
            ->header('Content-Type', self::CONTENT_TYPE)
 | 
			
		||||
        ;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,69 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * UpdateController.php
 | 
			
		||||
 * Copyright (c) 2025 james@firefly-iii.org.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of Firefly III (https://github.com/firefly-iii).
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Affero General Public License as
 | 
			
		||||
 * published by the Free Software Foundation, either version 3 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see https://www.gnu.org/licenses/.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate;
 | 
			
		||||
 | 
			
		||||
use FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate\UpdateRequest;
 | 
			
		||||
use FireflyIII\Api\V2\Controllers\Controller;
 | 
			
		||||
use FireflyIII\Models\CurrencyExchangeRate;
 | 
			
		||||
use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface;
 | 
			
		||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
 | 
			
		||||
use FireflyIII\Transformers\V2\ExchangeRateTransformer;
 | 
			
		||||
use Illuminate\Http\JsonResponse;
 | 
			
		||||
 | 
			
		||||
class UpdateController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    use ValidatesUserGroupTrait;
 | 
			
		||||
 | 
			
		||||
    public const string RESOURCE_KEY = 'exchange-rates';
 | 
			
		||||
 | 
			
		||||
    private ExchangeRateRepositoryInterface $repository;
 | 
			
		||||
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct();
 | 
			
		||||
        $this->middleware(
 | 
			
		||||
            function ($request, $next) {
 | 
			
		||||
                $this->repository = app(ExchangeRateRepositoryInterface::class);
 | 
			
		||||
                $this->repository->setUserGroup($this->validateUserGroup($request));
 | 
			
		||||
 | 
			
		||||
                return $next($request);
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function update(UpdateRequest $request, CurrencyExchangeRate $exchangeRate): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
        $date         = $request->getDate();
 | 
			
		||||
        $rate         = $request->getRate();
 | 
			
		||||
        $exchangeRate = $this->repository->updateExchangeRate($exchangeRate, $rate, $date);
 | 
			
		||||
        $transformer  = new ExchangeRateTransformer();
 | 
			
		||||
        $transformer->setParameters($this->parameters);
 | 
			
		||||
 | 
			
		||||
        return response()
 | 
			
		||||
            ->api($this->jsonApiObject(self::RESOURCE_KEY, $exchangeRate, $transformer))
 | 
			
		||||
            ->header('Content-Type', self::CONTENT_TYPE)
 | 
			
		||||
        ;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * DestroyController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ListController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ShowController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * UpdateController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * DestroyController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ListController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
@@ -27,8 +28,11 @@ use FireflyIII\Api\V1\Controllers\Controller;
 | 
			
		||||
use FireflyIII\Exceptions\FireflyException;
 | 
			
		||||
use FireflyIII\Models\PiggyBank;
 | 
			
		||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
 | 
			
		||||
use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment;
 | 
			
		||||
use FireflyIII\Transformers\AccountTransformer;
 | 
			
		||||
use FireflyIII\Transformers\AttachmentTransformer;
 | 
			
		||||
use FireflyIII\Transformers\PiggyBankEventTransformer;
 | 
			
		||||
use FireflyIII\User;
 | 
			
		||||
use Illuminate\Http\JsonResponse;
 | 
			
		||||
use Illuminate\Pagination\LengthAwarePaginator;
 | 
			
		||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
 | 
			
		||||
@@ -57,6 +61,47 @@ class ListController extends Controller
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This endpoint is documented at:
 | 
			
		||||
     * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/piggy_banks/listAccountByPiggyBank
 | 
			
		||||
     *
 | 
			
		||||
     * List single resource.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws FireflyException
 | 
			
		||||
     */
 | 
			
		||||
    public function accounts(PiggyBank $piggyBank): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
        // types to get, page size:
 | 
			
		||||
        $pageSize    = $this->parameters->get('limit');
 | 
			
		||||
        $manager     = $this->getManager();
 | 
			
		||||
 | 
			
		||||
        $collection  = $piggyBank->accounts;
 | 
			
		||||
        $count       = $collection->count();
 | 
			
		||||
        $accounts    = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
 | 
			
		||||
 | 
			
		||||
        // enrich
 | 
			
		||||
        /** @var User $admin */
 | 
			
		||||
        $admin       = auth()->user();
 | 
			
		||||
        $enrichment  = new AccountEnrichment();
 | 
			
		||||
        $enrichment->setUser($admin);
 | 
			
		||||
        $enrichment->setConvertToNative($this->convertToNative);
 | 
			
		||||
        $enrichment->setNative($this->nativeCurrency);
 | 
			
		||||
        $accounts    = $enrichment->enrich($accounts);
 | 
			
		||||
 | 
			
		||||
        // make paginator:
 | 
			
		||||
        $paginator   = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page'));
 | 
			
		||||
        $paginator->setPath(route('api.v1.piggy-banks.accounts', [$piggyBank->id]).$this->buildParams());
 | 
			
		||||
 | 
			
		||||
        /** @var AccountTransformer $transformer */
 | 
			
		||||
        $transformer = app(AccountTransformer::class);
 | 
			
		||||
        $transformer->setParameters($this->parameters);
 | 
			
		||||
 | 
			
		||||
        $resource    = new FractalCollection($accounts, $transformer, 'accounts');
 | 
			
		||||
        $resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
 | 
			
		||||
 | 
			
		||||
        return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This endpoint is documented at:
 | 
			
		||||
     * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/piggy_banks/listAttachmentByPiggyBank
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ShowController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
@@ -71,7 +72,7 @@ class ShowController extends Controller
 | 
			
		||||
        // types to get, page size:
 | 
			
		||||
        $pageSize    = $this->parameters->get('limit');
 | 
			
		||||
 | 
			
		||||
        // get list of budgets. Count it and split it.
 | 
			
		||||
        // get list of piggy banks. Count it and split it.
 | 
			
		||||
        $collection  = $this->repository->getPiggyBanks();
 | 
			
		||||
        $count       = $collection->count();
 | 
			
		||||
        $piggyBanks  = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * StoreController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * UpdateController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * DestroyController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ListController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
@@ -29,6 +30,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface;
 | 
			
		||||
use FireflyIII\Models\Recurrence;
 | 
			
		||||
use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface;
 | 
			
		||||
use FireflyIII\Support\Http\Api\TransactionFilter;
 | 
			
		||||
use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment;
 | 
			
		||||
use FireflyIII\Transformers\TransactionGroupTransformer;
 | 
			
		||||
use FireflyIII\User;
 | 
			
		||||
use Illuminate\Http\JsonResponse;
 | 
			
		||||
@@ -109,7 +111,11 @@ class ListController extends Controller
 | 
			
		||||
 | 
			
		||||
        $paginator    = $collector->getPaginatedGroups();
 | 
			
		||||
        $paginator->setPath(route('api.v1.transactions.index').$this->buildParams());
 | 
			
		||||
        $transactions = $paginator->getCollection();
 | 
			
		||||
 | 
			
		||||
        // enrich
 | 
			
		||||
        $enrichment   = new TransactionGroupEnrichment();
 | 
			
		||||
        $enrichment->setUser($admin);
 | 
			
		||||
        $transactions = $enrichment->enrich($paginator->getCollection());
 | 
			
		||||
 | 
			
		||||
        /** @var TransactionGroupTransformer $transformer */
 | 
			
		||||
        $transformer  = app(TransactionGroupTransformer::class);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ShowController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * StoreController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * UpdateController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * DestroyController.php
 | 
			
		||||
 * Copyright (c) 2021 james@firefly-iii.org
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ExpressionController.php
 | 
			
		||||
 * Copyright (c) 2024 Michael Thomas
 | 
			
		||||
@@ -36,7 +37,7 @@ class ExpressionController extends Controller
 | 
			
		||||
     * This endpoint is documented at:
 | 
			
		||||
     * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/rules/validateExpression
 | 
			
		||||
     *
 | 
			
		||||
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 | 
			
		||||
     * @SuppressWarnings("PHPMD.UnusedFormalParameter")
 | 
			
		||||
     */
 | 
			
		||||
    public function validateExpression(ValidateExpressionRequest $request): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user