mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 10:47:00 +00:00 
			
		
		
		
	Compare commits
	
		
			229 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 8081eeb007 | ||
|  | 56f91bd10d | ||
|  | 8e20b78731 | ||
|  | 23a09b7081 | ||
|  | 67fdd27499 | ||
|  | e1941daedd | ||
|  | f28bc568a4 | ||
|  | f24cfe39aa | ||
|  | 59d2bf3f79 | ||
|  | 3176e54614 | ||
|  | eb090f7265 | ||
|  | 6d3a9bfd18 | ||
|  | 76f08b7acb | ||
|  | 1ff99346aa | ||
|  | 369695ab32 | ||
|  | 7e23dd1d66 | ||
|  | 0205d3fc5c | ||
|  | 4660cf2ad5 | ||
|  | e26d08d674 | ||
|  | 0932bf2797 | ||
|  | f560fc6d76 | ||
|  | aa6209af00 | ||
|  | 4a51176193 | ||
|  | bb84f7a434 | ||
|  | 48168b1ef0 | ||
|  | 8281c7c83e | ||
|  | a07c1e3c71 | ||
|  | 0766bb31fe | ||
|  | ff4472c1a5 | ||
|  | 17424740e5 | ||
|  | dad0b2fcd3 | ||
|  | c48dbf030f | ||
|  | 617808d603 | ||
|  | 845149deee | ||
|  | 1a9e009327 | ||
|  | ae90815708 | ||
|  | 1c460343b7 | ||
|  | 26079622f9 | ||
|  | 06c6d6096f | ||
|  | c8183aea51 | ||
|  | 7531134ad2 | ||
|  | cd0c6439c2 | ||
|  | c918c93f51 | ||
|  | 97d3bd68ed | ||
|  | 75f1e034ae | ||
|  | 8e72f218f1 | ||
|  | d643e05c5a | ||
|  | fea44834d0 | ||
|  | 195a2d7523 | ||
|  | b2fd346ef8 | ||
|  | 1ff8b62cb7 | ||
|  | c7ae15a41a | ||
|  | efe6f59f79 | ||
|  | 8e31d0491d | ||
|  | 73d4a10351 | ||
|  | 81d9d4dbc7 | ||
|  | 184ec13f99 | ||
|  | dee0422eff | ||
|  | 81a2975f1a | ||
|  | 5cd2ef4a5e | ||
|  | 466c2a68c2 | ||
|  | 0fb9fba531 | ||
|  | 356dd2c6cd | ||
|  | 32c4661233 | ||
|  | a245b504ec | ||
|  | a2f5fbdfd3 | ||
|  | 04be26adc5 | ||
|  | be0adb7cf2 | ||
|  | 84fd92bf5a | ||
|  | ee4e061739 | ||
|  | 4a2b01cd9a | ||
|  | efdd6460fb | ||
|  | 803827e05c | ||
|  | a41d5e9ab3 | ||
|  | e94333f877 | ||
|  | 6dbb80d687 | ||
|  | 31a1031624 | ||
|  | f8e9ce0d52 | ||
|  | 11baa968cd | ||
|  | 3e5e5b376f | ||
|  | bda18f296d | ||
|  | 287d110c84 | ||
|  | c98275e73a | ||
|  | aa573cc951 | ||
|  | 883d3d86e3 | ||
|  | fb047bd5f4 | ||
|  | 66a04d8365 | ||
|  | a0e501f9fd | ||
|  | 8b40d3346d | ||
|  | eddf5cd250 | ||
|  | ee5c534ca3 | ||
|  | fd4e77ae0f | ||
|  | b747c50aa3 | ||
|  | deebdd86a6 | ||
|  | b2db79cc10 | ||
|  | bbab370b1e | ||
|  | db4adf399d | ||
|  | 0683c87e52 | ||
|  | 3f62b647fc | ||
|  | 2562a5b30d | ||
|  | e232f2e223 | ||
|  | 21644ff4dd | ||
|  | be96a4fce5 | ||
|  | a1cabcbed3 | ||
|  | ce933b1f06 | ||
|  | 51ae130922 | ||
|  | da1bc18a47 | ||
|  | e7165a526b | ||
|  | 6081cc399f | ||
|  | 7c5c24e15d | ||
|  | e3e55b4347 | ||
|  | 40d8e7d1ad | ||
|  | 59e23b89f2 | ||
|  | cc33af8193 | ||
|  | 0e1e7eb2a9 | ||
|  | 52a28a7758 | ||
|  | 3f752d6832 | ||
|  | fe714e9989 | ||
|  | 0d3213a379 | ||
|  | 44056629e8 | ||
|  | 54125c05d3 | ||
|  | 7d32e50f25 | ||
|  | 4af9ff49a0 | ||
|  | 23faef845c | ||
|  | 41dad4091a | ||
|  | daf859b977 | ||
|  | f47ba6c977 | ||
|  | 4b9b207d92 | ||
|  | 875cbf66af | ||
|  | 412d6d4fd7 | ||
|  | 91c6deeb1f | ||
|  | 6d1978fd9a | ||
|  | 52d23b6ef5 | ||
|  | 0656ccbdd9 | ||
|  | e774ebd0a3 | ||
|  | edbda32a84 | ||
|  | 721fa04e3c | ||
|  | 9fd8d8915d | ||
|  | 7a9f5ebdd1 | ||
|  | a3423f0321 | ||
|  | c37e9a4467 | ||
|  | 6157d82a0b | ||
|  | 38b27fec92 | ||
|  | c43439bb68 | ||
|  | 8d9561d7a5 | ||
|  | 2a72cce3b7 | ||
|  | d3bbb6fb1f | ||
|  | 7b6723e9a2 | ||
|  | 1ee741460d | ||
|  | 967b0b493b | ||
|  | b53aaf7dde | ||
|  | 714c13bdbf | ||
|  | 651a4fd3cc | ||
|  | 505aee22bb | ||
|  | ca3d59dc33 | ||
|  | 13890e32a1 | ||
|  | df8976eabe | ||
|  | 3e01daa172 | ||
|  | f6999f355b | ||
|  | 5c06b45eb1 | ||
|  | 1802bb967a | ||
|  | d8d92f147f | ||
|  | 4a95bdd8ba | ||
|  | db5d94d956 | ||
|  | 06f2e34bb5 | ||
|  | 2ef7a01945 | ||
|  | d3f642551d | ||
|  | 490997157e | ||
|  | 2432af7883 | ||
|  | 7abeece3f0 | ||
|  | 3851652821 | ||
|  | 1d67d2250a | ||
|  | 37f40d8637 | ||
|  | 0224d1d59b | ||
|  | 587b94153d | ||
|  | 5124ce0302 | ||
|  | 950c4045b0 | ||
|  | 9c8ba66873 | ||
|  | 25d1d1be1b | ||
|  | 339c352505 | ||
|  | c587081fe4 | ||
|  | 8f9b1b866b | ||
|  | ff5ecf6182 | ||
|  | 05670cf393 | ||
|  | f10f5d30bf | ||
|  | 0d336727e8 | ||
|  | bf354275b3 | ||
|  | 1932bf277a | ||
|  | 192db4bb6e | ||
|  | 701efb943d | ||
|  | b2674971f1 | ||
|  | c907cb4cf1 | ||
|  | bb1462b4d9 | ||
|  | 1035f0e139 | ||
|  | 8475757716 | ||
|  | 20ffd8d61b | ||
|  | 8601428c4c | ||
|  | 59998573ee | ||
|  | 293cd72001 | ||
|  | 22ab9ebb2f | ||
|  | 9136e592d3 | ||
|  | ed8e392616 | ||
|  | e57ce6e644 | ||
|  | 8204e46086 | ||
|  | 9e365d9f80 | ||
|  | 6b40a933e9 | ||
|  | 8520a5002f | ||
|  | b38ed06f6e | ||
|  | 48427b1143 | ||
|  | 5d505f4ed0 | ||
|  | 0c02a08954 | ||
|  | 0221bd0f80 | ||
|  | 28216cbcb5 | ||
|  | 3e08a8cd6b | ||
|  | 67fafdeef7 | ||
|  | cc82505b66 | ||
|  | fd5f075f63 | ||
|  | a115960411 | ||
|  | e9fa4ca816 | ||
|  | d5c39d54d8 | ||
|  | dca395a018 | ||
|  | fcc22c692a | ||
|  | 26eafb0bd2 | ||
|  | 6dd1b4537a | ||
|  | 2722f0b749 | ||
|  | ccf0e1875e | ||
|  | 7ed2e03654 | ||
|  | 549e0f3477 | ||
|  | b243ed93aa | 
| @@ -1,5 +1,5 @@ | ||||
| APP_ENV=local | ||||
| APP_DEBUG=true | ||||
| APP_ENV=production | ||||
| APP_DEBUG=false | ||||
| APP_KEY=SomeRandomString | ||||
|  | ||||
| DB_CONNECTION=mysql | ||||
|   | ||||
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -28,3 +28,6 @@ tests/_output/* | ||||
| clover.xml | ||||
| node_modules/ | ||||
| addNewLines.php | ||||
| .phpstorm.meta.php | ||||
| .env.backup | ||||
| .env.local | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| Firefly III (v3.3.5) | ||||
| Firefly III (v3.4.0.1) | ||||
| =========== | ||||
|  | ||||
| [](https://travis-ci.org/JC5/firefly-iii) | ||||
| @@ -6,7 +6,7 @@ Firefly III (v3.3.5) | ||||
| [](https://insight.sensiolabs.com/projects/d44c7012-5f50-41ad-add8-8445330e4102) | ||||
| [](https://codeclimate.com/github/JC5/firefly-iii) | ||||
| [](https://coveralls.io/r/JC5/firefly-iii?branch=master) | ||||
| [](https://coveralls.io/r/JC5/firefly-iii?branch=develop) | ||||
| [](https://coveralls.io/r/JC5/firefly-iii?branch=develop) | ||||
|  | ||||
| [](https://packagist.org/packages/grumpydictator/firefly-iii) | ||||
| [](https://packagist.org/packages/grumpydictator/firefly-iii) | ||||
| @@ -22,7 +22,9 @@ laptop and [Firefly II](https://github.com/JC5/Firefly) is live. | ||||
| If you're not sure if this tool is for you, please read the [full description](https://github.com/JC5/firefly-iii/wiki/full-description). | ||||
|  | ||||
| To install and use Firefly III, please read [the installation guide](https://github.com/JC5/firefly-iii/wiki/Installation), | ||||
|  [the upgrade guide](https://github.com/JC5/firefly-iii/wiki/Upgrade-instructions) (if applicable) and the **[first use guide](https://github.com/JC5/firefly-iii/wiki/First-use)** | ||||
|  [the upgrade guide](https://github.com/JC5/firefly-iii/wiki/Upgrade-instructions) (if applicable) and the **[first use guide](https://github.com/JC5/firefly-iii/wiki/First-use)**. | ||||
|   | ||||
| If you want to try out Firefly III, you can do so on [this dedicated website](https://geld.nder.be/). This site always runs the latest version of Firefly III. If you want to use it, please read the [privacy considerations](https://github.com/JC5/firefly-iii/wiki/Privacy-on-demo-site) for this demo-site. | ||||
|  | ||||
| ## Current features | ||||
|  | ||||
|   | ||||
| @@ -1,37 +0,0 @@ | ||||
| <?php namespace FireflyIII\Console\Commands; | ||||
|  | ||||
| use Illuminate\Console\Command; | ||||
| use Illuminate\Foundation\Inspiring; | ||||
|  | ||||
| /** | ||||
|  * Class Inspire | ||||
|  * | ||||
|  * @package FireflyIII\Console\Commands | ||||
|  */ | ||||
| class Inspire extends Command | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * The console command description. | ||||
|      * | ||||
|      * @var string | ||||
|      */ | ||||
|     protected $description = 'Display an inspiring quote'; | ||||
|     /** | ||||
|      * The console command name. | ||||
|      * | ||||
|      * @var string | ||||
|      */ | ||||
|     protected $name = 'inspire'; | ||||
|  | ||||
|     /** | ||||
|      * Execute the console command. | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function handle() | ||||
|     { | ||||
|         $this->comment(PHP_EOL . Inspiring::quote() . PHP_EOL); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -18,7 +18,6 @@ class Kernel extends ConsoleKernel | ||||
|      */ | ||||
|     protected $commands | ||||
|         = [ | ||||
|             'FireflyIII\Console\Commands\Inspire', | ||||
|         ]; | ||||
|  | ||||
|     /** | ||||
| @@ -30,8 +29,6 @@ class Kernel extends ConsoleKernel | ||||
|      */ | ||||
|     protected function schedule(Schedule $schedule) | ||||
|     { | ||||
|         $schedule->command('inspire') | ||||
|                  ->hourly(); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -19,7 +19,8 @@ class JournalCreated extends Event | ||||
|     /** | ||||
|      * Create a new event instance. | ||||
|      * | ||||
|      * @return void | ||||
|      * @param TransactionJournal $journal | ||||
|      * @param                    $piggyBankId | ||||
|      */ | ||||
|     public function __construct(TransactionJournal $journal, $piggyBankId) | ||||
|     { | ||||
|   | ||||
| @@ -2,6 +2,11 @@ | ||||
|  | ||||
| use Illuminate\Queue\SerializesModels; | ||||
|  | ||||
| /** | ||||
|  * Class JournalDeleted | ||||
|  * | ||||
|  * @package FireflyIII\Events | ||||
|  */ | ||||
| class JournalDeleted extends Event | ||||
| { | ||||
|  | ||||
| @@ -10,7 +15,6 @@ class JournalDeleted extends Event | ||||
|     /** | ||||
|      * Create a new event instance. | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|   | ||||
| @@ -3,6 +3,11 @@ | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Illuminate\Queue\SerializesModels; | ||||
|  | ||||
| /** | ||||
|  * Class JournalSaved | ||||
|  * | ||||
|  * @package FireflyIII\Events | ||||
|  */ | ||||
| class JournalSaved extends Event | ||||
| { | ||||
|  | ||||
| @@ -13,7 +18,7 @@ class JournalSaved extends Event | ||||
|     /** | ||||
|      * Create a new event instance. | ||||
|      * | ||||
|      * @return void | ||||
|      * @param TransactionJournal $journal | ||||
|      */ | ||||
|     public function __construct(TransactionJournal $journal) | ||||
|     { | ||||
|   | ||||
| @@ -49,8 +49,7 @@ class Handler extends ExceptionHandler | ||||
|      */ | ||||
|     public function report(Exception $e) | ||||
|     { | ||||
|         /** @noinspection PhpInconsistentReturnPointsInspection */ | ||||
|         return parent::report($e); | ||||
|         parent::report($e); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -19,7 +19,6 @@ class ConnectJournalToPiggyBank | ||||
|     /** | ||||
|      * Create the event handler. | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -51,14 +50,7 @@ class ConnectJournalToPiggyBank | ||||
|             return; | ||||
|         } | ||||
|         Log::debug('Found a piggy bank'); | ||||
|         $amount = 0; | ||||
|         /** @var Transaction $transaction */ | ||||
|         foreach ($journal->transactions()->get() as $transaction) { | ||||
|             if ($transaction->account_id === $piggyBank->account_id) { | ||||
|                 // this transaction is the relevant one. | ||||
|                 $amount = floatval($transaction->amount); | ||||
|             } | ||||
|         } | ||||
|         $amount = $journal->amount; | ||||
|         Log::debug('Amount: ' . $amount); | ||||
|         if ($amount == 0) { | ||||
|             return; | ||||
| @@ -72,6 +64,22 @@ class ConnectJournalToPiggyBank | ||||
|         } | ||||
|  | ||||
|         Log::debug('Found rep! ' . $repetition->id); | ||||
|  | ||||
|         /* | ||||
|          * Add amount when | ||||
|          */ | ||||
|         /** @var Transaction $transaction */ | ||||
|         foreach ($journal->transactions()->get() as $transaction) { | ||||
|             if ($transaction->account_id == $piggyBank->account_id) { | ||||
|                 if ($transaction->amount < 0) { | ||||
|                     $amount = $amount * -1; | ||||
|                     Log::debug('Transaction is away from piggy, so amount becomes ' . $amount); | ||||
|                 } else { | ||||
|                     Log::debug('Transaction is to from piggy, so amount stays ' . $amount); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $repetition->currentamount += $amount; | ||||
|         $repetition->save(); | ||||
|  | ||||
|   | ||||
| @@ -15,7 +15,6 @@ class RescanJournal | ||||
|     /** | ||||
|      * Create the event handler. | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -41,7 +40,7 @@ class RescanJournal | ||||
|  | ||||
|         Log::debug('Found ' . $list->count() . ' bills to check.'); | ||||
|  | ||||
|         /** @var Bill $bill */ | ||||
|         /** @var \FireflyIII\Models\Bill $bill */ | ||||
|         foreach ($list as $bill) { | ||||
|             Log::debug('Now calling bill #' . $bill->id . ' (' . $bill->name . ')'); | ||||
|             $repository->scan($bill, $journal); | ||||
|   | ||||
| @@ -15,7 +15,6 @@ class UpdateJournalConnection | ||||
|     /** | ||||
|      * Create the event handler. | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -45,17 +44,8 @@ class UpdateJournalConnection | ||||
|         if (is_null($repetition)) { | ||||
|             return; | ||||
|         } | ||||
|         $amount = 0; | ||||
|         /** @var Transaction $transaction */ | ||||
|         foreach ($journal->transactions()->get() as $transaction) { | ||||
|             if ($transaction->account_id === $piggyBank->account_id) { | ||||
|                 // this transaction is the relevant one. | ||||
|                 $amount = floatval($transaction->amount); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // update current repetition: | ||||
|         $diff = $amount - $event->amount; | ||||
|         $amount = $journal->amount; | ||||
|         $diff   = $amount - $event->amount;// update current repetition | ||||
|  | ||||
|         $repetition->currentamount += $diff; | ||||
|         $repetition->save(); | ||||
|   | ||||
							
								
								
									
										87
									
								
								app/Helpers/Help/Help.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								app/Helpers/Help/Help.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,87 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Help; | ||||
|  | ||||
| use Cache; | ||||
| use ErrorException; | ||||
| use League\CommonMark\CommonMarkConverter; | ||||
| use Log; | ||||
| use Route; | ||||
|  | ||||
| /** | ||||
|  * Class Help | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Help | ||||
|  */ | ||||
| class Help implements HelpInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param $key | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getFromCache($key) | ||||
|     { | ||||
|         return Cache::get($key); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $route | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getFromGithub($route) | ||||
|     { | ||||
|         $uri     = 'https://raw.githubusercontent.com/JC5/firefly-iii-help/master/' . e($route) . '.md'; | ||||
|         $content = [ | ||||
|             'text'  => '<p>There is no help for this route!</p>', | ||||
|             'title' => $route, | ||||
|         ]; | ||||
|         try { | ||||
|             $content['text'] = file_get_contents($uri); | ||||
|         } catch (ErrorException $e) { | ||||
|             Log::error(trim($e->getMessage())); | ||||
|         } | ||||
|         if (strlen(trim($content['text'])) == 0) { | ||||
|             $content['text'] = '<p>There is no help for this route.</p>'; | ||||
|         } | ||||
|         $converter       = new CommonMarkConverter(); | ||||
|         $content['text'] = $converter->convertToHtml($content['text']); | ||||
|  | ||||
|         return $content; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $route | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function hasRoute($route) | ||||
|     { | ||||
|         return Route::has($route); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param       $route | ||||
|      * @param array $content | ||||
|      * | ||||
|      * @internal param $title | ||||
|      */ | ||||
|     public function putInCache($route, array $content) | ||||
|     { | ||||
|         Cache::put('help.' . $route . '.text', $content['text'], 10080); // a week. | ||||
|         Cache::put('help.' . $route . '.title', $content['title'], 10080); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $route | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function inCache($route) | ||||
|     { | ||||
|         return Cache::has('help.' . $route . '.title') && Cache::has('help.' . $route . '.text'); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										48
									
								
								app/Helpers/Help/HelpInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								app/Helpers/Help/HelpInterface.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Helpers\Help; | ||||
|  | ||||
| /** | ||||
|  * Interface HelpInterface | ||||
|  * | ||||
|  * @package FireflyIII\Helpers\Help | ||||
|  */ | ||||
| interface HelpInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param $key | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getFromCache($key); | ||||
|  | ||||
|     /** | ||||
|      * @param $route | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getFromGithub($route); | ||||
|  | ||||
|     /** | ||||
|      * @param $route | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function hasRoute($route); | ||||
|  | ||||
|     /** | ||||
|      * @param $route | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function inCache($route); | ||||
|  | ||||
|     /** | ||||
|      * @param       $route | ||||
|      * @param array $content | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function putInCache($route, array $content); | ||||
| } | ||||
| @@ -60,23 +60,21 @@ class ReportHelper implements ReportHelperInterface | ||||
|                        $join->on('budget_limits.budget_id', '=', 'budgets.id')->where('budget_limits.startdate', '=', $date->format('Y-m-d')); | ||||
|                    } | ||||
|                    ) | ||||
|                    ->get(['budgets.*', 'budget_limits.amount as amount']); | ||||
|                    ->get(['budgets.*', 'budget_limits.amount as queryAmount']); | ||||
|  | ||||
|         $budgets              = Steam::makeArray($set); | ||||
|         $amountSet            = $query->journalsByBudget($start, $end, $showSharedReports); | ||||
|         $amounts              = Steam::makeArray($amountSet); | ||||
|         $budgets              = Steam::mergeArrays($budgets, $amounts); | ||||
|         $budgets[0]['spent']  = isset($budgets[0]['spent']) ? $budgets[0]['spent'] : 0.0; | ||||
|         $budgets[0]['amount'] = isset($budgets[0]['amount']) ? $budgets[0]['amount'] : 0.0; | ||||
|         $budgets[0]['name']   = 'No budget'; | ||||
|         $budgets                   = Steam::makeArray($set); | ||||
|         $amountSet                 = $query->journalsByBudget($start, $end, $showSharedReports); | ||||
|         $amounts                   = Steam::makeArray($amountSet); | ||||
|         $budgets                   = Steam::mergeArrays($budgets, $amounts); | ||||
|         $budgets[0]['spent']       = isset($budgets[0]['spent']) ? $budgets[0]['spent'] : 0.0; | ||||
|         $budgets[0]['queryAmount'] = isset($budgets[0]['queryAmount']) ? $budgets[0]['queryAmount'] : 0.0; | ||||
|         $budgets[0]['name']        = 'No budget'; | ||||
|  | ||||
|         // find transactions to shared asset accounts, which are without a budget by default: | ||||
|         // which is only relevant when shared asset accounts are hidden. | ||||
|         if ($showSharedReports === false) { | ||||
|             $transfers = $query->sharedExpenses($start, $end); | ||||
|             foreach ($transfers as $transfer) { | ||||
|                 $budgets[0]['spent'] += floatval($transfer->amount) * -1; | ||||
|             } | ||||
|             $transfers = $query->sharedExpenses($start, $end)->sum('queryAmount'); | ||||
|             $budgets[0]['spent'] += floatval($transfers) * -1; | ||||
|         } | ||||
|  | ||||
|         return $budgets; | ||||
| @@ -93,11 +91,11 @@ class ReportHelper implements ReportHelperInterface | ||||
|         $end    = Carbon::now(); | ||||
|         $months = []; | ||||
|         while ($start <= $end) { | ||||
|             $year            = $start->format('Y'); | ||||
|             $year            = $start->year; | ||||
|             $months[$year][] = [ | ||||
|                 'formatted' => $start->format('F Y'), | ||||
|                 'month'     => intval($start->format('m')), | ||||
|                 'year'      => intval($start->format('Y')), | ||||
|                 'month'     => $start->month, | ||||
|                 'year'      => $year, | ||||
|             ]; | ||||
|             $start->addMonth(); | ||||
|         } | ||||
| @@ -116,10 +114,10 @@ class ReportHelper implements ReportHelperInterface | ||||
|         $end   = Carbon::now(); | ||||
|         $years = []; | ||||
|         while ($start <= $end) { | ||||
|             $years[] = $start->format('Y'); | ||||
|             $years[] = $start->year; | ||||
|             $start->addYear(); | ||||
|         } | ||||
|         $years[] = Carbon::now()->format('Y'); | ||||
|         $years[] = Carbon::now()->year; | ||||
|         // force the current year. | ||||
|         $years = array_unique($years); | ||||
|  | ||||
|   | ||||
| @@ -96,7 +96,7 @@ class ReportQuery implements ReportQueryInterface | ||||
|                                  ->get( | ||||
|                                      [ | ||||
|                                          'transaction_journals.*', | ||||
|                                          'transactions.amount' | ||||
|                                          'transactions.amount as queryAmount' | ||||
|                                      ] | ||||
|                                  ); | ||||
|  | ||||
| @@ -111,17 +111,11 @@ class ReportQuery implements ReportQueryInterface | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * | ||||
|      * @return Collection | ||||
|      * @return float | ||||
|      */ | ||||
|     public function balancedTransactionsSum(Account $account, Carbon $start, Carbon $end) | ||||
|     { | ||||
|         $set = $this->balancedTransactionsList($account, $start, $end); | ||||
|         $sum = 0; | ||||
|         foreach ($set as $entry) { | ||||
|             $sum += floatval($entry->amount); | ||||
|         } | ||||
|  | ||||
|         return $sum; | ||||
|         return floatval($this->balancedTransactionsList($account, $start, $end)->sum('queryAmount')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -156,8 +150,16 @@ class ReportQuery implements ReportQueryInterface | ||||
|         $set = $query->get(['accounts.*']); | ||||
|         $set->each( | ||||
|             function (Account $account) use ($start, $end) { | ||||
|                 /** | ||||
|                  * The balance for today always incorporates transactions | ||||
|                  * made on today. So to get todays "start" balance, we sub one | ||||
|                  * day. | ||||
|                  */ | ||||
|                 $yesterday = clone $start; | ||||
|                 $yesterday->subDay(); | ||||
|  | ||||
|                 /** @noinspection PhpParamsInspection */ | ||||
|                 $account->startBalance = Steam::balance($account, $start); | ||||
|                 $account->startBalance = Steam::balance($account, $yesterday); | ||||
|                 $account->endBalance   = Steam::balance($account, $end); | ||||
|             } | ||||
|         ); | ||||
| @@ -178,7 +180,7 @@ class ReportQuery implements ReportQueryInterface | ||||
|     { | ||||
|         $query = $this->queryJournalsNoBudget($account, $start, $end); | ||||
|  | ||||
|         return $query->get(['budgets.id', 'budgets.name', DB::Raw('SUM(`transactions`.`amount`) as `amount`')]); | ||||
|         return $query->get(['budgets.id', 'budgets.name', DB::Raw('SUM(`transactions`.`amount`) as `queryAmount`')]); | ||||
|  | ||||
|     } | ||||
|  | ||||
| @@ -196,7 +198,7 @@ class ReportQuery implements ReportQueryInterface | ||||
|     { | ||||
|         $query = $this->queryJournalsNoBudget($account, $start, $end); | ||||
|  | ||||
|         return $query->get(['budgets.name', 'transactions.amount', 'transaction_journals.*']); | ||||
|         return $query->get(['budgets.name', 'transactions.amount as queryAmount', 'transaction_journals.*']); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -236,7 +238,7 @@ class ReportQuery implements ReportQueryInterface | ||||
|             // any deposit is fine. | ||||
|             $query->where('transaction_types.type', 'Deposit'); | ||||
|         } | ||||
|         $query->groupBy('t_from.account_id')->orderBy('transaction_journals.date'); | ||||
|         $query->groupBy('transaction_journals.id')->orderBy('transaction_journals.date'); | ||||
|  | ||||
|         // get everything, decrypt and return | ||||
|         $data = $query->get( | ||||
| @@ -244,7 +246,7 @@ class ReportQuery implements ReportQueryInterface | ||||
|              'transaction_journals.description', | ||||
|              'transaction_journals.encrypted', | ||||
|              'transaction_types.type', | ||||
|              DB::Raw('SUM(`t_to`.`amount`) as `amount`'), | ||||
|              DB::Raw('SUM(`t_to`.`amount`) as `queryAmount`'), | ||||
|              'transaction_journals.date', | ||||
|              't_from.account_id as account_id', | ||||
|              'ac_from.name as name', | ||||
| @@ -254,7 +256,6 @@ class ReportQuery implements ReportQueryInterface | ||||
|  | ||||
|         $data->each( | ||||
|             function (Model $object) { | ||||
| //                $object->description = intval($object->encrypted); | ||||
|                 $object->name = intval($object->account_encrypted) == 1 ? Crypt::decrypt($object->name) : $object->name; | ||||
|             } | ||||
|         ); | ||||
| @@ -335,9 +336,9 @@ class ReportQuery implements ReportQueryInterface | ||||
|               ->where('transaction_journals.date', '<=', $end->format('Y-m-d')) | ||||
|               ->where('transaction_types.type', 'Withdrawal') | ||||
|               ->groupBy('categories.id') | ||||
|               ->orderBy('amount'); | ||||
|               ->orderBy('queryAmount'); | ||||
|  | ||||
|         $data = $query->get(['categories.id', 'categories.encrypted', 'categories.name', DB::Raw('SUM(`transactions`.`amount`) AS `amount`')]); | ||||
|         $data = $query->get(['categories.id', 'categories.encrypted', 'categories.name', DB::Raw('SUM(`transactions`.`amount`) AS `queryAmount`')]); | ||||
|         // decrypt data: | ||||
|         $data->each( | ||||
|             function (Model $object) { | ||||
| @@ -390,9 +391,9 @@ class ReportQuery implements ReportQueryInterface | ||||
|         $query->before($end)->after($start) | ||||
|               ->where('transaction_journals.user_id', Auth::user()->id) | ||||
|               ->groupBy('t_to.account_id') | ||||
|               ->orderBy('amount', 'DESC'); | ||||
|               ->orderBy('queryAmount', 'DESC'); | ||||
|  | ||||
|         $data = $query->get(['t_to.account_id as id', 'ac_to.name as name', 'ac_to.encrypted', DB::Raw('SUM(t_to.amount) as `amount`')]); | ||||
|         $data = $query->get(['t_to.account_id as id', 'ac_to.name as name', 'ac_to.encrypted', DB::Raw('SUM(t_to.amount) as `queryAmount`')]); | ||||
|  | ||||
|         // decrypt | ||||
|         $data->each( | ||||
| @@ -441,10 +442,10 @@ class ReportQuery implements ReportQueryInterface | ||||
|             $query->where('transaction_types.type', 'Deposit'); | ||||
|         } | ||||
|  | ||||
|         $query->groupBy('t_from.account_id')->orderBy('amount'); | ||||
|         $query->groupBy('t_from.account_id')->orderBy('queryAmount'); | ||||
|  | ||||
|         $data = $query->get( | ||||
|             ['t_from.account_id as account_id', 'ac_from.name as name', 'ac_from.encrypted as encrypted', DB::Raw('SUM(t_from.amount) as `amount`')] | ||||
|             ['t_from.account_id as account_id', 'ac_from.name as name', 'ac_from.encrypted as encrypted', DB::Raw('SUM(t_from.amount) as `queryAmount`')] | ||||
|         ); | ||||
|         // decrypt | ||||
|         $data->each( | ||||
| @@ -489,7 +490,7 @@ class ReportQuery implements ReportQueryInterface | ||||
|                                  ->where('transaction_journals.user_id', Auth::user()->id) | ||||
|                                  ->get( | ||||
|                                      ['transaction_journals.id', 'transaction_journals.description', 'transactions.account_id', 'accounts.name', | ||||
|                                       'transactions.amount'] | ||||
|                                       'transactions.amount as queryAmount'] | ||||
|                                  ); | ||||
|  | ||||
|     } | ||||
| @@ -534,7 +535,7 @@ class ReportQuery implements ReportQueryInterface | ||||
|                                      [ | ||||
|                                          'categories.id', | ||||
|                                          'categories.name as name', | ||||
|                                          DB::Raw('SUM(`transactions`.`amount`) * -1 AS `amount`') | ||||
|                                          DB::Raw('SUM(`transactions`.`amount`) * -1 AS `queryAmount`') | ||||
|                                      ] | ||||
|                                  ); | ||||
|     } | ||||
|   | ||||
| @@ -43,7 +43,7 @@ interface ReportQueryInterface | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * | ||||
|      * @return Collection | ||||
|      * @return float | ||||
|      */ | ||||
|     public function balancedTransactionsSum(Account $account, Carbon $start, Carbon $end); | ||||
|  | ||||
|   | ||||
| @@ -7,12 +7,11 @@ use FireflyIII\Http\Requests; | ||||
| use FireflyIII\Http\Requests\AccountFormRequest; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use Illuminate\Database\Eloquent\Relations\HasMany; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use Input; | ||||
| use Redirect; | ||||
| use Session; | ||||
| use Steam; | ||||
| use URL; | ||||
| use View; | ||||
|  | ||||
| /** | ||||
| @@ -27,6 +26,7 @@ class AccountController extends Controller | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         View::share('mainTitleIcon', 'fa-credit-card'); | ||||
|         View::share('title', 'Accounts'); | ||||
|     } | ||||
| @@ -41,6 +41,12 @@ class AccountController extends Controller | ||||
|         $subTitleIcon = Config::get('firefly.subIconsByIdentifier.' . $what); | ||||
|         $subTitle     = 'Create a new ' . e($what) . ' account'; | ||||
|  | ||||
|         // put previous url in session if not redirect from store (not "create another"). | ||||
|         if (Session::get('accounts.create.fromStore') !== true) { | ||||
|             Session::put('accounts.create.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('accounts.create.fromStore'); | ||||
|  | ||||
|         return view('accounts.create', compact('subTitleIcon', 'what', 'subTitle')); | ||||
|  | ||||
|     } | ||||
| @@ -54,15 +60,19 @@ class AccountController extends Controller | ||||
|     { | ||||
|         $subTitle = 'Delete ' . strtolower(e($account->accountType->type)) . ' "' . e($account->name) . '"'; | ||||
|  | ||||
|         // put previous url in session | ||||
|         Session::put('accounts.delete.url', URL::previous()); | ||||
|  | ||||
|         return view('accounts.delete', compact('account', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Account $account | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * @param Account                    $account | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function destroy(Account $account, AccountRepositoryInterface $repository) | ||||
|     public function destroy(AccountRepositoryInterface $repository, Account $account) | ||||
|     { | ||||
|  | ||||
|         $type     = $account->accountType->type; | ||||
| @@ -73,16 +83,16 @@ class AccountController extends Controller | ||||
|  | ||||
|         Session::flash('success', 'The ' . e($typeName) . ' account "' . e($name) . '" was deleted.'); | ||||
|  | ||||
|         return Redirect::route('accounts.index', $typeName); | ||||
|         return Redirect::to(Session::get('accounts.delete.url')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Account                    $account | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * @param Account                    $account | ||||
|      * | ||||
|      * @return View | ||||
|      */ | ||||
|     public function edit(Account $account, AccountRepositoryInterface $repository) | ||||
|     public function edit(AccountRepositoryInterface $repository, Account $account) | ||||
|     { | ||||
|  | ||||
|         $what           = Config::get('firefly.shortNamesByFullName')[$account->accountType->type]; | ||||
| @@ -90,6 +100,12 @@ class AccountController extends Controller | ||||
|         $subTitleIcon   = Config::get('firefly.subIconsByIdentifier.' . $what); | ||||
|         $openingBalance = $repository->openingBalanceTransaction($account); | ||||
|  | ||||
|         // put previous url in session if not redirect from store (not "return_to_edit"). | ||||
|         if (Session::get('accounts.edit.fromUpdate') !== true) { | ||||
|             Session::put('accounts.edit.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('accounts.edit.fromUpdate'); | ||||
|  | ||||
|         // pre fill some useful values. | ||||
|  | ||||
|         // the opening balance is tricky: | ||||
| @@ -114,60 +130,41 @@ class AccountController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $what | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * @param                            $what | ||||
|      * | ||||
|      * @return View | ||||
|      */ | ||||
|     public function index($what = 'default') | ||||
|     public function index(AccountRepositoryInterface $repository, $what) | ||||
|     { | ||||
|         $subTitle     = Config::get('firefly.subTitlesByIdentifier.' . $what); | ||||
|         $subTitleIcon = Config::get('firefly.subIconsByIdentifier.' . $what); | ||||
|         $types        = Config::get('firefly.accountTypesByIdentifier.' . $what); | ||||
|         $size         = 50; | ||||
|         $page         = intval(Input::get('page')) == 0 ? 1 : intval(Input::get('page')); | ||||
|         $offset       = ($page - 1) * $size; | ||||
|  | ||||
|  | ||||
|         // move to repository: | ||||
|         $set   = Auth::user()->accounts()->with( | ||||
|             ['accountmeta' => function (HasMany $query) { | ||||
|                 $query->where('name', 'accountRole'); | ||||
|             }] | ||||
|         )->accountTypeIn($types)->take($size)->offset($offset)->orderBy('accounts.name', 'ASC')->get(['accounts.*']); | ||||
|         $total = Auth::user()->accounts()->accountTypeIn($types)->count(); | ||||
|  | ||||
|         $accounts     = $repository->getAccounts($types); | ||||
|         // last activity: | ||||
|         /** | ||||
|          * HERE WE ARE | ||||
|          */ | ||||
|         $start = clone Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $start->subDay(); | ||||
|         $set->each( | ||||
|             function (Account $account) use ($start) { | ||||
|                 $lastTransaction = $account->transactions()->leftJoin( | ||||
|                     'transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id' | ||||
|                 )->orderBy('transaction_journals.date', 'DESC')->first(['transactions.*', 'transaction_journals.date']); | ||||
|                 if ($lastTransaction) { | ||||
|                     $account->lastActivityDate = $lastTransaction->transactionjournal->date; | ||||
|                 } else { | ||||
|                     $account->lastActivityDate = null; | ||||
|                 } | ||||
|                 $account->startBalance = Steam::balance($account, $start); | ||||
|                 $account->endBalance   = Steam::balance($account, clone Session::get('end')); | ||||
|         $accounts->each( | ||||
|             function (Account $account) use ($start, $repository) { | ||||
|                 $account->lastActivityDate = $repository->getLastActivity($account); | ||||
|                 $account->startBalance     = Steam::balance($account, $start); | ||||
|                 $account->endBalance       = Steam::balance($account, clone Session::get('end', Carbon::now()->endOfMonth())); | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         $accounts = new LengthAwarePaginator($set, $total, $size, $page); | ||||
|         $accounts->setPath(route('accounts.index', $what)); | ||||
|  | ||||
|  | ||||
|         return view('accounts.index', compact('what', 'subTitleIcon', 'subTitle', 'accounts')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Account                    $account | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * @param Account                    $account | ||||
|      * | ||||
|      * @return View | ||||
|      */ | ||||
|     public function show(Account $account, AccountRepositoryInterface $repository) | ||||
|     public function show(AccountRepositoryInterface $repository, Account $account) | ||||
|     { | ||||
|         $page         = intval(Input::get('page')) == 0 ? 1 : intval(Input::get('page')); | ||||
|         $subTitleIcon = Config::get('firefly.subTitlesByIdentifier.' . $account->accountType->type); | ||||
| @@ -176,6 +173,7 @@ class AccountController extends Controller | ||||
|         $subTitle     = 'Details for ' . strtolower(e($account->accountType->type)) . ' "' . e($account->name) . '"'; | ||||
|         $journals->setPath('accounts/show/' . $account->id); | ||||
|  | ||||
|  | ||||
|         return view('accounts.show', compact('account', 'what', 'subTitleIcon', 'journals', 'subTitle')); | ||||
|     } | ||||
|  | ||||
| @@ -204,23 +202,28 @@ class AccountController extends Controller | ||||
|         Session::flash('success', 'New account "' . $account->name . '" stored!'); | ||||
|  | ||||
|         if (intval(Input::get('create_another')) === 1) { | ||||
|             return Redirect::route('accounts.create', $request->input('what'))->withInput(); | ||||
|             // set value so create routine will not overwrite URL: | ||||
|             Session::put('accounts.create.fromStore', true); | ||||
|  | ||||
|             return Redirect::route('accounts.create')->withInput(); | ||||
|         } | ||||
|  | ||||
|         return Redirect::route('accounts.index', $request->input('what')); | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('accounts.create.url')); | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Account                    $account | ||||
|      * @param AccountFormRequest         $request | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * @param Account                    $account | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      * @return $this|\Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function update(Account $account, AccountFormRequest $request, AccountRepositoryInterface $repository) | ||||
|     public function update(AccountFormRequest $request, AccountRepositoryInterface $repository, Account $account) | ||||
|     { | ||||
|         $what        = Config::get('firefly.shortNamesByFullName.' . $account->accountType->type); | ||||
|  | ||||
|         $accountData = [ | ||||
|             'name'                   => $request->input('name'), | ||||
|             'active'                 => $request->input('active'), | ||||
| @@ -239,10 +242,14 @@ class AccountController extends Controller | ||||
|         Session::flash('success', 'Account "' . $account->name . '" updated.'); | ||||
|  | ||||
|         if (intval(Input::get('return_to_edit')) === 1) { | ||||
|             return Redirect::route('accounts.edit', $account->id); | ||||
|             // set value so edit routine will not overwrite URL: | ||||
|             Session::put('accounts.edit.fromUpdate', true); | ||||
|  | ||||
|             return Redirect::route('accounts.edit', $account->id)->withInput(['return_to_edit' => 1]); | ||||
|         } | ||||
|  | ||||
|         return Redirect::route('accounts.index', $what); | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('accounts.edit.url')); | ||||
|  | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -8,6 +8,7 @@ use Illuminate\Http\Request; | ||||
| use Illuminate\Mail\Message; | ||||
| use Mail; | ||||
| use Session; | ||||
| use Twig; | ||||
|  | ||||
| /** | ||||
|  * Class AuthController | ||||
| @@ -47,6 +48,16 @@ class AuthController extends Controller | ||||
|         $this->middleware('guest', ['except' => 'getLogout']); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show the application login form. | ||||
|      * | ||||
|      * @return \Illuminate\Http\Response | ||||
|      */ | ||||
|     public function getLogin() | ||||
|     { | ||||
|         return Twig::render('auth.login'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Handle a registration request for the application. | ||||
|      * | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Auth; | ||||
| use Config; | ||||
| use FireflyIII\Http\Requests; | ||||
| use FireflyIII\Http\Requests\BillFormRequest; | ||||
| use FireflyIII\Models\Account; | ||||
| @@ -8,6 +8,7 @@ use FireflyIII\Models\AccountType; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Repositories\Bill\BillRepositoryInterface; | ||||
| use Input; | ||||
| use Redirect; | ||||
| @@ -28,24 +29,25 @@ class BillController extends Controller | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         View::share('title', 'Bills'); | ||||
|         View::share('mainTitleIcon', 'fa-calendar-o'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Bill $bill | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * @param Bill                       $bill | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function add(Bill $bill) | ||||
|     public function add(AccountRepositoryInterface $repository, Bill $bill) | ||||
|     { | ||||
|         $matches     = explode(',', $bill->match); | ||||
|         $description = []; | ||||
|         $expense     = null; | ||||
|  | ||||
|         // get users expense accounts: | ||||
|         $type     = AccountType::where('type', 'Expense account')->first(); | ||||
|         $accounts = Auth::user()->accounts()->where('account_type_id', $type->id)->get(); | ||||
|         $accounts = $repository->getAccounts(Config::get('firefly.accountTypesByIdentifier.expense')); | ||||
|  | ||||
|         foreach ($matches as $match) { | ||||
|             $match = strtolower($match); | ||||
| @@ -81,9 +83,16 @@ class BillController extends Controller | ||||
|      */ | ||||
|     public function create() | ||||
|     { | ||||
|         $periods = \Config::get('firefly.periods_to_text'); | ||||
|         $periods = Config::get('firefly.periods_to_text'); | ||||
|  | ||||
|         return view('bills.create')->with('periods', $periods)->with('subTitle', 'Create new'); | ||||
|         // put previous url in session if not redirect from store (not "create another"). | ||||
|         if (Session::get('bills.create.fromStore') !== true) { | ||||
|             Session::put('bills.create.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('bills.create.fromStore'); | ||||
|         $subTitle = 'Create new bill'; | ||||
|  | ||||
|         return view('bills.create', compact('periods', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -93,20 +102,26 @@ class BillController extends Controller | ||||
|      */ | ||||
|     public function delete(Bill $bill) | ||||
|     { | ||||
|         return view('bills.delete')->with('bill', $bill)->with('subTitle', 'Delete "' . e($bill->name) . '"'); | ||||
|         // put previous url in session | ||||
|         Session::put('bills.delete.url', URL::previous()); | ||||
|         $subTitle = 'Delete "' . e($bill->name) . '"'; | ||||
|  | ||||
|         return view('bills.delete', compact('bill', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Bill $bill | ||||
|      * @param BillRepositoryInterface $repository | ||||
|      * @param Bill                    $bill | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function destroy(Bill $bill) | ||||
|     public function destroy(BillRepositoryInterface $repository, Bill $bill) | ||||
|     { | ||||
|         $bill->delete(); | ||||
|         $repository->destroy($bill); | ||||
|  | ||||
|         Session::flash('success', 'The bill was deleted.'); | ||||
|  | ||||
|         return Redirect::route('bills.index'); | ||||
|         return Redirect::to(Session::get('bills.delete.url')); | ||||
|  | ||||
|     } | ||||
|  | ||||
| @@ -117,9 +132,16 @@ class BillController extends Controller | ||||
|      */ | ||||
|     public function edit(Bill $bill) | ||||
|     { | ||||
|         $periods = \Config::get('firefly.periods_to_text'); | ||||
|         $periods  = Config::get('firefly.periods_to_text'); | ||||
|         $subTitle = 'Edit "' . e($bill->name) . '"'; | ||||
|  | ||||
|         return view('bills.edit')->with('periods', $periods)->with('bill', $bill)->with('subTitle', 'Edit "' . e($bill->name) . '"'); | ||||
|         // put previous url in session if not redirect from store (not "return_to_edit"). | ||||
|         if (Session::get('bills.edit.fromUpdate') !== true) { | ||||
|             Session::put('bills.edit.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('bills.edit.fromUpdate'); | ||||
|  | ||||
|         return view('bills.edit', compact('subTitle', 'periods', 'bill')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -129,15 +151,11 @@ class BillController extends Controller | ||||
|      */ | ||||
|     public function index(BillRepositoryInterface $repository) | ||||
|     { | ||||
|         $bills = Auth::user()->bills()->orderBy('name', 'ASC')->get(); | ||||
|         $bills = $repository->getBills(); | ||||
|         $bills->each( | ||||
|             function (Bill $bill) use ($repository) { | ||||
|                 $bill->nextExpectedMatch = $repository->nextExpectedMatch($bill); | ||||
|                 $last                    = $bill->transactionjournals()->orderBy('date', 'DESC')->first(); | ||||
|                 $bill->lastFoundMatch    = null; | ||||
|                 if ($last) { | ||||
|                     $bill->lastFoundMatch = $last->date; | ||||
|                 } | ||||
|                 $bill->lastFoundMatch    = $repository->lastFoundMatch($bill); | ||||
|             } | ||||
|         ); | ||||
|  | ||||
| @@ -145,34 +163,25 @@ class BillController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Bill $bill | ||||
|      * @param BillRepositoryInterface $repository | ||||
|      * @param Bill                    $bill | ||||
|      * | ||||
|      * @return mixed | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function rescan(Bill $bill, BillRepositoryInterface $repository) | ||||
|     public function rescan(BillRepositoryInterface $repository, Bill $bill) | ||||
|     { | ||||
|         if (intval($bill->active) == 0) { | ||||
|             Session::flash('warning', 'Inactive bills cannot be scanned.'); | ||||
|  | ||||
|             return Redirect::intended('/'); | ||||
|             return Redirect::to(URL::previous()); | ||||
|         } | ||||
|  | ||||
|         $set = \DB::table('transactions')->where('amount', '>', 0)->where('amount', '>=', $bill->amount_min)->where('amount', '<=', $bill->amount_max)->get( | ||||
|             ['transaction_journal_id'] | ||||
|         ); | ||||
|         $ids = []; | ||||
|         $journals = $repository->getPossiblyRelatedJournals($bill); | ||||
|         /** @var TransactionJournal $journal */ | ||||
|         foreach ($journals as $journal) { | ||||
|             $repository->scan($bill, $journal); | ||||
|         } | ||||
|  | ||||
|         /** @var Transaction $entry */ | ||||
|         foreach ($set as $entry) { | ||||
|             $ids[] = intval($entry->transaction_journal_id); | ||||
|         } | ||||
|         if (count($ids) > 0) { | ||||
|             $journals = Auth::user()->transactionjournals()->whereIn('id', $ids)->get(); | ||||
|             /** @var TransactionJournal $journal */ | ||||
|             foreach ($journals as $journal) { | ||||
|                 $repository->scan($bill, $journal); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         Session::flash('success', 'Rescanned everything.'); | ||||
|  | ||||
| @@ -180,26 +189,26 @@ class BillController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Bill $bill | ||||
|      * @param BillRepositoryInterface $repository | ||||
|      * @param Bill                    $bill | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function show(Bill $bill, BillRepositoryInterface $repository) | ||||
|     public function show(BillRepositoryInterface $repository, Bill $bill) | ||||
|     { | ||||
|         $journals                = $bill->transactionjournals()->withRelevantData() | ||||
|                                         ->orderBy('transaction_journals.date', 'DESC') | ||||
|                                         ->orderBy('transaction_journals.order', 'ASC') | ||||
|                                         ->orderBy('transaction_journals.id', 'DESC') | ||||
|                                         ->get(); | ||||
|         $journals                = $repository->getJournals($bill); | ||||
|         $bill->nextExpectedMatch = $repository->nextExpectedMatch($bill); | ||||
|         $hideBill                = true; | ||||
|         $subTitle                = e($bill->name); | ||||
|  | ||||
|  | ||||
|         return view('bills.show', compact('journals', 'hideBill', 'bill'))->with('subTitle', e($bill->name)); | ||||
|         return view('bills.show', compact('journals', 'hideBill', 'bill', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return $this | ||||
|      * @param BillFormRequest         $request | ||||
|      * @param BillRepositoryInterface $repository | ||||
|      * | ||||
|      * @return $this|\Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function store(BillFormRequest $request, BillRepositoryInterface $repository) | ||||
|     { | ||||
| @@ -208,30 +217,40 @@ class BillController extends Controller | ||||
|         Session::flash('success', 'Bill "' . e($bill->name) . '" stored.'); | ||||
|  | ||||
|         if (intval(Input::get('create_another')) === 1) { | ||||
|             // set value so create routine will not overwrite URL: | ||||
|             Session::put('bills.create.fromStore', true); | ||||
|  | ||||
|             return Redirect::route('bills.create')->withInput(); | ||||
|         } | ||||
|  | ||||
|         return Redirect::route('bills.index'); | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('bills.create.url')); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Bill $bill | ||||
|      * @param BillFormRequest         $request | ||||
|      * @param BillRepositoryInterface $repository | ||||
|      * @param Bill                    $bill | ||||
|      * | ||||
|      * @return $this | ||||
|      * @return $this|\Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function update(Bill $bill, BillFormRequest $request, BillRepositoryInterface $repository) | ||||
|     public function update(BillFormRequest $request, BillRepositoryInterface $repository, Bill $bill) | ||||
|     { | ||||
|         $billData = $request->getBillData(); | ||||
|         $bill     = $repository->update($bill, $billData); | ||||
|  | ||||
|         if (intval(Input::get('return_to_edit')) === 1) { | ||||
|             return Redirect::route('bills.edit', $bill->id); | ||||
|         } | ||||
|  | ||||
|         Session::flash('success', 'Bill "' . e($bill->name) . '" updated.'); | ||||
|  | ||||
|         return Redirect::route('bills.index'); | ||||
|         if (intval(Input::get('return_to_edit')) === 1) { | ||||
|             // set value so edit routine will not overwrite URL: | ||||
|             Session::put('bills.edit.fromUpdate', true); | ||||
|  | ||||
|             return Redirect::route('bills.edit', $bill->id)->withInput(['return_to_edit' => 1]); | ||||
|         } | ||||
|  | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('bills.edit.url')); | ||||
|  | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -13,8 +13,9 @@ use Preferences; | ||||
| use Redirect; | ||||
| use Response; | ||||
| use Session; | ||||
| use View; | ||||
| use URL; | ||||
| use View; | ||||
|  | ||||
| /** | ||||
|  * Class BudgetController | ||||
|  * | ||||
| @@ -28,16 +29,19 @@ class BudgetController extends Controller | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         View::share('title', 'Budgets'); | ||||
|         View::share('mainTitleIcon', 'fa-tasks'); | ||||
|         View::share('hideBudgets', true); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
|      * @param Budget                    $budget | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function amount(Budget $budget, BudgetRepositoryInterface $repository) | ||||
|     public function amount(BudgetRepositoryInterface $repository, Budget $budget) | ||||
|     { | ||||
|         $amount          = intval(Input::get('amount')); | ||||
|         $date            = Session::get('start', Carbon::now()->startOfMonth()); | ||||
| @@ -57,8 +61,9 @@ class BudgetController extends Controller | ||||
|             Session::put('budgets.create.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('budgets.create.fromStore'); | ||||
|         $subTitle = 'Create a new budget'; | ||||
|  | ||||
|         return view('budgets.create')->with('subTitle', 'Create a new budget'); | ||||
|         return view('budgets.create', compact('subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -77,7 +82,8 @@ class BudgetController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * @param Budget                    $budget | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
| @@ -88,7 +94,6 @@ class BudgetController extends Controller | ||||
|         $repository->destroy($budget); | ||||
|  | ||||
|  | ||||
|  | ||||
|         Session::flash('success', 'The  budget "' . e($name) . '" was deleted.'); | ||||
|  | ||||
|         return Redirect::to(Session::get('budgets.delete.url')); | ||||
| @@ -114,12 +119,14 @@ class BudgetController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return mixed | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
|      * | ||||
|      * @return View | ||||
|      */ | ||||
|     public function index(BudgetRepositoryInterface $repository) | ||||
|     { | ||||
|         $budgets  = Auth::user()->budgets()->where('active', 1)->get(); | ||||
|         $inactive = Auth::user()->budgets()->where('active', 0)->get(); | ||||
|         $budgets  = $repository->getActiveBudgets(); | ||||
|         $inactive = $repository->getInactiveBudgets(); | ||||
|  | ||||
|         /** | ||||
|          * Do some cleanup: | ||||
| @@ -127,19 +134,18 @@ class BudgetController extends Controller | ||||
|         $repository->cleanupBudgets(); | ||||
|  | ||||
|  | ||||
|  | ||||
|         // loop the budgets: | ||||
|         $budgets->each( | ||||
|             function (Budget $budget) use ($repository) { | ||||
|                 $date               = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|                 $budget->spent      = $repository->spentInMonth($budget, $date); | ||||
|                 $budget->currentRep = $budget->limitrepetitions()->where('limit_repetitions.startdate', $date)->first(['limit_repetitions.*']); | ||||
|                 $budget->currentRep = $repository->getCurrentRepetition($budget, $date); | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         $date          = Session::get('start', Carbon::now()->startOfMonth())->format('FY'); | ||||
|         $dateAsString  = Session::get('start', Carbon::now()->startOfMonth())->format('FY'); | ||||
|         $spent         = $budgets->sum('spent'); | ||||
|         $amount        = Preferences::get('budgetIncomeTotal' . $date, 1000)->data; | ||||
|         $amount        = Preferences::get('budgetIncomeTotal' . $dateAsString, 1000)->data; | ||||
|         $overspent     = $spent > $amount; | ||||
|         $spentPCT      = $overspent ? ceil($amount / $spent * 100) : ceil($spent / $amount * 100); | ||||
|         $budgetMax     = Preferences::get('budgetMaximum', 1000); | ||||
| @@ -149,29 +155,22 @@ class BudgetController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\View\View | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
|      * | ||||
|      * @return View | ||||
|      */ | ||||
|     public function noBudget() | ||||
|     public function noBudget(BudgetRepositoryInterface $repository) | ||||
|     { | ||||
|         $start    = \Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end      = \Session::get('end', Carbon::now()->startOfMonth()); | ||||
|         $list     = Auth::user() | ||||
|                         ->transactionjournals() | ||||
|                         ->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') | ||||
|                         ->whereNull('budget_transaction_journal.id') | ||||
|                         ->before($end) | ||||
|                         ->after($start) | ||||
|                         ->orderBy('transaction_journals.date', 'DESC') | ||||
|                         ->orderBy('transaction_journals.order', 'ASC') | ||||
|                         ->orderBy('transaction_journals.id', 'DESC') | ||||
|                         ->get(['transaction_journals.*']); | ||||
|         $subTitle = 'Transactions without a budget in ' . $start->format('F Y'); | ||||
|         $start    = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end      = Session::get('end', Carbon::now()->startOfMonth()); | ||||
|         $list     = $repository->getWithoutBudget($start, $end); | ||||
|         $subTitle = 'Transactions without a budget between ' . $start->format('jS F Y') . ' and ' . $end->format('jS F Y'); | ||||
|  | ||||
|         return view('budgets.noBudget', compact('list', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return mixed | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function postUpdateIncome() | ||||
|     { | ||||
| @@ -182,6 +181,29 @@ class BudgetController extends Controller | ||||
|         return Redirect::route('budgets.index'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
|      * @param Budget                    $budget | ||||
|      * @param LimitRepetition           $repetition | ||||
|      * | ||||
|      * @return View | ||||
|      */ | ||||
|     public function show(BudgetRepositoryInterface $repository, Budget $budget, LimitRepetition $repetition = null) | ||||
|     { | ||||
|         if (!is_null($repetition->id) && $repetition->budgetLimit->budget->id != $budget->id) { | ||||
|             $message = 'Invalid selection.'; | ||||
|  | ||||
|             return view('error', compact('message')); | ||||
|         } | ||||
|  | ||||
|         $journals = $repository->getJournals($budget, $repetition); | ||||
|         $limits   = !is_null($repetition->id) ? [$repetition->budgetLimit] : $repository->getBudgetLimits($budget); | ||||
|         $subTitle = !is_null($repetition->id) ? e($budget->name) . ' in ' . $repetition->startdate->format('F Y') : e($budget->name); | ||||
|         $journals->setPath('/budgets/show/' . $budget->id); | ||||
|  | ||||
|         return view('budgets.show', compact('limits', 'budget', 'repetition', 'journals', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BudgetFormRequest         $request | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
| @@ -201,6 +223,7 @@ class BudgetController extends Controller | ||||
|         if (intval(Input::get('create_another')) === 1) { | ||||
|             // set value so create routine will not overwrite URL: | ||||
|             Session::put('budgets.create.fromStore', true); | ||||
|  | ||||
|             return Redirect::route('budgets.create')->withInput(); | ||||
|         } | ||||
|  | ||||
| @@ -210,34 +233,13 @@ class BudgetController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * @param Budget          $budget | ||||
|      * @param LimitRepetition $repetition | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function show(Budget $budget, LimitRepetition $repetition = null, BudgetRepositoryInterface $repository) | ||||
|     { | ||||
|         if (!is_null($repetition->id) && $repetition->budgetLimit->budget->id != $budget->id) { | ||||
|             return view('error')->with('message', 'Invalid selection.'); | ||||
|         } | ||||
|  | ||||
|         $hideBudget = true; // used in transaction list. | ||||
|         $journals   = $repository->getJournals($budget, $repetition); | ||||
|         $limits     = !is_null($repetition->id) ? [$repetition->budgetLimit] : $budget->budgetLimits()->orderBy('startdate', 'DESC')->get(); | ||||
|         $subTitle   = !is_null($repetition->id) ? e($budget->name) . ' in ' . $repetition->startdate->format('F Y') : e($budget->name); | ||||
|  | ||||
|         return view('budgets.show', compact('limits', 'budget', 'repetition', 'journals', 'subTitle', 'hideBudget')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Budget                    $budget | ||||
|      * @param BudgetFormRequest         $request | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
|      * @param Budget                    $budget | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      * @return $this|\Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function update(Budget $budget, BudgetFormRequest $request, BudgetRepositoryInterface $repository) | ||||
|     public function update(BudgetFormRequest $request, BudgetRepositoryInterface $repository, Budget $budget) | ||||
|     { | ||||
|         $budgetData = [ | ||||
|             'name'   => $request->input('name'), | ||||
| @@ -251,6 +253,7 @@ class BudgetController extends Controller | ||||
|         if (intval(Input::get('return_to_edit')) === 1) { | ||||
|             // set value so edit routine will not overwrite URL: | ||||
|             Session::put('budgets.edit.fromUpdate', true); | ||||
|  | ||||
|             return Redirect::route('budgets.edit', $budget->id)->withInput(['return_to_edit' => 1]); | ||||
|         } | ||||
|  | ||||
| @@ -260,14 +263,14 @@ class BudgetController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return $this | ||||
|      * @return View | ||||
|      */ | ||||
|     public function updateIncome() | ||||
|     { | ||||
|         $date         = Session::get('start', Carbon::now()->startOfMonth())->format('FY'); | ||||
|         $budgetAmount = Preferences::get('budgetIncomeTotal' . $date, 1000); | ||||
|         $date   = Session::get('start', Carbon::now()->startOfMonth())->format('FY'); | ||||
|         $amount = Preferences::get('budgetIncomeTotal' . $date, 1000); | ||||
|  | ||||
|         return view('budgets.income')->with('amount', $budgetAmount); | ||||
|         return view('budgets.income', compact('amount')); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -2,7 +2,6 @@ | ||||
|  | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Http\Requests; | ||||
| use FireflyIII\Http\Requests\CategoryFormRequest; | ||||
| use FireflyIII\Models\Category; | ||||
| use FireflyIII\Repositories\Category\CategoryRepositoryInterface; | ||||
| @@ -10,8 +9,8 @@ use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use Input; | ||||
| use Redirect; | ||||
| use Session; | ||||
| use View; | ||||
| use URL; | ||||
| use View; | ||||
|  | ||||
| /** | ||||
|  * Class CategoryController | ||||
| @@ -26,6 +25,7 @@ class CategoryController extends Controller | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         View::share('title', 'Categories'); | ||||
|         View::share('mainTitleIcon', 'fa-bar-chart'); | ||||
|     } | ||||
| @@ -40,8 +40,9 @@ class CategoryController extends Controller | ||||
|             Session::put('categories.create.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('categories.create.fromStore'); | ||||
|         $subTitle = 'Create a new category'; | ||||
|  | ||||
|         return view('categories.create')->with('subTitle', 'Create a new category'); | ||||
|         return view('categories.create', compact('subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -51,7 +52,7 @@ class CategoryController extends Controller | ||||
|      */ | ||||
|     public function delete(Category $category) | ||||
|     { | ||||
|         $subTitle = 'Delete category' . e($category->name) . '"'; | ||||
|         $subTitle = 'Delete category "' . e($category->name) . '"'; | ||||
|  | ||||
|         // put previous url in session | ||||
|         Session::put('categories.delete.url', URL::previous()); | ||||
| @@ -60,11 +61,12 @@ class CategoryController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Category $category | ||||
|      * @param CategoryRepositoryInterface $repository | ||||
|      * @param Category                    $category | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function destroy(Category $category, CategoryRepositoryInterface $repository) | ||||
|     public function destroy(CategoryRepositoryInterface $repository, Category $category) | ||||
|     { | ||||
|  | ||||
|         $name = $category->name; | ||||
| @@ -95,22 +97,17 @@ class CategoryController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param CategoryRepositoryInterface $repository | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function index() | ||||
|     public function index(CategoryRepositoryInterface $repository) | ||||
|     { | ||||
|         $categories = Auth::user()->categories()->orderBy('name', 'ASC')->get(); | ||||
|         $categories = $repository->getCategories(); | ||||
|  | ||||
|         $categories->each( | ||||
|             function (Category $category) { | ||||
|                 $latest = $category->transactionjournals() | ||||
|                                    ->orderBy('transaction_journals.date', 'DESC') | ||||
|                                    ->orderBy('transaction_journals.order', 'ASC') | ||||
|                                    ->orderBy('transaction_journals.id', 'DESC') | ||||
|                                    ->first(); | ||||
|                 if ($latest) { | ||||
|                     $category->lastActivity = $latest->date; | ||||
|                 } | ||||
|             function (Category $category) use ($repository) { | ||||
|                 $category->lastActivity = $repository->getLatestActivity($category); | ||||
|             } | ||||
|         ); | ||||
|  | ||||
| @@ -118,48 +115,34 @@ class CategoryController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param CategoryRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function noCategory() | ||||
|     public function noCategory(CategoryRepositoryInterface $repository) | ||||
|     { | ||||
|         $start = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end   = Session::get('end', Carbon::now()->startOfMonth()); | ||||
|         $list  = Auth::user() | ||||
|                      ->transactionjournals() | ||||
|                      ->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') | ||||
|                      ->whereNull('category_transaction_journal.id') | ||||
|                      ->before($end) | ||||
|                      ->after($start) | ||||
|                      ->orderBy('transaction_journals.date', 'DESC') | ||||
|                      ->orderBy('transaction_journals.order', 'ASC') | ||||
|                      ->orderBy('transaction_journals.id', 'DESC') | ||||
|                      ->get(['transaction_journals.*']); | ||||
|  | ||||
|         $start    = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end      = Session::get('end', Carbon::now()->startOfMonth()); | ||||
|         $list     = $repository->getWithoutCategory($start, $end); | ||||
|         $subTitle = 'Transactions without a category between ' . $start->format('jS F Y') . ' and ' . $end->format('jS F Y'); | ||||
|  | ||||
|         return view('categories.noCategory', compact('list', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Category $category | ||||
|      * @param CategoryRepositoryInterface $repository | ||||
|      * @param Category                    $category | ||||
|      * | ||||
|      * @return $this | ||||
|      * @return View | ||||
|      */ | ||||
|     public function show(Category $category, CategoryRepositoryInterface $repository) | ||||
|     public function show(CategoryRepositoryInterface $repository, Category $category) | ||||
|     { | ||||
|         $hideCategory = true; // used in list. | ||||
|         $page         = intval(Input::get('page')); | ||||
|         $offset       = $page > 0 ? $page * 50 : 0; | ||||
|         $set          = $category->transactionJournals()->withRelevantData()->take(50)->offset($offset) | ||||
|                                  ->orderBy('transaction_journals.date', 'DESC') | ||||
|                                  ->orderBy('transaction_journals.order', 'ASC') | ||||
|                                  ->orderBy('transaction_journals.id', 'DESC') | ||||
|                                  ->get( | ||||
|                                      ['transaction_journals.*'] | ||||
|                                  ); | ||||
|         $count        = $category->transactionJournals()->count(); | ||||
|  | ||||
|         $journals = new LengthAwarePaginator($set, $count, 50, $page); | ||||
|         $set          = $repository->getJournals($category, $page); | ||||
|         $count        = $repository->countJournals($category); | ||||
|         $journals     = new LengthAwarePaginator($set, $count, 50, $page); | ||||
|         $journals->setPath('categories/show/' . $category->id); | ||||
|  | ||||
|         return view('categories.show', compact('category', 'journals', 'hideCategory')); | ||||
|     } | ||||
| @@ -182,23 +165,22 @@ class CategoryController extends Controller | ||||
|  | ||||
|         if (intval(Input::get('create_another')) === 1) { | ||||
|             Session::put('categories.create.fromStore', true); | ||||
|  | ||||
|             return Redirect::route('categories.create')->withInput(); | ||||
|         } | ||||
|  | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('categories.create.url')); | ||||
|  | ||||
|         return Redirect::route('categories.index'); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @param Category                    $category | ||||
|      * @param CategoryFormRequest         $request | ||||
|      * @param CategoryRepositoryInterface $repository | ||||
|      * @param Category                    $category | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function update(Category $category, CategoryFormRequest $request, CategoryRepositoryInterface $repository) | ||||
|     public function update(CategoryFormRequest $request, CategoryRepositoryInterface $repository, Category $category) | ||||
|     { | ||||
|         $categoryData = [ | ||||
|             'name' => $request->input('name'), | ||||
| @@ -210,6 +192,7 @@ class CategoryController extends Controller | ||||
|  | ||||
|         if (intval(Input::get('return_to_edit')) === 1) { | ||||
|             Session::put('categories.edit.fromUpdate', true); | ||||
|  | ||||
|             return Redirect::route('categories.edit', $category->id); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| use Illuminate\Foundation\Bus\DispatchesCommands; | ||||
| use Illuminate\Foundation\Validation\ValidatesRequests; | ||||
| use Illuminate\Routing\Controller as BaseController; | ||||
| use View; | ||||
|  | ||||
| /** | ||||
|  * Class Controller | ||||
| @@ -14,4 +15,14 @@ abstract class Controller extends BaseController | ||||
|  | ||||
|     use DispatchesCommands, ValidatesRequests; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         View::share('hideBudgets', false); | ||||
|         View::share('hideCategories', false); | ||||
|         View::share('hideBills', false); | ||||
|         View::share('hideTags', false); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -5,12 +5,13 @@ use FireflyIII\Http\Requests; | ||||
| use FireflyIII\Http\Requests\CurrencyFormRequest; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | ||||
| use Input; | ||||
| use Preferences; | ||||
| use Redirect; | ||||
| use Session; | ||||
| use View; | ||||
| use URL; | ||||
| use View; | ||||
|  | ||||
| /** | ||||
|  * Class CurrencyController | ||||
| @@ -26,7 +27,7 @@ class CurrencyController extends Controller | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|  | ||||
|         parent::__construct(); | ||||
|         View::share('title', 'Currencies'); | ||||
|         View::share('mainTitleIcon', 'fa-usd'); | ||||
|     } | ||||
| @@ -56,9 +57,7 @@ class CurrencyController extends Controller | ||||
|     public function defaultCurrency(TransactionCurrency $currency) | ||||
|     { | ||||
|  | ||||
|         $currencyPreference       = Preferences::get('currencyPreference', 'EUR'); | ||||
|         $currencyPreference->data = $currency->code; | ||||
|         $currencyPreference->save(); | ||||
|         Preferences::set('currencyPreference', $currency->code); | ||||
|  | ||||
|         Session::flash('success', $currency->name . ' is now the default currency.'); | ||||
|         Cache::forget('FFCURRENCYSYMBOL'); | ||||
| @@ -69,34 +68,38 @@ class CurrencyController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionCurrency $currency | ||||
|      * @param CurrencyRepositoryInterface $repository | ||||
|      * @param TransactionCurrency         $currency | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View | ||||
|      * @return \Illuminate\Http\RedirectResponse|View | ||||
|      */ | ||||
|     public function delete(TransactionCurrency $currency) | ||||
|     public function delete(CurrencyRepositoryInterface $repository, TransactionCurrency $currency) | ||||
|     { | ||||
|         if ($currency->transactionJournals()->count() > 0) { | ||||
|             Session::flash('error', 'Cannot delete ' . e($currency->name) . ' because there are still transactions attached to it.'); | ||||
|  | ||||
|             // put previous url in session | ||||
|             Session::put('currency.delete.url', URL::previous()); | ||||
|         if ($repository->countJournals($currency) > 0) { | ||||
|             Session::flash('error', 'Cannot delete ' . e($currency->name) . ' because there are still transactions attached to it.'); | ||||
|  | ||||
|             return Redirect::route('currency.index'); | ||||
|         } | ||||
|  | ||||
|         // put previous url in session | ||||
|         Session::put('currency.delete.url', URL::previous()); | ||||
|  | ||||
|  | ||||
|         return view('currency.delete', compact('currency')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionCurrency $currency | ||||
|      * @param CurrencyRepositoryInterface $repository | ||||
|      * @param TransactionCurrency         $currency | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      * @throws \Exception | ||||
|      */ | ||||
|     public function destroy(TransactionCurrency $currency) | ||||
|     public function destroy(CurrencyRepositoryInterface $repository, TransactionCurrency $currency) | ||||
|     { | ||||
|         if ($currency->transactionJournals()->count() > 0) { | ||||
|             Session::flash('error', 'Cannot delete ' . e($currency->name) . ' because there are still transactions attached to it.'); | ||||
|         if ($repository->countJournals($currency) > 0) { | ||||
|             Session::flash('error', 'Cannot destroy ' . e($currency->name) . ' because there are still transactions attached to it.'); | ||||
|  | ||||
|             return Redirect::route('currency.index'); | ||||
|         } | ||||
| @@ -130,67 +133,63 @@ class CurrencyController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param CurrencyRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function index() | ||||
|     public function index(CurrencyRepositoryInterface $repository) | ||||
|     { | ||||
|         $currencies         = TransactionCurrency::get(); | ||||
|         $currencyPreference = Preferences::get('currencyPreference', 'EUR'); | ||||
|         $defaultCurrency    = TransactionCurrency::whereCode($currencyPreference->data)->first(); | ||||
|  | ||||
|         $currencies      = $repository->get(); | ||||
|         $defaultCurrency = $repository->getCurrencyByPreference(Preferences::get('currencyPreference', 'EUR')); | ||||
|  | ||||
|         return view('currency.index', compact('currencies', 'defaultCurrency')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind. | ||||
|      * | ||||
|      * @param CurrencyFormRequest         $request | ||||
|      * @param CurrencyRepositoryInterface $repository | ||||
|      * | ||||
|      * @return $this|\Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function store(CurrencyFormRequest $request) | ||||
|     public function store(CurrencyFormRequest $request, CurrencyRepositoryInterface $repository) | ||||
|     { | ||||
|         $data     = $request->getCurrencyData(); | ||||
|         $currency = $repository->store($data); | ||||
|  | ||||
|  | ||||
|         // no repository, because the currency controller is relatively simple. | ||||
|         $currency = TransactionCurrency::create( | ||||
|             [ | ||||
|                 'name'   => $request->get('name'), | ||||
|                 'code'   => $request->get('code'), | ||||
|                 'symbol' => $request->get('symbol'), | ||||
|             ] | ||||
|         ); | ||||
|  | ||||
|         Session::flash('success', 'Currency "' . $currency->name . '" created'); | ||||
|  | ||||
|         if (intval(Input::get('create_another')) === 1) { | ||||
|             Session::put('currency.create.fromStore', true); | ||||
|  | ||||
|             return Redirect::route('currency.create')->withInput(); | ||||
|         } | ||||
|  | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('categories.create.url')); | ||||
|         return Redirect::to(Session::get('currency.create.url')); | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionCurrency $currency | ||||
|      * @param CurrencyFormRequest         $request | ||||
|      * @param CurrencyRepositoryInterface $repository | ||||
|      * @param TransactionCurrency         $currency | ||||
|      * | ||||
|      * @return $this|\Illuminate\Http\RedirectResponse | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function update(TransactionCurrency $currency, CurrencyFormRequest $request) | ||||
|     public function update(CurrencyFormRequest $request, CurrencyRepositoryInterface $repository, TransactionCurrency $currency) | ||||
|     { | ||||
|  | ||||
|         $currency->code   = $request->get('code'); | ||||
|         $currency->symbol = $request->get('symbol'); | ||||
|         $currency->name   = $request->get('name'); | ||||
|         $currency->save(); | ||||
|         $data     = $request->getCurrencyData(); | ||||
|         $currency = $repository->update($currency, $data); | ||||
|  | ||||
|         Session::flash('success', 'Currency "' . e($currency->name) . '" updated.'); | ||||
|  | ||||
|  | ||||
|         if (intval(Input::get('return_to_edit')) === 1) { | ||||
|             Session::put('currency.edit.fromUpdate', true); | ||||
|  | ||||
|             return Redirect::route('currency.edit', $currency->id); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -1,12 +1,7 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Amount; | ||||
| use App; | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use Crypt; | ||||
| use DB; | ||||
| use Exception; | ||||
| use FireflyIII\Helpers\Report\ReportQueryInterface; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\Bill; | ||||
| @@ -17,11 +12,12 @@ use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Models\Preference; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Repositories\Bill\BillRepositoryInterface; | ||||
| use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; | ||||
| use FireflyIII\Repositories\Category\CategoryRepositoryInterface; | ||||
| use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; | ||||
| use Grumpydictator\Gchart\GChart; | ||||
| use Illuminate\Database\Query\Builder as QueryBuilder; | ||||
| use Illuminate\Database\Query\JoinClause; | ||||
| use Illuminate\Support\Collection; | ||||
| use Navigation; | ||||
| use Preferences; | ||||
| @@ -39,12 +35,12 @@ class GoogleChartController extends Controller | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @param GChart  $chart | ||||
|      * @param Account $account | ||||
|      * @param string  $view | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function accountBalanceChart(Account $account, GChart $chart) | ||||
|     public function accountBalanceChart(GChart $chart, Account $account) | ||||
|     { | ||||
|         $chart->addColumn('Day of month', 'date'); | ||||
|         $chart->addColumn('Balance for ' . $account->name, 'number'); | ||||
| @@ -68,23 +64,20 @@ class GoogleChartController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param GChart $chart | ||||
|      * @param GChart                     $chart | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function allAccountsBalanceChart(GChart $chart) | ||||
|     public function allAccountsBalanceChart(GChart $chart, AccountRepositoryInterface $repository) | ||||
|     { | ||||
|         $chart->addColumn('Day of the month', 'date'); | ||||
|  | ||||
|         $frontPage = Preferences::get('frontPageAccounts', []); | ||||
|         $start     = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end       = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|         $accounts  = $repository->getFrontpageAccounts($frontPage); | ||||
|  | ||||
|         if ($frontPage->data == []) { | ||||
|             $accounts = Auth::user()->accounts()->orderBy('accounts.name', 'ASC')->accountTypeIn(['Default account', 'Asset account'])->get(['accounts.*']); | ||||
|         } else { | ||||
|             $accounts = Auth::user()->accounts()->whereIn('id', $frontPage->data)->orderBy('accounts.name', 'ASC')->get(['accounts.*']); | ||||
|         } | ||||
|         $index = 1; | ||||
|         /** @var Account $account */ | ||||
|         foreach ($accounts as $account) { | ||||
| @@ -112,28 +105,24 @@ class GoogleChartController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param int $year | ||||
|      * @param GChart                    $chart | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
|      * @param                           $year | ||||
|      * | ||||
|      * @return $this|\Illuminate\Http\JsonResponse | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function allBudgetsAndSpending($year, GChart $chart, BudgetRepositoryInterface $repository) | ||||
|     public function allBudgetsAndSpending(GChart $chart, BudgetRepositoryInterface $repository, $year) | ||||
|     { | ||||
|         try { | ||||
|             new Carbon('01-01-' . $year); | ||||
|         } catch (Exception $e) { | ||||
|             return view('error')->with('message', 'Invalid year.'); | ||||
|         } | ||||
|         $budgets = Auth::user()->budgets()->get(); | ||||
|         $budgets->sortBy('name'); | ||||
|         $budgets = $repository->getBudgets(); | ||||
|         $chart->addColumn('Month', 'date'); | ||||
|         foreach ($budgets as $budget) { | ||||
|             $chart->addColumn($budget->name, 'number'); | ||||
|         } | ||||
|  | ||||
|         $start = Carbon::createFromDate(intval($year), 1, 1); | ||||
|         $end   = clone $start; | ||||
|         $end->endOfYear(); | ||||
|  | ||||
|  | ||||
|         while ($start <= $end) { | ||||
|             $row = [clone $start]; | ||||
|             foreach ($budgets as $budget) { | ||||
| @@ -144,7 +133,6 @@ class GoogleChartController extends Controller | ||||
|             $start->addMonth(); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         $chart->generate(); | ||||
|  | ||||
|         return Response::json($chart->getData()); | ||||
| @@ -152,112 +140,73 @@ class GoogleChartController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param GChart $chart | ||||
|      * @param GChart                    $chart | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function allBudgetsHomeChart(GChart $chart) | ||||
|     public function allBudgetsHomeChart(GChart $chart, BudgetRepositoryInterface $repository) | ||||
|     { | ||||
|         $chart->addColumn('Budget', 'string'); | ||||
|         $chart->addColumn('Budgeted', 'number'); | ||||
|         $chart->addColumn('Spent', 'number'); | ||||
|         $chart->addColumn('Left', 'number'); | ||||
|         $chart->addColumn('Overspent', 'number'); | ||||
|  | ||||
|         $budgets = Auth::user()->budgets()->orderBy('name', 'DESC')->get(); | ||||
|         $start   = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end     = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|         $budgets    = $repository->getBudgets(); | ||||
|         $start      = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end        = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|         $allEntries = new Collection; | ||||
|  | ||||
|         /** @var Budget $budget */ | ||||
|         foreach ($budgets as $budget) { | ||||
|  | ||||
|             /** @var Collection $repetitions */ | ||||
|             $repetitions = LimitRepetition:: | ||||
|             leftJoin('budget_limits', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id') | ||||
|                                           ->where('limit_repetitions.startdate', '<=', $end->format('Y-m-d 00:00:00')) | ||||
|                                           ->where('limit_repetitions.startdate', '>=', $start->format('Y-m-d 00:00:00')) | ||||
|                                           ->where('budget_limits.budget_id', $budget->id) | ||||
|                                           ->get(['limit_repetitions.*']); | ||||
|  | ||||
|             // no results? search entire range for expenses and list those. | ||||
|             $repetitions = $repository->getBudgetLimitRepetitions($budget, $start, $end); | ||||
|             if ($repetitions->count() == 0) { | ||||
|                 $expenses = floatval($budget->transactionjournals()->before($end)->after($start)->lessThan(0)->sum('amount')) * -1; | ||||
|                 if ($expenses > 0) { | ||||
|                     $chart->addRow($budget->name, 0, $expenses); | ||||
|                 } | ||||
|             } else { | ||||
|                 // add with foreach: | ||||
|                 /** @var LimitRepetition $repetition */ | ||||
|                 foreach ($repetitions as $repetition) { | ||||
|  | ||||
|                     $expenses | ||||
|                         = | ||||
|                         floatval($budget->transactionjournals()->before($repetition->enddate)->after($repetition->startdate)->lessThan(0)->sum('amount')) * -1; | ||||
|                     if ($expenses > 0) { | ||||
|                         $chart->addRow($budget->name . ' (' . $repetition->startdate->format('j M Y') . ')', floatval($repetition->amount), $expenses); | ||||
|                     } | ||||
|                 } | ||||
|                 $expenses = $repository->sumBudgetExpensesInPeriod($budget, $start, $end); | ||||
|                 $allEntries->push([$budget->name, 0, $expenses]); | ||||
|                 continue; | ||||
|             } | ||||
|             /** @var LimitRepetition $repetition */ | ||||
|             foreach ($repetitions as $repetition) { | ||||
|                 $expenses = $repository->sumBudgetExpensesInPeriod($budget, $repetition->startdate, $repetition->enddate); | ||||
|                 $allEntries->push([$budget->name . ' (' . $repetition->startdate->format('j M Y') . ')', floatval($repetition->amount), $expenses]); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $noBudgetExpenses = $repository->getWithoutBudgetSum($start, $end); | ||||
|         $allEntries->push(['(no budget)', 0, $noBudgetExpenses]); | ||||
|  | ||||
|         foreach ($allEntries as $entry) { | ||||
|             if ($entry[2] > 0) { | ||||
|                 $left = $entry[1] - $entry[2]; | ||||
|                 if ($left > 0) { | ||||
|                     $chart->addRow($entry[0], $left, null); | ||||
|                 } else { | ||||
|                     if ($left < 0) { | ||||
|                         $chart->addRow($entry[0], null, $left); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|             } | ||||
|  | ||||
|  | ||||
|         } | ||||
|  | ||||
|         $noBudgetSet = Auth::user() | ||||
|                            ->transactionjournals() | ||||
|                            ->whereNotIn( | ||||
|                                'transaction_journals.id', function (QueryBuilder $query) use ($start, $end) { | ||||
|                                $query | ||||
|                                    ->select('transaction_journals.id') | ||||
|                                    ->from('transaction_journals') | ||||
|                                    ->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') | ||||
|                                    ->where('transaction_journals.date', '>=', $start->format('Y-m-d 00:00:00')) | ||||
|                                    ->where('transaction_journals.date', '<=', $end->format('Y-m-d 00:00:00')) | ||||
|                                    ->whereNotNull('budget_transaction_journal.budget_id'); | ||||
|                            } | ||||
|                            ) | ||||
|                            ->before($end) | ||||
|                            ->after($start) | ||||
|                            ->lessThan(0) | ||||
|                            ->transactionTypes(['Withdrawal']) | ||||
|                            ->get(); | ||||
|         $sum         = $noBudgetSet->sum('amount') * -1; | ||||
|         $chart->addRow('No budget', 0, $sum); | ||||
|         $chart->generate(); | ||||
|  | ||||
|         return Response::json($chart->getData()); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param GChart $chart | ||||
|      * @param GChart                      $chart | ||||
|      * @param CategoryRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function allCategoriesHomeChart(GChart $chart) | ||||
|     public function allCategoriesHomeChart(GChart $chart, CategoryRepositoryInterface $repository) | ||||
|     { | ||||
|         $chart->addColumn('Category', 'string'); | ||||
|         $chart->addColumn('Spent', 'number'); | ||||
|  | ||||
|         // query! | ||||
|         $start = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end   = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|         $set   = TransactionJournal:: | ||||
|         where('transaction_journals.user_id', Auth::user()->id) | ||||
|                                    ->leftJoin( | ||||
|                                        'transactions', | ||||
|                                        function (JoinClause $join) { | ||||
|                                            $join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('amount', '>', 0); | ||||
|                                        } | ||||
|                                    ) | ||||
|                                    ->leftJoin( | ||||
|                                        'category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id' | ||||
|                                    ) | ||||
|                                    ->leftJoin('categories', 'categories.id', '=', 'category_transaction_journal.category_id') | ||||
|                                    ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') | ||||
|                                    ->before($end) | ||||
|                                    ->where('categories.user_id', Auth::user()->id) | ||||
|                                    ->after($start) | ||||
|                                    ->where('transaction_types.type', 'Withdrawal') | ||||
|                                    ->groupBy('categories.id') | ||||
|                                    ->orderBy('sum', 'DESC') | ||||
|                                    ->get(['categories.id', 'categories.encrypted', 'categories.name', \DB::Raw('SUM(`transactions`.`amount`) AS `sum`')]); | ||||
|         $set   = $repository->getCategoriesAndExpenses($start, $end); | ||||
|  | ||||
|         foreach ($set as $entry) { | ||||
|             $isEncrypted = intval($entry->encrypted) == 1 ? true : false; | ||||
| @@ -273,11 +222,13 @@ class GoogleChartController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Bill $bill | ||||
|      * @param GChart                  $chart | ||||
|      * @param BillRepositoryInterface $repository | ||||
|      * @param Bill                    $bill | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function billOverview(Bill $bill, GChart $chart) | ||||
|     public function billOverview(GChart $chart, BillRepositoryInterface $repository, Bill $bill) | ||||
|     { | ||||
|  | ||||
|         $chart->addColumn('Date', 'date'); | ||||
| @@ -286,24 +237,10 @@ class GoogleChartController extends Controller | ||||
|         $chart->addColumn('Recorded bill entry', 'number'); | ||||
|  | ||||
|         // get first transaction or today for start: | ||||
|         $first = $bill->transactionjournals()->orderBy('date', 'ASC')->first(); | ||||
|         if ($first) { | ||||
|             $start = $first->date; | ||||
|         } else { | ||||
|             $start = new Carbon; | ||||
|         } | ||||
|  | ||||
|         $results = $bill->transactionjournals()->after($start)->get(); | ||||
|         $results = $repository->getJournals($bill); | ||||
|         /** @var TransactionJournal $result */ | ||||
|         foreach ($results as $result) { | ||||
|             $amount = 0; | ||||
|             /** @var Transaction $tr */ | ||||
|             foreach ($result->transactions()->get() as $tr) { | ||||
|                 if (floatval($tr->amount) > 0) { | ||||
|                     $amount = floatval($tr->amount); | ||||
|                 } | ||||
|             } | ||||
|             $chart->addRow(clone $result->date, $bill->amount_max, $bill->amount_min, $amount); | ||||
|             $chart->addRow(clone $result->date, floatval($bill->amount_max), floatval($bill->amount_min), floatval($result->amount)); | ||||
|         } | ||||
|  | ||||
|         $chart->generate(); | ||||
| @@ -313,22 +250,28 @@ class GoogleChartController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param GChart $chart | ||||
|      * @param GChart                     $chart | ||||
|      * | ||||
|      * @param BillRepositoryInterface    $repository | ||||
|      * @param AccountRepositoryInterface $accounts | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function billsOverview(GChart $chart, BillRepositoryInterface $repository) | ||||
|     public function billsOverview(GChart $chart, BillRepositoryInterface $repository, AccountRepositoryInterface $accounts) | ||||
|     { | ||||
|         $chart->addColumn('Name', 'string'); | ||||
|         $chart->addColumn('Amount', 'number'); | ||||
|  | ||||
|  | ||||
|         $paid   = ['items' => [], 'amount' => 0]; | ||||
|         $unpaid = ['items' => [], 'amount' => 0]; | ||||
|         $start  = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end    = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|  | ||||
|         $bills = Auth::user()->bills()->where('active', 1)->get(); | ||||
|         $bills  = $repository->getActiveBills(); | ||||
|         $paid   = new Collection; // journals. | ||||
|         $unpaid = new Collection; // bills | ||||
|         // loop paid and create single entry: | ||||
|         $paidDescriptions   = []; | ||||
|         $paidAmount         = 0; | ||||
|         $unpaidDescriptions = []; | ||||
|         $unpaidAmount       = 0; | ||||
|  | ||||
|         /** @var Bill $bill */ | ||||
|         foreach ($bills as $bill) { | ||||
| @@ -336,84 +279,70 @@ class GoogleChartController extends Controller | ||||
|  | ||||
|             foreach ($ranges as $range) { | ||||
|                 // paid a bill in this range? | ||||
|                 $count = $bill->transactionjournals()->before($range['end'])->after($range['start'])->count(); | ||||
|                 if ($count == 0) { | ||||
|                     $unpaid['items'][] = $bill->name . ' (' . $range['start']->format('jS M Y') . ')'; | ||||
|                     $unpaid['amount'] += ($bill->amount_max + $bill->amount_min / 2); | ||||
|  | ||||
|                 $journals = $repository->getJournalsInRange($bill, $range['start'], $range['end']); | ||||
|                 if ($journals->count() == 0) { | ||||
|                     $unpaid->push([$bill, $range['start']]); | ||||
|                 } else { | ||||
|                     $journal         = $bill->transactionjournals()->with('transactions')->before($range['end'])->after($range['start'])->first(); | ||||
|                     $paid['items'][] = $journal->description; | ||||
|                     $amount          = 0; | ||||
|                     foreach ($journal->transactions as $t) { | ||||
|                         if (floatval($t->amount) > 0) { | ||||
|                             $amount = floatval($t->amount); | ||||
|                         } | ||||
|                     } | ||||
|                     $paid['amount'] += $amount; | ||||
|                     $paid = $paid->merge($journals); | ||||
|                 } | ||||
|  | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Find credit card accounts and possibly unpaid credit card bills. | ||||
|          */ | ||||
|         $creditCards = Auth::user()->accounts() | ||||
|                            ->hasMetaValue('accountRole', 'ccAsset') | ||||
|                            ->hasMetaValue('ccType', 'monthlyFull') | ||||
|                            ->get( | ||||
|                                [ | ||||
|                                    'accounts.*', | ||||
|                                    'ccType.data as ccType', | ||||
|                                    'accountRole.data as accountRole' | ||||
|                                ] | ||||
|                            ); | ||||
|         // if the balance is not zero, the monthly payment is still underway. | ||||
|         /** @var Account $creditCard */ | ||||
|         $creditCards = $accounts->getCreditCards(); | ||||
|         foreach ($creditCards as $creditCard) { | ||||
|             $balance = Steam::balance($creditCard, null, true); | ||||
|             $date    = new Carbon($creditCard->getMeta('ccMonthlyPaymentDate')); | ||||
|             if ($balance < 0) { | ||||
|                 // unpaid! | ||||
|                 $unpaid['amount'] += $balance * -1; | ||||
|                 $unpaid['items'][] = $creditCard->name . ' (expected ' . Amount::format(($balance * -1), false) . ') on the ' . $date->format('jS') . ')'; | ||||
|                 // unpaid! create a fake bill that matches the amount. | ||||
|                 $description = $creditCard->name; | ||||
|                 $amount      = $balance * -1; | ||||
|                 $fakeBill    = $repository->createFakeBill($description, $date, $amount); | ||||
|                 unset($description, $amount); | ||||
|                 $unpaid->push([$fakeBill, $date]); | ||||
|             } | ||||
|             if ($balance == 0) { | ||||
|                 // find a transfer TO the credit card which should account for | ||||
|                 // find transfer(s) TO the credit card which should account for | ||||
|                 // anything paid. If not, the CC is not yet used. | ||||
|                 $transactions = $creditCard->transactions() | ||||
|                                            ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') | ||||
|                                            ->before($end)->after($start)->get(); | ||||
|                 if ($transactions->count() > 0) { | ||||
|                     /** @var Transaction $transaction */ | ||||
|                     foreach ($transactions as $transaction) { | ||||
|                         $journal = $transaction->transactionJournal; | ||||
|                         if ($journal->transactionType->type == 'Transfer') { | ||||
|                             $paid['amount'] += floatval($transaction->amount); | ||||
|                             $paid['items'][] = $creditCard->name . | ||||
|                                                ' (paid ' . Amount::format((floatval($transaction->amount)), false) . | ||||
|                                                ' on the ' . $journal->date->format('jS') . ')'; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 $journals = $accounts->getTransfersInRange($creditCard, $start, $end); | ||||
|                 $paid     = $paid->merge($journals); | ||||
|             } | ||||
|         } | ||||
|         $chart->addRow('Unpaid: ' . join(', ', $unpaid['items']), $unpaid['amount']); | ||||
|         $chart->addRow('Paid: ' . join(', ', $paid['items']), $paid['amount']); | ||||
|  | ||||
|  | ||||
|         /** @var TransactionJournal $entry */ | ||||
|         foreach ($paid as $entry) { | ||||
|  | ||||
|             $paidDescriptions[] = $entry->description; | ||||
|             $paidAmount += floatval($entry->amount); | ||||
|         } | ||||
|  | ||||
|         // loop unpaid: | ||||
|         /** @var Bill $entry */ | ||||
|         foreach ($unpaid as $entry) { | ||||
|             $description          = $entry[0]->name . ' (' . $entry[1]->format('jS M Y') . ')'; | ||||
|             $amount               = ($entry[0]->amount_max + $entry[0]->amount_min) / 2; | ||||
|             $unpaidDescriptions[] = $description; | ||||
|             $unpaidAmount += $amount; | ||||
|             unset($amount, $description); | ||||
|         } | ||||
|  | ||||
|         $chart->addRow('Unpaid: ' . join(', ', $unpaidDescriptions), $unpaidAmount); | ||||
|         $chart->addRow('Paid: ' . join(', ', $paidDescriptions), $paidAmount); | ||||
|         $chart->generate(); | ||||
|  | ||||
|         return Response::json($chart->getData()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param GChart                    $chart | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
|      * @param Budget                    $budget | ||||
|      * @param LimitRepetition           $repetition | ||||
|      * | ||||
|      * @param Budget          $budget | ||||
|      * @param LimitRepetition $repetition | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function budgetLimitSpending(Budget $budget, LimitRepetition $repetition, GChart $chart) | ||||
|     public function budgetLimitSpending(GChart $chart, BudgetRepositoryInterface $repository, Budget $budget, LimitRepetition $repetition) | ||||
|     { | ||||
|         $start = clone $repetition->startdate; | ||||
|         $end   = $repetition->enddate; | ||||
| @@ -428,7 +357,7 @@ class GoogleChartController extends Controller | ||||
|             /* | ||||
|              * Sum of expenses on this day: | ||||
|              */ | ||||
|             $sum = floatval($budget->transactionjournals()->lessThan(0)->transactionTypes(['Withdrawal'])->onDate($start)->sum('amount')); | ||||
|             $sum = $repository->expensesOnDay($budget, $start); | ||||
|             $amount += $sum; | ||||
|             $chart->addRow(clone $start, $amount); | ||||
|             $start->addDay(); | ||||
| @@ -440,37 +369,22 @@ class GoogleChartController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param GChart                    $chart | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
|      * @param Budget                    $budget | ||||
|      * @param int                       $year | ||||
|      * | ||||
|      * @param Budget $budget | ||||
|      * | ||||
|      * @param int    $year | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function budgetsAndSpending(Budget $budget, $year = 0) | ||||
|     public function budgetsAndSpending(GChart $chart, BudgetRepositoryInterface $repository, Budget $budget, $year = 0) | ||||
|     { | ||||
|  | ||||
|         $chart      = App::make('Grumpydictator\Gchart\GChart'); | ||||
|         $repository = App::make('FireflyIII\Repositories\Budget\BudgetRepository'); | ||||
|         $chart->addColumn('Month', 'date'); | ||||
|         $chart->addColumn('Budgeted', 'number'); | ||||
|         $chart->addColumn('Spent', 'number'); | ||||
|         if ($year == 0) { | ||||
|             // grab the first budgetlimit ever: | ||||
|             $firstLimit = $budget->budgetlimits()->orderBy('startdate', 'ASC')->first(); | ||||
|             if ($firstLimit) { | ||||
|                 $start = new Carbon($firstLimit->startdate); | ||||
|             } else { | ||||
|                 $start = Carbon::now()->startOfYear(); | ||||
|             } | ||||
|  | ||||
|             // grab the last budget limit ever: | ||||
|             $lastLimit = $budget->budgetlimits()->orderBy('startdate', 'DESC')->first(); | ||||
|             if ($lastLimit) { | ||||
|                 $end = new Carbon($lastLimit->startdate); | ||||
|             } else { | ||||
|                 $end = Carbon::now()->endOfYear(); | ||||
|             } | ||||
|         if ($year == 0) { | ||||
|             $start = $repository->getFirstBudgetLimitDate($budget); | ||||
|             $end   = $repository->getLastBudgetLimitDate($budget); | ||||
|         } else { | ||||
|             $start = Carbon::createFromDate(intval($year), 1, 1); | ||||
|             $end   = clone $start; | ||||
| @@ -478,19 +392,8 @@ class GoogleChartController extends Controller | ||||
|         } | ||||
|  | ||||
|         while ($start <= $end) { | ||||
|             $spent      = $repository->spentInMonth($budget, $start); | ||||
|             $repetition = LimitRepetition::leftJoin('budget_limits', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id') | ||||
|                                          ->where('limit_repetitions.startdate', $start->format('Y-m-d 00:00:00')) | ||||
|                                          ->where('budget_limits.budget_id', $budget->id) | ||||
|                                          ->first(['limit_repetitions.*']); | ||||
|  | ||||
|             if ($repetition) { | ||||
|                 $budgeted = floatval($repetition->amount); | ||||
|                 \Log::debug('Found a repetition on ' . $start->format('Y-m-d') . ' for budget ' . $budget->name . '!'); | ||||
|             } else { | ||||
|                 \Log::debug('No repetition on ' . $start->format('Y-m-d') . ' for budget ' . $budget->name); | ||||
|                 $budgeted = null; | ||||
|             } | ||||
|             $spent    = $repository->spentInMonth($budget, $start); | ||||
|             $budgeted = $repository->getLimitAmountOnDate($budget, $start); | ||||
|             $chart->addRow(clone $start, $budgeted, $spent); | ||||
|             $start->addMonth(); | ||||
|         } | ||||
| @@ -503,17 +406,17 @@ class GoogleChartController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param GChart                      $chart | ||||
|      * @param CategoryRepositoryInterface $repository | ||||
|      * @param Category                    $category | ||||
|      * | ||||
|      * @param Category $category | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function categoryOverviewChart(Category $category, GChart $chart) | ||||
|     public function categoryOverviewChart(GChart $chart, CategoryRepositoryInterface $repository, Category $category) | ||||
|     { | ||||
|         // oldest transaction in category: | ||||
|         /** @var TransactionJournal $first */ | ||||
|         $first = $category->transactionjournals()->orderBy('date', 'ASC')->first(); | ||||
|         $start = $first->date; | ||||
|         $start = $repository->getFirstActivityDate($category); | ||||
|  | ||||
|         /** @var Preference $range */ | ||||
|         $range = Preferences::get('viewRange', '1M'); | ||||
|         // jump to start of week / month / year / etc (TODO). | ||||
| @@ -526,13 +429,12 @@ class GoogleChartController extends Controller | ||||
|         while ($start <= $end) { | ||||
|  | ||||
|             $currentEnd = Navigation::endOfPeriod($start, $range->data); | ||||
|             $spent      = floatval($category->transactionjournals()->before($currentEnd)->after($start)->lessThan(0)->sum('amount')) * -1; | ||||
|             $spent      = $repository->spentInPeriodSum($category, $start, $currentEnd); | ||||
|             $chart->addRow(clone $start, $spent); | ||||
|  | ||||
|             $start = Navigation::addPeriod($start, $range->data, 0); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         $chart->generate(); | ||||
|  | ||||
|         return Response::json($chart->getData()); | ||||
| @@ -541,22 +443,21 @@ class GoogleChartController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param GChart                      $chart | ||||
|      * @param CategoryRepositoryInterface $repository | ||||
|      * @param Category                    $category | ||||
|      * | ||||
|      * @param Category $category | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function categoryPeriodChart(Category $category, GChart $chart) | ||||
|     public function categoryPeriodChart(GChart $chart, CategoryRepositoryInterface $repository, Category $category) | ||||
|     { | ||||
|         // oldest transaction in category: | ||||
|         /** @var TransactionJournal $first */ | ||||
|         $start = clone Session::get('start'); | ||||
|         $start = clone Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $chart->addColumn('Period', 'date'); | ||||
|         $chart->addColumn('Spent', 'number'); | ||||
|  | ||||
|         $end = Session::get('end'); | ||||
|         $end = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|         while ($start <= $end) { | ||||
|             $spent = floatval($category->transactionjournals()->onDate($start)->lessThan(0)->sum('amount')) * -1; | ||||
|             $spent = $repository->spentOnDaySum($category, $start); | ||||
|             $chart->addRow(clone $start, $spent); | ||||
|             $start->addDay(); | ||||
|         } | ||||
| @@ -570,17 +471,19 @@ class GoogleChartController extends Controller | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * @param GChart                       $chart | ||||
|      * @param PiggyBankRepositoryInterface $repository | ||||
|      * @param PiggyBank                    $piggyBank | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function piggyBankHistory(PiggyBank $piggyBank, GChart $chart) | ||||
|     public function piggyBankHistory(GChart $chart, PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank) | ||||
|     { | ||||
|         $chart->addColumn('Date', 'date'); | ||||
|         $chart->addColumn('Balance', 'number'); | ||||
|  | ||||
|         /** @var Collection $set */ | ||||
|         $set = DB::table('piggy_bank_events')->where('piggy_bank_id', $piggyBank->id)->groupBy('date')->get(['date', DB::Raw('SUM(`amount`) AS `sum`')]); | ||||
|         $set = $repository->getEventSummarySet($piggyBank); | ||||
|         $sum = 0; | ||||
|  | ||||
|         foreach ($set as $entry) { | ||||
| @@ -595,18 +498,15 @@ class GoogleChartController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param GChart               $chart | ||||
|      * @param ReportQueryInterface $query | ||||
|      * @param                      $year | ||||
|      * | ||||
|      * @param $year | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function yearInExp($year, GChart $chart, ReportQueryInterface $query) | ||||
|     public function yearInExp(GChart $chart, ReportQueryInterface $query, $year) | ||||
|     { | ||||
|         try { | ||||
|             $start = new Carbon('01-01-' . $year); | ||||
|         } catch (Exception $e) { | ||||
|             return view('error')->with('message', 'Invalid year.'); | ||||
|         } | ||||
|         $start = new Carbon('01-01-' . $year); | ||||
|         $chart->addColumn('Month', 'date'); | ||||
|         $chart->addColumn('Income', 'number'); | ||||
|         $chart->addColumn('Expenses', 'number'); | ||||
| @@ -621,19 +521,9 @@ class GoogleChartController extends Controller | ||||
|         while ($start < $end) { | ||||
|             $currentEnd = clone $start; | ||||
|             $currentEnd->endOfMonth(); | ||||
|             // total income: | ||||
|             $income    = $query->incomeByPeriod($start, $currentEnd, $showSharedReports); | ||||
|             $incomeSum = 0; | ||||
|             foreach ($income as $entry) { | ||||
|                 $incomeSum += floatval($entry->amount); | ||||
|             } | ||||
|  | ||||
|             // total expenses: | ||||
|             $expense    = $query->journalsByExpenseAccount($start, $currentEnd, $showSharedReports); | ||||
|             $expenseSum = 0; | ||||
|             foreach ($expense as $entry) { | ||||
|                 $expenseSum += floatval($entry->amount); | ||||
|             } | ||||
|             // total income && total expenses: | ||||
|             $incomeSum  = floatval($query->incomeByPeriod($start, $currentEnd, $showSharedReports)->sum('queryAmount')); | ||||
|             $expenseSum = floatval($query->journalsByExpenseAccount($start, $currentEnd, $showSharedReports)->sum('queryAmount')); | ||||
|  | ||||
|             $chart->addRow(clone $start, $incomeSum, $expenseSum); | ||||
|             $start->addMonth(); | ||||
| @@ -647,18 +537,15 @@ class GoogleChartController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param GChart               $chart | ||||
|      * @param ReportQueryInterface $query | ||||
|      * @param                      $year | ||||
|      * | ||||
|      * @param $year | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function yearInExpSum($year, GChart $chart, ReportQueryInterface $query) | ||||
|     public function yearInExpSum(GChart $chart, ReportQueryInterface $query, $year) | ||||
|     { | ||||
|         try { | ||||
|             $start = new Carbon('01-01-' . $year); | ||||
|         } catch (Exception $e) { | ||||
|             return view('error')->with('message', 'Invalid year.'); | ||||
|         } | ||||
|         $start = new Carbon('01-01-' . $year); | ||||
|         $chart->addColumn('Summary', 'string'); | ||||
|         $chart->addColumn('Income', 'number'); | ||||
|         $chart->addColumn('Expenses', 'number'); | ||||
| @@ -676,18 +563,9 @@ class GoogleChartController extends Controller | ||||
|             $currentEnd = clone $start; | ||||
|             $currentEnd->endOfMonth(); | ||||
|             // total income: | ||||
|             $incomeResult = $query->incomeByPeriod($start, $currentEnd, $showSharedReports); | ||||
|             $incomeSum    = 0; | ||||
|             foreach ($incomeResult as $entry) { | ||||
|                 $incomeSum += floatval($entry->amount); | ||||
|             } | ||||
|  | ||||
|             $incomeSum = floatval($query->incomeByPeriod($start, $currentEnd, $showSharedReports)->sum('queryAmount')); | ||||
|             // total expenses: | ||||
|             $expenseResult = $query->journalsByExpenseAccount($start, $currentEnd, $showSharedReports); | ||||
|             $expenseSum    = 0; | ||||
|             foreach ($expenseResult as $entry) { | ||||
|                 $expenseSum += floatval($entry->amount); | ||||
|             } | ||||
|             $expenseSum = floatval($query->journalsByExpenseAccount($start, $currentEnd, $showSharedReports)->sum('queryAmount')); | ||||
|  | ||||
|             $income += $incomeSum; | ||||
|             $expense += $expenseSum; | ||||
|   | ||||
| @@ -1,10 +1,8 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Cache; | ||||
| use ErrorException; | ||||
| use League\CommonMark\CommonMarkConverter; | ||||
| use FireflyIII\Helpers\Help\HelpInterface; | ||||
| use Log; | ||||
| use Response; | ||||
| use Route; | ||||
|  | ||||
| /** | ||||
|  * Class HelpController | ||||
| @@ -15,77 +13,39 @@ class HelpController extends Controller | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param $route | ||||
|      * @param HelpInterface $help | ||||
|      * @param               $route | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function show($route) | ||||
|     public function show(HelpInterface $help, $route) | ||||
|     { | ||||
|         $content = [ | ||||
|             'text'  => '<p>There is no help for this route!</p>', | ||||
|             'title' => 'Help', | ||||
|         ]; | ||||
|  | ||||
|         if (!Route::has($route)) { | ||||
|             \Log::error('No such route: ' . $route); | ||||
|         if (!$help->hasRoute($route)) { | ||||
|             Log::error('No such route: ' . $route); | ||||
|  | ||||
|             return Response::json($content); | ||||
|         } | ||||
|  | ||||
|         if ($this->inCache($route)) { | ||||
|         if ($help->inCache($route)) { | ||||
|             $content = [ | ||||
|                 'text'  => Cache::get('help.' . $route . '.text'), | ||||
|                 'title' => Cache::get('help.' . $route . '.title'), | ||||
|                 'text'  => $help->getFromCache('help.' . $route . '.text'), | ||||
|                 'title' => $help->getFromCache('help.' . $route . '.title'), | ||||
|             ]; | ||||
|  | ||||
|             return Response::json($content); | ||||
|         } | ||||
|         $content = $this->getFromGithub($route); | ||||
|         $content = $help->getFromGithub($route); | ||||
|  | ||||
|  | ||||
|         Cache::put('help.' . $route . '.text', $content['text'], 10080); // a week. | ||||
|         Cache::put('help.' . $route . '.title', $content['title'], 10080); | ||||
|         $help->putInCache($route, $content); | ||||
|  | ||||
|         return Response::json($content); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $route | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     protected function inCache($route) | ||||
|     { | ||||
|         return Cache::has('help.' . $route . '.title') && Cache::has('help.' . $route . '.text'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $route | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     protected function getFromGithub($route) | ||||
|     { | ||||
|         $uri     = 'https://raw.githubusercontent.com/JC5/firefly-iii-help/master/' . e($route) . '.md'; | ||||
|         $content = [ | ||||
|             'text'  => '<p>There is no help for this route!</p>', | ||||
|             'title' => $route, | ||||
|         ]; | ||||
|         try { | ||||
|             $content['text'] = file_get_contents($uri); | ||||
|         } catch (ErrorException $e) { | ||||
|             \Log::error(trim($e->getMessage())); | ||||
|         } | ||||
|         if (strlen(trim($content['text'])) == 0) { | ||||
|             $content['text'] = '<p>There is no help for this route.</p>'; | ||||
|         } | ||||
|         $converter       = new CommonMarkConverter(); | ||||
|         $content['text'] = $converter->convertToHtml($content['text']); | ||||
|  | ||||
|         return $content; | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,12 +1,14 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use Config; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use Input; | ||||
| use Preferences; | ||||
| use Session; | ||||
| use Redirect; | ||||
| use Session; | ||||
| use Steam; | ||||
|  | ||||
| /** | ||||
|  * Class HomeController | ||||
|  * | ||||
| @@ -30,30 +32,45 @@ class HomeController extends Controller | ||||
|         Session::put('end', $end); | ||||
|     } | ||||
|  | ||||
|     public function flush() { | ||||
|     /** | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function flush() | ||||
|     { | ||||
|         Session::clear(); | ||||
|  | ||||
|         return Redirect::route('index'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function index(AccountRepositoryInterface $repository) | ||||
|     { | ||||
|  | ||||
|         $count         = $repository->countAssetAccounts(); | ||||
|         $title         = 'Firefly'; | ||||
|         $subTitle      = 'What\'s playing?'; | ||||
|         $mainTitleIcon = 'fa-fire'; | ||||
|         $transactions  = []; | ||||
|         $frontPage     = Preferences::get('frontPageAccounts', []); | ||||
|         $start         = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end           = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|         $accounts      = $repository->getFrontpageAccounts($frontPage); | ||||
|         $savings       = $repository->getSavingsAccounts(); | ||||
|         $types             = Config::get('firefly.accountTypesByIdentifier.asset'); | ||||
|         $count             = $repository->countAccounts($types); | ||||
|         $title             = 'Firefly'; | ||||
|         $subTitle          = 'What\'s playing?'; | ||||
|         $mainTitleIcon     = 'fa-fire'; | ||||
|         $transactions      = []; | ||||
|         $frontPage         = Preferences::get('frontPageAccounts', []); | ||||
|         $start             = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end               = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|         $accounts          = $repository->getFrontpageAccounts($frontPage); | ||||
|         $savings           = $repository->getSavingsAccounts(); | ||||
|         $piggyBankAccounts = $repository->getPiggyBankAccounts(); | ||||
|  | ||||
|  | ||||
|         $savingsTotal = 0; | ||||
|         foreach ($savings as $savingAccount) { | ||||
|             $savingsTotal += Steam::balance($savingAccount, $end); | ||||
|         } | ||||
|  | ||||
|         // check if all books are correct. | ||||
|         $sum = floatval(Auth::user()->transactions()->sum('amount')); | ||||
|         $sum = $repository->sumOfEverything(); | ||||
|         if ($sum != 0) { | ||||
|             Session::flash( | ||||
|                 'error', 'Your transactions are unbalanced. This means a' | ||||
| @@ -69,7 +86,7 @@ class HomeController extends Controller | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return view('index', compact('count', 'title', 'savings', 'subTitle', 'mainTitleIcon', 'transactions')); | ||||
|         return view('index', compact('count', 'title', 'savings', 'subTitle', 'mainTitleIcon', 'transactions', 'savingsTotal', 'piggyBankAccounts')); | ||||
|     } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1,15 +1,19 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Amount; | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use DB; | ||||
| use FireflyIII\Helpers\Report\ReportQueryInterface; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Models\Preference; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionType; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Repositories\Bill\BillRepositoryInterface; | ||||
| use Input; | ||||
| use FireflyIII\Repositories\Category\CategoryRepositoryInterface; | ||||
| use FireflyIII\Repositories\Journal\JournalRepositoryInterface; | ||||
| use FireflyIII\Repositories\Tag\TagRepositoryInterface; | ||||
| use Illuminate\Support\Collection; | ||||
| use Preferences; | ||||
| use Response; | ||||
| use Session; | ||||
| @@ -23,163 +27,143 @@ use Steam; | ||||
| class JsonController extends Controller | ||||
| { | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @param BillRepositoryInterface    $repository | ||||
|      * | ||||
|      * @param AccountRepositoryInterface $accountRepository | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function box(BillRepositoryInterface $repository) | ||||
|     public function boxBillsPaid(BillRepositoryInterface $repository, AccountRepositoryInterface $accountRepository) | ||||
|     { | ||||
|         $start  = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end    = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|         $amount = 0; | ||||
|         $start  = Session::get('start'); | ||||
|         $end    = Session::get('end'); | ||||
|         $box    = 'empty'; | ||||
|         switch (Input::get('box')) { | ||||
|             case 'in': | ||||
|                 $box = Input::get('box'); | ||||
|                 $in  = Auth::user()->transactionjournals() | ||||
|                            ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') | ||||
|                            ->before($end) | ||||
|                            ->after($start) | ||||
|                            ->transactionTypes(['Deposit']) | ||||
|                            ->where('transactions.amount', '>', 0) | ||||
|                            ->first([DB::Raw('SUM(transactions.amount) as `amount`')]); | ||||
|                 if (!is_null($in)) { | ||||
|                     $amount = floatval($in->amount); | ||||
|                 } | ||||
|  | ||||
|                 break; | ||||
|             case 'out': | ||||
|                 $box = Input::get('box'); | ||||
|                 $in  = Auth::user()->transactionjournals() | ||||
|                            ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') | ||||
|                            ->before($end) | ||||
|                            ->after($start) | ||||
|                            ->transactionTypes(['Withdrawal']) | ||||
|                            ->where('transactions.amount', '>', 0) | ||||
|                            ->first([DB::Raw('SUM(transactions.amount) as `amount`')]); | ||||
|                 if (!is_null($in)) { | ||||
|                     $amount = floatval($in->amount); | ||||
|                 } | ||||
|         // these two functions are the same as the chart TODO | ||||
|         $bills = $repository->getActiveBills(); | ||||
|  | ||||
|                 break; | ||||
|             case 'bills-unpaid': | ||||
|                 $box   = 'bills-unpaid'; | ||||
|                 $bills = Auth::user()->bills()->where('active', 1)->get(); | ||||
|         /** @var Bill $bill */ | ||||
|         foreach ($bills as $bill) { | ||||
|             $ranges = $repository->getRanges($bill, $start, $end); | ||||
|  | ||||
|                 /** @var Bill $bill */ | ||||
|                 foreach ($bills as $bill) { | ||||
|                     $ranges = $repository->getRanges($bill, $start, $end); | ||||
|             foreach ($ranges as $range) { | ||||
|                 // paid a bill in this range? | ||||
|                 $amount += $repository->getJournalsInRange($bill, $range['start'], $range['end'])->sum('amount'); | ||||
|             } | ||||
|         } | ||||
|         unset($ranges, $bill, $range, $bills); | ||||
|  | ||||
|                     foreach ($ranges as $range) { | ||||
|                         // paid a bill in this range? | ||||
|                         $count = $bill->transactionjournals()->before($range['end'])->after($range['start'])->count(); | ||||
|                         if ($count == 0) { | ||||
|                             $amount += floatval($bill->amount_max + $bill->amount_min / 2); | ||||
|                         } | ||||
|  | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 /** | ||||
|                  * Find credit card accounts and possibly unpaid credit card bills. | ||||
|                  */ | ||||
|                 $creditCards = Auth::user()->accounts() | ||||
|                                    ->hasMetaValue('accountRole', 'ccAsset') | ||||
|                                    ->hasMetaValue('ccType', 'monthlyFull') | ||||
|                                    ->get( | ||||
|                                        [ | ||||
|                                            'accounts.*', | ||||
|                                            'ccType.data as ccType', | ||||
|                                            'accountRole.data as accountRole' | ||||
|                                        ] | ||||
|                                    ); | ||||
|                 // if the balance is not zero, the monthly payment is still underway. | ||||
|                 /** @var Account $creditCard */ | ||||
|                 foreach ($creditCards as $creditCard) { | ||||
|                     $balance = Steam::balance($creditCard, null, true); | ||||
|                     if ($balance < 0) { | ||||
|                         // unpaid! | ||||
|                         $amount += $balance * -1; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 break; | ||||
|             case 'bills-paid': | ||||
|                 $box = 'bills-paid'; | ||||
|                 // these two functions are the same as the chart TODO | ||||
|                 $bills = Auth::user()->bills()->where('active', 1)->get(); | ||||
|  | ||||
|                 /** @var Bill $bill */ | ||||
|                 foreach ($bills as $bill) { | ||||
|                     $ranges = $repository->getRanges($bill, $start, $end); | ||||
|  | ||||
|                     foreach ($ranges as $range) { | ||||
|                         // paid a bill in this range? | ||||
|                         $count = $bill->transactionjournals()->before($range['end'])->after($range['start'])->count(); | ||||
|                         if ($count != 0) { | ||||
|                             $journal       = $bill->transactionjournals()->with('transactions')->before($range['end'])->after($range['start'])->first(); | ||||
|                             $currentAmount = 0; | ||||
|                             foreach ($journal->transactions as $t) { | ||||
|                                 if (floatval($t->amount) > 0) { | ||||
|                                     $currentAmount = floatval($t->amount); | ||||
|                                 } | ||||
|                             } | ||||
|                             $amount += $currentAmount; | ||||
|                         } | ||||
|  | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 /** | ||||
|                  * Find credit card accounts and possibly unpaid credit card bills. | ||||
|                  */ | ||||
|                 $creditCards = Auth::user()->accounts() | ||||
|                                    ->hasMetaValue('accountRole', 'ccAsset') | ||||
|                                    ->hasMetaValue('ccType', 'monthlyFull') | ||||
|                                    ->get( | ||||
|                                        [ | ||||
|                                            'accounts.*', | ||||
|                                            'ccType.data as ccType', | ||||
|                                            'accountRole.data as accountRole' | ||||
|                                        ] | ||||
|                                    ); | ||||
|                 // if the balance is not zero, the monthly payment is still underway. | ||||
|                 /** @var Account $creditCard */ | ||||
|                 foreach ($creditCards as $creditCard) { | ||||
|                     $balance = Steam::balance($creditCard, null, true); | ||||
|                     if ($balance == 0) { | ||||
|                         // find a transfer TO the credit card which should account for | ||||
|                         // anything paid. If not, the CC is not yet used. | ||||
|                         $transactions = $creditCard->transactions() | ||||
|                                                    ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') | ||||
|                                                    ->before($end)->after($start)->get(); | ||||
|                         if ($transactions->count() > 0) { | ||||
|                             /** @var Transaction $transaction */ | ||||
|                             foreach ($transactions as $transaction) { | ||||
|                                 $journal = $transaction->transactionJournal; | ||||
|                                 if ($journal->transactionType->type == 'Transfer') { | ||||
|                                     $amount += floatval($transaction->amount); | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|         /** | ||||
|          * Find credit card accounts and possibly unpaid credit card bills. | ||||
|          */ | ||||
|         $creditCards = $accountRepository->getCreditCards(); | ||||
|         // if the balance is not zero, the monthly payment is still underway. | ||||
|         /** @var Account $creditCard */ | ||||
|         foreach ($creditCards as $creditCard) { | ||||
|             $balance = Steam::balance($creditCard, null, true); | ||||
|             if ($balance == 0) { | ||||
|                 // find a transfer TO the credit card which should account for | ||||
|                 // anything paid. If not, the CC is not yet used. | ||||
|                 $amount += $accountRepository->getTransfersInRange($creditCard, $start, $end)->sum('amount'); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return Response::json(['box' => $box, 'amount' => Amount::format($amount, false), 'amount_raw' => $amount]); | ||||
|         return Response::json(['box' => 'bills-paid', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount]); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param BillRepositoryInterface    $repository | ||||
|      * @param AccountRepositoryInterface $accountRepository | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function boxBillsUnpaid(BillRepositoryInterface $repository, AccountRepositoryInterface $accountRepository) | ||||
|     { | ||||
|         $amount = 0; | ||||
|         $start  = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end    = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|         $bills  = $repository->getActiveBills(); | ||||
|         $unpaid = new Collection; // bills | ||||
|  | ||||
|         /** @var Bill $bill */ | ||||
|         foreach ($bills as $bill) { | ||||
|             $ranges = $repository->getRanges($bill, $start, $end); | ||||
|  | ||||
|             foreach ($ranges as $range) { | ||||
|                 $journals = $repository->getJournalsInRange($bill, $range['start'], $range['end']); | ||||
|                 if ($journals->count() == 0) { | ||||
|                     $unpaid->push([$bill, $range['start']]); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         unset($bill, $bills, $range, $ranges); | ||||
|  | ||||
|         $creditCards = $accountRepository->getCreditCards(); | ||||
|         foreach ($creditCards as $creditCard) { | ||||
|             $balance = Steam::balance($creditCard, null, true); | ||||
|             $date    = new Carbon($creditCard->getMeta('ccMonthlyPaymentDate')); | ||||
|             if ($balance < 0) { | ||||
|                 // unpaid! create a fake bill that matches the amount. | ||||
|                 $description = $creditCard->name; | ||||
|                 $fakeAmount  = $balance * -1; | ||||
|                 $fakeBill    = $repository->createFakeBill($description, $date, $fakeAmount); | ||||
|                 $unpaid->push([$fakeBill, $date]); | ||||
|             } | ||||
|         } | ||||
|         /** @var Bill $entry */ | ||||
|         foreach ($unpaid as $entry) { | ||||
|             $current = ($entry[0]->amount_max + $entry[0]->amount_min) / 2; | ||||
|             $amount += $current; | ||||
|         } | ||||
|  | ||||
|         return Response::json(['box' => 'bills-unpaid', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount]); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param ReportQueryInterface $reportQuery | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function boxIn(ReportQueryInterface $reportQuery) | ||||
|     { | ||||
|         $start  = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end    = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|         $amount = $reportQuery->incomeByPeriod($start, $end, true)->sum('queryAmount'); | ||||
|  | ||||
|         return Response::json(['box' => 'in', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount]); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param ReportQueryInterface $reportQuery | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function boxOut(ReportQueryInterface $reportQuery) | ||||
|     { | ||||
|         $start  = Session::get('start', Carbon::now()->startOfMonth()); | ||||
|         $end    = Session::get('end', Carbon::now()->endOfMonth()); | ||||
|         $amount = $reportQuery->journalsByExpenseAccount($start, $end, true)->sum('queryAmount'); | ||||
|  | ||||
|         return Response::json(['box' => 'out', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount]); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns a list of categories. | ||||
|      * | ||||
|      * @param CategoryRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function categories() | ||||
|     public function categories(CategoryRepositoryInterface $repository) | ||||
|     { | ||||
|         $list   = Auth::user()->categories()->orderBy('name', 'ASC')->get(); | ||||
|         $list   = $repository->getCategories(); | ||||
|         $return = []; | ||||
|         foreach ($list as $entry) { | ||||
|             $return[] = $entry->name; | ||||
|         } | ||||
|         sort($return); | ||||
|  | ||||
|         return Response::json($return); | ||||
|     } | ||||
| @@ -187,11 +171,13 @@ class JsonController extends Controller | ||||
|     /** | ||||
|      * Returns a JSON list of all beneficiaries. | ||||
|      * | ||||
|      * @param AccountRepositoryInterface $accountRepository | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function expenseAccounts() | ||||
|     public function expenseAccounts(AccountRepositoryInterface $accountRepository) | ||||
|     { | ||||
|         $list   = Auth::user()->accounts()->orderBy('accounts.name', 'ASC')->accountTypeIn(['Expense account', 'Beneficiary account'])->get(); | ||||
|         $list   = $accountRepository->getAccounts(['Expense account', 'Beneficiary account']); | ||||
|         $return = []; | ||||
|         foreach ($list as $entry) { | ||||
|             $return[] = $entry->name; | ||||
| @@ -202,11 +188,32 @@ class JsonController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns a JSON list of all beneficiaries. | ||||
|      * | ||||
|      * @param TagRepositoryInterface $tagRepository | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function revenueAccounts() | ||||
|     public function tags(TagRepositoryInterface $tagRepository) | ||||
|     { | ||||
|         $list   = Auth::user()->accounts()->accountTypeIn(['Revenue account'])->orderBy('accounts.name', 'ASC')->get(['accounts.*']); | ||||
|         $list   = $tagRepository->get(); | ||||
|         $return = []; | ||||
|         foreach ($list as $entry) { | ||||
|             $return[] = $entry->tag; | ||||
|         } | ||||
|  | ||||
|         return Response::json($return); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param AccountRepositoryInterface $accountRepository | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function revenueAccounts(AccountRepositoryInterface $accountRepository) | ||||
|     { | ||||
|         $list   = $accountRepository->getAccounts(['Revenue account']); | ||||
|         $return = []; | ||||
|         foreach ($list as $entry) { | ||||
|             $return[] = $entry->name; | ||||
| @@ -221,6 +228,7 @@ class JsonController extends Controller | ||||
|      */ | ||||
|     public function setSharedReports() | ||||
|     { | ||||
|         /** @var Preference $pref */ | ||||
|         $pref = Preferences::get('showSharedReports', false); | ||||
|         $new  = !$pref->data; | ||||
|         Preferences::set('showSharedReports', $new); | ||||
| @@ -239,13 +247,18 @@ class JsonController extends Controller | ||||
|         return Response::json(['value' => $pref->data]); | ||||
|     } | ||||
|  | ||||
|     public function transactionJournals($what) | ||||
|     /** | ||||
|      * @param JournalRepositoryInterface $repository | ||||
|      * @param                            $what | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function transactionJournals(JournalRepositoryInterface $repository, $what) | ||||
|     { | ||||
|         $descriptions = []; | ||||
|         $dbType       = TransactionType::whereType($what)->first(); | ||||
|         $journals     = Auth::user()->transactionjournals()->where('transaction_type_id', $dbType->id) | ||||
|                             ->orderBy('id', 'DESC')->take(50) | ||||
|                             ->get(); | ||||
|         $dbType       = $repository->getTransactionType($what); | ||||
|  | ||||
|         $journals = $repository->getJournalsOfType($dbType); | ||||
|         foreach ($journals as $j) { | ||||
|             $descriptions[] = $j->description; | ||||
|         } | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Amount; | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use Config; | ||||
| use ExpandedForm; | ||||
| use FireflyIII\Http\Requests; | ||||
| use FireflyIII\Http\Requests\PiggyBankFormRequest; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Models\PiggyBankEvent; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| @@ -16,8 +16,8 @@ use Input; | ||||
| use Redirect; | ||||
| use Session; | ||||
| use Steam; | ||||
| use View; | ||||
| use URL; | ||||
| use View; | ||||
|  | ||||
| /** | ||||
|  * Class PiggyBankController | ||||
| @@ -32,6 +32,7 @@ class PiggyBankController extends Controller | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         View::share('title', 'Piggy banks'); | ||||
|         View::share('mainTitleIcon', 'fa-sort-amount-asc'); | ||||
|     } | ||||
| @@ -39,11 +40,12 @@ class PiggyBankController extends Controller | ||||
|     /** | ||||
|      * Add money to piggy bank | ||||
|      * | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * @param PiggyBank                  $piggyBank | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function add(PiggyBank $piggyBank, AccountRepositoryInterface $repository) | ||||
|     public function add(AccountRepositoryInterface $repository, PiggyBank $piggyBank) | ||||
|     { | ||||
|         $leftOnAccount = $repository->leftOnAccount($piggyBank->account); | ||||
|         $savedSoFar    = $piggyBank->currentRelevantRep()->currentamount; | ||||
| @@ -54,15 +56,15 @@ class PiggyBankController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function create() | ||||
|     public function create(AccountRepositoryInterface $repository) | ||||
|     { | ||||
|  | ||||
|         $periods      = Config::get('firefly.piggy_bank_periods'); | ||||
|         $accounts     = ExpandedForm::makeSelectList( | ||||
|             Auth::user()->accounts()->orderBy('accounts.name', 'ASC')->accountTypeIn(['Default account', 'Asset account'])->get(['accounts.*']) | ||||
|         ); | ||||
|         $accounts     = ExpandedForm::makeSelectList($repository->getAccounts(['Default account', 'Asset account'])); | ||||
|         $subTitle     = 'Create new piggy bank'; | ||||
|         $subTitleIcon = 'fa-plus'; | ||||
|  | ||||
| @@ -91,33 +93,32 @@ class PiggyBankController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * @param PiggyBankRepositoryInterface $repository | ||||
|      * @param PiggyBank                    $piggyBank | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function destroy(PiggyBank $piggyBank) | ||||
|     public function destroy(PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank) | ||||
|     { | ||||
|  | ||||
|  | ||||
|         Session::flash('success', 'Piggy bank "' . e($piggyBank->name) . '" deleted.'); | ||||
|         $piggyBank->delete(); | ||||
|         $repository->destroy($piggyBank); | ||||
|  | ||||
|         return Redirect::to(Session::get('piggy-banks.delete.url')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind. | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * @param PiggyBank                  $piggyBank | ||||
|      * | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @return $this | ||||
|      * @return View | ||||
|      */ | ||||
|     public function edit(PiggyBank $piggyBank) | ||||
|     public function edit(AccountRepositoryInterface $repository, PiggyBank $piggyBank) | ||||
|     { | ||||
|  | ||||
|         $periods      = Config::get('firefly.piggy_bank_periods'); | ||||
|         $accounts     = ExpandedForm::makeSelectList( | ||||
|             Auth::user()->accounts()->orderBy('accounts.name', 'ASC')->accountTypeIn(['Default account', 'Asset account'])->get(['accounts.*']) | ||||
|         ); | ||||
|         $accounts     = ExpandedForm::makeSelectList($repository->getAccounts(['Default account', 'Asset account'])); | ||||
|         $subTitle     = 'Edit piggy bank "' . e($piggyBank->name) . '"'; | ||||
|         $subTitleIcon = 'fa-pencil'; | ||||
|  | ||||
| @@ -149,18 +150,21 @@ class PiggyBankController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return $this | ||||
|      * @param AccountRepositoryInterface   $repository | ||||
|      * @param PiggyBankRepositoryInterface $piggyRepository | ||||
|      * | ||||
|      * @return View | ||||
|      */ | ||||
|     public function index(AccountRepositoryInterface $repository) | ||||
|     public function index(AccountRepositoryInterface $repository, PiggyBankRepositoryInterface $piggyRepository) | ||||
|     { | ||||
|         /** @var Collection $piggyBanks */ | ||||
|         $piggyBanks = Auth::user()->piggyBanks()->orderBy('order', 'ASC')->get(); | ||||
|         $piggyBanks = $piggyRepository->getPiggyBanks(); | ||||
|  | ||||
|         $accounts = []; | ||||
|         /** @var PiggyBank $piggyBank */ | ||||
|         foreach ($piggyBanks as $piggyBank) { | ||||
|             $piggyBank->savedSoFar = floatval($piggyBank->currentRelevantRep()->currentamount); | ||||
|             $piggyBank->percentage = intval($piggyBank->savedSoFar / $piggyBank->targetamount * 100); | ||||
|             $piggyBank->percentage = $piggyBank->savedSoFar != 0 ? intval($piggyBank->savedSoFar / $piggyBank->targetamount * 100) : 0; | ||||
|             $piggyBank->leftToSave = $piggyBank->targetamount - $piggyBank->savedSoFar; | ||||
|  | ||||
|             /* | ||||
| @@ -170,7 +174,7 @@ class PiggyBankController extends Controller | ||||
|             if (!isset($accounts[$account->id])) { | ||||
|                 $accounts[$account->id] = [ | ||||
|                     'name'              => $account->name, | ||||
|                     'balance'           => Steam::balance($account,null,true), | ||||
|                     'balance'           => Steam::balance($account, null, true), | ||||
|                     'leftForPiggyBanks' => $repository->leftOnAccount($account), | ||||
|                     'sumOfSaved'        => $piggyBank->savedSoFar, | ||||
|                     'sumOfTargets'      => floatval($piggyBank->targetamount), | ||||
| @@ -187,7 +191,7 @@ class PiggyBankController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Allow user to order piggy banks. | ||||
|      * @param PiggyBankRepositoryInterface $repository | ||||
|      */ | ||||
|     public function order(PiggyBankRepositoryInterface $repository) | ||||
|     { | ||||
| @@ -204,13 +208,13 @@ class PiggyBankController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * POST add money to piggy bank | ||||
|      * | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * @param PiggyBankRepositoryInterface $repository | ||||
|      * @param AccountRepositoryInterface   $accounts | ||||
|      * @param PiggyBank                    $piggyBank | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function postAdd(PiggyBank $piggyBank, PiggyBankRepositoryInterface $repository, AccountRepositoryInterface $accounts) | ||||
|     public function postAdd(PiggyBankRepositoryInterface $repository, AccountRepositoryInterface $accounts, PiggyBank $piggyBank) | ||||
|     { | ||||
|         $amount        = round(floatval(Input::get('amount')), 2); | ||||
|         $leftOnAccount = $accounts->leftOnAccount($piggyBank->account); | ||||
| @@ -223,8 +227,8 @@ class PiggyBankController extends Controller | ||||
|             $repetition->currentamount += $amount; | ||||
|             $repetition->save(); | ||||
|  | ||||
|             // create event. | ||||
|             PiggyBankEvent::create(['date' => Carbon::now(), 'amount' => $amount, 'piggy_bank_id' => $piggyBank->id]); | ||||
|             // create event | ||||
|             $repository->createEvent($piggyBank, $amount); | ||||
|  | ||||
|             /* | ||||
|              * Create event! | ||||
| @@ -240,11 +244,12 @@ class PiggyBankController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * @param PiggyBankRepositoryInterface $repository | ||||
|      * @param PiggyBank                    $piggyBank | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function postRemove(PiggyBank $piggyBank) | ||||
|     public function postRemove(PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank) | ||||
|     { | ||||
|         $amount = floatval(Input::get('amount')); | ||||
|  | ||||
| @@ -255,12 +260,8 @@ class PiggyBankController extends Controller | ||||
|             $repetition->currentamount -= $amount; | ||||
|             $repetition->save(); | ||||
|  | ||||
|             PiggyBankEvent::create(['date' => Carbon::now(), 'amount' => $amount * -1, 'piggy_bank_id' => $piggyBank->id]); | ||||
|  | ||||
|             /* | ||||
|              * Create event! | ||||
|              */ | ||||
|             //Event::fire('piggy_bank.removeMoney', [$piggyBank, $amount]); // new and used. | ||||
|             // create event | ||||
|             $repository->createEvent($piggyBank, $amount * -1); | ||||
|  | ||||
|             Session::flash('success', 'Removed ' . Amount::format($amount, false) . ' from "' . e($piggyBank->name) . '".'); | ||||
|         } else { | ||||
| @@ -273,7 +274,6 @@ class PiggyBankController extends Controller | ||||
|     /** | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @SuppressWarnings("Unused") | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
| @@ -283,14 +283,14 @@ class PiggyBankController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * @param PiggyBankRepositoryInterface $repository | ||||
|      * @param PiggyBank                    $piggyBank | ||||
|      * | ||||
|      * @return $this | ||||
|      * @return View | ||||
|      */ | ||||
|     public function show(PiggyBank $piggyBank) | ||||
|     public function show(PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank) | ||||
|     { | ||||
|  | ||||
|         $events = $piggyBank->piggyBankEvents()->orderBy('date', 'DESC')->orderBy('id', 'DESC')->get(); | ||||
|         $events = $repository->getEvents($piggyBank); | ||||
|  | ||||
|         /* | ||||
|          * Number of reminders: | ||||
| @@ -310,6 +310,7 @@ class PiggyBankController extends Controller | ||||
|      */ | ||||
|     public function store(PiggyBankFormRequest $request, PiggyBankRepositoryInterface $repository) | ||||
|     { | ||||
|  | ||||
|         $piggyBankData = [ | ||||
|             'name'         => $request->get('name'), | ||||
|             'startdate'    => new Carbon, | ||||
| @@ -326,6 +327,7 @@ class PiggyBankController extends Controller | ||||
|  | ||||
|         if (intval(Input::get('create_another')) === 1) { | ||||
|             Session::put('piggy-banks.create.fromStore', true); | ||||
|  | ||||
|             return Redirect::route('piggy-banks.create')->withInput(); | ||||
|         } | ||||
|  | ||||
| @@ -335,13 +337,13 @@ class PiggyBankController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind. | ||||
|      * @param PiggyBankRepositoryInterface $repository | ||||
|      * @param PiggyBankFormRequest         $request | ||||
|      * @param PiggyBank                    $piggyBank | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function update(PiggyBank $piggyBank, PiggyBankRepositoryInterface $repository, PiggyBankFormRequest $request) | ||||
|     public function update(PiggyBankRepositoryInterface $repository, PiggyBankFormRequest $request, PiggyBank $piggyBank) | ||||
|     { | ||||
|         $piggyBankData = [ | ||||
|             'name'         => $request->get('name'), | ||||
| @@ -353,13 +355,13 @@ class PiggyBankController extends Controller | ||||
|             'remind_me'    => $request->get('remind_me') | ||||
|         ]; | ||||
|  | ||||
|  | ||||
|         $piggyBank = $repository->update($piggyBank, $piggyBankData); | ||||
|  | ||||
|         Session::flash('success', 'Updated piggy bank "' . e($piggyBank->name) . '".'); | ||||
|  | ||||
|         if (intval(Input::get('return_to_edit')) === 1) { | ||||
|             Session::put('piggy-banks.edit.fromUpdate', true); | ||||
|  | ||||
|             return Redirect::route('piggy-banks.edit', $piggyBank->id); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use Input; | ||||
| use Preferences; | ||||
| use Redirect; | ||||
| @@ -20,26 +20,26 @@ class PreferencesController extends Controller | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|  | ||||
|         parent::__construct(); | ||||
|         View::share('title', 'Preferences'); | ||||
|         View::share('mainTitleIcon', 'fa-gear'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * | ||||
|      * @return $this|\Illuminate\View\View | ||||
|      */ | ||||
|     public function index() | ||||
|     public function index(AccountRepositoryInterface $repository) | ||||
|     { | ||||
|         $accounts       = Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->orderBy('accounts.name', 'ASC')->get(['accounts.*']); | ||||
|         $viewRange      = Preferences::get('viewRange', '1M'); | ||||
|         $viewRangeValue = $viewRange->data; | ||||
|         $frontPage      = Preferences::get('frontPageAccounts', []); | ||||
|         $budgetMax      = Preferences::get('budgetMaximum', 1000); | ||||
|         $budgetMaximum  = $budgetMax->data; | ||||
|         $accounts          = $repository->getAccounts(['Default account', 'Asset account']); | ||||
|         $viewRangePref     = Preferences::get('viewRange', '1M'); | ||||
|         $viewRange         = $viewRangePref->data; | ||||
|         $frontPageAccounts = Preferences::get('frontPageAccounts', []); | ||||
|         $budgetMax         = Preferences::get('budgetMaximum', 1000); | ||||
|         $budgetMaximum     = $budgetMax->data; | ||||
|  | ||||
|         return view('preferences.index', compact('budgetMaximum'))->with('accounts', $accounts)->with('frontPageAccounts', $frontPage)->with( | ||||
|             'viewRange', $viewRangeValue | ||||
|         ); | ||||
|         return view('preferences.index', compact('budgetMaximum', 'accounts', 'frontPageAccounts', 'viewRange')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Http\Requests; | ||||
| use FireflyIII\Http\Requests\DeleteAccountFormRequest; | ||||
| use FireflyIII\Http\Requests\ProfileFormRequest; | ||||
| use Hash; | ||||
| use Redirect; | ||||
| @@ -25,6 +26,16 @@ class ProfileController extends Controller | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function deleteAccount() | ||||
|     { | ||||
|         return view('profile.delete-account')->with('title', Auth::user()->email)->with('subTitle', 'Delete account')->with( | ||||
|             'mainTitleIcon', 'fa-user' | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\View\View | ||||
|      * | ||||
| @@ -35,6 +46,8 @@ class ProfileController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param ProfileFormRequest $request | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View | ||||
|      */ | ||||
|     public function postChangePassword(ProfileFormRequest $request) | ||||
| @@ -45,7 +58,7 @@ class ProfileController extends Controller | ||||
|  | ||||
|             return Redirect::route('change-password'); | ||||
|         } | ||||
|         $result = $this->validatePassword($request->get('current_password'), $request->get('new_password'), $request->get('new_password_confirmation')); | ||||
|         $result = $this->validatePassword($request->get('current_password'), $request->get('new_password')); | ||||
|         if (!($result === true)) { | ||||
|             Session::flash('error', $result); | ||||
|  | ||||
| @@ -62,29 +75,43 @@ class ProfileController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind. | ||||
|      * | ||||
|      * @param string $old | ||||
|      * @param string $new1 | ||||
|      * @param string $new2 | ||||
|      * | ||||
|      * @return string|bool | ||||
|      */ | ||||
|     protected function validatePassword($old, $new1, $new2) | ||||
|     protected function validatePassword($old, $new1) | ||||
|     { | ||||
|         if (strlen($new1) == 0 || strlen($new2) == 0) { | ||||
|             return 'Do fill in a password!'; | ||||
|  | ||||
|         } | ||||
|         if ($new1 == $old) { | ||||
|             return 'The idea is to change your password.'; | ||||
|         } | ||||
|  | ||||
|         if ($new1 !== $new2) { | ||||
|             return 'New passwords do not match!'; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param DeleteAccountFormRequest $request | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      * @throws \Exception | ||||
|      */ | ||||
|     public function postDeleteAccount(DeleteAccountFormRequest $request) | ||||
|     { | ||||
|         // old, new1, new2 | ||||
|         if (!Hash::check($request->get('password'), Auth::user()->password)) { | ||||
|             Session::flash('error', 'Invalid password!'); | ||||
|  | ||||
|             return Redirect::route('delete-account'); | ||||
|         } | ||||
|  | ||||
|         // DELETE! | ||||
|         Auth::user()->delete(); | ||||
|         Session::flush(); | ||||
|  | ||||
|         return Redirect::route('index'); | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,176 +0,0 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionGroup; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Repositories\Journal\JournalRepositoryInterface; | ||||
| use Illuminate\Support\Collection; | ||||
| use Input; | ||||
| use Redirect; | ||||
| use Response; | ||||
| use URL; | ||||
|  | ||||
| /** | ||||
|  * Class RelatedController | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers | ||||
|  */ | ||||
| class RelatedController extends Controller | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * @param TransactionJournal $journal | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function alreadyRelated(TransactionJournal $journal) | ||||
|     { | ||||
|         $ids = []; | ||||
|         /** @var TransactionGroup $group */ | ||||
|         foreach ($journal->transactiongroups()->get() as $group) { | ||||
|             /** @var TransactionJournal $loopJournal */ | ||||
|             foreach ($group->transactionjournals()->get() as $loopJournal) { | ||||
|                 if ($loopJournal->id != $journal->id) { | ||||
|                     $ids[] = $loopJournal->id; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         $unique   = array_unique($ids); | ||||
|         $journals = new Collection; | ||||
|         if (count($unique) > 0) { | ||||
|  | ||||
|             $journals = Auth::user()->transactionjournals()->whereIn('id', $unique)->get(); | ||||
|             $journals->each( | ||||
|                 function (TransactionJournal $journal) { | ||||
|                     /** @var Transaction $t */ | ||||
|                     foreach ($journal->transactions()->get() as $t) { | ||||
|                         if ($t->amount > 0) { | ||||
|                             $journal->amount = $t->amount; | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                 } | ||||
|             ); | ||||
|         } | ||||
|         $parent = $journal; | ||||
|  | ||||
|         return view('related.alreadyRelated', compact('parent', 'journals')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind. | ||||
|      * | ||||
|      * @param TransactionJournal $parentJournal | ||||
|      * @param TransactionJournal $childJournal | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @throws Exception | ||||
|      */ | ||||
|     public function getRemoveRelation(TransactionJournal $parentJournal, TransactionJournal $childJournal) | ||||
|     { | ||||
|         $groups = $parentJournal->transactiongroups()->get(); | ||||
|         /** @var TransactionGroup $group */ | ||||
|         foreach ($groups as $group) { | ||||
|             foreach ($group->transactionjournals()->get() as $loopJournal) { | ||||
|                 if ($loopJournal->id == $childJournal->id) { | ||||
|                     // remove from group: | ||||
|                     $group->transactionjournals()->detach($childJournal); | ||||
|                 } | ||||
|             } | ||||
|             if ($group->transactionjournals()->count() == 1) { | ||||
|                 $group->delete(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return Redirect::to(URL::previous()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionJournal $parentJournal | ||||
|      * @param TransactionJournal $childJournal | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function relate(TransactionJournal $parentJournal, TransactionJournal $childJournal) | ||||
|     { | ||||
|         $group           = new TransactionGroup; | ||||
|         $group->relation = 'balance'; | ||||
|         $group->user_id  = Auth::user()->id; | ||||
|         $group->save(); | ||||
|         $group->transactionjournals()->save($parentJournal); | ||||
|         $group->transactionjournals()->save($childJournal); | ||||
|  | ||||
|         return Response::json(true); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionJournal $journal | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function related(TransactionJournal $journal) | ||||
|     { | ||||
|         $groups  = $journal->transactiongroups()->get(); | ||||
|         $members = new Collection; | ||||
|         /** @var TransactionGroup $group */ | ||||
|         foreach ($groups as $group) { | ||||
|             /** @var TransactionJournal $loopJournal */ | ||||
|             foreach ($group->transactionjournals()->get() as $loopJournal) { | ||||
|                 if ($loopJournal->id != $journal->id) { | ||||
|                     $members->push($loopJournal); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return view('related.relate', compact('journal', 'members')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind. | ||||
|      * | ||||
|      * @param TransactionJournal $parentJournal | ||||
|      * @param TransactionJournal $childJournal | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @throws Exception | ||||
|      */ | ||||
|     public function removeRelation(TransactionJournal $parentJournal, TransactionJournal $childJournal) | ||||
|     { | ||||
|         $groups = $parentJournal->transactiongroups()->get(); | ||||
|         /** @var TransactionGroup $group */ | ||||
|         foreach ($groups as $group) { | ||||
|             foreach ($group->transactionjournals()->get() as $loopJournal) { | ||||
|                 if ($loopJournal->id == $childJournal->id) { | ||||
|                     // remove from group: | ||||
|                     $group->transactionjournals()->detach($childJournal); | ||||
|                 } | ||||
|             } | ||||
|             if ($group->transactionjournals()->count() == 1) { | ||||
|                 $group->delete(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return Response::json(true); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionJournal $journal | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function search(TransactionJournal $journal, JournalRepositoryInterface $repository) | ||||
|     { | ||||
|  | ||||
|         $search = e(trim(Input::get('searchValue'))); | ||||
|         $parent = $journal; | ||||
|  | ||||
|         $journals = $repository->searchRelated($search, $journal); | ||||
|  | ||||
|         return view('related.searchResult', compact('journals', 'search', 'parent')); | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1,9 +1,7 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Helpers\Reminders\ReminderHelperInterface; | ||||
| use FireflyIII\Models\Reminder; | ||||
| use FireflyIII\Repositories\Reminder\ReminderRepositoryInterface; | ||||
| use Redirect; | ||||
| use Session; | ||||
| use URL; | ||||
| @@ -19,6 +17,8 @@ class ReminderController extends Controller | ||||
|  | ||||
|     /** | ||||
|      * @param Reminder $reminder | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function act(Reminder $reminder) | ||||
|     { | ||||
| @@ -36,6 +36,8 @@ class ReminderController extends Controller | ||||
|  | ||||
|     /** | ||||
|      * @param Reminder $reminder | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function dismiss(Reminder $reminder) | ||||
|     { | ||||
| @@ -48,55 +50,18 @@ class ReminderController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param ReminderRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function index(ReminderHelperInterface $helper) | ||||
|     public function index(ReminderRepositoryInterface $repository) | ||||
|     { | ||||
|  | ||||
|         $reminders = Auth::user()->reminders()->get(); | ||||
|  | ||||
|         $reminders->each( | ||||
|             function (Reminder $reminder) use ($helper) { | ||||
|                 $reminder->description = $helper->getReminderText($reminder); | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         $today = new Carbon; | ||||
|         // active reminders: | ||||
|         $active = $reminders->filter( | ||||
|             function (Reminder $reminder) use ($today) { | ||||
|                 if ($reminder->notnow === false && $reminder->active === true && $reminder->startdate <= $today && $reminder->enddate >= $today) { | ||||
|                     return $reminder; | ||||
|                 } | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         // expired reminders: | ||||
|         $expired = $reminders->filter( | ||||
|             function (Reminder $reminder) use ($today) { | ||||
|                 if ($reminder->notnow === false && $reminder->active === true && $reminder->startdate > $today || $reminder->enddate < $today) { | ||||
|                     return $reminder; | ||||
|                 } | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         // inactive reminders | ||||
|         $inactive = $reminders->filter( | ||||
|             function (Reminder $reminder) { | ||||
|                 if ($reminder->active === false) { | ||||
|                     return $reminder; | ||||
|                 } | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         // dismissed reminders | ||||
|         $dismissed = $reminders->filter( | ||||
|             function (Reminder $reminder) { | ||||
|                 if ($reminder->notnow === true) { | ||||
|                     return $reminder; | ||||
|                 } | ||||
|             } | ||||
|         ); | ||||
|         $active    = $repository->getActiveReminders(); | ||||
|         $expired   = $repository->getExpiredReminders(); | ||||
|         $inactive  = $repository->getInactiveReminders(); | ||||
|         $dismissed = $repository->getDismissedReminders(); | ||||
|  | ||||
|         $title         = 'Reminders'; | ||||
|         $mainTitleIcon = 'fa-clock-o'; | ||||
| @@ -106,6 +71,8 @@ class ReminderController extends Controller | ||||
|  | ||||
|     /** | ||||
|      * @param Reminder $reminder | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function show(Reminder $reminder) | ||||
|     { | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use Exception; | ||||
| use FireflyIII\Helpers\Report\ReportHelperInterface; | ||||
| use FireflyIII\Helpers\Report\ReportQueryInterface; | ||||
| use FireflyIII\Models\Account; | ||||
| @@ -11,7 +10,6 @@ use Preferences; | ||||
| use Session; | ||||
| use Steam; | ||||
| use View; | ||||
| use Crypt; | ||||
|  | ||||
| /** | ||||
|  * Class ReportController | ||||
| @@ -48,50 +46,52 @@ class ReportController extends Controller | ||||
|      */ | ||||
|     public function budget($year = '2014', $month = '1') | ||||
|     { | ||||
|         try { | ||||
|             new Carbon($year . '-' . $month . '-01'); | ||||
|         } catch (Exception $e) { | ||||
|             return view('error')->with('message', 'Invalid date'); | ||||
|         } | ||||
|         $date  = new Carbon($year . '-' . $month . '-01'); | ||||
|         $start = clone $date; | ||||
|         $date         = new Carbon($year . '-' . $month . '-01'); | ||||
|         $subTitle     = 'Budget report for ' . $date->format('F Y'); | ||||
|         $subTitleIcon = 'fa-calendar'; | ||||
|         $start        = clone $date; | ||||
|  | ||||
|  | ||||
|         $start->startOfMonth(); | ||||
|         $end = clone $date; | ||||
|         $end->endOfMonth(); | ||||
|         $start->subDay(); | ||||
|  | ||||
|         // should show shared reports? | ||||
|         /** @var Preference $pref */ | ||||
|         $pref              = Preferences::get('showSharedReports', false); | ||||
|         $showSharedReports = $pref->data; | ||||
|         $accountAmounts    = []; // array with sums of spent amounts on each account. | ||||
|         $accounts          = $this->query->getAllAccounts($start, $end, $showSharedReports); // all accounts and some data. | ||||
|  | ||||
|         foreach ($accounts as $account) { | ||||
|  | ||||
|         $dayEarly     = clone $date; | ||||
|         $subTitle     = 'Budget report for ' . $date->format('F Y'); | ||||
|         $subTitleIcon = 'fa-calendar'; | ||||
|         $dayEarly     = $dayEarly->subDay(); | ||||
|         $accounts     = $this->query->getAllAccounts($start, $end, $showSharedReports); | ||||
|         $start->addDay(); | ||||
|             $budgets                      = $this->query->getBudgetSummary($account, $start, $end);// get budget summary for this account: | ||||
|             $balancedAmount               = $this->query->balancedTransactionsSum($account, $start, $end); | ||||
|             $accountAmounts[$account->id] = $balancedAmount; | ||||
|             // balance out the transactions (see transaction groups & tags) ^^ | ||||
|  | ||||
|         $accounts->each( | ||||
|             function (Account $account) use ($start, $end) { | ||||
|                 $budgets        = $this->query->getBudgetSummary($account, $start, $end); | ||||
|                 $balancedAmount = $this->query->balancedTransactionsSum($account, $start, $end); | ||||
|                 $array          = []; | ||||
|                 $hide           = true; | ||||
|                 foreach ($budgets as $budget) { | ||||
|                     $id         = intval($budget->id); | ||||
|                     $data       = $budget->toArray(); | ||||
|                     $array[$id] = $data; | ||||
|                     if (floatval($data['amount']) != 0) { | ||||
|                         $hide = false; | ||||
|                     } | ||||
|             // array with budget information for each account: | ||||
|             $array = []; | ||||
|             // should always hide account | ||||
|             $hide = true; | ||||
|             // loop all budgets | ||||
|             /** @var \FireflyIII\Models\Budget $budget */ | ||||
|             foreach ($budgets as $budget) { | ||||
|                 $id         = intval($budget->id); | ||||
|                 $data       = $budget->toArray(); | ||||
|                 $array[$id] = $data; | ||||
|  | ||||
|                 // no longer hide account if any budget has money in it. | ||||
|                 if (floatval($data['queryAmount']) != 0) { | ||||
|                     $hide = false; | ||||
|                 } | ||||
|                 $account->hide              = $hide; | ||||
|                 $account->budgetInformation = $array; | ||||
|                 $account->balancedAmount    = $balancedAmount; | ||||
|  | ||||
|                 $accountAmounts[$account->id] += $data['queryAmount']; | ||||
|             } | ||||
|         ); | ||||
|             $account->hide              = $hide; | ||||
|             $account->budgetInformation = $array; | ||||
|             $account->balancedAmount    = $balancedAmount; | ||||
|  | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Start getBudgetsForMonth DONE | ||||
| @@ -102,14 +102,14 @@ class ReportController extends Controller | ||||
|          * End getBudgetsForMonth DONE | ||||
|          */ | ||||
|  | ||||
|         return view('reports.budget', compact('subTitle', 'year', 'month', 'subTitleIcon', 'date', 'accounts', 'budgets', 'dayEarly')); | ||||
|         return view('reports.budget', compact('subTitle', 'accountAmounts', 'year', 'month', 'subTitleIcon', 'date', 'accounts', 'budgets')); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param ReportHelperInterface $helper | ||||
|      * | ||||
|      * @return View | ||||
|      * @internal param ReportHelperInterface $helper | ||||
|      * | ||||
|      */ | ||||
|     public function index() | ||||
|     { | ||||
| @@ -132,11 +132,6 @@ class ReportController extends Controller | ||||
|     public function modalBalancedTransfers(Account $account, $year = '2014', $month = '1') | ||||
|     { | ||||
|  | ||||
|         try { | ||||
|             new Carbon($year . '-' . $month . '-01'); | ||||
|         } catch (Exception $e) { | ||||
|             return view('error')->with('message', 'Invalid date'); | ||||
|         } | ||||
|         $start = new Carbon($year . '-' . $month . '-01'); | ||||
|         $end   = clone $start; | ||||
|         $end->endOfMonth(); | ||||
| @@ -149,20 +144,16 @@ class ReportController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Account              $account | ||||
|      * @param string               $year | ||||
|      * @param string               $month | ||||
|      * @param ReportQueryInterface $query | ||||
|      * @param Account $account | ||||
|      * @param string  $year | ||||
|      * @param string  $month | ||||
|      * | ||||
|      * @return View | ||||
|      * @internal param ReportQueryInterface $query | ||||
|      * | ||||
|      */ | ||||
|     public function modalLeftUnbalanced(Account $account, $year = '2014', $month = '1') | ||||
|     { | ||||
|         try { | ||||
|             new Carbon($year . '-' . $month . '-01'); | ||||
|         } catch (Exception $e) { | ||||
|             return view('error')->with('message', 'Invalid date'); | ||||
|         } | ||||
|         $start = new Carbon($year . '-' . $month . '-01'); | ||||
|         $end   = clone $start; | ||||
|         $end->endOfMonth(); | ||||
| @@ -174,6 +165,8 @@ class ReportController extends Controller | ||||
|                 if ($count == 0) { | ||||
|                     return $journal; | ||||
|                 } | ||||
|  | ||||
|                 return null; | ||||
|             } | ||||
|         ); | ||||
|  | ||||
| @@ -189,11 +182,6 @@ class ReportController extends Controller | ||||
|      */ | ||||
|     public function modalNoBudget(Account $account, $year = '2014', $month = '1') | ||||
|     { | ||||
|         try { | ||||
|             new Carbon($year . '-' . $month . '-01'); | ||||
|         } catch (Exception $e) { | ||||
|             return view('error')->with('message', 'Invalid date'); | ||||
|         } | ||||
|         $start = new Carbon($year . '-' . $month . '-01'); | ||||
|         $end   = clone $start; | ||||
|         $end->endOfMonth(); | ||||
| @@ -211,11 +199,6 @@ class ReportController extends Controller | ||||
|      */ | ||||
|     public function month($year = '2014', $month = '1') | ||||
|     { | ||||
|         try { | ||||
|             new Carbon($year . '-' . $month . '-01'); | ||||
|         } catch (Exception $e) { | ||||
|             return view('error')->with('message', 'Invalid date.'); | ||||
|         } | ||||
|         $date         = new Carbon($year . '-' . $month . '-01'); | ||||
|         $subTitle     = 'Report for ' . $date->format('F Y'); | ||||
|         $subTitleIcon = 'fa-calendar'; | ||||
| @@ -246,7 +229,7 @@ class ReportController extends Controller | ||||
|         /** | ||||
|          * Start getExpenseGroupedForMonth DONE | ||||
|          */ | ||||
|         $set      = $this->query->journalsByExpenseAccount($start, $end, $showSharedReports); | ||||
|         $set = $this->query->journalsByExpenseAccount($start, $end, $showSharedReports); | ||||
|  | ||||
|         $expenses = Steam::makeArray($set); | ||||
|         $expenses = Steam::sortArray($expenses); | ||||
| @@ -327,11 +310,6 @@ class ReportController extends Controller | ||||
|      */ | ||||
|     public function year($year) | ||||
|     { | ||||
|         try { | ||||
|             new Carbon('01-01-' . $year); | ||||
|         } catch (Exception $e) { | ||||
|             return view('error')->with('message', 'Invalid date.'); | ||||
|         } | ||||
|         /** @var Preference $pref */ | ||||
|         $pref              = Preferences::get('showSharedReports', false); | ||||
|         $showSharedReports = $pref->data; | ||||
|   | ||||
| @@ -12,6 +12,10 @@ class SearchController extends Controller | ||||
| { | ||||
|     /** | ||||
|      * Results always come in the form of an array [results, count, fullCount] | ||||
|      * | ||||
|      * @param SearchInterface $searcher | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function index(SearchInterface $searcher) | ||||
|     { | ||||
|   | ||||
							
								
								
									
										325
									
								
								app/Http/Controllers/TagController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										325
									
								
								app/Http/Controllers/TagController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,325 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Http\Requests\TagFormRequest; | ||||
| use FireflyIII\Models\Preference; | ||||
| use FireflyIII\Models\Tag; | ||||
| use FireflyIII\Repositories\Tag\TagRepositoryInterface; | ||||
| use Input; | ||||
| use Preferences; | ||||
| use Redirect; | ||||
| use Response; | ||||
| use Session; | ||||
| use URL; | ||||
| use View; | ||||
|  | ||||
| /** | ||||
|  * Class TagController | ||||
|  * | ||||
|  * Remember: a balancingAct takes at most one expense and one transfer. | ||||
|  *           an advancePayment takes at most one expense, infinite deposits and NO transfers. | ||||
|  * | ||||
|  * TODO transaction can only have one advancePayment OR balancingAct. | ||||
|  * TODO Other attempts to put in such a tag are blocked. | ||||
|  * TODO also show an error when editing a tag and it becomes either | ||||
|  * TODO of these two types. Or rather, block editing of the tag. | ||||
|  * | ||||
|  * @package FireflyIII\Http\Controllers | ||||
|  */ | ||||
| class TagController extends Controller | ||||
| { | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         View::share('title', 'Tags'); | ||||
|         View::share('mainTitleIcon', 'fa-tags'); | ||||
|         View::share('hideTags', true); | ||||
|         $tagOptions = [ | ||||
|             'nothing'        => 'Just a regular tag.', | ||||
|             'balancingAct'   => 'The tag takes at most two transactions; an expense and a transfer. They\'ll balance each other out.', | ||||
|             'advancePayment' => 'The tag accepts one expense and any number of deposits aimed to repay the original expense.', | ||||
|         ]; | ||||
|         View::share('tagOptions', $tagOptions); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function create() | ||||
|     { | ||||
|         $subTitle     = 'New tag'; | ||||
|         $subTitleIcon = 'fa-tag'; | ||||
|  | ||||
|         $preFilled = [ | ||||
|             'tagMode' => 'nothing' | ||||
|         ]; | ||||
|         if (!Input::old('tagMode')) { | ||||
|             Session::flash('preFilled', $preFilled); | ||||
|         } | ||||
|         // put previous url in session if not redirect from store (not "create another"). | ||||
|         if (Session::get('tags.create.fromStore') !== true) { | ||||
|             Session::put('tags.create.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('tags.create.fromStore'); | ||||
|  | ||||
|         return view('tags.create', compact('subTitle', 'subTitleIcon')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Tag $tag | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function delete(Tag $tag) | ||||
|     { | ||||
|         $subTitle = 'Delete "' . e($tag->tag) . '"'; | ||||
|  | ||||
|         // put previous url in session | ||||
|         Session::put('tags.delete.url', URL::previous()); | ||||
|  | ||||
|         return view('tags.delete', compact('tag', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TagRepositoryInterface $repository | ||||
|      * @param Tag                    $tag | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function destroy(TagRepositoryInterface $repository, Tag $tag) | ||||
|     { | ||||
|  | ||||
|         $tagName = $tag->tag; | ||||
|         $repository->destroy($tag); | ||||
|  | ||||
|         Session::flash('success', 'Tag "' . e($tagName) . '" was deleted.'); | ||||
|  | ||||
|         return Redirect::to(route('tags.index')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Tag $tag | ||||
|      * | ||||
|      * @return View | ||||
|      */ | ||||
|     public function edit(Tag $tag) | ||||
|     { | ||||
|         $subTitle     = 'Edit tag "' . e($tag->tag) . '"'; | ||||
|         $subTitleIcon = 'fa-tag'; | ||||
|  | ||||
|         /* | ||||
|          * Default tag options (again) | ||||
|          */ | ||||
|         $tagOptions = [ | ||||
|             'nothing'        => 'Just a regular tag.', | ||||
|             'balancingAct'   => 'The tag takes at most two transactions; an expense and a transfer. They\'ll balance each other out.', | ||||
|             'advancePayment' => 'The tag accepts one expense and any number of deposits aimed to repay the original expense.', | ||||
|         ]; | ||||
|  | ||||
|         /* | ||||
|          * Can this tag become another type? | ||||
|          */ | ||||
|         $allowToAdvancePayment = true; | ||||
|         $allowToBalancingAct   = true; | ||||
|  | ||||
|         /* | ||||
|          * If this tag is a balancing act, and it contains transfers, it cannot be | ||||
|          * changes to an advancePayment. | ||||
|          */ | ||||
|  | ||||
|         if ($tag->tagMode == 'balancingAct') { | ||||
|             foreach ($tag->transactionjournals as $journal) { | ||||
|                 if ($journal->transactionType->type == 'Transfer') { | ||||
|                     $allowToAdvancePayment = false; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /* | ||||
|          * If this tag contains more than one expenses, it cannot become an advance payment. | ||||
|          */ | ||||
|         $count = 0; | ||||
|         foreach ($tag->transactionjournals as $journal) { | ||||
|             if ($journal->transactionType->type == 'Withdrawal') { | ||||
|                 $count++; | ||||
|             } | ||||
|         } | ||||
|         if ($count > 1) { | ||||
|             $allowToAdvancePayment = false; | ||||
|         } | ||||
|  | ||||
|         /* | ||||
|          * If has more than two transactions already, cannot become a balancing act: | ||||
|          */ | ||||
|         if ($tag->transactionjournals->count() > 2) { | ||||
|             $allowToBalancingAct = false; | ||||
|         } | ||||
|  | ||||
|         /* | ||||
|          * If any transaction is a deposit, cannot become a balancing act. | ||||
|          */ | ||||
|         $count = 0; | ||||
|         foreach ($tag->transactionjournals as $journal) { | ||||
|             if ($journal->transactionType->type == 'Deposit') { | ||||
|                 $count++; | ||||
|             } | ||||
|         } | ||||
|         if ($count > 0) { | ||||
|             $allowToBalancingAct = false; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         // edit tag options: | ||||
|         if ($allowToAdvancePayment === false) { | ||||
|             unset($tagOptions['advancePayment']); | ||||
|         } | ||||
|         if ($allowToBalancingAct === false) { | ||||
|             unset($tagOptions['balancingAct']); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         // put previous url in session if not redirect from store (not "return_to_edit"). | ||||
|         if (Session::get('tags.edit.fromUpdate') !== true) { | ||||
|             Session::put('tags.edit.url', URL::previous()); | ||||
|         } | ||||
|         Session::forget('tags.edit.fromUpdate'); | ||||
|  | ||||
|         return view('tags.edit', compact('tag', 'subTitle', 'subTitleIcon', 'tagOptions')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $state | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function hideTagHelp($state) | ||||
|     { | ||||
|  | ||||
|         $state = $state == 'true' ? true : false; | ||||
|         Preferences::set('hideTagHelp', $state); | ||||
|  | ||||
|         return Response::json(true); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function index() | ||||
|     { | ||||
|         /** @var Preference $helpHiddenPref */ | ||||
|         $helpHiddenPref = Preferences::get('hideTagHelp', false); | ||||
|         $title          = 'Tags'; | ||||
|         $mainTitleIcon  = 'fa-tags'; | ||||
|         $helpHidden     = $helpHiddenPref->data; | ||||
|         $tags           = Auth::user()->tags()->get(); | ||||
|  | ||||
|         return view('tags.index', compact('title', 'mainTitleIcon', 'helpHidden', 'tags')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Tag $tag | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      */ | ||||
|     public function show(Tag $tag) | ||||
|     { | ||||
|         $subTitle     = $tag->tag; | ||||
|         $subTitleIcon = 'fa-tag'; | ||||
|  | ||||
|         return view('tags.show', compact('tag', 'subTitle', 'subTitleIcon')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TagFormRequest         $request | ||||
|      * | ||||
|      * @param TagRepositoryInterface $repository | ||||
|      * | ||||
|      * @return $this|\Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function store(TagFormRequest $request, TagRepositoryInterface $repository) | ||||
|     { | ||||
|         if (Input::get('setTag') == 'true') { | ||||
|             $latitude  = strlen($request->get('latitude')) > 0 ? $request->get('latitude') : null; | ||||
|             $longitude = strlen($request->get('longitude')) > 0 ? $request->get('longitude') : null; | ||||
|             $zoomLevel = strlen($request->get('zoomLevel')) > 0 ? $request->get('zoomLevel') : null; | ||||
|         } else { | ||||
|             $latitude  = null; | ||||
|             $longitude = null; | ||||
|             $zoomLevel = null; | ||||
|         } | ||||
|  | ||||
|         $data = [ | ||||
|             'tag'         => $request->get('tag'), | ||||
|             'date'        => strlen($request->get('date')) > 0 ? new Carbon($request->get('date')) : null, | ||||
|             'description' => strlen($request->get('description')) > 0 ? $request->get('description') : '', | ||||
|             'latitude'    => $latitude, | ||||
|             'longitude'   => $longitude, | ||||
|             'zoomLevel'   => $zoomLevel, | ||||
|             'tagMode'     => $request->get('tagMode'), | ||||
|         ]; | ||||
|         $repository->store($data); | ||||
|  | ||||
|         Session::flash('success', 'The tag has been created!'); | ||||
|  | ||||
|         if (intval(Input::get('create_another')) === 1) { | ||||
|             // set value so create routine will not overwrite URL: | ||||
|             Session::put('tags.create.fromStore', true); | ||||
|  | ||||
|             return Redirect::route('tags.create')->withInput(); | ||||
|         } | ||||
|  | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('tags.create.url')); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TagFormRequest         $request | ||||
|      * @param TagRepositoryInterface $repository | ||||
|      * @param Tag                    $tag | ||||
|      * | ||||
|      * @return $this|\Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function update(TagFormRequest $request, TagRepositoryInterface $repository, Tag $tag) | ||||
|     { | ||||
|         if (Input::get('setTag') == 'true') { | ||||
|             $latitude  = strlen($request->get('latitude')) > 0 ? $request->get('latitude') : null; | ||||
|             $longitude = strlen($request->get('longitude')) > 0 ? $request->get('longitude') : null; | ||||
|             $zoomLevel = strlen($request->get('zoomLevel')) > 0 ? $request->get('zoomLevel') : null; | ||||
|         } else { | ||||
|             $latitude  = null; | ||||
|             $longitude = null; | ||||
|             $zoomLevel = null; | ||||
|         } | ||||
|  | ||||
|         $data = [ | ||||
|             'tag'         => $request->get('tag'), | ||||
|             'date'        => strlen($request->get('date')) > 0 ? new Carbon($request->get('date')) : null, | ||||
|             'description' => strlen($request->get('description')) > 0 ? $request->get('description') : '', | ||||
|             'latitude'    => $latitude, | ||||
|             'longitude'   => $longitude, | ||||
|             'zoomLevel'   => $zoomLevel, | ||||
|             'tagMode'     => $request->get('tagMode'), | ||||
|         ]; | ||||
|  | ||||
|         $repository->update($tag, $data); | ||||
|  | ||||
|         Session::flash('success', 'Tag "' . e($data['tag']) . '" updated.'); | ||||
|  | ||||
|         if (intval(Input::get('return_to_edit')) === 1) { | ||||
|             // set value so edit routine will not overwrite URL: | ||||
|             Session::put('tags.edit.fromUpdate', true); | ||||
|  | ||||
|             return Redirect::route('tags.edit', $tag->id)->withInput(['return_to_edit' => 1]); | ||||
|         } | ||||
|  | ||||
|         // redirect to previous URL. | ||||
|         return Redirect::to(Session::get('tags.edit.url')); | ||||
|     } | ||||
| } | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?php namespace FireflyIII\Http\Controllers; | ||||
|  | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use ExpandedForm; | ||||
| use FireflyIII\Events\JournalCreated; | ||||
| use FireflyIII\Events\JournalSaved; | ||||
| @@ -8,8 +9,8 @@ use FireflyIII\Http\Requests; | ||||
| use FireflyIII\Http\Requests\JournalFormRequest; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Repositories\Journal\JournalRepositoryInterface; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use Input; | ||||
| use Redirect; | ||||
| use Response; | ||||
| @@ -28,24 +29,20 @@ class TransactionController extends Controller | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         View::share('title', 'Transactions'); | ||||
|         View::share('mainTitleIcon', 'fa-repeat'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Shows the view helping the user to create a new transaction journal. | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * @param string                     $what | ||||
|      * | ||||
|      * @param string $what | ||||
|      * | ||||
|      * @return \Illuminate\View\View | ||||
|      * @return View | ||||
|      */ | ||||
|     public function create($what = 'deposit') | ||||
|     public function create(AccountRepositoryInterface $repository, $what = 'deposit') | ||||
|     { | ||||
|         $accounts   = ExpandedForm::makeSelectList( | ||||
|             Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->orderBy('accounts.name', 'ASC')->orderBy('name', 'ASC')->where( | ||||
|                 'active', 1 | ||||
|             )->orderBy('name', 'DESC')->get(['accounts.*']) | ||||
|         ); | ||||
|         $accounts   = ExpandedForm::makeSelectList($repository->getAccounts(['Default account', 'Asset account'])); | ||||
|         $budgets    = ExpandedForm::makeSelectList(Auth::user()->budgets()->get()); | ||||
|         $budgets[0] = '(no budget)'; | ||||
|         $piggies    = ExpandedForm::makeSelectList(Auth::user()->piggyBanks()->get()); | ||||
| @@ -88,21 +85,22 @@ class TransactionController extends Controller | ||||
|         // put previous url in session | ||||
|         Session::put('transactions.delete.url', URL::previous()); | ||||
|  | ||||
|         return View::make('transactions.delete', compact('journal', 'subTitle')); | ||||
|         return view('transactions.delete', compact('journal', 'subTitle')); | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionJournal $transactionJournal | ||||
|      * @param JournalRepositoryInterface $repository | ||||
|      * @param TransactionJournal         $transactionJournal | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function destroy(TransactionJournal $transactionJournal) | ||||
|     public function destroy(JournalRepositoryInterface $repository, TransactionJournal $transactionJournal) | ||||
|     { | ||||
|         Session::flash('success', 'Transaction "' . e($transactionJournal->description) . '" destroyed.'); | ||||
|  | ||||
|         $transactionJournal->delete(); | ||||
|         $repository->delete($transactionJournal); | ||||
|  | ||||
|         // redirect to previous URL: | ||||
|         return Redirect::to(Session::get('transactions.delete.url')); | ||||
| @@ -111,18 +109,15 @@ class TransactionController extends Controller | ||||
|     /** | ||||
|      * Shows the view to edit a transaction. | ||||
|      * | ||||
|      * @param TransactionJournal $journal | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * @param TransactionJournal         $journal | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function edit(TransactionJournal $journal, JournalRepositoryInterface $repository) | ||||
|     public function edit(AccountRepositoryInterface $repository, TransactionJournal $journal) | ||||
|     { | ||||
|         $what         = strtolower($journal->transactiontype->type); | ||||
|         $accounts     = ExpandedForm::makeSelectList( | ||||
|             Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->orderBy('accounts.name', 'ASC')->where('active', 1)->orderBy( | ||||
|                 'name', 'DESC' | ||||
|             )->get(['accounts.*']) | ||||
|         ); | ||||
|         $accounts     = ExpandedForm::makeSelectList($repository->getAccounts(['Default account', 'Asset account'])); | ||||
|         $budgets      = ExpandedForm::makeSelectList(Auth::user()->budgets()->get()); | ||||
|         $budgets[0]   = '(no budget)'; | ||||
|         $transactions = $journal->transactions()->orderBy('amount', 'DESC')->get(); | ||||
| @@ -134,6 +129,12 @@ class TransactionController extends Controller | ||||
|             'budget_id'     => 0, | ||||
|             'piggy_bank_id' => 0 | ||||
|         ]; | ||||
|         // get tags: | ||||
|         $tags = []; | ||||
|         foreach ($journal->tags as $tag) { | ||||
|             $tags[] = $tag->tag; | ||||
|         } | ||||
|         $preFilled['tags'] = join(',', $tags); | ||||
|  | ||||
|         $category = $journal->categories()->first(); | ||||
|         if (!is_null($category)) { | ||||
| @@ -149,19 +150,15 @@ class TransactionController extends Controller | ||||
|             $preFilled['piggy_bank_id'] = $journal->piggyBankEvents()->orderBy('date', 'DESC')->first()->piggy_bank_id; | ||||
|         } | ||||
|  | ||||
|         $preFilled['amount'] = 0; | ||||
|         /** @var Transaction $t */ | ||||
|         foreach ($transactions as $t) { | ||||
|             if (floatval($t->amount) > 0) { | ||||
|                 $preFilled['amount'] = floatval($t->amount); | ||||
|             } | ||||
|         } | ||||
|         $preFilled['account_id']      = $repository->getAssetAccount($journal); | ||||
|         $preFilled['amount']          = $journal->amount; | ||||
|         $preFilled['account_id']      = $journal->assetAccount->id; | ||||
|         $preFilled['expense_account'] = $transactions[0]->account->name; | ||||
|         $preFilled['revenue_account'] = $transactions[1]->account->name; | ||||
|         $preFilled['account_from_id'] = $transactions[1]->account->id; | ||||
|         $preFilled['account_to_id']   = $transactions[0]->account->id; | ||||
|  | ||||
|         Session::flash('preFilled', $preFilled); | ||||
|  | ||||
|         // put previous url in session if not redirect from store (not "return_to_edit"). | ||||
|         if (Session::get('transactions.edit.fromUpdate') !== true) { | ||||
|             Session::put('transactions.edit.url', URL::previous()); | ||||
| @@ -173,12 +170,14 @@ class TransactionController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $what | ||||
|      * @param JournalRepositoryInterface $repository | ||||
|      * @param                            $what | ||||
|      * | ||||
|      * @return $this | ||||
|      * @return View | ||||
|      */ | ||||
|     public function index($what) | ||||
|     public function index(JournalRepositoryInterface $repository, $what) | ||||
|     { | ||||
|         $types = []; | ||||
|         switch ($what) { | ||||
|             case 'expenses': | ||||
|             case 'withdrawal': | ||||
| @@ -200,18 +199,10 @@ class TransactionController extends Controller | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         $page   = intval(\Input::get('page')); | ||||
|         $offset = $page > 0 ? ($page - 1) * 50 : 0; | ||||
|         $page     = intval(Input::get('page')); | ||||
|         $offset   = $page > 0 ? ($page - 1) * 50 : 0; | ||||
|         $journals = $repository->getJournalsOfTypes($types, $offset, $page); | ||||
|  | ||||
|         $set      = Auth::user()->transactionJournals()->transactionTypes($types)->withRelevantData()->take(50)->offset($offset) | ||||
|                         ->orderBy('date', 'DESC') | ||||
|                         ->orderBy('order', 'ASC') | ||||
|                         ->orderBy('id', 'DESC') | ||||
|                         ->get( | ||||
|                             ['transaction_journals.*'] | ||||
|                         ); | ||||
|         $count    = Auth::user()->transactionJournals()->transactionTypes($types)->count(); | ||||
|         $journals = new LengthAwarePaginator($set, $count, 50, $page); | ||||
|         $journals->setPath('transactions/' . $what); | ||||
|  | ||||
|         return view('transactions.index', compact('subTitle', 'what', 'subTitleIcon', 'journals')); | ||||
| @@ -219,15 +210,19 @@ class TransactionController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Reorder transactions (which all must have the same date) | ||||
|      * @param JournalRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Symfony\Component\HttpFoundation\Response | ||||
|      */ | ||||
|     public function reorder() | ||||
|     public function reorder(JournalRepositoryInterface $repository) | ||||
|     { | ||||
|         $ids = Input::get('items'); | ||||
|         $ids  = Input::get('items'); | ||||
|         $date = new Carbon(Input::get('date')); | ||||
|         if (count($ids) > 0) { | ||||
|             $order = 0; | ||||
|             foreach ($ids as $id) { | ||||
|                 $journal = Auth::user()->transactionjournals()->where('id', $id)->where('date', Input::get('date'))->first(); | ||||
|  | ||||
|                 $journal = $repository->getWithDate($id, $date); | ||||
|                 if ($journal) { | ||||
|                     $journal->order = $order; | ||||
|                     $order++; | ||||
| @@ -241,31 +236,22 @@ class TransactionController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionJournal $journal | ||||
|      * @param JournalRepositoryInterface $repository | ||||
|      * @param TransactionJournal         $journal | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function show(TransactionJournal $journal) | ||||
|     public function show(JournalRepositoryInterface $repository, TransactionJournal $journal) | ||||
|     { | ||||
|         $journal->transactions->each( | ||||
|             function (Transaction $t) use ($journal) { | ||||
|                 $t->before = floatval( | ||||
|                     $t->account->transactions()->leftJoin( | ||||
|                         'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id' | ||||
|                     ) | ||||
|                                ->where('transaction_journals.date', '<=', $journal->date->format('Y-m-d')) | ||||
|                                ->where('transaction_journals.order', '>=', $journal->order) | ||||
|                                ->where('transaction_journals.id', '!=', $journal->id) | ||||
|                                ->sum('transactions.amount') | ||||
|                 ); | ||||
|             function (Transaction $t) use ($journal, $repository) { | ||||
|                 $t->before = $repository->getAmountBefore($journal, $t); | ||||
|                 $t->after  = $t->before + $t->amount; | ||||
|             } | ||||
|         ); | ||||
|         $subTitle = e($journal->transactiontype->type) . ' "' . e($journal->description) . '"'; | ||||
|  | ||||
|  | ||||
|         return view('transactions.show', compact('journal'))->with( | ||||
|             'subTitle', e($journal->transactiontype->type) . ' "' . e($journal->description) . '"' | ||||
|         ); | ||||
|         return view('transactions.show', compact('journal', 'subTitle')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -285,11 +271,7 @@ class TransactionController extends Controller | ||||
|         // ConnectJournalToPiggyBank | ||||
|         event(new JournalCreated($journal, intval($request->get('piggy_bank_id')))); | ||||
|  | ||||
|         if (intval($request->get('reminder_id')) > 0) { | ||||
|             $reminder         = Auth::user()->reminders()->find($request->get('reminder_id')); | ||||
|             $reminder->active = 0; | ||||
|             $reminder->save(); | ||||
|         } | ||||
|         $repository->deactivateReminder($request->get('reminder_id')); | ||||
|  | ||||
|         Session::flash('success', 'New transaction "' . $journal->description . '" stored!'); | ||||
|  | ||||
| @@ -305,14 +287,15 @@ class TransactionController extends Controller | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionJournal $journal | ||||
|      * @param JournalFormRequest         $request | ||||
|      * @param JournalRepositoryInterface $repository | ||||
|      * @param TransactionJournal         $journal | ||||
|      * | ||||
|      * @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind. | ||||
|      * | ||||
|      * @return $this | ||||
|      * @return $this|\Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function update(TransactionJournal $journal, JournalFormRequest $request, JournalRepositoryInterface $repository) | ||||
|     public function update(JournalFormRequest $request, JournalRepositoryInterface $repository, TransactionJournal $journal) | ||||
|     { | ||||
|  | ||||
|         $journalData = $request->getJournalData(); | ||||
|   | ||||
| @@ -3,17 +3,13 @@ | ||||
| namespace FireflyIII\Http\Middleware; | ||||
|  | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use App; | ||||
| use Closure; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Models\PiggyBankRepetition; | ||||
| use Illuminate\Contracts\Auth\Guard; | ||||
| use Illuminate\Database\Query\JoinClause; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Support\Collection; | ||||
| use Navigation; | ||||
| use Session; | ||||
| use App; | ||||
|  | ||||
| /** | ||||
|  * Class PiggyBanks | ||||
|   | ||||
| @@ -32,11 +32,11 @@ class AccountFormRequest extends Request | ||||
|         $types          = join(',', array_keys(Config::get('firefly.subTitlesByIdentifier'))); | ||||
|         $ccPaymentTypes = join(',', array_keys(Config::get('firefly.ccTypes'))); | ||||
|  | ||||
|         $nameRule = 'required|between:1,100|uniqueAccountForUser'; | ||||
|         $nameRule = 'required|min:1|uniqueAccountForUser'; | ||||
|         $idRule   = ''; | ||||
|         if (Account::find(Input::get('id'))) { | ||||
|             $idRule   = 'belongsToUser:accounts'; | ||||
|             $nameRule = 'required|between:1,100|uniqueAccountForUser:' . Input::get('id'); | ||||
|             $nameRule = 'required|min:1|uniqueAccountForUser:' . Input::get('id'); | ||||
|         } | ||||
|  | ||||
|         return [ | ||||
|   | ||||
| @@ -30,7 +30,7 @@ class BudgetFormRequest extends Request | ||||
|  | ||||
|         $nameRule = 'required|between:1,100|uniqueObjectForUser:budgets,name,encrypted'; | ||||
|         if (Budget::find(Input::get('id'))) { | ||||
|             $nameRule = 'required|between:1,100|uniqueObjectForUser:budgets,name,encrypted,'.intval(Input::get('id')); | ||||
|             $nameRule = 'required|between:1,100|uniqueObjectForUser:budgets,name,encrypted,' . intval(Input::get('id')); | ||||
|         } | ||||
|  | ||||
|         return [ | ||||
|   | ||||
| @@ -30,7 +30,7 @@ class CategoryFormRequest extends Request | ||||
|  | ||||
|         $nameRule = 'required|between:1,100|uniqueObjectForUser:categories,name,encrypted'; | ||||
|         if (Category::find(Input::get('id'))) { | ||||
|             $nameRule = 'required|between:1,100|uniqueObjectForUser:categories,name,encrypted,'.intval(Input::get('id')); | ||||
|             $nameRule = 'required|between:1,100|uniqueObjectForUser:categories,name,encrypted,' . intval(Input::get('id')); | ||||
|         } | ||||
|  | ||||
|         return [ | ||||
|   | ||||
| @@ -21,6 +21,18 @@ class CurrencyFormRequest extends Request | ||||
|         return Auth::check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getCurrencyData() | ||||
|     { | ||||
|         return [ | ||||
|             'name'   => $this->get('name'), | ||||
|             'code'   => $this->get('code'), | ||||
|             'symbol' => $this->get('symbol'), | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|   | ||||
							
								
								
									
										32
									
								
								app/Http/Requests/DeleteAccountFormRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								app/Http/Requests/DeleteAccountFormRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Http\Requests; | ||||
|  | ||||
| use Auth; | ||||
|  | ||||
| /** | ||||
|  * Class DeleteAccountFormRequest | ||||
|  * | ||||
|  * @package FireflyIII\Http\Requests | ||||
|  */ | ||||
| class DeleteAccountFormRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize() | ||||
|     { | ||||
|         // Only allow logged in users | ||||
|         return Auth::check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules() | ||||
|     { | ||||
|         return [ | ||||
|             'password' => 'required', | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
| @@ -42,6 +42,7 @@ class JournalFormRequest extends Request | ||||
|             'date'               => new Carbon($this->get('date')), | ||||
|             'budget_id'          => intval($this->get('budget_id')), | ||||
|             'category'           => $this->get('category'), | ||||
|             'tags'               => explode(',', $this->get('tags')), | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
| @@ -56,7 +57,7 @@ class JournalFormRequest extends Request | ||||
|  | ||||
|         $rules = [ | ||||
|             'description'        => 'required|min:1,max:255', | ||||
|             'what'               => 'required|in:withdrawal,deposit,transfer|exists:transaction_types,type', | ||||
|             'what'               => 'required|in:withdrawal,deposit,transfer', | ||||
|             'amount'             => 'numeric|required|min:0.01', | ||||
|             'date'               => 'required|date', | ||||
|             'reminder_id'        => 'numeric|exists:reminders,id', | ||||
|   | ||||
| @@ -3,9 +3,7 @@ | ||||
| namespace FireflyIII\Http\Requests; | ||||
|  | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use Input; | ||||
| use Navigation; | ||||
|  | ||||
| /** | ||||
|  * Class PiggyBankFormRequest | ||||
| @@ -32,7 +30,7 @@ class PiggyBankFormRequest extends Request | ||||
|         $nameRule       = 'required|between:1,255|uniquePiggyBankForUser'; | ||||
|         $targetDateRule = 'date'; | ||||
|         if (intval(Input::get('id'))) { | ||||
|             $nameRule = 'required|between:1,255|uniquePiggyBankForUser:'.intval(Input::get('id')); | ||||
|             $nameRule = 'required|between:1,255|uniquePiggyBankForUser:' . intval(Input::get('id')); | ||||
|         } | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										53
									
								
								app/Http/Requests/TagFormRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								app/Http/Requests/TagFormRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| <?php | ||||
| /** | ||||
|  * Created by PhpStorm. | ||||
|  * User: sander | ||||
|  * Date: 27/04/15 | ||||
|  * Time: 12:50 | ||||
|  */ | ||||
|  | ||||
| namespace FireflyIII\Http\Requests; | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Tag; | ||||
| use Input; | ||||
|  | ||||
| /** | ||||
|  * Class TagFormRequest | ||||
|  * | ||||
|  * @package FireflyIII\Http\Requests | ||||
|  */ | ||||
| class TagFormRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize() | ||||
|     { | ||||
|         // Only allow logged in users | ||||
|         return Auth::check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules() | ||||
|     { | ||||
|         $idRule  = ''; | ||||
|         $tagRule = 'required|min:1|uniqueObjectForUser:tags,tag,TRUE'; | ||||
|         if (Tag::find(Input::get('id'))) { | ||||
|             $idRule  = 'belongsToUser:tags'; | ||||
|             $tagRule = 'required|min:1|uniqueObjectForUser:tags,tag,TRUE,' . Input::get('id'); | ||||
|         } | ||||
|  | ||||
|         return [ | ||||
|             'tag'         => $tagRule, | ||||
|             'id'          => $idRule, | ||||
|             'description' => 'min:1', | ||||
|             'date'        => 'date', | ||||
|             'latitude'    => 'numeric|min:-90|max:90', | ||||
|             'longitude'   => 'numeric|min:-90|max:90', | ||||
|             'tagMode'     => 'required|in:nothing,balancingAct,advancePayment' | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
| @@ -9,6 +9,8 @@ use FireflyIII\Models\Category; | ||||
| use FireflyIII\Models\LimitRepetition; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Models\Reminder; | ||||
| use FireflyIII\Models\Tag; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
|  | ||||
| /* | ||||
| @@ -22,6 +24,14 @@ Breadcrumbs::register( | ||||
|     } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'index', | ||||
|     function (Generator $breadcrumbs) { | ||||
|  | ||||
|         $breadcrumbs->push('Home', route('index')); | ||||
|     } | ||||
| ); | ||||
|  | ||||
| // accounts | ||||
| Breadcrumbs::register( | ||||
|     'accounts.index', function (Generator $breadcrumbs, $what) { | ||||
| @@ -95,6 +105,13 @@ Breadcrumbs::register( | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'budgets.noBudget', function (Generator $breadcrumbs, $subTitle) { | ||||
|     $breadcrumbs->parent('budgets.index'); | ||||
|     $breadcrumbs->push($subTitle, route('budgets.noBudget')); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'budgets.show', function (Generator $breadcrumbs, Budget $budget, LimitRepetition $repetition = null) { | ||||
|     $breadcrumbs->parent('budgets.index'); | ||||
| @@ -142,6 +159,34 @@ Breadcrumbs::register( | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'categories.noCategory', function (Generator $breadcrumbs, $subTitle) { | ||||
|     $breadcrumbs->parent('categories.index'); | ||||
|     $breadcrumbs->push($subTitle, route('categories.noCategory')); | ||||
| } | ||||
| ); | ||||
|  | ||||
| // currencies. | ||||
| Breadcrumbs::register( | ||||
|     'currency.index', function (Generator $breadcrumbs) { | ||||
|     $breadcrumbs->parent('home'); | ||||
|     $breadcrumbs->push('Currencies', route('currency.index')); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'currency.edit', function (Generator $breadcrumbs, TransactionCurrency $currency) { | ||||
|     $breadcrumbs->parent('currency.index'); | ||||
|     $breadcrumbs->push('Edit ' . $currency->name, route('currency.edit', $currency->id)); | ||||
| } | ||||
| ); | ||||
| Breadcrumbs::register( | ||||
|     'currency.delete', function (Generator $breadcrumbs, TransactionCurrency $currency) { | ||||
|     $breadcrumbs->parent('currency.index'); | ||||
|     $breadcrumbs->push('Delete ' . $currency->name, route('currency.delete', $currency->id)); | ||||
| } | ||||
| ); | ||||
|  | ||||
|  | ||||
| // piggy banks | ||||
| Breadcrumbs::register( | ||||
| @@ -268,21 +313,21 @@ Breadcrumbs::register( | ||||
| Breadcrumbs::register( | ||||
|     'reports.year', function (Generator $breadcrumbs, Carbon $date) { | ||||
|     $breadcrumbs->parent('reports.index'); | ||||
|     $breadcrumbs->push($date->format('Y'), route('reports.year', $date->format('Y'))); | ||||
|     $breadcrumbs->push($date->year, route('reports.year', $date->year)); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'reports.month', function (Generator $breadcrumbs, Carbon $date) { | ||||
|     $breadcrumbs->parent('reports.index'); | ||||
|     $breadcrumbs->push('Monthly report for ' . $date->format('F Y'), route('reports.month', $date)); | ||||
|     $breadcrumbs->push('Monthly report for ' . $date->format('F Y'), route('reports.month', [$date->year, $date->month])); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'reports.budget', function (Generator $breadcrumbs, Carbon $date) { | ||||
|     $breadcrumbs->parent('reports.index'); | ||||
|     $breadcrumbs->push('Budget report for ' . $date->format('F Y'), route('reports.budget', $date)); | ||||
|     $breadcrumbs->push('Budget report for ' . $date->format('F Y'), route('reports.budget', [$date->year, $date->month])); | ||||
| } | ||||
| ); | ||||
|  | ||||
| @@ -350,3 +395,24 @@ Breadcrumbs::register( | ||||
|  | ||||
| } | ||||
| ); | ||||
|  | ||||
| // tags | ||||
| Breadcrumbs::register( | ||||
|     'tags.index', function (Generator $breadcrumbs) { | ||||
|     $breadcrumbs->parent('home'); | ||||
|     $breadcrumbs->push('Tags', route('tags.index')); | ||||
| } | ||||
| ); | ||||
|  | ||||
| Breadcrumbs::register( | ||||
|     'tags.create', function (Generator $breadcrumbs) { | ||||
|     $breadcrumbs->parent('tags.index'); | ||||
|     $breadcrumbs->push('Create tag', route('tags.create')); | ||||
| } | ||||
| ); | ||||
| Breadcrumbs::register( | ||||
|     'tags.show', function (Generator $breadcrumbs, Tag $tag) { | ||||
|     $breadcrumbs->parent('tags.index'); | ||||
|     $breadcrumbs->push(e($tag->tag), route('tags.show', $tag->id)); | ||||
| } | ||||
| ); | ||||
| @@ -6,121 +6,177 @@ use FireflyIII\Models\Category; | ||||
| use FireflyIII\Models\LimitRepetition; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Models\Reminder; | ||||
| use FireflyIII\Models\Tag; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | ||||
|  | ||||
|  | ||||
| // models | ||||
| /** @noinspection PhpUnusedParameterInspection */ | ||||
| Route::bind( | ||||
|     'account', | ||||
|     function ($value, $route) { | ||||
|         if (Auth::check()) { | ||||
|             $account = Account::leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') | ||||
|                               ->where('account_types.editable', 1) | ||||
|                               ->where('accounts.id', $value) | ||||
|                               ->where('user_id', Auth::user()->id) | ||||
|                               ->first(['accounts.*']); | ||||
|             if ($account) { | ||||
|                 return $account; | ||||
|             $object = Account::leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') | ||||
|                              ->where('account_types.editable', 1) | ||||
|                              ->where('accounts.id', $value) | ||||
|                              ->where('user_id', Auth::user()->id) | ||||
|                              ->first(['accounts.*']); | ||||
|             if ($object) { | ||||
|                 return $object; | ||||
|             } | ||||
|         } | ||||
|         App::abort(404); | ||||
|         throw new NotFoundHttpException; | ||||
|     } | ||||
| ); | ||||
|  | ||||
| Route::bind( | ||||
|     'tjSecond', function ($value, $route) { | ||||
|     if (Auth::check()) { | ||||
|         return TransactionJournal:: | ||||
|         where('id', $value)->where('user_id', Auth::user()->id)->first(); | ||||
|     } | ||||
|  | ||||
|     return null; | ||||
| } | ||||
| ); | ||||
|  | ||||
| /** @noinspection PhpUnusedParameterInspection */ | ||||
| Route::bind( | ||||
|     'tj', function ($value, $route) { | ||||
|     if (Auth::check()) { | ||||
|         return TransactionJournal:: | ||||
|         where('id', $value)->where('user_id', Auth::user()->id)->first(); | ||||
|         $object = TransactionJournal::where('id', $value)->where('user_id', Auth::user()->id)->first(); | ||||
|         if ($object) { | ||||
|             return $object; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return null; | ||||
|     throw new NotFoundHttpException; | ||||
| } | ||||
| ); | ||||
|  | ||||
| /** @noinspection PhpUnusedParameterInspection */ | ||||
| Route::bind( | ||||
|     'currency', function ($value, $route) { | ||||
|     return TransactionCurrency::find($value); | ||||
|     if (Auth::check()) { | ||||
|         $object = TransactionCurrency::find($value); | ||||
|         if ($object) { | ||||
|             return $object; | ||||
|         } | ||||
|     } | ||||
|     throw new NotFoundHttpException; | ||||
| } | ||||
| ); | ||||
|  | ||||
| /** @noinspection PhpUnusedParameterInspection */ | ||||
| Route::bind( | ||||
|     'bill', function ($value, $route) { | ||||
|     if (Auth::check()) { | ||||
|         return Bill::where('id', $value)->where('user_id', Auth::user()->id)->first(); | ||||
|         $object = Bill::where('id', $value)->where('user_id', Auth::user()->id)->first(); | ||||
|         if ($object) { | ||||
|             return $object; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return null; | ||||
|     throw new NotFoundHttpException; | ||||
| } | ||||
| ); | ||||
|  | ||||
| /** @noinspection PhpUnusedParameterInspection */ | ||||
| Route::bind( | ||||
|     'budget', function ($value, $route) { | ||||
|     if (Auth::check()) { | ||||
|         return Budget::where('id', $value)->where('user_id', Auth::user()->id)->first(); | ||||
|         $object = Budget::where('id', $value)->where('user_id', Auth::user()->id)->first(); | ||||
|         if ($object) { | ||||
|             return $object; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return null; | ||||
|     throw new NotFoundHttpException; | ||||
| } | ||||
| ); | ||||
|  | ||||
| /** @noinspection PhpUnusedParameterInspection */ | ||||
| Route::bind( | ||||
|     'reminder', function ($value, $route) { | ||||
|     if (Auth::check()) { | ||||
|         return Reminder::where('id', $value)->where('user_id', Auth::user()->id)->first(); | ||||
|         $object = Reminder::where('id', $value)->where('user_id', Auth::user()->id)->first(); | ||||
|         if ($object) { | ||||
|             return $object; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return null; | ||||
|     throw new NotFoundHttpException; | ||||
| } | ||||
| ); | ||||
|  | ||||
| /** @noinspection PhpUnusedParameterInspection */ | ||||
| Route::bind( | ||||
|     'limitrepetition', function ($value, $route) { | ||||
|     if (Auth::check()) { | ||||
|         return LimitRepetition::where('limit_repetitions.id', $value) | ||||
|                               ->leftjoin('budget_limits', 'budget_limits.id', '=', 'limit_repetitions.budget_limit_id') | ||||
|                               ->leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id') | ||||
|                               ->where('budgets.user_id', Auth::user()->id) | ||||
|                               ->first(['limit_repetitions.*']); | ||||
|         $object = LimitRepetition::where('limit_repetitions.id', $value) | ||||
|                                  ->leftjoin('budget_limits', 'budget_limits.id', '=', 'limit_repetitions.budget_limit_id') | ||||
|                                  ->leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id') | ||||
|                                  ->where('budgets.user_id', Auth::user()->id) | ||||
|                                  ->first(['limit_repetitions.*']); | ||||
|         if ($object) { | ||||
|             return $object; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return null; | ||||
|     throw new NotFoundHttpException; | ||||
| } | ||||
| ); | ||||
|  | ||||
| /** @noinspection PhpUnusedParameterInspection */ | ||||
| Route::bind( | ||||
|     'piggyBank', function ($value, $route) { | ||||
|     if (Auth::check()) { | ||||
|         return PiggyBank:: | ||||
|         where('piggy_banks.id', $value) | ||||
|                         ->leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id') | ||||
|                         ->where('accounts.user_id', Auth::user()->id) | ||||
|                         ->first(['piggy_banks.*']); | ||||
|         $object = PiggyBank::where('piggy_banks.id', $value) | ||||
|                            ->leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id') | ||||
|                            ->where('accounts.user_id', Auth::user()->id) | ||||
|                            ->first(['piggy_banks.*']); | ||||
|         if ($object) { | ||||
|             return $object; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return null; | ||||
|     throw new NotFoundHttpException; | ||||
| } | ||||
| ); | ||||
|  | ||||
| /** @noinspection PhpUnusedParameterInspection */ | ||||
| Route::bind( | ||||
|     'category', function ($value, $route) { | ||||
|     if (Auth::check()) { | ||||
|         return Category::where('id', $value)->where('user_id', Auth::user()->id)->first(); | ||||
|         $object = Category::where('id', $value)->where('user_id', Auth::user()->id)->first(); | ||||
|         if ($object) { | ||||
|             return $object; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return null; | ||||
|     throw new NotFoundHttpException; | ||||
| } | ||||
| ); | ||||
|  | ||||
| /** @noinspection PhpUnusedParameterInspection */ | ||||
| Route::bind( | ||||
|     'reminder', function ($value, $route) { | ||||
|     if (Auth::check()) { | ||||
|         /** @var \FireflyIII\Models\Reminder $object */ | ||||
|         $object = Reminder::find($value); | ||||
|         if ($object) { | ||||
|             if ($object->remindersable->account->user_id == Auth::user()->id) { | ||||
|                 return $object; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     throw new NotFoundHttpException; | ||||
| } | ||||
| ); | ||||
|  | ||||
| /** @noinspection PhpUnusedParameterInspection */ | ||||
| Route::bind( | ||||
|     'tag', function ($value, $route) { | ||||
|     if (Auth::check()) { | ||||
|         $object = Tag::where('id', $value)->where('user_id', Auth::user()->id)->first(); | ||||
|         if ($object) { | ||||
|             return $object; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     throw new NotFoundHttpException; | ||||
| } | ||||
| ); | ||||
|  | ||||
| @@ -170,7 +226,6 @@ Route::group( | ||||
|     Route::get('/bills/add/{bill}', ['uses' => 'BillController@add', 'as' => 'bills.add']); | ||||
|     Route::get('/bills/delete/{bill}', ['uses' => 'BillController@delete', 'as' => 'bills.delete']); | ||||
|     Route::get('/bills/show/{bill}', ['uses' => 'BillController@show', 'as' => 'bills.show']); | ||||
|  | ||||
|     Route::post('/bills/store', ['uses' => 'BillController@store', 'as' => 'bills.store']); | ||||
|     Route::post('/bills/update/{bill}', ['uses' => 'BillController@update', 'as' => 'bills.update']); | ||||
|     Route::post('/bills/destroy/{bill}', ['uses' => 'BillController@destroy', 'as' => 'bills.destroy']); | ||||
| @@ -226,7 +281,7 @@ Route::group( | ||||
|     Route::get('/chart/home/bills', ['uses' => 'GoogleChartController@billsOverview']); | ||||
|     Route::get('/chart/account/{account}/{view?}', ['uses' => 'GoogleChartController@accountBalanceChart']); | ||||
|     Route::get('/chart/budget/{budget}/spending/{year?}', ['uses' => 'GoogleChartController@budgetsAndSpending']); | ||||
|     Route::get('/chart/budgets/spending/{year?}', ['uses' => 'GoogleChartController@allBudgetsAndSpending']); | ||||
|     Route::get('/chart/budgets/spending/{year?}', ['uses' => 'GoogleChartController@allBudgetsAndSpending'])->where(['year' => '[0-9]+']); | ||||
|     Route::get('/chart/budget/{budget}/{limitrepetition}', ['uses' => 'GoogleChartController@budgetLimitSpending']); | ||||
|     Route::get('/chart/reports/income-expenses/{year}', ['uses' => 'GoogleChartController@yearInExp']); | ||||
|     Route::get('/chart/reports/income-expenses-sum/{year}', ['uses' => 'GoogleChartController@yearInExpSum']); | ||||
| @@ -246,7 +301,11 @@ Route::group( | ||||
|     Route::get('/json/expense-accounts', ['uses' => 'JsonController@expenseAccounts', 'as' => 'json.expense-accounts']); | ||||
|     Route::get('/json/revenue-accounts', ['uses' => 'JsonController@revenueAccounts', 'as' => 'json.revenue-accounts']); | ||||
|     Route::get('/json/categories', ['uses' => 'JsonController@categories', 'as' => 'json.categories']); | ||||
|     Route::get('/json/box', ['uses' => 'JsonController@box', 'as' => 'json.box']); | ||||
|     Route::get('/json/tags', ['uses' => 'JsonController@tags', 'as' => 'json.tags']); | ||||
|     Route::get('/json/box/in', ['uses' => 'JsonController@boxIn', 'as' => 'json.box.in']); | ||||
|     Route::get('/json/box/out', ['uses' => 'JsonController@boxOut', 'as' => 'json.box.out']); | ||||
|     Route::get('/json/box/bills-unpaid', ['uses' => 'JsonController@boxBillsUnpaid', 'as' => 'json.box.paid']); | ||||
|     Route::get('/json/box/bills-paid', ['uses' => 'JsonController@boxBillsPaid', 'as' => 'json.box.unpaid']); | ||||
|     Route::get('/json/show-shared-reports', 'JsonController@showSharedReports'); | ||||
|     Route::get('/json/transaction-journals/{what}', 'JsonController@transactionJournals'); | ||||
|     Route::get('/json/show-shared-reports/set', 'JsonController@setSharedReports'); | ||||
| @@ -280,18 +339,10 @@ Route::group( | ||||
|      */ | ||||
|     Route::get('/profile', ['uses' => 'ProfileController@index', 'as' => 'profile']); | ||||
|     Route::get('/profile/change-password', ['uses' => 'ProfileController@changePassword', 'as' => 'change-password']); | ||||
|     Route::get('/profile/delete-account', ['uses' => 'ProfileController@deleteAccount', 'as' => 'delete-account']); | ||||
|     Route::post('/profile/delete-account', ['uses' => 'ProfileController@postDeleteAccount', 'as' => 'delete-account-post']); | ||||
|     Route::post('/profile/change-password', ['uses' => 'ProfileController@postChangePassword', 'as' => 'change-password-post']); | ||||
|  | ||||
|     /** | ||||
|      * Related transactions controller | ||||
|      */ | ||||
|     Route::get('/related/alreadyRelated/{tj}', ['uses' => 'RelatedController@alreadyRelated', 'as' => 'related.alreadyRelated']); | ||||
|     Route::post('/related/relate/{tj}/{tjSecond}', ['uses' => 'RelatedController@relate', 'as' => 'related.relate']); | ||||
|     Route::post('/related/removeRelation/{tj}/{tjSecond}', ['uses' => 'RelatedController@removeRelation', 'as' => 'related.removeRelation']); | ||||
|     Route::get('/related/remove/{tj}/{tjSecond}', ['uses' => 'RelatedController@getRemoveRelation', 'as' => 'related.getRemoveRelation']); | ||||
|     Route::get('/related/related/{tj}', ['uses' => 'RelatedController@related', 'as' => 'related.related']); | ||||
|     Route::post('/related/search/{tj}', ['uses' => 'RelatedController@search', 'as' => 'related.search']); | ||||
|  | ||||
|     /** | ||||
|      * Reminder Controller | ||||
|      */ | ||||
| @@ -323,6 +374,22 @@ Route::group( | ||||
|      */ | ||||
|     Route::get('/search', ['uses' => 'SearchController@index', 'as' => 'search']); | ||||
|  | ||||
|     /** | ||||
|      * Tag Controller | ||||
|      */ | ||||
|     Route::get('/tags', ['uses' => 'TagController@index', 'as' => 'tags.index']); | ||||
|     Route::get('/tags/create', ['uses' => 'TagController@create', 'as' => 'tags.create']); | ||||
|     Route::get('/tags/show/{tag}', ['uses' => 'TagController@show', 'as' => 'tags.show']); | ||||
|     Route::get('/tags/edit/{tag}', ['uses' => 'TagController@edit', 'as' => 'tags.edit']); | ||||
|     Route::get('/tags/delete/{tag}', ['uses' => 'TagController@delete', 'as' => 'tags.delete']); | ||||
|  | ||||
|     Route::post('/tags/store', ['uses' => 'TagController@store', 'as' => 'tags.store']); | ||||
|     Route::post('/tags/update/{tag}', ['uses' => 'TagController@update', 'as' => 'tags.update']); | ||||
|     Route::post('/tags/destroy/{tag}', ['uses' => 'TagController@destroy', 'as' => 'tags.destroy']); | ||||
|  | ||||
|     Route::post('/tags/hideTagHelp/{state}', ['uses' => 'TagController@hideTagHelp', 'as' => 'tags.hideTagHelp']); | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Transaction Controller | ||||
|      */ | ||||
|   | ||||
| @@ -51,10 +51,13 @@ class Account extends Model | ||||
|         $account = Account::create($fields); | ||||
|         if (is_null($account->id)) { | ||||
|             // could not create account: | ||||
|             App::abort(500, 'Could not create new account with data: ' . json_encode($fields)); | ||||
|             App::abort(500, 'Could not create new account with data: ' . json_encode($fields) . ' because ' . json_encode($account->getErrors())); | ||||
|  | ||||
|  | ||||
|         } | ||||
|  | ||||
|         return $account; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -1,8 +1,10 @@ | ||||
| <?php namespace FireflyIII\Models; | ||||
|  | ||||
| use App; | ||||
| use Crypt; | ||||
| use Illuminate\Database\Eloquent\Model; | ||||
| use Illuminate\Database\Eloquent\SoftDeletes; | ||||
| use Crypt; | ||||
|  | ||||
| /** | ||||
|  * Class Category | ||||
|  * | ||||
| @@ -30,6 +32,39 @@ class Category extends Model | ||||
|         return $this->belongsToMany('FireflyIII\Models\TransactionJournal', 'category_transaction_journal', 'category_id'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $fields | ||||
|      * | ||||
|      * @return Account|null | ||||
|      */ | ||||
|     public static function firstOrCreateEncrypted(array $fields) | ||||
|     { | ||||
|         // everything but the name: | ||||
|         $query = Category::orderBy('id'); | ||||
|         foreach ($fields as $name => $value) { | ||||
|             if ($name != 'name') { | ||||
|                 $query->where($name, $value); | ||||
|             } | ||||
|         } | ||||
|         $set = $query->get(['categories.*']); | ||||
|         /** @var Category $category */ | ||||
|         foreach ($set as $category) { | ||||
|             if ($category->name == $fields['name']) { | ||||
|                 return $category; | ||||
|             } | ||||
|         } | ||||
|         // create it! | ||||
|         $category = Category::create($fields); | ||||
|         if (is_null($category->id)) { | ||||
|             // could not create account: | ||||
|             App::abort(500, 'Could not create new category with data: ' . json_encode($fields)); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         return $category; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||||
|      */ | ||||
| @@ -46,6 +81,7 @@ class Category extends Model | ||||
|         $this->attributes['name']      = Crypt::encrypt($value); | ||||
|         $this->attributes['encrypted'] = true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      * | ||||
|   | ||||
| @@ -1,5 +1,7 @@ | ||||
| <?php namespace FireflyIII\Models; | ||||
|  | ||||
| use Auth; | ||||
| use DB; | ||||
| use Illuminate\Database\Eloquent\Model; | ||||
|  | ||||
| /** | ||||
| @@ -26,18 +28,23 @@ class LimitRepetition extends Model | ||||
|         return ['created_at', 'updated_at', 'startdate', 'enddate']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return float | ||||
|      */ | ||||
|     public function spentInRepetition() | ||||
|     { | ||||
|         $sum = \DB::table('transactions') | ||||
|                   ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') | ||||
|                   ->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') | ||||
|                   ->leftJoin('budget_limits', 'budget_limits.budget_id', '=', 'budget_transaction_journal.budget_id') | ||||
|                   ->leftJoin('limit_repetitions', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id') | ||||
|                   ->where('transaction_journals.date', '>=', $this->startdate->format('Y-m-d')) | ||||
|                   ->where('transaction_journals.date', '<=', $this->enddate->format('Y-m-d')) | ||||
|                   ->where('transactions.amount', '>', 0) | ||||
|                   ->where('limit_repetitions.id', '=', $this->id) | ||||
|                   ->sum('transactions.amount'); | ||||
|         $sum = DB::table('transactions') | ||||
|                  ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') | ||||
|                  ->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') | ||||
|                  ->leftJoin('budget_limits', 'budget_limits.budget_id', '=', 'budget_transaction_journal.budget_id') | ||||
|                  ->leftJoin('limit_repetitions', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id') | ||||
|                  ->where('transaction_journals.date', '>=', $this->startdate->format('Y-m-d')) | ||||
|                  ->where('transaction_journals.date', '<=', $this->enddate->format('Y-m-d')) | ||||
|                  ->where('transaction_journals.user_id', Auth::user()->id) | ||||
|                  ->whereNull('transactions.deleted_at') | ||||
|                  ->where('transactions.amount', '>', 0) | ||||
|                  ->where('limit_repetitions.id', '=', $this->id) | ||||
|                  ->sum('transactions.amount'); | ||||
|  | ||||
|         return floatval($sum); | ||||
|     } | ||||
|   | ||||
| @@ -1,8 +1,9 @@ | ||||
| <?php namespace FireflyIII\Models; | ||||
|  | ||||
| use Crypt; | ||||
| use Illuminate\Database\Eloquent\Model; | ||||
| use Illuminate\Database\Eloquent\SoftDeletes; | ||||
| use Crypt; | ||||
|  | ||||
| /** | ||||
|  * Class PiggyBank | ||||
|  * | ||||
| @@ -13,7 +14,7 @@ class PiggyBank extends Model | ||||
|     use SoftDeletes; | ||||
|  | ||||
|     protected $fillable | ||||
|         = ['name', 'account_id', 'reminder_skip', 'targetamount', 'startdate', 'targetdate', 'reminder', 'remind_me']; | ||||
|         = ['name', 'account_id', 'order', 'reminder_skip', 'targetamount', 'startdate', 'targetdate', 'reminder', 'remind_me']; | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||||
| @@ -92,6 +93,7 @@ class PiggyBank extends Model | ||||
|         $this->attributes['name']      = Crypt::encrypt($value); | ||||
|         $this->attributes['encrypted'] = true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      * | ||||
|   | ||||
| @@ -1,9 +1,10 @@ | ||||
| <?php namespace FireflyIII\Models; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use Crypt; | ||||
| use Illuminate\Database\Eloquent\Builder as EloquentBuilder; | ||||
| use Illuminate\Database\Eloquent\Model; | ||||
| use Crypt; | ||||
|  | ||||
| /** | ||||
|  * Class Reminder | ||||
|  * | ||||
| @@ -43,6 +44,7 @@ class Reminder extends Model | ||||
|         if (intval($this->encrypted) == 1) { | ||||
|             return json_decode(Crypt::decrypt($value)); | ||||
|         } | ||||
|  | ||||
|         return json_decode($value); | ||||
|     } | ||||
|  | ||||
| @@ -76,6 +78,11 @@ class Reminder extends Model | ||||
|         return $query->where('reminders.startdate', '=', $start->format('Y-m-d 00:00:00'))->where('reminders.enddate', '=', $end->format('Y-m-d 00:00:00')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param EloquentBuilder $query | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function scopeToday(EloquentBuilder $query) | ||||
|     { | ||||
|         $today = new Carbon; | ||||
| @@ -90,7 +97,7 @@ class Reminder extends Model | ||||
|     public function setMetadataAttribute($value) | ||||
|     { | ||||
|         $this->attributes['encrypted'] = true; | ||||
|         $this->attributes['metadata'] = Crypt::encrypt(json_encode($value)); | ||||
|         $this->attributes['metadata']  = Crypt::encrypt(json_encode($value)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
							
								
								
									
										128
									
								
								app/Models/Tag.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								app/Models/Tag.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Models; | ||||
|  | ||||
| use App; | ||||
| use Crypt; | ||||
| use Illuminate\Database\Eloquent\Model; | ||||
| use Watson\Validating\ValidatingTrait; | ||||
|  | ||||
| /** | ||||
|  * Class Tag | ||||
|  * | ||||
|  * @package FireflyIII\Models | ||||
|  */ | ||||
| class Tag extends Model | ||||
| { | ||||
|     use ValidatingTrait; | ||||
|  | ||||
|     protected $fillable = ['user_id', 'tag', 'date', 'description', 'longitude', 'latitude', 'zoomLevel', 'tagMode']; | ||||
|     protected $rules | ||||
|                         = [ | ||||
|             'tag'         => 'required|min:1|uniqueObjectForUser:tags,tag,TRUE', | ||||
|             'description' => 'min:1', | ||||
|             'date'        => 'date', | ||||
|             'latitude'    => 'numeric|min:-90|max:90', | ||||
|             'longitude'   => 'numeric|min:-90|max:90', | ||||
|             'tagMode'     => 'required|in:nothing,balancingAct,advancePayment' | ||||
|         ]; | ||||
|  | ||||
|     /** | ||||
|      * @param array $fields | ||||
|      * | ||||
|      * @return Tag|null | ||||
|      */ | ||||
|     public static function firstOrCreateEncrypted(array $fields) | ||||
|     { | ||||
|         // everything but the tag: | ||||
|         if (isset($fields['tagMode'])) { | ||||
|             unset($fields['tagMode']); | ||||
|         } | ||||
|         $query = Tag::orderBy('id'); | ||||
|         foreach ($fields as $name => $value) { | ||||
|             if ($name != 'tag') { | ||||
|                 $query->where($name, $value); | ||||
|             } | ||||
|         } | ||||
|         $set = $query->get(['tags.*']); | ||||
|         /** @var Tag $tag */ | ||||
|         foreach ($set as $tag) { | ||||
|             if ($tag->tag == $fields['tag']) { | ||||
|                 return $tag; | ||||
|             } | ||||
|         } | ||||
|         // create it! | ||||
|         $fields['tagMode']     = 'nothing'; | ||||
|         $fields['description'] = isset($fields['description']) && !is_null($fields['description']) ? $fields['description'] : ''; | ||||
|         $tag                   = Tag::create($fields); | ||||
|         if (is_null($tag->id)) { | ||||
|             // could not create account: | ||||
|             App::abort(500, 'Could not create new tag with data: ' . json_encode($fields) . ' because ' . json_encode($tag->getErrors())); | ||||
|  | ||||
|  | ||||
|         } | ||||
|  | ||||
|         return $tag; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getDates() | ||||
|     { | ||||
|         return ['created_at', 'updated_at', 'date']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getDescriptionAttribute($value) | ||||
|     { | ||||
|         return Crypt::decrypt($value); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getTagAttribute($value) | ||||
|     { | ||||
|         return Crypt::decrypt($value); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      */ | ||||
|     public function setDescriptionAttribute($value) | ||||
|     { | ||||
|         $this->attributes['description'] = Crypt::encrypt($value); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      */ | ||||
|     public function setTagAttribute($value) | ||||
|     { | ||||
|         $this->attributes['tag'] = Crypt::encrypt($value); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany | ||||
|      */ | ||||
|     public function transactionjournals() | ||||
|     { | ||||
|         return $this->belongsToMany('FireflyIII\Models\TransactionJournal'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||||
|      */ | ||||
|     public function user() | ||||
|     { | ||||
|         return $this->belongsTo('FireflyIII\User'); | ||||
|     } | ||||
| } | ||||
| @@ -1,10 +1,11 @@ | ||||
| <?php namespace FireflyIII\Models; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use Illuminate\Database\Eloquent\Builder as EloquentBuilder; | ||||
| use Illuminate\Database\Eloquent\Model; | ||||
| use Illuminate\Database\Eloquent\SoftDeletes; | ||||
| use Watson\Validating\ValidatingTrait; | ||||
| use Illuminate\Database\Eloquent\Builder as EloquentBuilder; | ||||
| use Carbon\Carbon; | ||||
|  | ||||
| /** | ||||
|  * Class Transaction | ||||
|  * | ||||
|   | ||||
| @@ -55,6 +55,52 @@ class TransactionJournal extends Model | ||||
|         return $this->belongsToMany('FireflyIII\Models\Category'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return float | ||||
|      */ | ||||
|     public function getAmountAttribute() | ||||
|     { | ||||
|         /** @var Transaction $t */ | ||||
|         foreach ($this->transactions as $t) { | ||||
|             if ($t->amount > 0) { | ||||
|                 return floatval($t->amount); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Account|mixed | ||||
|      */ | ||||
|     public function getAssetAccountAttribute() | ||||
|     { | ||||
|         $positive = true; // the asset account is in the transaction with the positive amount. | ||||
|         if ($this->transactionType->type === 'Withdrawal') { | ||||
|             $positive = false; | ||||
|         } | ||||
|         /** @var Transaction $transaction */ | ||||
|         foreach ($this->transactions()->get() as $transaction) { | ||||
|             if (floatval($transaction->amount) > 0 && $positive === true) { | ||||
|                 return $transaction->account; | ||||
|             } | ||||
|             if (floatval($transaction->amount) < 0 && $positive === false) { | ||||
|                 return $transaction->account; | ||||
|             } | ||||
|  | ||||
|         } | ||||
|  | ||||
|         return $this->transactions()->first(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\HasMany | ||||
|      */ | ||||
|     public function transactions() | ||||
|     { | ||||
|         return $this->hasMany('FireflyIII\Models\Transaction'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
| @@ -188,6 +234,14 @@ class TransactionJournal extends Model | ||||
|         $this->attributes['encrypted']   = true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany | ||||
|      */ | ||||
|     public function tags() | ||||
|     { | ||||
|         return $this->belongsToMany('FireflyIII\Models\Tag'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||||
|      */ | ||||
| @@ -212,14 +266,6 @@ class TransactionJournal extends Model | ||||
|         return $this->belongsToMany('FireflyIII\Models\TransactionGroup'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\HasMany | ||||
|      */ | ||||
|     public function transactions() | ||||
|     { | ||||
|         return $this->hasMany('FireflyIII\Models\Transaction'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||||
|      */ | ||||
|   | ||||
| @@ -35,6 +35,7 @@ class AppServiceProvider extends ServiceProvider | ||||
|             'Illuminate\Contracts\Auth\Registrar', | ||||
|             'FireflyIII\Services\Registrar' | ||||
|         ); | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -23,7 +23,227 @@ class ConfigServiceProvider extends ServiceProvider | ||||
|     { | ||||
|         config( | ||||
|             [ | ||||
|                 // | ||||
|                 'twigbridge' => [ | ||||
|  | ||||
|                     'twig'       => [ | ||||
|                         /* | ||||
|                         |-------------------------------------------------------------------------- | ||||
|                         | Extension | ||||
|                         |-------------------------------------------------------------------------- | ||||
|                         | | ||||
|                         | File extension for Twig view files. | ||||
|                         | | ||||
|                         */ | ||||
|                         'extension'   => 'twig', | ||||
|  | ||||
|                         /* | ||||
|                         |-------------------------------------------------------------------------- | ||||
|                         | Accepts all Twig environment configuration options | ||||
|                         |-------------------------------------------------------------------------- | ||||
|                         | | ||||
|                         | http://twig.sensiolabs.org/doc/api.html#environment-options | ||||
|                         | | ||||
|                         */ | ||||
|                         'environment' => [ | ||||
|  | ||||
|                             // When set to true, the generated templates have a __toString() method | ||||
|                             // that you can use to display the generated nodes. | ||||
|                             // default: false | ||||
|                             'debug'               => config('app.debug', false), | ||||
|  | ||||
|                             // The charset used by the templates. | ||||
|                             // default: utf-8 | ||||
|                             'charset'             => 'utf-8', | ||||
|  | ||||
|                             // The base template class to use for generated templates. | ||||
|                             // default: TwigBridge\Twig\Template | ||||
|                             'base_template_class' => 'TwigBridge\Twig\Template', | ||||
|  | ||||
|                             // An absolute path where to store the compiled templates, or false to disable caching. If null | ||||
|                             // then the cache file path is used. | ||||
|                             // default: cache file storage path | ||||
|                             'cache'               => null, | ||||
|  | ||||
|                             // When developing with Twig, it's useful to recompile the template | ||||
|                             // whenever the source code changes. If you don't provide a value | ||||
|                             // for the auto_reload option, it will be determined automatically based on the debug value. | ||||
|                             'auto_reload'         => true, | ||||
|  | ||||
|                             // If set to false, Twig will silently ignore invalid variables | ||||
|                             // (variables and or attributes/methods that do not exist) and | ||||
|                             // replace them with a null value. When set to true, Twig throws an exception instead. | ||||
|                             // default: false | ||||
|                             'strict_variables'    => false, | ||||
|  | ||||
|                             // If set to true, auto-escaping will be enabled by default for all templates. | ||||
|                             // default: true | ||||
|                             'autoescape'          => true, | ||||
|  | ||||
|                             // A flag that indicates which optimizations to apply | ||||
|                             // (default to -1 -- all optimizations are enabled; set it to 0 to disable) | ||||
|                             'optimizations'       => -1, | ||||
|                         ], | ||||
|  | ||||
|                         /* | ||||
|                         |-------------------------------------------------------------------------- | ||||
|                         | Global variables | ||||
|                         |-------------------------------------------------------------------------- | ||||
|                         | | ||||
|                         | These will always be passed in and can be accessed as Twig variables. | ||||
|                         | NOTE: these will be overwritten if you pass data into the view with the same key. | ||||
|                         | | ||||
|                         */ | ||||
|                         'globals'     => [], | ||||
|                     ], | ||||
|  | ||||
|                     'extensions' => [ | ||||
|  | ||||
|                         /* | ||||
|                         |-------------------------------------------------------------------------- | ||||
|                         | Extensions | ||||
|                         |-------------------------------------------------------------------------- | ||||
|                         | | ||||
|                         | Enabled extensions. | ||||
|                         | | ||||
|                         | `Twig_Extension_Debug` is enabled automatically if twig.debug is TRUE. | ||||
|                         | | ||||
|                         */ | ||||
|                         'enabled'   => [ | ||||
|                             'TwigBridge\Extension\Loader\Facades', | ||||
|                             'TwigBridge\Extension\Loader\Filters', | ||||
|                             'TwigBridge\Extension\Loader\Functions', | ||||
|  | ||||
|                             'TwigBridge\Extension\Laravel\Auth', | ||||
|                             'TwigBridge\Extension\Laravel\Config', | ||||
|                             'TwigBridge\Extension\Laravel\Dump', | ||||
|                             'TwigBridge\Extension\Laravel\Input', | ||||
|                             'TwigBridge\Extension\Laravel\Session', | ||||
|                             'TwigBridge\Extension\Laravel\String', | ||||
|                             'TwigBridge\Extension\Laravel\Translator', | ||||
|                             'TwigBridge\Extension\Laravel\Url', | ||||
|  | ||||
|                             //                             'TwigBridge\Extension\Laravel\Form', | ||||
|                             // 'TwigBridge\Extension\Laravel\Html', | ||||
|                             // 'TwigBridge\Extension\Laravel\Legacy\Facades', | ||||
|                         ], | ||||
|  | ||||
|                         /* | ||||
|                         |-------------------------------------------------------------------------- | ||||
|                         | Facades | ||||
|                         |-------------------------------------------------------------------------- | ||||
|                         | | ||||
|                         | Available facades. Access like `{{ Config.get('foo.bar') }}`. | ||||
|                         | | ||||
|                         | Each facade can take an optional array of options. To mark the whole facade | ||||
|                         | as safe you can set the option `'is_safe' => true`. Setting the facade as | ||||
|                         | safe means that any HTML returned will not be escaped. | ||||
|                         | | ||||
|                         | It is advisable to not set the whole facade as safe and instead mark the | ||||
|                         | each appropriate method as safe for security reasons. You can do that with | ||||
|                         | the following syntax: | ||||
|                         | | ||||
|                         | <code> | ||||
|                         |     'Form' => [ | ||||
|                         |         'is_safe' => [ | ||||
|                         |             'open' | ||||
|                         |         ] | ||||
|                         |     ] | ||||
|                         | </code> | ||||
|                         | | ||||
|                         | The values of the `is_safe` array must match the called method on the facade | ||||
|                         | in order to be marked as safe. | ||||
|                         | | ||||
|                         */ | ||||
|                         'facades'   => [ | ||||
|                             'Breadcrumbs'  => [ | ||||
|                                 'is_safe' => [ | ||||
|                                     'renderIfExists' | ||||
|                                 ] | ||||
|                             ], | ||||
|                             'Session', | ||||
|                             'Route', | ||||
|                             'Auth', | ||||
|                             'URL', | ||||
|                             'Config', | ||||
|                             'ExpandedForm' => [ | ||||
|                                 'is_safe' => [ | ||||
|                                     'date', 'text', 'select', 'balance', 'optionsList', 'checkbox', 'amount', 'tags', 'integer', 'textarea', 'location', | ||||
|                                     'multiRadio' | ||||
|                                 ] | ||||
|                             ], | ||||
|                             'Form'         => [ | ||||
|                                 'is_safe' => [ | ||||
|                                     'input', 'select', 'checkbox', 'model', 'open', 'radio', 'textarea' | ||||
|                                 ] | ||||
|                             ], | ||||
|                         ], | ||||
|  | ||||
|                         /* | ||||
|                         |-------------------------------------------------------------------------- | ||||
|                         | Functions | ||||
|                         |-------------------------------------------------------------------------- | ||||
|                         | | ||||
|                         | Available functions. Access like `{{ secure_url(...) }}`. | ||||
|                         | | ||||
|                         | Each function can take an optional array of options. These options are | ||||
|                         | passed directly to `Twig_SimpleFunction`. | ||||
|                         | | ||||
|                         | So for example, to mark a function as safe you can do the following: | ||||
|                         | | ||||
|                         | <code> | ||||
|                         |     'link_to' => [ | ||||
|                         |         'is_safe' => ['html'] | ||||
|                         |     ] | ||||
|                         | </code> | ||||
|                         | | ||||
|                         | The options array also takes a `callback` that allows you to name the | ||||
|                         | function differently in your Twig templates than what it's actually called. | ||||
|                         | | ||||
|                         | <code> | ||||
|                         |     'link' => [ | ||||
|                         |         'callback' => 'link_to' | ||||
|                         |     ] | ||||
|                         | </code> | ||||
|                         | | ||||
|                         */ | ||||
|                         'functions' => [ | ||||
|                             'elixir', | ||||
|                             'head', | ||||
|                             'last', | ||||
|                             'old' | ||||
|                         ], | ||||
|  | ||||
|                         /* | ||||
|                         |-------------------------------------------------------------------------- | ||||
|                         | Filters | ||||
|                         |-------------------------------------------------------------------------- | ||||
|                         | | ||||
|                         | Available filters. Access like `{{ variable|filter }}`. | ||||
|                         | | ||||
|                         | Each filter can take an optional array of options. These options are | ||||
|                         | passed directly to `Twig_SimpleFilter`. | ||||
|                         | | ||||
|                         | So for example, to mark a filter as safe you can do the following: | ||||
|                         | | ||||
|                         | <code> | ||||
|                         |     'studly_case' => [ | ||||
|                         |         'is_safe' => ['html'] | ||||
|                         |     ] | ||||
|                         | </code> | ||||
|                         | | ||||
|                         | The options array also takes a `callback` that allows you to name the | ||||
|                         | filter differently in your Twig templates than what is actually called. | ||||
|                         | | ||||
|                         | <code> | ||||
|                         |     'snake' => [ | ||||
|                         |         'callback' => 'snake_case' | ||||
|                         |     ] | ||||
|                         | </code> | ||||
|                         | | ||||
|                         */ | ||||
|                         'filters'   => [], | ||||
|                     ], | ||||
|                 ] | ||||
|             ] | ||||
|         ); | ||||
|     } | ||||
|   | ||||
| @@ -1,10 +1,12 @@ | ||||
| <?php namespace FireflyIII\Providers; | ||||
|  | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Models\BudgetLimit; | ||||
| use FireflyIII\Models\LimitRepetition; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Models\PiggyBankRepetition; | ||||
| use FireflyIII\Models\Reminder; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Support\Facades\Navigation; | ||||
| @@ -12,7 +14,7 @@ use Illuminate\Contracts\Events\Dispatcher as DispatcherContract; | ||||
| use Illuminate\Database\QueryException; | ||||
| use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; | ||||
| use Log; | ||||
| use Reminder; | ||||
|  | ||||
| /** | ||||
|  * Class EventServiceProvider | ||||
|  * | ||||
| @@ -60,14 +62,15 @@ class EventServiceProvider extends ServiceProvider | ||||
|         ); | ||||
|  | ||||
|  | ||||
|         PiggyBank::deleting(function(PiggyBank $piggyBank) { | ||||
|             $reminders = $piggyBank->reminders()->get(); | ||||
|             /** @var Reminder $reminder */ | ||||
|             foreach($reminders as $reminder) { | ||||
|                 $reminder->delete(); | ||||
|         PiggyBank::deleting( | ||||
|             function (PiggyBank $piggyBank) { | ||||
|                 $reminders = $piggyBank->reminders()->get(); | ||||
|                 /** @var Reminder $reminder */ | ||||
|                 foreach ($reminders as $reminder) { | ||||
|                     $reminder->delete(); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         ); | ||||
|  | ||||
|         Account::deleted( | ||||
|             function (Account $account) { | ||||
|   | ||||
| @@ -2,13 +2,21 @@ | ||||
|  | ||||
| namespace FireflyIII\Providers; | ||||
|  | ||||
| use App; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Support\Amount; | ||||
| use FireflyIII\Support\ExpandedForm; | ||||
| use FireflyIII\Support\Navigation; | ||||
| use FireflyIII\Support\Preferences; | ||||
| use FireflyIII\Support\Steam; | ||||
| use FireflyIII\Support\Twig\Budget; | ||||
| use FireflyIII\Support\Twig\General; | ||||
| use FireflyIII\Support\Twig\Journal; | ||||
| use FireflyIII\Support\Twig\PiggyBank; | ||||
| use FireflyIII\Validation\FireflyValidator; | ||||
| use Illuminate\Support\ServiceProvider; | ||||
| use Twig; | ||||
| use TwigBridge\Extension\Loader\Functions; | ||||
| use Validator; | ||||
|  | ||||
| /** | ||||
| @@ -25,10 +33,22 @@ class FireflyServiceProvider extends ServiceProvider | ||||
|                 return new FireflyValidator($translator, $data, $rules, $messages); | ||||
|             } | ||||
|         ); | ||||
|         /* | ||||
|          * Default Twig configuration: | ||||
|          */ | ||||
|  | ||||
|         $config = App::make('config'); | ||||
|         Twig::addExtension(new Functions($config)); | ||||
|         Twig::addExtension(new PiggyBank); | ||||
|         Twig::addExtension(new General); | ||||
|         Twig::addExtension(new Journal); | ||||
|         Twig::addExtension(new Budget); | ||||
|     } | ||||
|  | ||||
|     public function register() | ||||
|     { | ||||
|  | ||||
|  | ||||
|         $this->app->bind( | ||||
|             'preferences', function () { | ||||
|             return new Preferences; | ||||
| @@ -62,13 +82,18 @@ class FireflyServiceProvider extends ServiceProvider | ||||
|         $this->app->bind('FireflyIII\Repositories\Journal\JournalRepositoryInterface', 'FireflyIII\Repositories\Journal\JournalRepository'); | ||||
|         $this->app->bind('FireflyIII\Repositories\Bill\BillRepositoryInterface', 'FireflyIII\Repositories\Bill\BillRepository'); | ||||
|         $this->app->bind('FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface', 'FireflyIII\Repositories\PiggyBank\PiggyBankRepository'); | ||||
|         $this->app->bind('FireflyIII\Repositories\Currency\CurrencyRepositoryInterface', 'FireflyIII\Repositories\Currency\CurrencyRepository'); | ||||
|         $this->app->bind('FireflyIII\Repositories\Tag\TagRepositoryInterface', 'FireflyIII\Repositories\Tag\TagRepository'); | ||||
|         $this->app->bind('FireflyIII\Repositories\Reminder\ReminderRepositoryInterface', 'FireflyIII\Repositories\Reminder\ReminderRepository'); | ||||
|         $this->app->bind('FireflyIII\Support\Search\SearchInterface', 'FireflyIII\Support\Search\Search'); | ||||
|  | ||||
|  | ||||
|         $this->app->bind('FireflyIII\Helpers\Help\HelpInterface', 'FireflyIII\Helpers\Help\Help'); | ||||
|         $this->app->bind('FireflyIII\Helpers\Reminders\ReminderHelperInterface', 'FireflyIII\Helpers\Reminders\ReminderHelper'); | ||||
|         $this->app->bind('FireflyIII\Helpers\Report\ReportHelperInterface', 'FireflyIII\Helpers\Report\ReportHelper'); | ||||
|         $this->app->bind('FireflyIII\Helpers\Report\ReportQueryInterface', 'FireflyIII\Helpers\Report\ReportQuery'); | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -6,6 +6,7 @@ use App; | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use Config; | ||||
| use DB; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\AccountMeta; | ||||
| use FireflyIII\Models\AccountType; | ||||
| @@ -14,6 +15,7 @@ use FireflyIII\Models\Preference; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Models\TransactionType; | ||||
| use Illuminate\Database\Eloquent\Relations\HasMany; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use Illuminate\Support\Collection; | ||||
| use Log; | ||||
| @@ -29,11 +31,13 @@ class AccountRepository implements AccountRepositoryInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param array $types | ||||
|      * | ||||
|      * @return int | ||||
|      */ | ||||
|     public function countAssetAccounts() | ||||
|     public function countAccounts(array $types) | ||||
|     { | ||||
|         return Auth::user()->accounts()->accountTypeIn(['Asset account', 'Default account'])->count(); | ||||
|         return Auth::user()->accounts()->accountTypeIn($types)->count(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -48,6 +52,40 @@ class AccountRepository implements AccountRepositoryInterface | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $types | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getAccounts(array $types) | ||||
|     { | ||||
|         $result = Auth::user()->accounts()->with( | ||||
|             ['accountmeta' => function (HasMany $query) { | ||||
|                 $query->where('name', 'accountRole'); | ||||
|             }] | ||||
|         )->accountTypeIn($types)->orderBy('accounts.name', 'ASC')->get(['accounts.*'])->sortBy('name'); | ||||
|  | ||||
|         return $result; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getCreditCards() | ||||
|     { | ||||
|         return Auth::user()->accounts() | ||||
|                    ->hasMetaValue('accountRole', 'ccAsset') | ||||
|                    ->hasMetaValue('ccType', 'monthlyFull') | ||||
|                    ->get( | ||||
|                        [ | ||||
|                            'accounts.*', | ||||
|                            'ccType.data as ccType', | ||||
|                            'accountRole.data as accountRole' | ||||
|                        ] | ||||
|                    ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionJournal $journal | ||||
|      * @param Account            $account | ||||
| @@ -108,7 +146,7 @@ class AccountRepository implements AccountRepositoryInterface | ||||
|      * @param Account $account | ||||
|      * @param int     $page | ||||
|      * | ||||
|      * @return mixed | ||||
|      * @return LengthAwarePaginator | ||||
|      */ | ||||
|     public function getJournals(Account $account, $page) | ||||
|     { | ||||
| @@ -133,6 +171,68 @@ class AccountRepository implements AccountRepositoryInterface | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Account $account | ||||
|      * | ||||
|      * @return Carbon|null | ||||
|      */ | ||||
|     public function getLastActivity(Account $account) | ||||
|     { | ||||
|         $lastTransaction = $account->transactions()->leftJoin( | ||||
|             'transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id' | ||||
|         )->orderBy('transaction_journals.date', 'DESC')->first(['transactions.*', 'transaction_journals.date']); | ||||
|         if ($lastTransaction) { | ||||
|             return $lastTransaction->transactionjournal->date; | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the accounts of a user that have piggy banks connected to them. | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getPiggyBankAccounts() | ||||
|     { | ||||
|         $ids        = []; | ||||
|         $start      = clone Session::get('start', new Carbon); | ||||
|         $end        = clone Session::get('end', new Carbon); | ||||
|         $accountIds = DB::table('piggy_banks')->distinct()->get(['piggy_banks.account_id']); | ||||
|         $accounts   = new Collection; | ||||
|  | ||||
|         foreach ($accountIds as $id) { | ||||
|             $ids[] = intval($id->account_id); | ||||
|         } | ||||
|  | ||||
|         $ids = array_unique($ids); | ||||
|         if (count($ids) > 0) { | ||||
|             $accounts = Auth::user()->accounts()->whereIn('id', $ids)->get(); | ||||
|         } | ||||
|  | ||||
|         $accounts->each( | ||||
|             function (Account $account) use ($start, $end) { | ||||
|                 $account->startBalance = Steam::balance($account, $start, true); | ||||
|                 $account->endBalance   = Steam::balance($account, $end, true); | ||||
|                 $account->piggyBalance = 0; | ||||
|                 /** @var PiggyBank $piggyBank */ | ||||
|                 foreach ($account->piggyBanks as $piggyBank) { | ||||
|                     $account->piggyBalance += $piggyBank->currentRelevantRep()->currentamount; | ||||
|                 } | ||||
|                 // sum of piggy bank amounts on this account: | ||||
|                 // diff between endBalance and piggyBalance. | ||||
|                 // then, percentage. | ||||
|                 $difference          = $account->endBalance - $account->piggyBalance; | ||||
|                 $account->difference = $difference; | ||||
|                 $account->percentage = $difference != 0 ? round((($difference / $account->endBalance) * 100)) : 100; | ||||
|  | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         return $accounts; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get savings accounts and the balance difference in the period. | ||||
|      * | ||||
| @@ -175,6 +275,34 @@ class AccountRepository implements AccountRepositoryInterface | ||||
|         return $accounts; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all transfers TO this account in this range. | ||||
|      * | ||||
|      * @param Account $account | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getTransfersInRange(Account $account, Carbon $start, Carbon $end) | ||||
|     { | ||||
|         return TransactionJournal::whereIn( | ||||
|             'id', function ($q) use ($account, $start, $end) { | ||||
|             $q->select('transaction_journals.id') | ||||
|               ->from('transactions') | ||||
|               ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') | ||||
|               ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') | ||||
|               ->where('transactions.account_id', $account->id) | ||||
|               ->where('transaction_journals.user_id', Auth::user()->id) | ||||
|               ->where('transaction_journals.date', '>=', $start->format('Y-m-d')) | ||||
|               ->where('transaction_journals.date', '<=', $end->format('Y-m-d')) | ||||
|               ->where('transactions.amount', '>', 0) | ||||
|               ->where('transaction_types.type', 'Transfer'); | ||||
|  | ||||
|         } | ||||
|         )->get(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Account $account | ||||
|      * | ||||
| @@ -235,9 +363,19 @@ class AccountRepository implements AccountRepositoryInterface | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return float | ||||
|      */ | ||||
|     public function sumOfEverything() | ||||
|     { | ||||
|         return floatval(Auth::user()->transactions()->sum('amount')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Account $account | ||||
|      * @param array   $data | ||||
|      * | ||||
|      * @return Account | ||||
|      */ | ||||
|     public function update(Account $account, array $data) | ||||
|     { | ||||
| @@ -417,7 +555,6 @@ class AccountRepository implements AccountRepositoryInterface | ||||
|     protected function updateMetadata(Account $account, array $data) | ||||
|     { | ||||
|         $validFields = ['accountRole', 'ccMonthlyPaymentDate', 'ccType']; | ||||
|         $updated     = false; | ||||
|  | ||||
|         foreach ($validFields as $field) { | ||||
|             $entry = $account->accountMeta()->where('name', $field)->first(); | ||||
|   | ||||
| @@ -7,6 +7,7 @@ use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\Preference; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
| @@ -16,6 +17,13 @@ use Illuminate\Support\Collection; | ||||
|  */ | ||||
| interface AccountRepositoryInterface | ||||
| { | ||||
|     /** | ||||
|      * @param array $types | ||||
|      * | ||||
|      * @return int | ||||
|      */ | ||||
|     public function countAccounts(array $types); | ||||
|  | ||||
|     /** | ||||
|      * @param Account $account | ||||
|      * | ||||
| @@ -24,9 +32,43 @@ interface AccountRepositoryInterface | ||||
|     public function destroy(Account $account); | ||||
|  | ||||
|     /** | ||||
|      * @return int | ||||
|      * @param array $types | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function countAssetAccounts(); | ||||
|     public function getAccounts(array $types); | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionJournal $journal | ||||
|      * @param Account            $account | ||||
|      * | ||||
|      * @return Transaction | ||||
|      */ | ||||
|     public function getFirstTransaction(TransactionJournal $journal, Account $account); | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getCreditCards(); | ||||
|  | ||||
|     /** | ||||
|      * Get the accounts of a user that have piggy banks connected to them. | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getPiggyBankAccounts(); | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Get all transfers TO this account in this range. | ||||
|      * | ||||
|      * @param Account $account | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getTransfersInRange(Account $account, Carbon $start, Carbon $end); | ||||
|  | ||||
|     /** | ||||
|      * @param Preference $preference | ||||
| @@ -46,12 +88,38 @@ interface AccountRepositoryInterface | ||||
|  | ||||
|     /** | ||||
|      * @param Account $account | ||||
|      * @param string  $range | ||||
|      * @param         $page | ||||
|      * | ||||
|      * @return mixed | ||||
|      * @return LengthAwarePaginator | ||||
|      */ | ||||
|     public function getJournals(Account $account, $page); | ||||
|  | ||||
|     /** | ||||
|      * @param Account $account | ||||
|      * | ||||
|      * @return Carbon|null | ||||
|      */ | ||||
|     public function getLastActivity(Account $account); | ||||
|  | ||||
|     /** | ||||
|      * @return float | ||||
|      */ | ||||
|     public function sumOfEverything(); | ||||
|  | ||||
|     /** | ||||
|      * Get savings accounts and the balance difference in the period. | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getSavingsAccounts(); | ||||
|  | ||||
|     /** | ||||
|      * @param Account $account | ||||
|      * | ||||
|      * @return float | ||||
|      */ | ||||
|     public function leftOnAccount(Account $account); | ||||
|  | ||||
|     /** | ||||
|      * @param Account $account | ||||
|      * | ||||
| @@ -73,27 +141,4 @@ interface AccountRepositoryInterface | ||||
|      * @return Account | ||||
|      */ | ||||
|     public function update(Account $account, array $data); | ||||
|  | ||||
|     /** | ||||
|      * @param Account $account | ||||
|      * | ||||
|      * @return float | ||||
|      */ | ||||
|     public function leftOnAccount(Account $account); | ||||
|  | ||||
|     /** | ||||
|      * Get savings accounts and the balance difference in the period. | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getSavingsAccounts(); | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionJournal $journal | ||||
|      * @param Account            $account | ||||
|      * | ||||
|      * @return Transaction | ||||
|      */ | ||||
|     public function getFirstTransaction(TransactionJournal $journal, Account $account); | ||||
| } | ||||
|   | ||||
| @@ -2,9 +2,15 @@ | ||||
|  | ||||
| namespace FireflyIII\Repositories\Bill; | ||||
|  | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\AccountType; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Illuminate\Database\Query\JoinClause; | ||||
| use Illuminate\Support\Collection; | ||||
| use Log; | ||||
| use Navigation; | ||||
|  | ||||
| @@ -15,6 +21,121 @@ use Navigation; | ||||
|  */ | ||||
| class BillRepository implements BillRepositoryInterface | ||||
| { | ||||
|     /** | ||||
|      * Create a fake bill to help the chart controller. | ||||
|      * | ||||
|      * @param string $description | ||||
|      * @param Carbon $date | ||||
|      * @param float  $amount | ||||
|      * | ||||
|      * @return Bill | ||||
|      */ | ||||
|     public function createFakeBill($description, Carbon $date, $amount) | ||||
|     { | ||||
|         $bill              = new Bill; | ||||
|         $bill->name        = $description; | ||||
|         $bill->match       = $description; | ||||
|         $bill->amount_min  = $amount; | ||||
|         $bill->amount_max  = $amount; | ||||
|         $bill->date        = $date; | ||||
|         $bill->repeat_freq = 'monthly'; | ||||
|         $bill->skip        = 0; | ||||
|         $bill->automatch   = false; | ||||
|         $bill->active      = false; | ||||
|  | ||||
|         return $bill; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Bill $bill | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function destroy(Bill $bill) | ||||
|     { | ||||
|         return $bill->delete(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getActiveBills() | ||||
|     { | ||||
|         /** @var Collection $set */ | ||||
|         $set = Auth::user()->bills()->orderBy('name', 'ASC')->where('active', 1)->get()->sortBy('name'); | ||||
|  | ||||
|         return $set; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getBills() | ||||
|     { | ||||
|         /** @var Collection $set */ | ||||
|         $set = Auth::user()->bills()->orderBy('name', 'ASC')->get()->sortBy('name'); | ||||
|  | ||||
|         return $set; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Bill $bill | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getJournals(Bill $bill) | ||||
|     { | ||||
|         return $bill->transactionjournals()->withRelevantData() | ||||
|                     ->leftJoin( | ||||
|                         'transactions', function (JoinClause $join) { | ||||
|                         $join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id') | ||||
|                              ->where('transactions.amount', '>', 0); | ||||
|                     } | ||||
|                     ) | ||||
|                     ->orderBy('transaction_journals.date', 'DESC') | ||||
|                     ->orderBy('transaction_journals.order', 'ASC') | ||||
|                     ->orderBy('transaction_journals.id', 'DESC') | ||||
|                     ->get(['transaction_journals.*', 'transactions.amount']); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all journals that were recorded on this bill between these dates. | ||||
|      * | ||||
|      * @param Bill   $bill | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getJournalsInRange(Bill $bill, Carbon $start, Carbon $end) | ||||
|     { | ||||
|         return $bill->transactionjournals()->before($end)->after($start)->get(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Bill $bill | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getPossiblyRelatedJournals(Bill $bill) | ||||
|     { | ||||
|         $set = \DB::table('transactions')->where('amount', '>', 0)->where('amount', '>=', $bill->amount_min)->where('amount', '<=', $bill->amount_max)->get( | ||||
|             ['transaction_journal_id'] | ||||
|         ); | ||||
|         $ids = []; | ||||
|  | ||||
|         /** @var Transaction $entry */ | ||||
|         foreach ($set as $entry) { | ||||
|             $ids[] = intval($entry->transaction_journal_id); | ||||
|         } | ||||
|         $journals = new Collection; | ||||
|         if (count($ids) > 0) { | ||||
|             $journals = Auth::user()->transactionjournals()->whereIn('id', $ids)->get(); | ||||
|         } | ||||
|  | ||||
|         return $journals; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Every bill repeats itself weekly, monthly or yearly (or whatever). This method takes a date-range (usually the view-range of Firefly itself) | ||||
|      * and returns date ranges that fall within the given range; those ranges are the bills expected. When a bill is due on the 14th of the month and | ||||
| @@ -58,6 +179,21 @@ class BillRepository implements BillRepositoryInterface | ||||
|         return $validRanges; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Bill $bill | ||||
|      * | ||||
|      * @return Carbon|null | ||||
|      */ | ||||
|     public function lastFoundMatch(Bill $bill) | ||||
|     { | ||||
|         $last = $bill->transactionjournals()->orderBy('date', 'DESC')->first(); | ||||
|         if ($last) { | ||||
|             return $last->date; | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Bill $bill | ||||
|      * | ||||
| @@ -75,10 +211,12 @@ class BillRepository implements BillRepositoryInterface | ||||
|          * $today is the start of the next period, to make sure FF3 won't miss anything | ||||
|          * when the current period has a transaction journal. | ||||
|          */ | ||||
|         $today = Navigation::addPeriod(new Carbon, $bill->repeat_freq, 0); | ||||
|         /** @var \Carbon\Carbon $obj */ | ||||
|         $obj = new Carbon; | ||||
|         $today = Navigation::addPeriod($obj, $bill->repeat_freq, 0); | ||||
|  | ||||
|         $skip  = $bill->skip + 1; | ||||
|         $start = Navigation::startOfPeriod(new Carbon, $bill->repeat_freq); | ||||
|         $start = Navigation::startOfPeriod($obj, $bill->repeat_freq); | ||||
|         /* | ||||
|          * go back exactly one month/week/etc because FF3 does not care about 'next' | ||||
|          * bills if they're too far into the past. | ||||
| @@ -179,6 +317,12 @@ class BillRepository implements BillRepositoryInterface | ||||
|             Log::debug('TOTAL match is true!'); | ||||
|             $journal->bill()->associate($bill); | ||||
|             $journal->save(); | ||||
|         } else { | ||||
|             if ((!$wordMatch || !$amountMatch) && $bill->id == $journal->bill_id) { | ||||
|                 // if no match, but bill used to match, remove it: | ||||
|                 $journal->bill_id = null; | ||||
|                 $journal->save(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -5,6 +5,7 @@ namespace FireflyIII\Repositories\Bill; | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * Interface BillRepositoryInterface | ||||
| @@ -14,12 +15,58 @@ use FireflyIII\Models\TransactionJournal; | ||||
| interface BillRepositoryInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * Create a fake bill to help the chart controller. | ||||
|      * | ||||
|      * @param string $description | ||||
|      * @param Carbon $date | ||||
|      * @param float  $amount | ||||
|      * | ||||
|      * @return Bill | ||||
|      */ | ||||
|     public function createFakeBill($description, Carbon $date, $amount); | ||||
|  | ||||
|     /** | ||||
|      * @param Bill $bill | ||||
|      * | ||||
|      * @return Carbon|null | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function nextExpectedMatch(Bill $bill); | ||||
|     public function destroy(Bill $bill); | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getActiveBills(); | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getBills(); | ||||
|  | ||||
|     /** | ||||
|      * @param Bill $bill | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getJournals(Bill $bill); | ||||
|  | ||||
|     /** | ||||
|      * Get all journals that were recorded on this bill between these dates. | ||||
|      * | ||||
|      * @param Bill   $bill | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getJournalsInRange(Bill $bill, Carbon $start, Carbon $end); | ||||
|  | ||||
|     /** | ||||
|      * @param Bill $bill | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getPossiblyRelatedJournals(Bill $bill); | ||||
|  | ||||
|     /** | ||||
|      * Every bill repeats itself weekly, monthly or yearly (or whatever). This method takes a date-range (usually the view-range of Firefly itself) | ||||
| @@ -34,6 +81,29 @@ interface BillRepositoryInterface | ||||
|      */ | ||||
|     public function getRanges(Bill $bill, Carbon $start, Carbon $end); | ||||
|  | ||||
|     /** | ||||
|      * @param Bill $bill | ||||
|      * | ||||
|      * @return Carbon|null | ||||
|      */ | ||||
|     public function lastFoundMatch(Bill $bill); | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @param Bill $bill | ||||
|      * | ||||
|      * @return Carbon|null | ||||
|      */ | ||||
|     public function nextExpectedMatch(Bill $bill); | ||||
|  | ||||
|     /** | ||||
|      * @param Bill               $bill | ||||
|      * @param TransactionJournal $journal | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function scan(Bill $bill, TransactionJournal $journal); | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      * | ||||
| @@ -49,12 +119,4 @@ interface BillRepositoryInterface | ||||
|      */ | ||||
|     public function update(Bill $bill, array $data); | ||||
|  | ||||
|     /** | ||||
|      * @param Bill               $bill | ||||
|      * @param TransactionJournal $journal | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function scan(Bill $bill, TransactionJournal $journal); | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -2,11 +2,14 @@ | ||||
|  | ||||
| namespace FireflyIII\Repositories\Budget; | ||||
|  | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Models\Budget; | ||||
| use FireflyIII\Models\BudgetLimit; | ||||
| use FireflyIII\Models\LimitRepetition; | ||||
| use Illuminate\Database\Query\Builder as QueryBuilder; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * Class BudgetRepository | ||||
| @@ -37,7 +40,7 @@ class BudgetRepository implements BudgetRepositoryInterface | ||||
|         } | ||||
|  | ||||
|         // delete limits with amount 0: | ||||
|         BudgetLimit::where('amount',0)->delete(); | ||||
|         BudgetLimit::where('amount', 0)->delete(); | ||||
|  | ||||
|     } | ||||
|  | ||||
| @@ -53,6 +56,101 @@ class BudgetRepository implements BudgetRepositoryInterface | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * @param Carbon $date | ||||
|      * | ||||
|      * @return float | ||||
|      */ | ||||
|     public function expensesOnDay(Budget $budget, Carbon $date) | ||||
|     { | ||||
|         return floatval($budget->transactionjournals()->lessThan(0)->transactionTypes(['Withdrawal'])->onDate($date)->sum('amount')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getActiveBudgets() | ||||
|     { | ||||
|         $budgets = Auth::user()->budgets()->where('active', 1)->get(); | ||||
|         $budgets->sortBy('name'); | ||||
|  | ||||
|         return $budgets; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getBudgetLimitRepetitions(Budget $budget, Carbon $start, Carbon $end) | ||||
|     { | ||||
|         /** @var Collection $repetitions */ | ||||
|         return LimitRepetition:: | ||||
|         leftJoin('budget_limits', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id') | ||||
|                               ->where('limit_repetitions.startdate', '<=', $end->format('Y-m-d 00:00:00')) | ||||
|                               ->where('limit_repetitions.startdate', '>=', $start->format('Y-m-d 00:00:00')) | ||||
|                               ->where('budget_limits.budget_id', $budget->id) | ||||
|                               ->get(['limit_repetitions.*']); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getBudgetLimits(Budget $budget) | ||||
|     { | ||||
|         return $budget->budgetLimits()->orderBy('startdate', 'DESC')->get(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getBudgets() | ||||
|     { | ||||
|         $budgets = Auth::user()->budgets()->get(); | ||||
|         $budgets->sortBy('name'); | ||||
|  | ||||
|         return $budgets; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * @param Carbon $date | ||||
|      * | ||||
|      * @return LimitRepetition|null | ||||
|      */ | ||||
|     public function getCurrentRepetition(Budget $budget, Carbon $date) | ||||
|     { | ||||
|         return $budget->limitrepetitions()->where('limit_repetitions.startdate', $date)->first(['limit_repetitions.*']); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * | ||||
|      * @return Carbon | ||||
|      */ | ||||
|     public function getFirstBudgetLimitDate(Budget $budget) | ||||
|     { | ||||
|         $limit = $budget->budgetlimits()->orderBy('startdate', 'ASC')->first(); | ||||
|         if ($limit) { | ||||
|             return $limit->startdate; | ||||
|         } | ||||
|  | ||||
|         return Carbon::now()->startOfYear(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getInactiveBudgets() | ||||
|     { | ||||
|         return Auth::user()->budgets()->where('active', 0)->get(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns all the transaction journals for a limit, possibly limited by a limit repetition. | ||||
|      * | ||||
| @@ -86,6 +184,91 @@ class BudgetRepository implements BudgetRepositoryInterface | ||||
|         return new LengthAwarePaginator($set, $count, $take, $offset); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * | ||||
|      * @return Carbon | ||||
|      */ | ||||
|     public function getLastBudgetLimitDate(Budget $budget) | ||||
|     { | ||||
|         $limit = $budget->budgetlimits()->orderBy('startdate', 'DESC')->first(); | ||||
|         if ($limit) { | ||||
|             return $limit->startdate; | ||||
|         } | ||||
|  | ||||
|         return Carbon::now()->startOfYear(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * @param Carbon $date | ||||
|      * | ||||
|      * @return float|null | ||||
|      */ | ||||
|     public function getLimitAmountOnDate(Budget $budget, Carbon $date) | ||||
|     { | ||||
|         $repetition = LimitRepetition::leftJoin('budget_limits', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id') | ||||
|                                      ->where('limit_repetitions.startdate', $date->format('Y-m-d 00:00:00')) | ||||
|                                      ->where('budget_limits.budget_id', $budget->id) | ||||
|                                      ->first(['limit_repetitions.*']); | ||||
|  | ||||
|         if ($repetition) { | ||||
|             return floatval($repetition->amount); | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getWithoutBudget(Carbon $start, Carbon $end) | ||||
|     { | ||||
|         return Auth::user() | ||||
|                    ->transactionjournals() | ||||
|                    ->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') | ||||
|                    ->whereNull('budget_transaction_journal.id') | ||||
|                    ->before($end) | ||||
|                    ->after($start) | ||||
|                    ->orderBy('transaction_journals.date', 'DESC') | ||||
|                    ->orderBy('transaction_journals.order', 'ASC') | ||||
|                    ->orderBy('transaction_journals.id', 'DESC') | ||||
|                    ->get(['transaction_journals.*']); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function getWithoutBudgetSum(Carbon $start, Carbon $end) | ||||
|     { | ||||
|         $noBudgetSet = Auth::user() | ||||
|                            ->transactionjournals() | ||||
|                            ->whereNotIn( | ||||
|                                'transaction_journals.id', function (QueryBuilder $query) use ($start, $end) { | ||||
|                                $query | ||||
|                                    ->select('transaction_journals.id') | ||||
|                                    ->from('transaction_journals') | ||||
|                                    ->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') | ||||
|                                    ->where('transaction_journals.date', '>=', $start->format('Y-m-d 00:00:00')) | ||||
|                                    ->where('transaction_journals.date', '<=', $end->format('Y-m-d 00:00:00')) | ||||
|                                    ->whereNotNull('budget_transaction_journal.budget_id'); | ||||
|                            } | ||||
|                            ) | ||||
|                            ->before($end) | ||||
|                            ->after($start) | ||||
|                            ->lessThan(0) | ||||
|                            ->transactionTypes(['Withdrawal']) | ||||
|                            ->get(); | ||||
|  | ||||
|         return floatval($noBudgetSet->sum('amount')) * -1; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * @param Carbon $date | ||||
| @@ -120,6 +303,18 @@ class BudgetRepository implements BudgetRepositoryInterface | ||||
|         return $newBudget; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return float | ||||
|      */ | ||||
|     public function sumBudgetExpensesInPeriod(Budget $budget, $start, $end) | ||||
|     { | ||||
|         return floatval($budget->transactionjournals()->before($end)->after($start)->lessThan(0)->sum('amount')) * -1; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * @param array  $data | ||||
|   | ||||
| @@ -5,6 +5,7 @@ namespace FireflyIII\Repositories\Budget; | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Models\Budget; | ||||
| use FireflyIII\Models\LimitRepetition; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * Interface BudgetRepositoryInterface | ||||
| @@ -13,6 +14,11 @@ use FireflyIII\Models\LimitRepetition; | ||||
|  */ | ||||
| interface BudgetRepositoryInterface | ||||
| { | ||||
|     /** | ||||
|      * @return void | ||||
|      */ | ||||
|     public function cleanupBudgets(); | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * | ||||
| @@ -20,42 +26,59 @@ interface BudgetRepositoryInterface | ||||
|      */ | ||||
|     public function destroy(Budget $budget); | ||||
|  | ||||
|     /** | ||||
|      * @return void | ||||
|      */ | ||||
|     public function cleanupBudgets(); | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * @param Carbon $date | ||||
|      * | ||||
|      * @return float | ||||
|      */ | ||||
|     public function spentInMonth(Budget $budget, Carbon $date); | ||||
|     public function expensesOnDay(Budget $budget, Carbon $date); | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getActiveBudgets(); | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getBudgetLimitRepetitions(Budget $budget, Carbon $start, Carbon $end); | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getBudgetLimits(Budget $budget); | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getBudgets(); | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * @param Carbon $date | ||||
|      * @param        $amount | ||||
|      * | ||||
|      * @return mixed | ||||
|      * @return LimitRepetition|null | ||||
|      */ | ||||
|     public function updateLimitAmount(Budget $budget, Carbon $date, $amount); | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      * | ||||
|      * @return Budget | ||||
|      */ | ||||
|     public function store(array $data); | ||||
|     public function getCurrentRepetition(Budget $budget, Carbon $date); | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * @param array  $data | ||||
|      * | ||||
|      * @return Budget | ||||
|      * @return Carbon | ||||
|      */ | ||||
|     public function update(Budget $budget, array $data); | ||||
|     public function getFirstBudgetLimitDate(Budget $budget); | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getInactiveBudgets(); | ||||
|  | ||||
|     /** | ||||
|      * Returns all the transaction journals for a limit, possibly limited by a limit repetition. | ||||
| @@ -68,4 +91,76 @@ interface BudgetRepositoryInterface | ||||
|      */ | ||||
|     public function getJournals(Budget $budget, LimitRepetition $repetition = null, $take = 50); | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * | ||||
|      * @return Carbon | ||||
|      */ | ||||
|     public function getLastBudgetLimitDate(Budget $budget); | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * @param Carbon $date | ||||
|      * | ||||
|      * @return float | ||||
|      */ | ||||
|     public function getLimitAmountOnDate(Budget $budget, Carbon $date); | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getWithoutBudget(Carbon $start, Carbon $end); | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function getWithoutBudgetSum(Carbon $start, Carbon $end); | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * @param Carbon $date | ||||
|      * | ||||
|      * @return float | ||||
|      */ | ||||
|     public function spentInMonth(Budget $budget, Carbon $date); | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      * | ||||
|      * @return Budget | ||||
|      */ | ||||
|     public function store(array $data); | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return float | ||||
|      */ | ||||
|     public function sumBudgetExpensesInPeriod(Budget $budget, $start, $end); | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * @param array  $data | ||||
|      * | ||||
|      * @return Budget | ||||
|      */ | ||||
|     public function update(Budget $budget, array $data); | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * @param Carbon $date | ||||
|      * @param        $amount | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function updateLimitAmount(Budget $budget, Carbon $date, $amount); | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -2,7 +2,13 @@ | ||||
|  | ||||
| namespace FireflyIII\Repositories\Category; | ||||
|  | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use DB; | ||||
| use FireflyIII\Models\Category; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Illuminate\Database\Query\JoinClause; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * Class CategoryRepository | ||||
| @@ -12,6 +18,17 @@ use FireflyIII\Models\Category; | ||||
| class CategoryRepository implements CategoryRepositoryInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param Category $category | ||||
|      * | ||||
|      * @return int | ||||
|      */ | ||||
|     public function countJournals(Category $category) | ||||
|     { | ||||
|         return $category->transactionJournals()->count(); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Category $category | ||||
|      * | ||||
| @@ -24,6 +41,150 @@ class CategoryRepository implements CategoryRepositoryInterface | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getCategories() | ||||
|     { | ||||
|         /** @var Collection $set */ | ||||
|         $set = Auth::user()->categories()->orderBy('name', 'ASC')->get(); | ||||
|         $set->sortBy( | ||||
|             function (Category $category) { | ||||
|                 return $category->name; | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         return $set; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getCategoriesAndExpenses($start, $end) | ||||
|     { | ||||
|         return TransactionJournal:: | ||||
|         where('transaction_journals.user_id', Auth::user()->id) | ||||
|                                  ->leftJoin( | ||||
|                                      'transactions', | ||||
|                                      function (JoinClause $join) { | ||||
|                                          $join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('amount', '>', 0); | ||||
|                                      } | ||||
|                                  ) | ||||
|                                  ->leftJoin( | ||||
|                                      'category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id' | ||||
|                                  ) | ||||
|                                  ->leftJoin('categories', 'categories.id', '=', 'category_transaction_journal.category_id') | ||||
|                                  ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') | ||||
|                                  ->before($end) | ||||
|                                  ->where('categories.user_id', Auth::user()->id) | ||||
|                                  ->after($start) | ||||
|                                  ->where('transaction_types.type', 'Withdrawal') | ||||
|                                  ->groupBy('categories.id') | ||||
|                                  ->orderBy('sum', 'DESC') | ||||
|                                  ->get(['categories.id', 'categories.encrypted', 'categories.name', DB::Raw('SUM(`transactions`.`amount`) AS `sum`')]); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Category $category | ||||
|      * | ||||
|      * @return Carbon | ||||
|      */ | ||||
|     public function getFirstActivityDate(Category $category) | ||||
|     { | ||||
|         /** @var TransactionJournal $first */ | ||||
|         $first = $category->transactionjournals()->orderBy('date', 'ASC')->first(); | ||||
|         if ($first) { | ||||
|             return $first->date; | ||||
|         } | ||||
|  | ||||
|         return new Carbon; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Category $category | ||||
|      * @param int      $page | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getJournals(Category $category, $page) | ||||
|     { | ||||
|         $offset = $page > 0 ? $page * 50 : 0; | ||||
|  | ||||
|         return $category->transactionJournals()->withRelevantData()->take(50)->offset($offset) | ||||
|                         ->orderBy('transaction_journals.date', 'DESC') | ||||
|                         ->orderBy('transaction_journals.order', 'ASC') | ||||
|                         ->orderBy('transaction_journals.id', 'DESC') | ||||
|                         ->get( | ||||
|                             ['transaction_journals.*'] | ||||
|                         ); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Category $category | ||||
|      * | ||||
|      * @return Carbon|null | ||||
|      */ | ||||
|     public function getLatestActivity(Category $category) | ||||
|     { | ||||
|         $latest = $category->transactionjournals() | ||||
|                            ->orderBy('transaction_journals.date', 'DESC') | ||||
|                            ->orderBy('transaction_journals.order', 'ASC') | ||||
|                            ->orderBy('transaction_journals.id', 'DESC') | ||||
|                            ->first(); | ||||
|         if ($latest) { | ||||
|             return $latest->date; | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getWithoutCategory(Carbon $start, Carbon $end) | ||||
|     { | ||||
|         return Auth::user() | ||||
|                    ->transactionjournals() | ||||
|                    ->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') | ||||
|                    ->whereNull('category_transaction_journal.id') | ||||
|                    ->before($end) | ||||
|                    ->after($start) | ||||
|                    ->orderBy('transaction_journals.date', 'DESC') | ||||
|                    ->orderBy('transaction_journals.order', 'ASC') | ||||
|                    ->orderBy('transaction_journals.id', 'DESC') | ||||
|                    ->get(['transaction_journals.*']); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Category $category | ||||
|      * @param Carbon   $start | ||||
|      * @param Carbon   $end | ||||
|      * | ||||
|      * @return float | ||||
|      */ | ||||
|     public function spentInPeriodSum(Category $category, Carbon $start, Carbon $end) | ||||
|     { | ||||
|         return floatval($category->transactionjournals()->before($end)->after($start)->lessThan(0)->sum('amount')) * -1; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Category $category | ||||
|      * @param Carbon   $date | ||||
|      * | ||||
|      * @return float | ||||
|      */ | ||||
|     public function spentOnDaySum(Category $category, Carbon $date) | ||||
|     { | ||||
|         return floatval($category->transactionjournals()->onDate($date)->lessThan(0)->sum('amount')) * -1; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
| @@ -57,5 +218,4 @@ class CategoryRepository implements CategoryRepositoryInterface | ||||
|  | ||||
|         return $category; | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -2,7 +2,9 @@ | ||||
|  | ||||
| namespace FireflyIII\Repositories\Category; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Models\Category; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * Interface CategoryRepositoryInterface | ||||
| @@ -11,6 +13,13 @@ use FireflyIII\Models\Category; | ||||
|  */ | ||||
| interface CategoryRepositoryInterface | ||||
| { | ||||
|     /** | ||||
|      * @param Category $category | ||||
|      * | ||||
|      * @return int | ||||
|      */ | ||||
|     public function countJournals(Category $category); | ||||
|  | ||||
|     /** | ||||
|      * @param Category $category | ||||
|      * | ||||
| @@ -18,6 +27,66 @@ interface CategoryRepositoryInterface | ||||
|      */ | ||||
|     public function destroy(Category $category); | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getCategories(); | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getCategoriesAndExpenses($start, $end); | ||||
|  | ||||
|     /** | ||||
|      * @param Category $category | ||||
|      * | ||||
|      * @return Carbon | ||||
|      */ | ||||
|     public function getFirstActivityDate(Category $category); | ||||
|  | ||||
|     /** | ||||
|      * @param Category $category | ||||
|      * @param int      $page | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getJournals(Category $category, $page); | ||||
|  | ||||
|     /** | ||||
|      * @param Category $category | ||||
|      * | ||||
|      * @return Carbon|null | ||||
|      */ | ||||
|     public function getLatestActivity(Category $category); | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getWithoutCategory(Carbon $start, Carbon $end); | ||||
|  | ||||
|     /** | ||||
|      * @param Category $category | ||||
|      * @param \Carbon\Carbon   $start | ||||
|      * @param \Carbon\Carbon   $end | ||||
|      * | ||||
|      * @return float | ||||
|      */ | ||||
|     public function spentInPeriodSum(Category $category, Carbon $start, Carbon $end); | ||||
|  | ||||
|     /** | ||||
|      * @param Category $category | ||||
|      * @param Carbon   $date | ||||
|      * | ||||
|      * @return float | ||||
|      */ | ||||
|     public function spentOnDaySum(Category $category, Carbon $date); | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      * | ||||
|   | ||||
							
								
								
									
										84
									
								
								app/Repositories/Currency/CurrencyRepository.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								app/Repositories/Currency/CurrencyRepository.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Repositories\Currency; | ||||
|  | ||||
|  | ||||
| use FireflyIII\Models\Preference; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * Class CurrencyRepository | ||||
|  * | ||||
|  * @package FireflyIII\Repositories\Currency | ||||
|  */ | ||||
| class CurrencyRepository implements CurrencyRepositoryInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionCurrency $currency | ||||
|      * | ||||
|      * @return int | ||||
|      */ | ||||
|     public function countJournals(TransactionCurrency $currency) | ||||
|     { | ||||
|         return $currency->transactionJournals()->count(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function get() | ||||
|     { | ||||
|         return TransactionCurrency::get(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Preference $preference | ||||
|      * | ||||
|      * @return TransactionCurrency | ||||
|      */ | ||||
|     public function getCurrencyByPreference(Preference $preference) | ||||
|     { | ||||
|         $preferred = TransactionCurrency::whereCode($preference->data)->first(); | ||||
|         if (is_null($preferred)) { | ||||
|             $preferred = TransactionCurrency::first(); | ||||
|         } | ||||
|  | ||||
|         return $preferred; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      * | ||||
|      * @return TransactionCurrency | ||||
|      */ | ||||
|     public function store(array $data) | ||||
|     { | ||||
|         $currency = TransactionCurrency::create( | ||||
|             [ | ||||
|                 'name'   => $data['name'], | ||||
|                 'code'   => $data['code'], | ||||
|                 'symbol' => $data['symbol'], | ||||
|             ] | ||||
|         ); | ||||
|  | ||||
|         return $currency; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionCurrency $currency | ||||
|      * @param array               $data | ||||
|      * | ||||
|      * @return TransactionCurrency | ||||
|      */ | ||||
|     public function update(TransactionCurrency $currency, array $data) | ||||
|     { | ||||
|         $currency->code   = $data['code']; | ||||
|         $currency->symbol = $data['symbol']; | ||||
|         $currency->name   = $data['name']; | ||||
|         $currency->save(); | ||||
|  | ||||
|         return $currency; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										52
									
								
								app/Repositories/Currency/CurrencyRepositoryInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								app/Repositories/Currency/CurrencyRepositoryInterface.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Repositories\Currency; | ||||
|  | ||||
|  | ||||
| use FireflyIII\Models\Preference; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * Interface CurrencyRepositoryInterface | ||||
|  * | ||||
|  * @package FireflyIII\Repositories\Currency | ||||
|  */ | ||||
| interface CurrencyRepositoryInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionCurrency $currency | ||||
|      * | ||||
|      * @return int | ||||
|      */ | ||||
|     public function countJournals(TransactionCurrency $currency); | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function get(); | ||||
|  | ||||
|     /** | ||||
|      * @param Preference $preference | ||||
|      * | ||||
|      * @return TransactionCurrency | ||||
|      */ | ||||
|     public function getCurrencyByPreference(Preference $preference); | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      * | ||||
|      * @return TransactionCurrency | ||||
|      */ | ||||
|     public function store(array $data); | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionCurrency $currency | ||||
|      * @param array               $data | ||||
|      * | ||||
|      * @return TransactionCurrency | ||||
|      */ | ||||
|     public function update(TransactionCurrency $currency, array $data); | ||||
|  | ||||
| } | ||||
| @@ -4,13 +4,17 @@ namespace FireflyIII\Repositories\Journal; | ||||
|  | ||||
| use App; | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use DB; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\AccountType; | ||||
| use FireflyIII\Models\Budget; | ||||
| use FireflyIII\Models\Category; | ||||
| use FireflyIII\Models\Tag; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Models\TransactionType; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use Illuminate\Support\Collection; | ||||
| use Log; | ||||
|  | ||||
| @@ -22,6 +26,38 @@ use Log; | ||||
| class JournalRepository implements JournalRepositoryInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param int $reminderId | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function deactivateReminder($reminderId) | ||||
|     { | ||||
|         $reminder = Auth::user()->reminders()->find($reminderId); | ||||
|         if ($reminder) { | ||||
|             $reminder->active = 0; | ||||
|             $reminder->save(); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionJournal $journal | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function delete(TransactionJournal $journal) | ||||
|     { | ||||
|         // delete transactions first: | ||||
|         /** @var Transaction $transaction */ | ||||
|         foreach ($journal->transactions()->get() as $transaction) { | ||||
|             $transaction->delete(); | ||||
|         } | ||||
|         $journal->delete(); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get users first transaction journal | ||||
|      * | ||||
| @@ -33,85 +69,98 @@ class JournalRepository implements JournalRepositoryInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * Get the account_id, which is the asset account that paid for the transaction. | ||||
|      * | ||||
|      * @param TransactionJournal $journal | ||||
|      * @param Transaction        $transaction | ||||
|      * | ||||
|      * @return mixed | ||||
|      * @return float | ||||
|      */ | ||||
|     public function getAssetAccount(TransactionJournal $journal) | ||||
|     public function getAmountBefore(TransactionJournal $journal, Transaction $transaction) | ||||
|     { | ||||
|         $positive = true; // the asset account is in the transaction with the positive amount. | ||||
|         switch ($journal->transactionType->type) { | ||||
|             case 'Withdrawal': | ||||
|                 $positive = false; | ||||
|                 break; | ||||
|         } | ||||
|         /** @var Transaction $transaction */ | ||||
|         foreach ($journal->transactions()->get() as $transaction) { | ||||
|             if (floatval($transaction->amount) > 0 && $positive === true) { | ||||
|                 return $transaction->account_id; | ||||
|             } | ||||
|             if (floatval($transaction->amount) < 0 && $positive === false) { | ||||
|                 return $transaction->account_id; | ||||
|             } | ||||
|  | ||||
|         } | ||||
|  | ||||
|         return $journal->transactions()->first()->account_id; | ||||
|         return floatval( | ||||
|             $transaction->account->transactions()->leftJoin( | ||||
|                 'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id' | ||||
|             ) | ||||
|                                  ->where('transaction_journals.date', '<=', $journal->date->format('Y-m-d')) | ||||
|                                  ->where('transaction_journals.order', '>=', $journal->order) | ||||
|                                  ->where('transaction_journals.id', '!=', $journal->id) | ||||
|                                  ->sum('transactions.amount') | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string             $query | ||||
|      * @param TransactionJournal $journal | ||||
|      * @param TransactionType $dbType | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function searchRelated($query, TransactionJournal $journal) | ||||
|     public function getJournalsOfType(TransactionType $dbType) | ||||
|     { | ||||
|         $start = clone $journal->date; | ||||
|         $end   = clone $journal->date; | ||||
|         $start->startOfMonth(); | ||||
|         $end->endOfMonth(); | ||||
|         return Auth::user()->transactionjournals()->where('transaction_type_id', $dbType->id)->orderBy('id', 'DESC')->take(50)->get(); | ||||
|     } | ||||
|  | ||||
|         // get already related transactions: | ||||
|         $exclude = [$journal->id]; | ||||
|         foreach ($journal->transactiongroups()->get() as $group) { | ||||
|             foreach ($group->transactionjournals()->get() as $current) { | ||||
|                 $exclude[] = $current->id; | ||||
|     /** | ||||
|      * @param array $types | ||||
|      * @param int   $offset | ||||
|      * @param int   $page | ||||
|      * | ||||
|      * @return LengthAwarePaginator | ||||
|      */ | ||||
|     public function getJournalsOfTypes(array $types, $offset, $page) | ||||
|     { | ||||
|         $set      = Auth::user()->transactionJournals()->transactionTypes($types)->withRelevantData()->take(50)->offset($offset) | ||||
|                         ->orderBy('date', 'DESC') | ||||
|                         ->orderBy('order', 'ASC') | ||||
|                         ->orderBy('id', 'DESC') | ||||
|                         ->get( | ||||
|                             ['transaction_journals.*'] | ||||
|                         ); | ||||
|         $count    = Auth::user()->transactionJournals()->transactionTypes($types)->count(); | ||||
|         $journals = new LengthAwarePaginator($set, $count, 50, $page); | ||||
|  | ||||
|         return $journals; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $type | ||||
|      * | ||||
|      * @return TransactionType | ||||
|      */ | ||||
|     public function getTransactionType($type) | ||||
|     { | ||||
|         return TransactionType::whereType($type)->first(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param        $id | ||||
|      * @param Carbon $date | ||||
|      * | ||||
|      * @return TransactionJournal | ||||
|      */ | ||||
|     public function getWithDate($id, Carbon $date) | ||||
|     { | ||||
|         return Auth::user()->transactionjournals()->where('id', $id)->where('date', $date->format('Y-m-d'))->first(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * * Remember: a balancingAct takes at most one expense and one transfer. | ||||
|      *            an advancePayment takes at most one expense, infinite deposits and NO transfers. | ||||
|      * | ||||
|      * @param TransactionJournal $journal | ||||
|      * @param array              $array | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function saveTags(TransactionJournal $journal, array $array) | ||||
|     { | ||||
|         /** @var \FireflyIII\Repositories\Tag\TagRepositoryInterface $tagRepository */ | ||||
|         $tagRepository = App::make('FireflyIII\Repositories\Tag\TagRepositoryInterface'); | ||||
|  | ||||
|         foreach ($array as $name) { | ||||
|             if (strlen(trim($name)) > 0) { | ||||
|                 $tag = Tag::firstOrCreateEncrypted(['tag' => $name, 'user_id' => $journal->user_id]); | ||||
|                 $tagRepository->connect($journal, $tag); | ||||
|             } | ||||
|         } | ||||
|         $exclude = array_unique($exclude); | ||||
|  | ||||
|         /** @var Collection $collection */ | ||||
|         $collection = Auth::user()->transactionjournals() | ||||
|                           ->withRelevantData() | ||||
|                           ->before($end)->after($start)->where('encrypted', 0) | ||||
|                           ->whereNotIn('id', $exclude) | ||||
|                           ->where('description', 'LIKE', '%' . $query . '%') | ||||
|                           ->get(); | ||||
|  | ||||
|         // manually search encrypted entries: | ||||
|         /** @var Collection $encryptedCollection */ | ||||
|         $encryptedCollection = Auth::user()->transactionjournals() | ||||
|                                    ->withRelevantData() | ||||
|                                    ->before($end)->after($start) | ||||
|                                    ->where('encrypted', 1) | ||||
|                                    ->whereNotIn('id', $exclude) | ||||
|                                    ->get(); | ||||
|         $encrypted           = $encryptedCollection->filter( | ||||
|             function (TransactionJournal $journal) use ($query) { | ||||
|                 $strPos = strpos(strtolower($journal->description), strtolower($query)); | ||||
|                 if ($strPos !== false) { | ||||
|                     return $journal; | ||||
|                 } | ||||
|  | ||||
|                 return null; | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         return $collection->merge($encrypted); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -140,12 +189,13 @@ class JournalRepository implements JournalRepositoryInterface | ||||
|  | ||||
|         // store or get category | ||||
|         if (strlen($data['category']) > 0) { | ||||
|             $category = Category::firstOrCreate(['name' => $data['category'], 'user_id' => $data['user']]); | ||||
|             $category = Category::firstOrCreateEncrypted(['name' => $data['category'], 'user_id' => $data['user']]); | ||||
|             $journal->categories()->save($category); | ||||
|         } | ||||
|  | ||||
|         // store or get budget | ||||
|         if (intval($data['budget_id']) > 0) { | ||||
|             /** @var \FireflyIII\Models\Budget $budget */ | ||||
|             $budget = Budget::find($data['budget_id']); | ||||
|             $journal->budgets()->save($budget); | ||||
|         } | ||||
| @@ -171,6 +221,11 @@ class JournalRepository implements JournalRepositoryInterface | ||||
|         $journal->completed = 1; | ||||
|         $journal->save(); | ||||
|  | ||||
|         // store tags | ||||
|         if (isset($data['tags']) && is_array($data['tags'])) { | ||||
|             $this->saveTags($journal, $data['tags']); | ||||
|         } | ||||
|  | ||||
|         return $journal; | ||||
|  | ||||
|  | ||||
| @@ -193,13 +248,14 @@ class JournalRepository implements JournalRepositoryInterface | ||||
|         // unlink all categories, recreate them: | ||||
|         $journal->categories()->detach(); | ||||
|         if (strlen($data['category']) > 0) { | ||||
|             $category = Category::firstOrCreate(['name' => $data['category'], 'user_id' => $data['user']]); | ||||
|             $category = Category::firstOrCreateEncrypted(['name' => $data['category'], 'user_id' => $data['user']]); | ||||
|             $journal->categories()->save($category); | ||||
|         } | ||||
|  | ||||
|         // unlink all budgets and recreate them: | ||||
|         $journal->budgets()->detach(); | ||||
|         if (intval($data['budget_id']) > 0) { | ||||
|             /** @var \FireflyIII\Models\Budget $budget */ | ||||
|             $budget = Budget::find($data['budget_id']); | ||||
|             $journal->budgets()->save($budget); | ||||
|         } | ||||
| @@ -226,9 +282,54 @@ class JournalRepository implements JournalRepositoryInterface | ||||
|  | ||||
|         $journal->save(); | ||||
|  | ||||
|         // update tags: | ||||
|         if (isset($data['tags']) && is_array($data['tags'])) { | ||||
|             $this->updateTags($journal, $data['tags']); | ||||
|         } | ||||
|  | ||||
|         return $journal; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionJournal $journal | ||||
|      * @param array              $array | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function updateTags(TransactionJournal $journal, array $array) | ||||
|     { | ||||
|         // create tag repository | ||||
|         /** @var \FireflyIII\Repositories\Tag\TagRepositoryInterface $tagRepository */ | ||||
|         $tagRepository = App::make('FireflyIII\Repositories\Tag\TagRepositoryInterface'); | ||||
|  | ||||
|  | ||||
|         // find or create all tags: | ||||
|         $tags = []; | ||||
|         $ids  = []; | ||||
|         foreach ($array as $name) { | ||||
|             if (strlen(trim($name)) > 0) { | ||||
|                 $tag    = Tag::firstOrCreateEncrypted(['tag' => $name, 'user_id' => $journal->user_id]); | ||||
|                 $tags[] = $tag; | ||||
|                 $ids[]  = $tag->id; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // delete all tags connected to journal not in this array: | ||||
|         if (count($ids) > 0) { | ||||
|             DB::table('tag_transaction_journal')->where('transaction_journal_id', $journal->id)->whereNotIn('tag_id', $ids)->delete(); | ||||
|         } | ||||
|         // if count is zero, delete them all: | ||||
|         if (count($ids) == 0) { | ||||
|             DB::table('tag_transaction_journal')->where('transaction_journal_id', $journal->id)->delete(); | ||||
|         } | ||||
|  | ||||
|         // connect each tag to journal (if not yet connected): | ||||
|         /** @var Tag $tag */ | ||||
|         foreach ($tags as $tag) { | ||||
|             $tagRepository->connect($journal, $tag); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionType $type | ||||
|      * @param array           $data | ||||
| @@ -289,5 +390,4 @@ class JournalRepository implements JournalRepositoryInterface | ||||
|  | ||||
|         return [$from, $to]; | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -2,8 +2,11 @@ | ||||
|  | ||||
| namespace FireflyIII\Repositories\Journal; | ||||
|  | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Models\TransactionType; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
| @@ -14,22 +17,79 @@ use Illuminate\Support\Collection; | ||||
| interface JournalRepositoryInterface | ||||
| { | ||||
|     /** | ||||
|      * @param int $reminderId | ||||
|      * | ||||
|      * Get the account_id, which is the asset account that paid for the transaction. | ||||
|      * | ||||
|      * @param TransactionJournal $journal | ||||
|      * | ||||
|      * @return int | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function getAssetAccount(TransactionJournal $journal); | ||||
|     public function deactivateReminder($reminderId); | ||||
|  | ||||
|     /** | ||||
|      * @param string             $query | ||||
|      * @param TransactionJournal $journal | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function delete(TransactionJournal $journal); | ||||
|  | ||||
|     /** | ||||
|      * Get users first transaction journal | ||||
|      * | ||||
|      * @return TransactionJournal | ||||
|      */ | ||||
|     public function first(); | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionJournal $journal | ||||
|      * @param Transaction        $transaction | ||||
|      * | ||||
|      * @return float | ||||
|      */ | ||||
|     public function getAmountBefore(TransactionJournal $journal, Transaction $transaction); | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionType $dbType | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function searchRelated($query, TransactionJournal $journal); | ||||
|     public function getJournalsOfType(TransactionType $dbType); | ||||
|  | ||||
|     /** | ||||
|      * @param array $types | ||||
|      * @param int   $offset | ||||
|      * @param int   $page | ||||
|      * | ||||
|      * @return LengthAwarePaginator | ||||
|      */ | ||||
|     public function getJournalsOfTypes(array $types, $offset, $page); | ||||
|  | ||||
|     /** | ||||
|      * @param $type | ||||
|      * | ||||
|      * @return TransactionType | ||||
|      */ | ||||
|     public function getTransactionType($type); | ||||
|  | ||||
|     /** | ||||
|      * @param        $id | ||||
|      * @param Carbon $date | ||||
|      * | ||||
|      * @return TransactionJournal | ||||
|      */ | ||||
|     public function getWithDate($id, Carbon $date); | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionJournal $journal | ||||
|      * @param array              $array | ||||
|      * | ||||
|      * @return void | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * @param TransactionJournal $journal | ||||
|      * @param array              $array | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function saveTags(TransactionJournal $journal, array $array); | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
| @@ -47,8 +107,10 @@ interface JournalRepositoryInterface | ||||
|     public function update(TransactionJournal $journal, array $data); | ||||
|  | ||||
|     /** | ||||
|      * Get users first transaction journal | ||||
|      * @return TransactionJournal | ||||
|      * @param TransactionJournal $journal | ||||
|      * @param array              $array | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function first(); | ||||
|     public function updateTags(TransactionJournal $journal, array $array); | ||||
| } | ||||
|   | ||||
| @@ -3,8 +3,10 @@ | ||||
| namespace FireflyIII\Repositories\PiggyBank; | ||||
|  | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use DB; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Models\PiggyBankEvent; | ||||
| use FireflyIII\Models\PiggyBankRepetition; | ||||
| use Illuminate\Support\Collection; | ||||
| use Navigation; | ||||
| @@ -17,8 +19,8 @@ use Navigation; | ||||
| class PiggyBankRepository implements PiggyBankRepositoryInterface | ||||
| { | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind. | ||||
|      * | ||||
|      * Based on the piggy bank, the reminder-setting and | ||||
|      * other variables this method tries to divide the piggy bank into equal parts. Each is | ||||
| @@ -68,6 +70,19 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface | ||||
|         return $bars; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * @param           $amount | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function createEvent(PiggyBank $piggyBank, $amount) | ||||
|     { | ||||
|         PiggyBankEvent::create(['date' => Carbon::now(), 'amount' => $amount, 'piggy_bank_id' => $piggyBank->id]); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      * | ||||
| @@ -86,6 +101,47 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface | ||||
|         return $part; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function destroy(PiggyBank $piggyBank) | ||||
|     { | ||||
|         return $piggyBank->delete(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getEventSummarySet(PiggyBank $piggyBank) | ||||
|     { | ||||
|         return DB::table('piggy_bank_events')->where('piggy_bank_id', $piggyBank->id)->groupBy('date')->get(['date', DB::Raw('SUM(`amount`) AS `sum`')]); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getEvents(PiggyBank $piggyBank) | ||||
|     { | ||||
|         return $piggyBank->piggyBankEvents()->orderBy('date', 'DESC')->orderBy('id', 'DESC')->get(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getPiggyBanks() | ||||
|     { | ||||
|         /** @var Collection $set */ | ||||
|         $set = Auth::user()->piggyBanks()->orderBy('order', 'ASC')->get(); | ||||
|  | ||||
|         return $set; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set all piggy banks to order 0. | ||||
|      * | ||||
| @@ -132,10 +188,11 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBank $account | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * @param array     $data | ||||
|      * | ||||
|      * @return PiggyBank | ||||
|      * @internal param PiggyBank $account | ||||
|      */ | ||||
|     public function update(PiggyBank $piggyBank, array $data) | ||||
|     { | ||||
|   | ||||
| @@ -14,9 +14,7 @@ use Illuminate\Support\Collection; | ||||
| interface PiggyBankRepositoryInterface | ||||
| { | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind. | ||||
|      * | ||||
|      * Based on the piggy bank, the reminder-setting and | ||||
|      * other variables this method tries to divide the piggy bank into equal parts. Each is | ||||
| @@ -28,6 +26,18 @@ interface PiggyBankRepositoryInterface | ||||
|      */ | ||||
|     public function calculateParts(PiggyBankRepetition $repetition); | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getPiggyBanks(); | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getEvents(PiggyBank $piggyBank); | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      * | ||||
| @@ -35,6 +45,28 @@ interface PiggyBankRepositoryInterface | ||||
|      */ | ||||
|     public function createPiggyBankPart(array $data); | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * @param           $amount | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function createEvent(PiggyBank $piggyBank, $amount); | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getEventSummarySet(PiggyBank $piggyBank); | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function destroy(PiggyBank $piggyBank); | ||||
|  | ||||
|     /** | ||||
|      * Set all piggy banks to order 0. | ||||
|      * | ||||
| @@ -62,7 +94,7 @@ interface PiggyBankRepositoryInterface | ||||
|     public function store(array $data); | ||||
|  | ||||
|     /** | ||||
|      * @param PiggyBank $account | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * @param array     $data | ||||
|      * | ||||
|      * @return PiggyBank | ||||
|   | ||||
							
								
								
									
										116
									
								
								app/Repositories/Reminder/ReminderRepository.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								app/Repositories/Reminder/ReminderRepository.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,116 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Repositories\Reminder; | ||||
|  | ||||
| use App; | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Models\Reminder; | ||||
| use Illuminate\Database\Eloquent\Builder; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * Class ReminderRepository | ||||
|  * | ||||
|  * @package FireflyIII\Repositories\Reminder | ||||
|  */ | ||||
| class ReminderRepository implements ReminderRepositoryInterface | ||||
| { | ||||
|     /** @var \FireflyIII\Helpers\Reminders\ReminderHelperInterface */ | ||||
|     protected $helper; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         /** @var \FireflyIII\Helpers\Reminders\ReminderHelperInterface helper */ | ||||
|         $this->helper = App::make('FireflyIII\Helpers\Reminders\ReminderHelperInterface'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getActiveReminders() | ||||
|     { | ||||
|         $today = new Carbon; | ||||
|         // active reminders: | ||||
|         $active = Auth::user()->reminders() | ||||
|                       ->where('notnow', 0) | ||||
|                       ->where('active', 1) | ||||
|                       ->where('startdate', '<=', $today->format('Y-m-d 00:00:00')) | ||||
|                       ->where('enddate', '>=', $today->format('Y-m-d 00:00:00')) | ||||
|                       ->get(); | ||||
|  | ||||
|         $active->each( | ||||
|             function (Reminder $reminder) { | ||||
|                 $reminder->description = $this->helper->getReminderText($reminder); | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         return $active; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getDismissedReminders() | ||||
|     { | ||||
|         $dismissed = Auth::user()->reminders() | ||||
|                          ->where('notnow', 1) | ||||
|                          ->get(); | ||||
|  | ||||
|         $dismissed->each( | ||||
|             function (Reminder $reminder) { | ||||
|                 $reminder->description = $this->helper->getReminderText($reminder); | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         return $dismissed; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getExpiredReminders() | ||||
|     { | ||||
|  | ||||
|         $expired = Auth::user()->reminders() | ||||
|                        ->where('notnow', 0) | ||||
|                        ->where('active', 1) | ||||
|                        ->where( | ||||
|                            function (Builder $q) { | ||||
|                                $today = new Carbon; | ||||
|                                $q->where('startdate', '>', $today->format('Y-m-d 00:00:00')); | ||||
|                                $q->orWhere('enddate', '<', $today->format('Y-m-d 00:00:00')); | ||||
|                            } | ||||
|                        )->get(); | ||||
|  | ||||
|         $expired->each( | ||||
|             function (Reminder $reminder) { | ||||
|                 $reminder->description = $this->helper->getReminderText($reminder); | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         return $expired; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getInactiveReminders() | ||||
|     { | ||||
|         $inactive = Auth::user()->reminders() | ||||
|                         ->where('active', 0) | ||||
|                         ->get(); | ||||
|  | ||||
|         $inactive->each( | ||||
|             function (Reminder $reminder) { | ||||
|                 $reminder->description = $this->helper->getReminderText($reminder); | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         return $inactive; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										35
									
								
								app/Repositories/Reminder/ReminderRepositoryInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								app/Repositories/Reminder/ReminderRepositoryInterface.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Repositories\Reminder; | ||||
|  | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Interface ReminderRepositoryInterface | ||||
|  * | ||||
|  * @package FireflyIII\Repositories\Reminder | ||||
|  */ | ||||
| interface ReminderRepositoryInterface | ||||
| { | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getActiveReminders(); | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getDismissedReminders(); | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getExpiredReminders(); | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getInactiveReminders(); | ||||
|  | ||||
| } | ||||
							
								
								
									
										180
									
								
								app/Repositories/Tag/TagRepository.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								app/Repositories/Tag/TagRepository.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,180 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Repositories\Tag; | ||||
|  | ||||
|  | ||||
| use Auth; | ||||
| use FireflyIII\Models\Tag; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Models\TransactionType; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * Class TagRepository | ||||
|  * | ||||
|  * @package FireflyIII\Repositories\Tag | ||||
|  */ | ||||
| class TagRepository implements TagRepositoryInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionJournal $journal | ||||
|      * @param Tag                $tag | ||||
|      * | ||||
|      * @return boolean | ||||
|      */ | ||||
|     public function connect(TransactionJournal $journal, Tag $tag) | ||||
|     { | ||||
|  | ||||
|         /* | ||||
|          * Already connected: | ||||
|          */ | ||||
|         if ($journal->tags()->find($tag->id)) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         if ($tag->tagMode == 'nothing') { | ||||
|             // save it, no problem: | ||||
|             $journal->tags()->save($tag); | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         /* | ||||
|          * get some withdrawal types: | ||||
|          */ | ||||
|         /** @var TransactionType $withdrawal */ | ||||
|         $withdrawal = TransactionType::whereType('Withdrawal')->first(); | ||||
|         /** @var TransactionType $deposit */ | ||||
|         $deposit = TransactionType::whereType('Deposit')->first(); | ||||
|         /** @var TransactionType $transfer */ | ||||
|         $transfer = TransactionType::whereType('Transfer')->first(); | ||||
|  | ||||
|         $withdrawals = $tag->transactionjournals()->where('transaction_type_id', $withdrawal->id)->count(); | ||||
|         $transfers   = $tag->transactionjournals()->where('transaction_type_id', $transfer->id)->count(); | ||||
|  | ||||
|         if ($tag->tagMode == 'balancingAct') { | ||||
|  | ||||
|             // only if this is the only withdrawal. | ||||
|             if ($journal->transaction_type_id == $withdrawal->id && $withdrawals < 1) { | ||||
|                 $journal->tags()->save($tag); | ||||
|  | ||||
|                 return true; | ||||
|             } | ||||
|             // and only if this is the only transfer | ||||
|             if ($journal->transaction_type_id == $transfer->id && $transfers < 1) { | ||||
|                 $journal->tags()->save($tag); | ||||
|  | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             // ignore expense | ||||
|             return false; | ||||
|         } | ||||
|         if ($tag->tagMode == 'advancePayment') { | ||||
|  | ||||
|  | ||||
|             // only if this is the only withdrawal | ||||
|             if ($journal->transaction_type_id == $withdrawal->id && $withdrawals < 1) { | ||||
|                 $journal->tags()->save($tag); | ||||
|  | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             // only if this is a deposit. | ||||
|             if ($journal->transaction_type_id == $deposit->id) { | ||||
|  | ||||
|                 // if this is a deposit, account must match the current only journal | ||||
|                 // (if already present): | ||||
|                 $currentWithdrawal = $tag->transactionjournals()->where('transaction_type_id', $withdrawal->id)->first(); | ||||
|  | ||||
|                 if ($currentWithdrawal && $currentWithdrawal->assetAccount->id == $journal->assetAccount->id) { | ||||
|                     $journal->tags()->save($tag); | ||||
|  | ||||
|                     return true; | ||||
|                 } else { | ||||
|                     if (is_null($currentWithdrawal)) { | ||||
|                         $journal->tags()->save($tag); | ||||
|  | ||||
|                         return true; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Tag $tag | ||||
|      * | ||||
|      * @return boolean | ||||
|      */ | ||||
|     public function destroy(Tag $tag) | ||||
|     { | ||||
|         $tag->delete(); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function get() | ||||
|     { | ||||
|         /** @var Collection $tags */ | ||||
|         $tags = Auth::user()->tags()->get(); | ||||
|         $tags->sortBy( | ||||
|             function (Tag $tag) { | ||||
|                 return $tag->tag; | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         return $tags; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      * | ||||
|      * @return Tag | ||||
|      */ | ||||
|     public function store(array $data) | ||||
|     { | ||||
|         $tag              = new Tag; | ||||
|         $tag->tag         = $data['tag']; | ||||
|         $tag->date        = $data['date']; | ||||
|         $tag->description = $data['description']; | ||||
|         $tag->latitude    = $data['latitude']; | ||||
|         $tag->longitude   = $data['longitude']; | ||||
|         $tag->zoomLevel   = $data['zoomLevel']; | ||||
|         $tag->tagMode     = $data['tagMode']; | ||||
|         $tag->user()->associate(Auth::user()); | ||||
|         $tag->save(); | ||||
|  | ||||
|         return $tag; | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Tag   $tag | ||||
|      * @param array $data | ||||
|      * | ||||
|      * @return Tag | ||||
|      */ | ||||
|     public function update(Tag $tag, array $data) | ||||
|     { | ||||
|         $tag->tag         = $data['tag']; | ||||
|         $tag->date        = $data['date']; | ||||
|         $tag->description = $data['description']; | ||||
|         $tag->latitude    = $data['latitude']; | ||||
|         $tag->longitude   = $data['longitude']; | ||||
|         $tag->zoomLevel   = $data['zoomLevel']; | ||||
|         $tag->tagMode     = $data['tagMode']; | ||||
|         $tag->save(); | ||||
|  | ||||
|         return $tag; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										52
									
								
								app/Repositories/Tag/TagRepositoryInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								app/Repositories/Tag/TagRepositoryInterface.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Repositories\Tag; | ||||
|  | ||||
| use FireflyIII\Models\Tag; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Interface TagRepositoryInterface | ||||
|  * | ||||
|  * @package FireflyIII\Repositories\Tag | ||||
|  */ | ||||
| interface TagRepositoryInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      * | ||||
|      * @return Tag | ||||
|      */ | ||||
|     public function store(array $data); | ||||
|  | ||||
|     /** | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function get(); | ||||
|  | ||||
|     /** | ||||
|      * @param Tag   $tag | ||||
|      * @param array $data | ||||
|      * | ||||
|      * @return Tag | ||||
|      */ | ||||
|     public function update(Tag $tag, array $data); | ||||
|  | ||||
|     /** | ||||
|      * @param Tag $tag | ||||
|      * | ||||
|      * @return boolean | ||||
|      */ | ||||
|     public function destroy(Tag $tag); | ||||
|  | ||||
|     /** | ||||
|      * @param TransactionJournal $journal | ||||
|      * @param Tag                $tag | ||||
|      * | ||||
|      * @return boolean | ||||
|      */ | ||||
|     public function connect(TransactionJournal $journal, Tag $tag); | ||||
| } | ||||
| @@ -84,9 +84,11 @@ class Amount | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return string | ||||
|      * | ||||
|      * @param TransactionJournal $journal | ||||
|      * @param bool               $coloured | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function formatJournal(TransactionJournal $journal, $coloured = true) | ||||
|     { | ||||
| @@ -151,23 +153,25 @@ class Amount | ||||
|         if (defined('FFCURRENCYCODE')) { | ||||
|             return FFCURRENCYCODE; | ||||
|         } | ||||
|         if (Cache::has('FFCURRENCYCODE')) { | ||||
|             define('FFCURRENCYCODE', Cache::get('FFCURRENCYCODE')); | ||||
|  | ||||
|             return FFCURRENCYCODE; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         $currencyPreference = Prefs::get('currencyPreference', 'EUR'); | ||||
|         $currency           = TransactionCurrency::whereCode($currencyPreference->data)->first(); | ||||
|  | ||||
|         \Cache::forever('FFCURRENCYCODE', $currency->code); | ||||
|         $currency = TransactionCurrency::whereCode($currencyPreference->data)->first(); | ||||
|         if ($currency) { | ||||
|  | ||||
|         define('FFCURRENCYCODE', $currency->code); | ||||
|             Cache::forever('FFCURRENCYCODE', $currency->code); | ||||
|             define('FFCURRENCYCODE', $currency->code); | ||||
|  | ||||
|         return $currency->code; | ||||
|             return $currency->code; | ||||
|         } | ||||
|  | ||||
|         return 'EUR'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return mixed|static | ||||
|      */ | ||||
|     public function getDefaultCurrency() | ||||
|     { | ||||
|         $currencyPreference = Prefs::get('currencyPreference', 'EUR'); | ||||
|   | ||||
| @@ -62,7 +62,10 @@ class ExpandedForm | ||||
|             'account_id'           => 'Asset account', | ||||
|             'budget_id'            => 'Budget', | ||||
|             'openingBalance'       => 'Opening balance', | ||||
|             'tagMode'              => 'Tag mode', | ||||
|             'tagPosition'          => 'Tag location', | ||||
|             'virtualBalance'       => 'Virtual balance', | ||||
|             'longitude_latitude'   => 'Location', | ||||
|             'targetamount'         => 'Target amount', | ||||
|             'accountRole'          => 'Account role', | ||||
|             'openingBalanceDate'   => 'Opening balance date', | ||||
| @@ -194,24 +197,6 @@ class ExpandedForm | ||||
|         return $html; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param       $name | ||||
|      * @param null  $value | ||||
|      * @param array $options | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function month($name, $value = null, array $options = []) | ||||
|     { | ||||
|         $label   = $this->label($name, $options); | ||||
|         $options = $this->expandOptionArray($name, $label, $options); | ||||
|         $classes = $this->getHolderClasses($name); | ||||
|         $value   = $this->fillFieldValue($name, $value); | ||||
|         $html    = View::make('form.month', compact('classes', 'name', 'label', 'value', 'options'))->render(); | ||||
|  | ||||
|         return $html; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param       $name | ||||
|      * @param null  $value | ||||
| @@ -233,12 +218,30 @@ class ExpandedForm | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind. | ||||
|      * @param       $name | ||||
|      * @param null  $value | ||||
|      * @param array $options | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function location($name, $value = null, array $options = []) | ||||
|     { | ||||
|         $label   = $this->label($name, $options); | ||||
|         $options = $this->expandOptionArray($name, $label, $options); | ||||
|         $classes = $this->getHolderClasses($name); | ||||
|         $value   = $this->fillFieldValue($name, $value); | ||||
|         $html    = View::make('form.location', compact('classes', 'name', 'label', 'value', 'options'))->render(); | ||||
|  | ||||
|         return $html; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * Takes any collection and tries to make a sensible select list compatible array of it. | ||||
|      * | ||||
|      * @param Collection $set | ||||
|      * @param bool       $addEmpty | ||||
|      * @param \Illuminate\Support\Collection $set | ||||
|      * @param bool                           $addEmpty | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
| @@ -265,6 +268,46 @@ class ExpandedForm | ||||
|         return $selectList; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param       $name | ||||
|      * @param null  $value | ||||
|      * @param array $options | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function month($name, $value = null, array $options = []) | ||||
|     { | ||||
|         $label   = $this->label($name, $options); | ||||
|         $options = $this->expandOptionArray($name, $label, $options); | ||||
|         $classes = $this->getHolderClasses($name); | ||||
|         $value   = $this->fillFieldValue($name, $value); | ||||
|         $html    = View::make('form.month', compact('classes', 'name', 'label', 'value', 'options'))->render(); | ||||
|  | ||||
|         return $html; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param       $name | ||||
|      * @param array $list | ||||
|      * @param null  $selected | ||||
|      * @param array $options | ||||
|      * | ||||
|      * @return string | ||||
|      * @internal param null $value | ||||
|      */ | ||||
|     public function multiRadio($name, array $list = [], $selected = null, array $options = []) | ||||
|     { | ||||
|         $label    = $this->label($name, $options); | ||||
|         $options  = $this->expandOptionArray($name, $label, $options); | ||||
|         $classes  = $this->getHolderClasses($name); | ||||
|         $selected = $this->fillFieldValue($name, $selected); | ||||
|  | ||||
|         unset($options['class']); | ||||
|         $html = View::make('form.multiRadio', compact('classes', 'name', 'label', 'selected', 'options', 'list'))->render(); | ||||
|  | ||||
|         return $html; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $type | ||||
|      * @param $name | ||||
| @@ -336,4 +379,24 @@ class ExpandedForm | ||||
|         return $html; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param       $name | ||||
|      * @param null  $value | ||||
|      * @param array $options | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function textarea($name, $value = null, array $options = []) | ||||
|     { | ||||
|         $label           = $this->label($name, $options); | ||||
|         $options         = $this->expandOptionArray($name, $label, $options); | ||||
|         $classes         = $this->getHolderClasses($name); | ||||
|         $value           = $this->fillFieldValue($name, $value); | ||||
|         $options['rows'] = 4; | ||||
|         $html            = View::make('form.textarea', compact('classes', 'name', 'label', 'value', 'options'))->render(); | ||||
|  | ||||
|         return $html; | ||||
|  | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -15,7 +15,7 @@ class Navigation | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon         $theDate | ||||
|      * @param \Carbon\Carbon $theDate | ||||
|      * @param                $repeatFreq | ||||
|      * @param                $skip | ||||
|      * | ||||
| @@ -64,10 +64,10 @@ class Navigation | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon         $theCurrentEnd | ||||
|      * @param \Carbon\Carbon $theCurrentEnd | ||||
|      * @param                $repeatFreq | ||||
|      * | ||||
|      * @return Carbon | ||||
|      * @return \Carbon\Carbon | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function endOfPeriod(Carbon $theCurrentEnd, $repeatFreq) | ||||
| @@ -148,9 +148,8 @@ class Navigation | ||||
|  | ||||
|         } | ||||
|         if (isset($specials[$repeatFreq])) { | ||||
|             $month = intval($theCurrentEnd->format('m')); | ||||
|             $currentEnd->endOfYear(); | ||||
|             if ($month <= 6) { | ||||
|             if ($theCurrentEnd->month <= 6) { | ||||
|                 $currentEnd->subMonths(6); | ||||
|             } | ||||
|         } | ||||
| @@ -184,7 +183,7 @@ class Navigation | ||||
|                 $date->lastOfQuarter()->addDay(); | ||||
|                 break; | ||||
|             case '6M': | ||||
|                 if (intval($date->format('m')) >= 7) { | ||||
|                 if ($date->month >= 7) { | ||||
|                     $date->startOfYear()->addYear(); | ||||
|                 } else { | ||||
|                     $date->startOfYear()->addMonths(6); | ||||
| @@ -230,9 +229,8 @@ class Navigation | ||||
|             return $date; | ||||
|         } | ||||
|         if ($range == '6M') { | ||||
|             $month = intval($date->format('m')); | ||||
|             $date->startOfYear(); | ||||
|             if ($month <= 6) { | ||||
|             if ($date->month <= 6) { | ||||
|                 $date->subMonths(6); | ||||
|             } | ||||
|  | ||||
| @@ -260,16 +258,15 @@ class Navigation | ||||
|             return $date->format($formatMap[$range]); | ||||
|         } | ||||
|         if ($range == '3M') { | ||||
|             $month = intval($date->format('m')); | ||||
|  | ||||
|             return 'Q' . ceil(($month / 12) * 4) . ' ' . $date->format('Y'); | ||||
|  | ||||
|             return 'Q' . ceil(($date->month / 12) * 4) . ' ' . $date->year; | ||||
|         } | ||||
|         if ($range == '6M') { | ||||
|             $month    = intval($date->format('m')); | ||||
|             $half     = ceil(($month / 12) * 2); | ||||
|             $half     = ceil(($date->month / 12) * 2); | ||||
|             $halfName = $half == 1 ? 'first' : 'second'; | ||||
|  | ||||
|             return $halfName . ' half of ' . $date->format('Y'); | ||||
|             return $halfName . ' half of ' . $date->year; | ||||
|         } | ||||
|         throw new FireflyException('No _periodName() for range "' . $range . '"'); | ||||
|     } | ||||
| @@ -301,10 +298,10 @@ class Navigation | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Carbon         $theDate | ||||
|      * @param \Carbon\Carbon $theDate | ||||
|      * @param                $repeatFreq | ||||
|      * | ||||
|      * @return Carbon | ||||
|      * @return \Carbon\Carbon | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function startOfPeriod(Carbon $theDate, $repeatFreq) | ||||
| @@ -333,7 +330,7 @@ class Navigation | ||||
|             return $date; | ||||
|         } | ||||
|         if ($repeatFreq == 'half-year' || $repeatFreq == '6M') { | ||||
|             $month = intval($date->format('m')); | ||||
|             $month = $date->month; | ||||
|             $date->startOfYear(); | ||||
|             if ($month >= 7) { | ||||
|                 $date->addMonths(6); | ||||
| @@ -388,9 +385,9 @@ class Navigation | ||||
|  | ||||
|     /** | ||||
|      * @param        $range | ||||
|      * @param Carbon $start | ||||
|      * @param \Carbon\Carbon $start | ||||
|      * | ||||
|      * @return Carbon | ||||
|      * @return \Carbon\Carbon | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function updateEndDate($range, Carbon $start) | ||||
| @@ -411,7 +408,7 @@ class Navigation | ||||
|             return $end; | ||||
|         } | ||||
|         if ($range == '6M') { | ||||
|             if (intval($start->format('m')) >= 7) { | ||||
|             if ($start->month >= 7) { | ||||
|                 $end->endOfYear(); | ||||
|             } else { | ||||
|                 $end->startOfYear()->addMonths(6); | ||||
| @@ -423,10 +420,10 @@ class Navigation | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param        $range | ||||
|      * @param Carbon $start | ||||
|      * @param                $range | ||||
|      * @param \Carbon\Carbon $start | ||||
|      * | ||||
|      * @return Carbon | ||||
|      * @return \Carbon\Carbon | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function updateStartDate($range, Carbon $start) | ||||
| @@ -445,7 +442,7 @@ class Navigation | ||||
|             return $start; | ||||
|         } | ||||
|         if ($range == '6M') { | ||||
|             if (intval($start->format('m')) >= 7) { | ||||
|             if ($start->month >= 7) { | ||||
|                 $start->startOfYear()->addMonths(6); | ||||
|             } else { | ||||
|                 $start->startOfYear(); | ||||
|   | ||||
| @@ -16,7 +16,7 @@ class Preferences | ||||
|      * @param      $name | ||||
|      * @param null $default | ||||
|      * | ||||
|      * @return null|Preference | ||||
|      * @return null|\FireflyIII\Models\Preference | ||||
|      */ | ||||
|     public function get($name, $default = null) | ||||
|     { | ||||
|   | ||||
| @@ -84,7 +84,6 @@ class Search implements SearchInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||
|      * | ||||
|      * @param array $words | ||||
|      * | ||||
| @@ -122,6 +121,7 @@ class Search implements SearchInterface | ||||
|                         return $journal; | ||||
|                     } | ||||
|                 } | ||||
|                 return null; | ||||
|  | ||||
|             } | ||||
|         ); | ||||
|   | ||||
| @@ -17,8 +17,8 @@ class Steam | ||||
| { | ||||
|     /** | ||||
|      * | ||||
|      * @param Account $account | ||||
|      * @param Carbon  $date | ||||
|      * @param \FireflyIII\Models\Account $account | ||||
|      * @param \Carbon\Carbon  $date | ||||
|      * @param bool    $ignoreVirtualBalance | ||||
|      * | ||||
|      * @return float | ||||
| @@ -67,8 +67,8 @@ class Steam | ||||
|     public function limitArray(array $array, $limit = 10) | ||||
|     { | ||||
|         $others = [ | ||||
|             'name'   => 'Others', | ||||
|             'amount' => 0 | ||||
|             'name'        => 'Others', | ||||
|             'queryAmount' => 0 | ||||
|         ]; | ||||
|         $return = []; | ||||
|         $count  = 0; | ||||
| @@ -76,7 +76,7 @@ class Steam | ||||
|             if ($count < ($limit - 1)) { | ||||
|                 $return[$id] = $entry; | ||||
|             } else { | ||||
|                 $others['amount'] += $entry['amount']; | ||||
|                 $others['queryAmount'] += $entry['queryAmount']; | ||||
|             } | ||||
|  | ||||
|             $count++; | ||||
| @@ -91,7 +91,7 @@ class Steam | ||||
|      * Turns a collection into an array. Needs the field 'id' for the key, | ||||
|      * and saves only 'name' and 'amount' as a sub array. | ||||
|      * | ||||
|      * @param Collection $collection | ||||
|      * @param \Illuminate\Support\Collection $collection | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
| @@ -103,14 +103,16 @@ class Steam | ||||
|             $id           = intval($entry->id); | ||||
|             if (isset($array[$id])) { | ||||
|                 $array[$id]['amount'] += floatval($entry->amount); | ||||
|                 $array[$id]['queryAmount'] += floatval($entry->queryAmount); | ||||
|                 $array[$id]['spent'] += floatval($entry->spent); | ||||
|                 $array[$id]['encrypted'] = intval($entry->encrypted); | ||||
|             } else { | ||||
|                 $array[$id] = [ | ||||
|                     'amount'    => floatval($entry->amount), | ||||
|                     'spent'     => floatval($entry->spent), | ||||
|                     'encrypted' => intval($entry->encrypted), | ||||
|                     'name'      => $entry->name | ||||
|                     'amount'      => floatval($entry->amount), | ||||
|                     'queryAmount' => floatval($entry->queryAmount), | ||||
|                     'spent'       => floatval($entry->spent), | ||||
|                     'encrypted'   => intval($entry->encrypted), | ||||
|                     'name'        => $entry->name | ||||
|                 ]; | ||||
|             } | ||||
|         } | ||||
| @@ -131,7 +133,7 @@ class Steam | ||||
|         foreach ($two as $id => $value) { | ||||
|             // $otherId also exists in $one: | ||||
|             if (isset($one[$id])) { | ||||
|                 $one[$id]['amount'] += $value['amount']; | ||||
|                 $one[$id]['queryAmount'] += $value['queryAmount']; | ||||
|                 $one[$id]['spent'] += $value['spent']; | ||||
|             } else { | ||||
|                 $one[$id] = $value; | ||||
| @@ -170,11 +172,11 @@ class Steam | ||||
|     { | ||||
|         uasort( | ||||
|             $array, function ($left, $right) { | ||||
|             if ($left['amount'] == $right['amount']) { | ||||
|             if ($left['queryAmount'] == $right['queryAmount']) { | ||||
|                 return 0; | ||||
|             } | ||||
|  | ||||
|             return ($left['amount'] < $right['amount']) ? 1 : -1; | ||||
|             return ($left['queryAmount'] < $right['queryAmount']) ? 1 : -1; | ||||
|         } | ||||
|         ); | ||||
|  | ||||
| @@ -193,11 +195,11 @@ class Steam | ||||
|     { | ||||
|         uasort( | ||||
|             $array, function ($left, $right) { | ||||
|             if ($left['amount'] == $right['amount']) { | ||||
|             if ($left['queryAmount'] == $right['queryAmount']) { | ||||
|                 return 0; | ||||
|             } | ||||
|  | ||||
|             return ($left['amount'] < $right['amount']) ? -1 : 1; | ||||
|             return ($left['queryAmount'] < $right['queryAmount']) ? -1 : 1; | ||||
|         } | ||||
|         ); | ||||
|  | ||||
|   | ||||
							
								
								
									
										53
									
								
								app/Support/Twig/Budget.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								app/Support/Twig/Budget.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Support\Twig; | ||||
|  | ||||
| use Auth; | ||||
| use DB; | ||||
| use FireflyIII\Models\LimitRepetition; | ||||
| use Twig_Extension; | ||||
| use Twig_SimpleFunction; | ||||
|  | ||||
| /** | ||||
|  * Class Budget | ||||
|  * | ||||
|  * @package FireflyIII\Support\Twig | ||||
|  */ | ||||
| class Budget extends Twig_Extension | ||||
| { | ||||
|     /** | ||||
|      * {@inheritDoc} | ||||
|      */ | ||||
|     public function getFunctions() | ||||
|     { | ||||
|         $functions[] = new Twig_SimpleFunction( | ||||
|             'spentInRepetition', function (LimitRepetition $repetition) { | ||||
|             $sum = DB::table('transactions') | ||||
|                      ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') | ||||
|                      ->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') | ||||
|                      ->leftJoin('budget_limits', 'budget_limits.budget_id', '=', 'budget_transaction_journal.budget_id') | ||||
|                      ->leftJoin('limit_repetitions', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id') | ||||
|                      ->where('transaction_journals.date', '>=', $repetition->startdate->format('Y-m-d')) | ||||
|                      ->where('transaction_journals.date', '<=', $repetition->enddate->format('Y-m-d')) | ||||
|                      ->where('transaction_journals.user_id', Auth::user()->id) | ||||
|                      ->whereNull('transactions.deleted_at') | ||||
|                      ->where('transactions.amount', '>', 0) | ||||
|                      ->where('limit_repetitions.id', '=', $repetition->id) | ||||
|                      ->sum('transactions.amount'); | ||||
|  | ||||
|             return floatval($sum); | ||||
|         } | ||||
|         ); | ||||
|  | ||||
|         return $functions; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * {@inheritDoc} | ||||
|      */ | ||||
|     public function getName() | ||||
|     { | ||||
|         return 'FireflyIII\Support\Twig\Budget'; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										146
									
								
								app/Support/Twig/General.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								app/Support/Twig/General.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,146 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Support\Twig; | ||||
|  | ||||
| use App; | ||||
| use Config; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use Route; | ||||
| use Twig_Extension; | ||||
| use Twig_SimpleFilter; | ||||
| use Twig_SimpleFunction; | ||||
|  | ||||
| /** | ||||
|  * Class TwigSupport | ||||
|  * | ||||
|  * @package FireflyIII\Support | ||||
|  */ | ||||
| class General extends Twig_Extension | ||||
| { | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getFilters() | ||||
|     { | ||||
|         $filters = []; | ||||
|  | ||||
|         $filters[] = new Twig_SimpleFilter( | ||||
|             'formatAmount', function ($string) { | ||||
|             return App::make('amount')->format($string); | ||||
|         }, ['is_safe' => ['html']] | ||||
|         ); | ||||
|  | ||||
|         $filters[] = new Twig_SimpleFilter( | ||||
|             'formatTransaction', function (Transaction $transaction) { | ||||
|             return App::make('amount')->formatTransaction($transaction); | ||||
|         }, ['is_safe' => ['html']] | ||||
|         ); | ||||
|  | ||||
|         $filters[] = new Twig_SimpleFilter( | ||||
|             'formatAmountPlain', function ($string) { | ||||
|             return App::make('amount')->format($string, false); | ||||
|         }, ['is_safe' => ['html']] | ||||
|         ); | ||||
|  | ||||
|         $filters[] = new Twig_SimpleFilter( | ||||
|             'formatJournal', function ($journal) { | ||||
|             return App::make('amount')->formatJournal($journal); | ||||
|         }, ['is_safe' => ['html']] | ||||
|         ); | ||||
|  | ||||
|         $filters[] = new Twig_SimpleFilter( | ||||
|             'balance', function (Account $account = null) { | ||||
|             if (is_null($account)) { | ||||
|                 return 'NULL'; | ||||
|             } | ||||
|  | ||||
|             return App::make('steam')->balance($account); | ||||
|         } | ||||
|         ); | ||||
|  | ||||
|         // should be a function but OK | ||||
|         $filters[] = new Twig_SimpleFilter( | ||||
|             'getAccountRole', function ($name) { | ||||
|             return Config::get('firefly.accountRoles.' . $name); | ||||
|         } | ||||
|         ); | ||||
|  | ||||
|         return $filters; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * {@inheritDoc} | ||||
|      */ | ||||
|     public function getFunctions() | ||||
|     { | ||||
|         $functions = []; | ||||
|  | ||||
|         $functions[] = new Twig_SimpleFunction( | ||||
|             'getCurrencyCode', function () { | ||||
|             return App::make('amount')->getCurrencyCode(); | ||||
|         } | ||||
|         ); | ||||
|  | ||||
|         $functions[] = new Twig_SimpleFunction( | ||||
|             'getCurrencySymbol', function () { | ||||
|             return App::make('amount')->getCurrencySymbol(); | ||||
|         } | ||||
|         ); | ||||
|  | ||||
|         $functions[] = new Twig_SimpleFunction( | ||||
|             'phpdate', function ($str) { | ||||
|             return date($str); | ||||
|         } | ||||
|         ); | ||||
|  | ||||
|  | ||||
|         $functions[] = new Twig_SimpleFunction( | ||||
|             'env', function ($name, $default) { | ||||
|             return env($name, $default); | ||||
|         } | ||||
|         ); | ||||
|  | ||||
|         $functions[] = new Twig_SimpleFunction( | ||||
|             'activeRoute', function ($context) { | ||||
|             $args       = func_get_args(); | ||||
|             $route      = $args[1]; | ||||
|             $what       = isset($args[2]) ? $args[2] : false; | ||||
|             $strict     = isset($args[3]) ? $args[3] : false; | ||||
|             $activeWhat = isset($context['what']) ? $context['what'] : false; | ||||
|  | ||||
|             // activeRoute | ||||
|             if (!($what === false)) { | ||||
|                 if ($what == $activeWhat && Route::getCurrentRoute()->getName() == $route) { | ||||
|                     return 'active because-active-what'; | ||||
|                 } | ||||
|             } else { | ||||
|                 if (!$strict && !(strpos(Route::getCurrentRoute()->getName(), $route) === false)) { | ||||
|                     return 'active because-route-matches-non-strict'; | ||||
|                 } else { | ||||
|                     if ($strict && Route::getCurrentRoute()->getName() == $route) { | ||||
|                         return 'active because-route-matches-strict'; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return 'not-xxx-at-all'; | ||||
|         }, ['needs_context' => true] | ||||
|         ); | ||||
|  | ||||
|         return $functions; | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * {@inheritDoc} | ||||
|      */ | ||||
|     public function getName() | ||||
|     { | ||||
|         return 'FireflyIII\Support\Twig\General'; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										99
									
								
								app/Support/Twig/Journal.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								app/Support/Twig/Journal.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,99 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Support\Twig; | ||||
|  | ||||
|  | ||||
| use App; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Twig_Extension; | ||||
| use Twig_SimpleFilter; | ||||
| use Twig_SimpleFunction; | ||||
|  | ||||
| /** | ||||
|  * Class Journal | ||||
|  * | ||||
|  * @package FireflyIII\Support\Twig | ||||
|  */ | ||||
| class Journal extends Twig_Extension | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getFilters() | ||||
|     { | ||||
|         $filters = []; | ||||
|  | ||||
|         $filters[] = new Twig_SimpleFilter( | ||||
|             'typeIcon', function (TransactionJournal $journal) { | ||||
|             $type = $journal->transactionType->type; | ||||
|             if ($type == 'Withdrawal') { | ||||
|                 return '<span class="glyphicon glyphicon-arrow-left" title="Withdrawal"></span>'; | ||||
|             } | ||||
|             if ($type == 'Deposit') { | ||||
|                 return '<span class="glyphicon glyphicon-arrow-right" title="Deposit"></span>'; | ||||
|             } | ||||
|             if ($type == 'Transfer') { | ||||
|                 return '<i class="fa fa-fw fa-exchange" title="Transfer"></i>'; | ||||
|             } | ||||
|             if ($type == 'Opening balance') { | ||||
|                 return '<span class="glyphicon glyphicon-ban-circle" title="Opening balance"></span>'; | ||||
|             } | ||||
|             return ''; | ||||
|  | ||||
|         }, ['is_safe' => ['html']] | ||||
|         ); | ||||
|  | ||||
|         return $filters; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getFunctions() | ||||
|     { | ||||
|         $functions = []; | ||||
|  | ||||
|         $functions[] = new Twig_SimpleFunction( | ||||
|             'invalidJournal', function (TransactionJournal $journal) { | ||||
|             if (!isset($journal->transactions[1]) || !isset($journal->transactions[0])) { | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|         ); | ||||
|  | ||||
|         $functions[] = new Twig_SimpleFunction( | ||||
|             'relevantTags', function (TransactionJournal $journal) { | ||||
|             if ($journal->tags->count() == 0) { | ||||
|                 return App::make('amount')->formatJournal($journal); | ||||
|             } | ||||
|             foreach ($journal->tags as $tag) { | ||||
|                 if ($tag->tagMode == 'balancingAct') { | ||||
|                     // return tag formatted for a "balancing act". | ||||
|                     $amount = App::make('amount')->formatJournal($journal, false); | ||||
|  | ||||
|                     return '<a href="' . route('tags.show', $tag->id) . '" class="label label-success" title="' . $amount | ||||
|                            . '"><i class="fa fa-fw fa-refresh"></i> ' . $tag->tag . '</span>'; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|  | ||||
|             return 'TODO: ' . $journal->amount; | ||||
|         } | ||||
|         ); | ||||
|  | ||||
|         return $functions; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns the name of the extension. | ||||
|      * | ||||
|      * @return string The extension name | ||||
|      */ | ||||
|     public function getName() | ||||
|     { | ||||
|         return 'FireflyIII\Support\Twig\Journals'; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										42
									
								
								app/Support/Twig/PiggyBank.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								app/Support/Twig/PiggyBank.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| <?php | ||||
|  | ||||
| namespace FireflyIII\Support\Twig; | ||||
|  | ||||
| use FireflyIII\Models\PiggyBank as PB; | ||||
| use Twig_Extension; | ||||
| use Twig_SimpleFunction; | ||||
|  | ||||
| /** | ||||
|  * Class PiggyBank | ||||
|  * | ||||
|  * @package FireflyIII\Support\Twig | ||||
|  */ | ||||
| class PiggyBank extends Twig_Extension | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function getFunctions() | ||||
|     { | ||||
|         $functions = []; | ||||
|  | ||||
|         $functions[] = new Twig_SimpleFunction( | ||||
|             'currentRelevantRepAmount', function (PB $piggyBank) { | ||||
|             return $piggyBank->currentRelevantRep()->currentamount; | ||||
|         } | ||||
|         ); | ||||
|  | ||||
|         return $functions; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns the name of the extension. | ||||
|      * | ||||
|      * @return string The extension name | ||||
|      */ | ||||
|     public function getName() | ||||
|     { | ||||
|         return 'FireflyIII\Support\Twig\PiggyBank'; | ||||
|     } | ||||
| } | ||||
| @@ -43,6 +43,14 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon | ||||
|         return $this->hasMany('FireflyIII\Models\Account'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\HasMany | ||||
|      */ | ||||
|     public function tags() | ||||
|     { | ||||
|         return $this->hasMany('FireflyIII\Models\Tag'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\HasMany | ||||
|      */ | ||||
|   | ||||
| @@ -13,6 +13,7 @@ use Illuminate\Contracts\Encryption\DecryptException; | ||||
| use Illuminate\Validation\Validator; | ||||
| use Log; | ||||
| use Navigation; | ||||
| use Symfony\Component\Translation\TranslatorInterface; | ||||
|  | ||||
| /** | ||||
|  * Class FireflyValidator | ||||
| @@ -22,6 +23,18 @@ use Navigation; | ||||
| class FireflyValidator extends Validator | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param TranslatorInterface $translator | ||||
|      * @param array               $data | ||||
|      * @param array               $rules | ||||
|      * @param array               $messages | ||||
|      * @param array               $customAttributes | ||||
|      */ | ||||
|     public function __construct(TranslatorInterface $translator, array $data, array $rules, array $messages = [], array $customAttributes = []) | ||||
|     { | ||||
|         parent::__construct($translator, $data, $rules, $messages); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $attribute | ||||
|      * @param $value | ||||
| @@ -181,12 +194,22 @@ class FireflyValidator extends Validator | ||||
|      */ | ||||
|     public function validateUniqueObjectForUser($attribute, $value, $parameters) | ||||
|     { | ||||
|         $table     = $parameters[0]; | ||||
|         $field     = $parameters[1]; | ||||
|         $encrypted = isset($parameters[2]) ? $parameters[2] : 'encrypted'; | ||||
|         $exclude   = isset($parameters[3]) ? $parameters[3] : null; | ||||
|         $table           = $parameters[0]; | ||||
|         $field           = $parameters[1]; | ||||
|         $encrypted       = isset($parameters[2]) ? $parameters[2] : 'encrypted'; | ||||
|         $exclude         = isset($parameters[3]) ? $parameters[3] : null; | ||||
|         $alwaysEncrypted = false; | ||||
|         if ($encrypted == 'TRUE') { | ||||
|             $alwaysEncrypted = true; | ||||
|         } | ||||
|  | ||||
|         if (is_null(Auth::user())) { | ||||
|             // user is not logged in.. weird. | ||||
|             return true; | ||||
|         } else { | ||||
|             $query = DB::table($table)->where('user_id', Auth::user()->id); | ||||
|         } | ||||
|  | ||||
|         $query = DB::table($table)->where('user_id', Auth::user()->id); | ||||
|  | ||||
|         if (!is_null($exclude)) { | ||||
|             $query->where('id', '!=', $exclude); | ||||
| @@ -195,8 +218,12 @@ class FireflyValidator extends Validator | ||||
|  | ||||
|         $set = $query->get(); | ||||
|         foreach ($set as $entry) { | ||||
|             $isEncrypted = intval($entry->$encrypted) == 1 ? true : false; | ||||
|             $checkValue  = $isEncrypted ? Crypt::decrypt($entry->$field) : $entry->$field; | ||||
|             if (!$alwaysEncrypted) { | ||||
|                 $isEncrypted = intval($entry->$encrypted) == 1 ? true : false; | ||||
|             } else { | ||||
|                 $isEncrypted = true; | ||||
|             } | ||||
|             $checkValue = $isEncrypted ? Crypt::decrypt($entry->$field) : $entry->$field; | ||||
|             if ($checkValue == $value) { | ||||
|                 return false; | ||||
|             } | ||||
| @@ -223,10 +250,10 @@ class FireflyValidator extends Validator | ||||
|         } | ||||
|         $set = $query->get(['piggy_banks.*']); | ||||
|  | ||||
|         foreach($set as $entry) { | ||||
|         foreach ($set as $entry) { | ||||
|             $isEncrypted = intval($entry->encrypted) == 1 ? true : false; | ||||
|             $checkValue = $isEncrypted ? Crypt::decrypt($entry->name) : $entry->name; | ||||
|             if($checkValue == $value) { | ||||
|             $checkValue  = $isEncrypted ? Crypt::decrypt($entry->name) : $entry->name; | ||||
|             if ($checkValue == $value) { | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -11,6 +11,7 @@ | ||||
| | | ||||
| */ | ||||
|  | ||||
|  | ||||
| $app = new Illuminate\Foundation\Application( | ||||
|     realpath(__DIR__ . '/../') | ||||
| ); | ||||
| @@ -26,6 +27,8 @@ $app = new Illuminate\Foundation\Application( | ||||
| | | ||||
| */ | ||||
|  | ||||
|  | ||||
|  | ||||
| $app->singleton( | ||||
|     'Illuminate\Contracts\Http\Kernel', | ||||
|     'FireflyIII\Http\Kernel' | ||||
| @@ -41,6 +44,9 @@ $app->singleton( | ||||
|     'FireflyIII\Exceptions\Handler' | ||||
| ); | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
| |-------------------------------------------------------------------------- | ||||
| | Return The Application | ||||
|   | ||||
| @@ -26,7 +26,9 @@ | ||||
|         "watson/validating": "~1.0", | ||||
|         "doctrine/dbal": "~2.5", | ||||
|         "illuminate/html": "~5.0", | ||||
|         "league/commonmark": "0.7.*" | ||||
|         "league/commonmark": "0.7.*", | ||||
|         "rcrowe/twigbridge": "0.7.x@dev", | ||||
|         "twig/extensions": "~1.2" | ||||
|     }, | ||||
|     "require-dev": { | ||||
|         "barryvdh/laravel-debugbar": "@stable", | ||||
|   | ||||
							
								
								
									
										412
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										412
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							| @@ -4,24 +4,24 @@ | ||||
|         "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", | ||||
|         "This file is @generated automatically" | ||||
|     ], | ||||
|     "hash": "0d43c4c85607c5cdc901cde2d18b75d5", | ||||
|     "hash": "e3e90dd365b74f4878cf3b5b4a1c4007", | ||||
|     "packages": [ | ||||
|         { | ||||
|             "name": "classpreloader/classpreloader", | ||||
|             "version": "1.2.0", | ||||
|             "version": "1.3.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/ClassPreloader/ClassPreloader.git", | ||||
|                 "reference": "f0bfbf71fb3335c9473f695d4d966ba2fb879a9f" | ||||
|                 "reference": "0544616ba33fb2a6b792b3a7822650810c6d65d9" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/ClassPreloader/ClassPreloader/zipball/f0bfbf71fb3335c9473f695d4d966ba2fb879a9f", | ||||
|                 "reference": "f0bfbf71fb3335c9473f695d4d966ba2fb879a9f", | ||||
|                 "url": "https://api.github.com/repos/ClassPreloader/ClassPreloader/zipball/0544616ba33fb2a6b792b3a7822650810c6d65d9", | ||||
|                 "reference": "0544616ba33fb2a6b792b3a7822650810c6d65d9", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "nikic/php-parser": "~1.0", | ||||
|                 "nikic/php-parser": "^1.2.2", | ||||
|                 "php": ">=5.3.3", | ||||
|                 "symfony/console": "~2.1", | ||||
|                 "symfony/filesystem": "~2.1", | ||||
| @@ -36,7 +36,7 @@ | ||||
|             "type": "library", | ||||
|             "extra": { | ||||
|                 "branch-alias": { | ||||
|                     "dev-master": "1.2-dev" | ||||
|                     "dev-master": "1.3-dev" | ||||
|                 } | ||||
|             }, | ||||
|             "autoload": { | ||||
| @@ -64,7 +64,7 @@ | ||||
|                 "class", | ||||
|                 "preload" | ||||
|             ], | ||||
|             "time": "2015-01-26 22:06:19" | ||||
|             "time": "2015-04-15 21:59:30" | ||||
|         }, | ||||
|         { | ||||
|             "name": "danielstjules/stringy", | ||||
| @@ -206,16 +206,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "doctrine/annotations", | ||||
|             "version": "v1.2.3", | ||||
|             "version": "v1.2.4", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/doctrine/annotations.git", | ||||
|                 "reference": "eeda578cbe24a170331a1cfdf78be723412df7a4" | ||||
|                 "reference": "b5202eb9e83f8db52e0e58867e0a46e63be8332e" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/doctrine/annotations/zipball/eeda578cbe24a170331a1cfdf78be723412df7a4", | ||||
|                 "reference": "eeda578cbe24a170331a1cfdf78be723412df7a4", | ||||
|                 "url": "https://api.github.com/repos/doctrine/annotations/zipball/b5202eb9e83f8db52e0e58867e0a46e63be8332e", | ||||
|                 "reference": "b5202eb9e83f8db52e0e58867e0a46e63be8332e", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -270,20 +270,20 @@ | ||||
|                 "docblock", | ||||
|                 "parser" | ||||
|             ], | ||||
|             "time": "2014-12-20 20:49:38" | ||||
|             "time": "2014-12-23 22:40:37" | ||||
|         }, | ||||
|         { | ||||
|             "name": "doctrine/cache", | ||||
|             "version": "v1.4.0", | ||||
|             "version": "v1.4.1", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/doctrine/cache.git", | ||||
|                 "reference": "2346085d2b027b233ae1d5de59b07440b9f288c8" | ||||
|                 "reference": "c9eadeb743ac6199f7eec423cb9426bc518b7b03" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/doctrine/cache/zipball/2346085d2b027b233ae1d5de59b07440b9f288c8", | ||||
|                 "reference": "2346085d2b027b233ae1d5de59b07440b9f288c8", | ||||
|                 "url": "https://api.github.com/repos/doctrine/cache/zipball/c9eadeb743ac6199f7eec423cb9426bc518b7b03", | ||||
|                 "reference": "c9eadeb743ac6199f7eec423cb9426bc518b7b03", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -294,13 +294,13 @@ | ||||
|             }, | ||||
|             "require-dev": { | ||||
|                 "phpunit/phpunit": ">=3.7", | ||||
|                 "predis/predis": "~0.8", | ||||
|                 "predis/predis": "~1.0", | ||||
|                 "satooshi/php-coveralls": "~0.6" | ||||
|             }, | ||||
|             "type": "library", | ||||
|             "extra": { | ||||
|                 "branch-alias": { | ||||
|                     "dev-master": "1.4.x-dev" | ||||
|                     "dev-master": "1.5.x-dev" | ||||
|                 } | ||||
|             }, | ||||
|             "autoload": { | ||||
| @@ -340,25 +340,28 @@ | ||||
|                 "cache", | ||||
|                 "caching" | ||||
|             ], | ||||
|             "time": "2015-01-15 20:38:55" | ||||
|             "time": "2015-04-15 00:11:59" | ||||
|         }, | ||||
|         { | ||||
|             "name": "doctrine/collections", | ||||
|             "version": "v1.2", | ||||
|             "version": "v1.3.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/doctrine/collections.git", | ||||
|                 "reference": "b99c5c46c87126201899afe88ec490a25eedd6a2" | ||||
|                 "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/doctrine/collections/zipball/b99c5c46c87126201899afe88ec490a25eedd6a2", | ||||
|                 "reference": "b99c5c46c87126201899afe88ec490a25eedd6a2", | ||||
|                 "url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a", | ||||
|                 "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "php": ">=5.3.2" | ||||
|             }, | ||||
|             "require-dev": { | ||||
|                 "phpunit/phpunit": "~4.0" | ||||
|             }, | ||||
|             "type": "library", | ||||
|             "extra": { | ||||
|                 "branch-alias": { | ||||
| @@ -375,17 +378,6 @@ | ||||
|                 "MIT" | ||||
|             ], | ||||
|             "authors": [ | ||||
|                 { | ||||
|                     "name": "Jonathan Wage", | ||||
|                     "email": "jonwage@gmail.com", | ||||
|                     "homepage": "http://www.jwage.com/", | ||||
|                     "role": "Creator" | ||||
|                 }, | ||||
|                 { | ||||
|                     "name": "Guilherme Blanco", | ||||
|                     "email": "guilhermeblanco@gmail.com", | ||||
|                     "homepage": "http://www.instaclick.com" | ||||
|                 }, | ||||
|                 { | ||||
|                     "name": "Roman Borschel", | ||||
|                     "email": "roman@code-factory.org" | ||||
| @@ -394,11 +386,17 @@ | ||||
|                     "name": "Benjamin Eberlei", | ||||
|                     "email": "kontakt@beberlei.de" | ||||
|                 }, | ||||
|                 { | ||||
|                     "name": "Guilherme Blanco", | ||||
|                     "email": "guilhermeblanco@gmail.com" | ||||
|                 }, | ||||
|                 { | ||||
|                     "name": "Jonathan Wage", | ||||
|                     "email": "jonwage@gmail.com" | ||||
|                 }, | ||||
|                 { | ||||
|                     "name": "Johannes Schmitt", | ||||
|                     "email": "schmittjoh@gmail.com", | ||||
|                     "homepage": "https://github.com/schmittjoh", | ||||
|                     "role": "Developer of wrapped JMSSerializerBundle" | ||||
|                     "email": "schmittjoh@gmail.com" | ||||
|                 } | ||||
|             ], | ||||
|             "description": "Collections Abstraction library", | ||||
| @@ -408,7 +406,7 @@ | ||||
|                 "collections", | ||||
|                 "iterator" | ||||
|             ], | ||||
|             "time": "2014-02-03 23:07:43" | ||||
|             "time": "2015-04-14 22:21:58" | ||||
|         }, | ||||
|         { | ||||
|             "name": "doctrine/common", | ||||
| @@ -677,16 +675,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "grumpydictator/gchart", | ||||
|             "version": "1.0.8", | ||||
|             "version": "1.0.9", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/JC5/gchart.git", | ||||
|                 "reference": "24d06101cfda7ff336ecb10f7f0cb0d6004cb83c" | ||||
|                 "reference": "920a0494a0697472bf81c0111b6825c516099e59" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/JC5/gchart/zipball/24d06101cfda7ff336ecb10f7f0cb0d6004cb83c", | ||||
|                 "reference": "24d06101cfda7ff336ecb10f7f0cb0d6004cb83c", | ||||
|                 "url": "https://api.github.com/repos/JC5/gchart/zipball/920a0494a0697472bf81c0111b6825c516099e59", | ||||
|                 "reference": "920a0494a0697472bf81c0111b6825c516099e59", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -709,7 +707,7 @@ | ||||
|                 } | ||||
|             ], | ||||
|             "description": "GChart is a small package that allows you to easily generate data for the Google Charts API.", | ||||
|             "time": "2015-02-20 20:07:26" | ||||
|             "time": "2015-04-05 19:17:17" | ||||
|         }, | ||||
|         { | ||||
|             "name": "illuminate/html", | ||||
| @@ -945,16 +943,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "laravel/framework", | ||||
|             "version": "v5.0.26", | ||||
|             "version": "v5.0.28", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/laravel/framework.git", | ||||
|                 "reference": "8e53c33e144f94032cc6ecbfee0be2a96ed63be0" | ||||
|                 "reference": "06a09429322cf53e5bd4587db1060f02a291562e" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/laravel/framework/zipball/8e53c33e144f94032cc6ecbfee0be2a96ed63be0", | ||||
|                 "reference": "8e53c33e144f94032cc6ecbfee0be2a96ed63be0", | ||||
|                 "url": "https://api.github.com/repos/laravel/framework/zipball/06a09429322cf53e5bd4587db1060f02a291562e", | ||||
|                 "reference": "06a09429322cf53e5bd4587db1060f02a291562e", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -1024,7 +1022,7 @@ | ||||
|                 "predis/predis": "~1.0" | ||||
|             }, | ||||
|             "suggest": { | ||||
|                 "aws/aws-sdk-php": "Required to use the SQS queue driver (~2.4).", | ||||
|                 "aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (~2.4).", | ||||
|                 "doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.4).", | ||||
|                 "guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers (~5.0).", | ||||
|                 "iron-io/iron_mq": "Required to use the iron queue driver (~1.5).", | ||||
| @@ -1067,7 +1065,7 @@ | ||||
|                 "framework", | ||||
|                 "laravel" | ||||
|             ], | ||||
|             "time": "2015-04-03 02:58:05" | ||||
|             "time": "2015-04-21 01:44:32" | ||||
|         }, | ||||
|         { | ||||
|             "name": "league/commonmark", | ||||
| @@ -1377,16 +1375,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "nikic/php-parser", | ||||
|             "version": "v1.2.1", | ||||
|             "version": "v1.3.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/nikic/PHP-Parser.git", | ||||
|                 "reference": "dba7524b3724f25b947cd26a580787c55c8a6f9b" | ||||
|                 "reference": "dff239267fd1befa1cd40430c9ed12591aa720ca" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dba7524b3724f25b947cd26a580787c55c8a6f9b", | ||||
|                 "reference": "dba7524b3724f25b947cd26a580787c55c8a6f9b", | ||||
|                 "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dff239267fd1befa1cd40430c9ed12591aa720ca", | ||||
|                 "reference": "dff239267fd1befa1cd40430c9ed12591aa720ca", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -1396,7 +1394,7 @@ | ||||
|             "type": "library", | ||||
|             "extra": { | ||||
|                 "branch-alias": { | ||||
|                     "dev-master": "1.2-dev" | ||||
|                     "dev-master": "1.3-dev" | ||||
|                 } | ||||
|             }, | ||||
|             "autoload": { | ||||
| @@ -1418,7 +1416,7 @@ | ||||
|                 "parser", | ||||
|                 "php" | ||||
|             ], | ||||
|             "time": "2015-03-24 19:10:28" | ||||
|             "time": "2015-05-02 15:40:40" | ||||
|         }, | ||||
|         { | ||||
|             "name": "psr/log", | ||||
| @@ -1529,6 +1527,70 @@ | ||||
|             ], | ||||
|             "time": "2015-03-26 18:43:54" | ||||
|         }, | ||||
|         { | ||||
|             "name": "rcrowe/twigbridge", | ||||
|             "version": "0.7.x-dev", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/rcrowe/TwigBridge.git", | ||||
|                 "reference": "ac0bfb5bcdb4fcd0cd01ab8425620ff07f6af026" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/rcrowe/TwigBridge/zipball/ac0bfb5bcdb4fcd0cd01ab8425620ff07f6af026", | ||||
|                 "reference": "ac0bfb5bcdb4fcd0cd01ab8425620ff07f6af026", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "illuminate/support": "5.0.*", | ||||
|                 "illuminate/view": "5.0.*", | ||||
|                 "php": ">=5.4.0", | ||||
|                 "twig/twig": "~1.15" | ||||
|             }, | ||||
|             "require-dev": { | ||||
|                 "laravel/framework": "5.0.*", | ||||
|                 "mockery/mockery": "0.9.*", | ||||
|                 "phpunit/phpunit": "~4.0", | ||||
|                 "satooshi/php-coveralls": "~0.6", | ||||
|                 "squizlabs/php_codesniffer": "~1.5" | ||||
|             }, | ||||
|             "suggest": { | ||||
|                 "laravelcollective/html": "For bringing back html/form in Laravel 5.x", | ||||
|                 "twig/extensions": "~1.0" | ||||
|             }, | ||||
|             "type": "library", | ||||
|             "extra": { | ||||
|                 "branch-alias": { | ||||
|                     "dev-master": "0.7-dev" | ||||
|                 } | ||||
|             }, | ||||
|             "autoload": { | ||||
|                 "psr-4": { | ||||
|                     "TwigBridge\\": "src", | ||||
|                     "TwigBridge\\Tests\\": "tests" | ||||
|                 } | ||||
|             }, | ||||
|             "notification-url": "https://packagist.org/downloads/", | ||||
|             "license": [ | ||||
|                 "MIT" | ||||
|             ], | ||||
|             "authors": [ | ||||
|                 { | ||||
|                     "name": "Barry vd. Heuvel", | ||||
|                     "email": "barryvdh@gmail.com" | ||||
|                 }, | ||||
|                 { | ||||
|                     "name": "Rob Crowe", | ||||
|                     "email": "hello@vivalacrowe.com" | ||||
|                 } | ||||
|             ], | ||||
|             "description": "Adds the power of Twig to Laravel", | ||||
|             "keywords": [ | ||||
|                 "laravel", | ||||
|                 "twig" | ||||
|             ], | ||||
|             "time": "2015-04-22 09:19:03" | ||||
|         }, | ||||
|         { | ||||
|             "name": "swiftmailer/swiftmailer", | ||||
|             "version": "v5.4.0", | ||||
| @@ -2293,6 +2355,115 @@ | ||||
|             ], | ||||
|             "time": "2015-03-31 08:12:29" | ||||
|         }, | ||||
|         { | ||||
|             "name": "twig/extensions", | ||||
|             "version": "v1.2.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/twigphp/Twig-extensions.git", | ||||
|                 "reference": "8cf4b9fe04077bd54fc73f4fde83347040c3b8cd" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/twigphp/Twig-extensions/zipball/8cf4b9fe04077bd54fc73f4fde83347040c3b8cd", | ||||
|                 "reference": "8cf4b9fe04077bd54fc73f4fde83347040c3b8cd", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "twig/twig": "~1.12" | ||||
|             }, | ||||
|             "require-dev": { | ||||
|                 "symfony/translation": "~2.3" | ||||
|             }, | ||||
|             "suggest": { | ||||
|                 "symfony/translation": "Allow the time_diff output to be translated" | ||||
|             }, | ||||
|             "type": "library", | ||||
|             "extra": { | ||||
|                 "branch-alias": { | ||||
|                     "dev-master": "1.2.x-dev" | ||||
|                 } | ||||
|             }, | ||||
|             "autoload": { | ||||
|                 "psr-0": { | ||||
|                     "Twig_Extensions_": "lib/" | ||||
|                 } | ||||
|             }, | ||||
|             "notification-url": "https://packagist.org/downloads/", | ||||
|             "license": [ | ||||
|                 "MIT" | ||||
|             ], | ||||
|             "authors": [ | ||||
|                 { | ||||
|                     "name": "Fabien Potencier", | ||||
|                     "email": "fabien@symfony.com" | ||||
|                 } | ||||
|             ], | ||||
|             "description": "Common additional features for Twig that do not directly belong in core", | ||||
|             "homepage": "http://twig.sensiolabs.org/doc/extensions/index.html", | ||||
|             "keywords": [ | ||||
|                 "i18n", | ||||
|                 "text" | ||||
|             ], | ||||
|             "time": "2014-10-30 14:30:03" | ||||
|         }, | ||||
|         { | ||||
|             "name": "twig/twig", | ||||
|             "version": "v1.18.1", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/twigphp/Twig.git", | ||||
|                 "reference": "9f70492f44398e276d1b81c1b43adfe6751c7b7f" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/twigphp/Twig/zipball/9f70492f44398e276d1b81c1b43adfe6751c7b7f", | ||||
|                 "reference": "9f70492f44398e276d1b81c1b43adfe6751c7b7f", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "php": ">=5.2.7" | ||||
|             }, | ||||
|             "type": "library", | ||||
|             "extra": { | ||||
|                 "branch-alias": { | ||||
|                     "dev-master": "1.18-dev" | ||||
|                 } | ||||
|             }, | ||||
|             "autoload": { | ||||
|                 "psr-0": { | ||||
|                     "Twig_": "lib/" | ||||
|                 } | ||||
|             }, | ||||
|             "notification-url": "https://packagist.org/downloads/", | ||||
|             "license": [ | ||||
|                 "BSD-3-Clause" | ||||
|             ], | ||||
|             "authors": [ | ||||
|                 { | ||||
|                     "name": "Fabien Potencier", | ||||
|                     "email": "fabien@symfony.com", | ||||
|                     "homepage": "http://fabien.potencier.org", | ||||
|                     "role": "Lead Developer" | ||||
|                 }, | ||||
|                 { | ||||
|                     "name": "Armin Ronacher", | ||||
|                     "email": "armin.ronacher@active-4.com", | ||||
|                     "role": "Project Founder" | ||||
|                 }, | ||||
|                 { | ||||
|                     "name": "Twig Team", | ||||
|                     "homepage": "http://twig.sensiolabs.org/contributors", | ||||
|                     "role": "Contributors" | ||||
|                 } | ||||
|             ], | ||||
|             "description": "Twig, the flexible, fast, and secure template language for PHP", | ||||
|             "homepage": "http://twig.sensiolabs.org", | ||||
|             "keywords": [ | ||||
|                 "templating" | ||||
|             ], | ||||
|             "time": "2015-04-19 08:30:27" | ||||
|         }, | ||||
|         { | ||||
|             "name": "vlucas/phpdotenv", | ||||
|             "version": "v1.1.0", | ||||
| @@ -3027,23 +3198,23 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "phpspec/phpspec", | ||||
|             "version": "2.1.1", | ||||
|             "version": "2.2.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/phpspec/phpspec.git", | ||||
|                 "reference": "66a1df93099282b1514e9e001fcf6e9393f7783d" | ||||
|                 "reference": "9727d75919a00455433e867565bc022f0b985a39" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/phpspec/phpspec/zipball/66a1df93099282b1514e9e001fcf6e9393f7783d", | ||||
|                 "reference": "66a1df93099282b1514e9e001fcf6e9393f7783d", | ||||
|                 "url": "https://api.github.com/repos/phpspec/phpspec/zipball/9727d75919a00455433e867565bc022f0b985a39", | ||||
|                 "reference": "9727d75919a00455433e867565bc022f0b985a39", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "doctrine/instantiator": "~1.0,>=1.0.1", | ||||
|                 "doctrine/instantiator": "^1.0.1", | ||||
|                 "php": ">=5.3.3", | ||||
|                 "phpspec/php-diff": "~1.0.0", | ||||
|                 "phpspec/prophecy": "~1.1", | ||||
|                 "phpspec/prophecy": "~1.4", | ||||
|                 "sebastian/exporter": "~1.0", | ||||
|                 "symfony/console": "~2.3", | ||||
|                 "symfony/event-dispatcher": "~2.1", | ||||
| @@ -3052,9 +3223,11 @@ | ||||
|                 "symfony/yaml": "~2.1" | ||||
|             }, | ||||
|             "require-dev": { | ||||
|                 "behat/behat": "~3.0,>=3.0.11", | ||||
|                 "behat/behat": "^3.0.11", | ||||
|                 "bossa/phpspec2-expect": "~1.0", | ||||
|                 "symfony/filesystem": "~2.1" | ||||
|                 "phpunit/phpunit": "~4.4", | ||||
|                 "symfony/filesystem": "~2.1", | ||||
|                 "symfony/process": "~2.1" | ||||
|             }, | ||||
|             "suggest": { | ||||
|                 "phpspec/nyan-formatters": "~1.0 – Adds Nyan formatters" | ||||
| @@ -3065,7 +3238,7 @@ | ||||
|             "type": "library", | ||||
|             "extra": { | ||||
|                 "branch-alias": { | ||||
|                     "dev-master": "2.1.x-dev" | ||||
|                     "dev-master": "2.2.x-dev" | ||||
|                 } | ||||
|             }, | ||||
|             "autoload": { | ||||
| @@ -3099,20 +3272,20 @@ | ||||
|                 "testing", | ||||
|                 "tests" | ||||
|             ], | ||||
|             "time": "2015-01-09 13:21:45" | ||||
|             "time": "2015-04-18 16:22:51" | ||||
|         }, | ||||
|         { | ||||
|             "name": "phpspec/prophecy", | ||||
|             "version": "1.4.0", | ||||
|             "version": "v1.4.1", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/phpspec/prophecy.git", | ||||
|                 "reference": "8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5" | ||||
|                 "reference": "3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/phpspec/prophecy/zipball/8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5", | ||||
|                 "reference": "8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5", | ||||
|                 "url": "https://api.github.com/repos/phpspec/prophecy/zipball/3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373", | ||||
|                 "reference": "3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -3159,20 +3332,20 @@ | ||||
|                 "spy", | ||||
|                 "stub" | ||||
|             ], | ||||
|             "time": "2015-03-27 19:31:25" | ||||
|             "time": "2015-04-27 22:15:08" | ||||
|         }, | ||||
|         { | ||||
|             "name": "phpunit/php-code-coverage", | ||||
|             "version": "2.0.15", | ||||
|             "version": "2.0.16", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/sebastianbergmann/php-code-coverage.git", | ||||
|                 "reference": "34cc484af1ca149188d0d9e91412191e398e0b67" | ||||
|                 "reference": "934fd03eb6840508231a7f73eb8940cf32c3b66c" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/34cc484af1ca149188d0d9e91412191e398e0b67", | ||||
|                 "reference": "34cc484af1ca149188d0d9e91412191e398e0b67", | ||||
|                 "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/934fd03eb6840508231a7f73eb8940cf32c3b66c", | ||||
|                 "reference": "934fd03eb6840508231a7f73eb8940cf32c3b66c", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -3221,35 +3394,37 @@ | ||||
|                 "testing", | ||||
|                 "xunit" | ||||
|             ], | ||||
|             "time": "2015-01-24 10:06:35" | ||||
|             "time": "2015-04-11 04:35:00" | ||||
|         }, | ||||
|         { | ||||
|             "name": "phpunit/php-file-iterator", | ||||
|             "version": "1.3.4", | ||||
|             "version": "1.4.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/sebastianbergmann/php-file-iterator.git", | ||||
|                 "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb" | ||||
|                 "reference": "a923bb15680d0089e2316f7a4af8f437046e96bb" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb", | ||||
|                 "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb", | ||||
|                 "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a923bb15680d0089e2316f7a4af8f437046e96bb", | ||||
|                 "reference": "a923bb15680d0089e2316f7a4af8f437046e96bb", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "php": ">=5.3.3" | ||||
|             }, | ||||
|             "type": "library", | ||||
|             "extra": { | ||||
|                 "branch-alias": { | ||||
|                     "dev-master": "1.4.x-dev" | ||||
|                 } | ||||
|             }, | ||||
|             "autoload": { | ||||
|                 "classmap": [ | ||||
|                     "File/" | ||||
|                     "src/" | ||||
|                 ] | ||||
|             }, | ||||
|             "notification-url": "https://packagist.org/downloads/", | ||||
|             "include-path": [ | ||||
|                 "" | ||||
|             ], | ||||
|             "license": [ | ||||
|                 "BSD-3-Clause" | ||||
|             ], | ||||
| @@ -3266,7 +3441,7 @@ | ||||
|                 "filesystem", | ||||
|                 "iterator" | ||||
|             ], | ||||
|             "time": "2013-10-10 15:34:57" | ||||
|             "time": "2015-04-02 05:19:05" | ||||
|         }, | ||||
|         { | ||||
|             "name": "phpunit/php-text-template", | ||||
| @@ -3358,16 +3533,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "phpunit/php-token-stream", | ||||
|             "version": "1.4.0", | ||||
|             "version": "1.4.1", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/sebastianbergmann/php-token-stream.git", | ||||
|                 "reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74" | ||||
|                 "reference": "eab81d02569310739373308137284e0158424330" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/db32c18eba00b121c145575fcbcd4d4d24e6db74", | ||||
|                 "reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74", | ||||
|                 "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/eab81d02569310739373308137284e0158424330", | ||||
|                 "reference": "eab81d02569310739373308137284e0158424330", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -3403,20 +3578,20 @@ | ||||
|             "keywords": [ | ||||
|                 "tokenizer" | ||||
|             ], | ||||
|             "time": "2015-01-17 09:51:32" | ||||
|             "time": "2015-04-08 04:46:07" | ||||
|         }, | ||||
|         { | ||||
|             "name": "phpunit/phpunit", | ||||
|             "version": "4.5.1", | ||||
|             "version": "4.6.6", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/sebastianbergmann/phpunit.git", | ||||
|                 "reference": "d6429b0995b24a2d9dfe5587ee3a7071c1161af4" | ||||
|                 "reference": "3afe303d873a4d64c62ef84de491b97b006fbdac" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d6429b0995b24a2d9dfe5587ee3a7071c1161af4", | ||||
|                 "reference": "d6429b0995b24a2d9dfe5587ee3a7071c1161af4", | ||||
|                 "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3afe303d873a4d64c62ef84de491b97b006fbdac", | ||||
|                 "reference": "3afe303d873a4d64c62ef84de491b97b006fbdac", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -3428,17 +3603,17 @@ | ||||
|                 "php": ">=5.3.3", | ||||
|                 "phpspec/prophecy": "~1.3,>=1.3.1", | ||||
|                 "phpunit/php-code-coverage": "~2.0,>=2.0.11", | ||||
|                 "phpunit/php-file-iterator": "~1.3.2", | ||||
|                 "phpunit/php-file-iterator": "~1.4", | ||||
|                 "phpunit/php-text-template": "~1.2", | ||||
|                 "phpunit/php-timer": "~1.0.2", | ||||
|                 "phpunit/php-timer": "~1.0", | ||||
|                 "phpunit/phpunit-mock-objects": "~2.3", | ||||
|                 "sebastian/comparator": "~1.1", | ||||
|                 "sebastian/diff": "~1.1", | ||||
|                 "sebastian/diff": "~1.2", | ||||
|                 "sebastian/environment": "~1.2", | ||||
|                 "sebastian/exporter": "~1.2", | ||||
|                 "sebastian/global-state": "~1.0", | ||||
|                 "sebastian/version": "~1.0", | ||||
|                 "symfony/yaml": "~2.0" | ||||
|                 "symfony/yaml": "~2.1|~3.0" | ||||
|             }, | ||||
|             "suggest": { | ||||
|                 "phpunit/php-invoker": "~1.1" | ||||
| @@ -3449,7 +3624,7 @@ | ||||
|             "type": "library", | ||||
|             "extra": { | ||||
|                 "branch-alias": { | ||||
|                     "dev-master": "4.5.x-dev" | ||||
|                     "dev-master": "4.6.x-dev" | ||||
|                 } | ||||
|             }, | ||||
|             "autoload": { | ||||
| @@ -3475,7 +3650,7 @@ | ||||
|                 "testing", | ||||
|                 "xunit" | ||||
|             ], | ||||
|             "time": "2015-03-29 09:24:05" | ||||
|             "time": "2015-04-29 15:18:52" | ||||
|         }, | ||||
|         { | ||||
|             "name": "phpunit/phpunit-mock-objects", | ||||
| @@ -3666,16 +3841,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "sebastian/diff", | ||||
|             "version": "1.2.0", | ||||
|             "version": "1.3.0", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/sebastianbergmann/diff.git", | ||||
|                 "reference": "5843509fed39dee4b356a306401e9dd1a931fec7" | ||||
|                 "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/5843509fed39dee4b356a306401e9dd1a931fec7", | ||||
|                 "reference": "5843509fed39dee4b356a306401e9dd1a931fec7", | ||||
|                 "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/863df9687835c62aa423a22412d26fa2ebde3fd3", | ||||
|                 "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
| @@ -3687,7 +3862,7 @@ | ||||
|             "type": "library", | ||||
|             "extra": { | ||||
|                 "branch-alias": { | ||||
|                     "dev-master": "1.2-dev" | ||||
|                     "dev-master": "1.3-dev" | ||||
|                 } | ||||
|             }, | ||||
|             "autoload": { | ||||
| @@ -3714,32 +3889,32 @@ | ||||
|             "keywords": [ | ||||
|                 "diff" | ||||
|             ], | ||||
|             "time": "2014-08-15 10:29:00" | ||||
|             "time": "2015-02-22 15:13:53" | ||||
|         }, | ||||
|         { | ||||
|             "name": "sebastian/environment", | ||||
|             "version": "1.2.1", | ||||
|             "version": "1.2.2", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/sebastianbergmann/environment.git", | ||||
|                 "reference": "6e6c71d918088c251b181ba8b3088af4ac336dd7" | ||||
|                 "reference": "5a8c7d31914337b69923db26c4221b81ff5a196e" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e6c71d918088c251b181ba8b3088af4ac336dd7", | ||||
|                 "reference": "6e6c71d918088c251b181ba8b3088af4ac336dd7", | ||||
|                 "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5a8c7d31914337b69923db26c4221b81ff5a196e", | ||||
|                 "reference": "5a8c7d31914337b69923db26c4221b81ff5a196e", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "php": ">=5.3.3" | ||||
|             }, | ||||
|             "require-dev": { | ||||
|                 "phpunit/phpunit": "~4.3" | ||||
|                 "phpunit/phpunit": "~4.4" | ||||
|             }, | ||||
|             "type": "library", | ||||
|             "extra": { | ||||
|                 "branch-alias": { | ||||
|                     "dev-master": "1.2.x-dev" | ||||
|                     "dev-master": "1.3.x-dev" | ||||
|                 } | ||||
|             }, | ||||
|             "autoload": { | ||||
| @@ -3764,7 +3939,7 @@ | ||||
|                 "environment", | ||||
|                 "hhvm" | ||||
|             ], | ||||
|             "time": "2014-10-25 08:00:45" | ||||
|             "time": "2015-01-01 10:01:08" | ||||
|         }, | ||||
|         { | ||||
|             "name": "sebastian/exporter", | ||||
| @@ -3938,16 +4113,16 @@ | ||||
|         }, | ||||
|         { | ||||
|             "name": "sebastian/version", | ||||
|             "version": "1.0.4", | ||||
|             "version": "1.0.5", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/sebastianbergmann/version.git", | ||||
|                 "reference": "a77d9123f8e809db3fbdea15038c27a95da4058b" | ||||
|                 "reference": "ab931d46cd0d3204a91e1b9a40c4bc13032b58e4" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/a77d9123f8e809db3fbdea15038c27a95da4058b", | ||||
|                 "reference": "a77d9123f8e809db3fbdea15038c27a95da4058b", | ||||
|                 "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/ab931d46cd0d3204a91e1b9a40c4bc13032b58e4", | ||||
|                 "reference": "ab931d46cd0d3204a91e1b9a40c4bc13032b58e4", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "type": "library", | ||||
| @@ -3969,7 +4144,7 @@ | ||||
|             ], | ||||
|             "description": "Library that helps with managing the version number of Git-hosted PHP projects", | ||||
|             "homepage": "https://github.com/sebastianbergmann/version", | ||||
|             "time": "2014-12-15 14:25:24" | ||||
|             "time": "2015-02-24 06:35:25" | ||||
|         }, | ||||
|         { | ||||
|             "name": "symfony/class-loader", | ||||
| @@ -4177,6 +4352,7 @@ | ||||
|     "aliases": [], | ||||
|     "minimum-stability": "stable", | ||||
|     "stability-flags": { | ||||
|         "rcrowe/twigbridge": 20, | ||||
|         "barryvdh/laravel-debugbar": 0 | ||||
|     }, | ||||
|     "prefer-stable": false, | ||||
|   | ||||
| @@ -136,9 +136,11 @@ return [ | ||||
|         'Illuminate\Validation\ValidationServiceProvider', | ||||
|         'Illuminate\View\ViewServiceProvider', | ||||
|         'Illuminate\Html\HtmlServiceProvider', | ||||
|         'TwigBridge\ServiceProvider', | ||||
|  | ||||
|         'DaveJamesMiller\Breadcrumbs\ServiceProvider', | ||||
|         'Barryvdh\Debugbar\ServiceProvider', | ||||
|         'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider', | ||||
|         'DaveJamesMiller\Breadcrumbs\ServiceProvider', | ||||
|  | ||||
|         /* | ||||
|          * Application Service Providers... | ||||
| @@ -151,6 +153,7 @@ return [ | ||||
|         'FireflyIII\Providers\FireflyServiceProvider', | ||||
|         'FireflyIII\Providers\TestingServiceProvider', | ||||
|  | ||||
|  | ||||
|     ], | ||||
|  | ||||
|     /* | ||||
| @@ -200,13 +203,14 @@ return [ | ||||
|         'View'         => 'Illuminate\Support\Facades\View', | ||||
|         'Form'         => 'Illuminate\Html\FormFacade', | ||||
|         'Html'         => 'Illuminate\Html\HtmlFacade', | ||||
|         'Breadcrumbs' => 'DaveJamesMiller\Breadcrumbs\Facade', | ||||
|  | ||||
|         'Breadcrumbs'  => 'DaveJamesMiller\Breadcrumbs\Facade', | ||||
|         'Preferences'  => 'FireflyIII\Support\Facades\Preferences', | ||||
|         'Navigation'   => 'FireflyIII\Support\Facades\Navigation', | ||||
|         'Amount'       => 'FireflyIII\Support\Facades\Amount', | ||||
|         'Steam'        => 'FireflyIII\Support\Facades\Steam', | ||||
|         'ExpandedForm' => 'FireflyIII\Support\Facades\ExpandedForm', | ||||
|         'Twig'         => 'TwigBridge\Facade\Twig', | ||||
|  | ||||
|  | ||||
|     ], | ||||
|  | ||||
|   | ||||
| @@ -48,7 +48,7 @@ return [ | ||||
|  | ||||
|         'sqlite' => [ | ||||
|             'driver'   => 'sqlite', | ||||
|             'database' => ':memory:', | ||||
|             'database' =>  __DIR__.'/../storage/database/testing.db', | ||||
|             'prefix'   => '', | ||||
|         ], | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,7 @@ return [ | ||||
| 	*/ | ||||
|  | ||||
| 	'paths' => [ | ||||
| 		realpath(base_path('resources/views')) | ||||
| 		realpath(base_path('resources/twig')) | ||||
| 	], | ||||
|  | ||||
| 	/* | ||||
|   | ||||
| @@ -4,6 +4,8 @@ use Illuminate\Database\Migrations\Migration; | ||||
| use Illuminate\Database\Schema\Blueprint; | ||||
|  | ||||
| /** | ||||
|  * @SuppressWarnings(PHPMD.ShortMethodName) | ||||
|  * | ||||
|  * Class CreatePasswordResetsTable | ||||
|  */ | ||||
| class CreatePasswordResetsTable extends Migration | ||||
|   | ||||
| @@ -41,6 +41,9 @@ class CreateAccountMetaTable extends Migration | ||||
|  | ||||
|             $table->unique(['account_id', 'name']); | ||||
|  | ||||
|             // link to account! | ||||
|             $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade'); | ||||
|  | ||||
|  | ||||
|         } | ||||
|         ); | ||||
|   | ||||
| @@ -7,6 +7,7 @@ use FireflyIII\Models\Component; | ||||
| use Illuminate\Database\Migrations\Migration; | ||||
| use Illuminate\Database\Schema\Blueprint; | ||||
| use Illuminate\Support\Facades\Schema; | ||||
|  | ||||
| /** | ||||
|  * @SuppressWarnings(PHPMD.ShortMethodName) // method names are mandated by laravel. | ||||
|  * @SuppressWarnings("TooManyMethods") // I'm fine with this | ||||
| @@ -426,7 +427,6 @@ class ChangesForV321 extends Migration | ||||
|  | ||||
|     public function moveComponentIdToBudgetId() | ||||
|     { | ||||
|         //Log::debug('Now in moveComponentIdToBudgetId()'); | ||||
|         BudgetLimit::get()->each( | ||||
|             function (BudgetLimit $bl) { | ||||
|                 Log::debug('Now at budgetLimit #' . $bl->id . ' with component_id: ' . $bl->component_id); | ||||
| @@ -447,7 +447,6 @@ class ChangesForV321 extends Migration | ||||
|                 } | ||||
|             } | ||||
|         ); | ||||
|         //Log::debug('Done with moveComponentIdToBudgetId()'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -5,7 +5,7 @@ use Illuminate\Database\Schema\Blueprint; | ||||
|  | ||||
| /** | ||||
|  * @SuppressWarnings(PHPMD.ShortMethodName) | ||||
|  * @SuppressWarnings("MethodLength") // I don't mind this in case of migrations. | ||||
|  * @SuppressWarnings("PHPMD.ExcessiveMethodLength") | ||||
|  * | ||||
|  * Class ChangesForV322 | ||||
|  */ | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user