| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  | <?php | 
					
						
							| 
									
										
										
										
											2020-06-30 19:05:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * AmountController.php | 
					
						
							|  |  |  |  * Copyright (c) 2020 james@firefly-iii.org | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This file is part of Firefly III (https://github.com/firefly-iii). | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU Affero General Public License as | 
					
						
							|  |  |  |  * published by the Free Software Foundation, either version 3 of the | 
					
						
							|  |  |  |  * License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU Affero General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Affero General Public License | 
					
						
							|  |  |  |  * along with this program.  If not, see <https://www.gnu.org/licenses/>. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  | declare(strict_types=1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace FireflyIII\Http\Controllers\PiggyBank; | 
					
						
							| 
									
										
										
										
											2021-03-28 11:46:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  | use Carbon\Carbon; | 
					
						
							|  |  |  | use FireflyIII\Http\Controllers\Controller; | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  | use FireflyIII\Models\Account; | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  | use FireflyIII\Models\PiggyBank; | 
					
						
							|  |  |  | use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; | 
					
						
							|  |  |  | use Illuminate\Contracts\View\Factory; | 
					
						
							|  |  |  | use Illuminate\Http\RedirectResponse; | 
					
						
							|  |  |  | use Illuminate\Http\Request; | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  | use Illuminate\Support\Facades\Log; | 
					
						
							| 
									
										
										
										
											2023-05-29 13:56:55 +02:00
										 |  |  | use Illuminate\View\View; | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Class AmountController | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class AmountController extends Controller | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     private PiggyBankRepositoryInterface $piggyRepos; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * PiggyBankController constructor. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function __construct() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         parent::__construct(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $this->middleware( | 
					
						
							|  |  |  |             function ($request, $next) { | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |                 app('view')->share('title', (string) trans('firefly.piggyBanks')); | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  |                 app('view')->share('mainTitleIcon', 'fa-bullseye'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-05 07:31:26 +01:00
										 |  |  |                 $this->piggyRepos = app(PiggyBankRepositoryInterface::class); | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 return $next($request); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Add money to piggy bank. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return Factory|View | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function add(PiggyBank $piggyBank) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-02-01 12:50:48 +01:00
										 |  |  |         /** @var Carbon $date */ | 
					
						
							| 
									
										
										
										
											2025-02-01 19:06:02 +01:00
										 |  |  |         $date       = session('end', today(config('app.timezone'))); | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |         $accounts   = []; | 
					
						
							|  |  |  |         $total      = '0'; | 
					
						
							|  |  |  |         $totalSaved = $this->piggyRepos->getCurrentAmount($piggyBank); | 
					
						
							|  |  |  |         foreach ($piggyBank->accounts as $account) { | 
					
						
							| 
									
										
										
										
											2025-02-01 12:50:48 +01:00
										 |  |  |             $leftOnAccount = $this->piggyRepos->leftOnAccount($piggyBank, $account, $date); | 
					
						
							| 
									
										
										
										
											2025-06-02 20:32:58 +02:00
										 |  |  |             $leftToSave    = bcsub($piggyBank->target_amount, $totalSaved); | 
					
						
							| 
									
										
										
										
											2025-02-01 19:06:02 +01:00
										 |  |  |             $maxAmount     = 0 === bccomp($piggyBank->target_amount, '0') ? $leftOnAccount : min($leftOnAccount, $leftToSave); | 
					
						
							| 
									
										
										
										
											2025-06-02 20:32:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-03 19:32:21 +02:00
										 |  |  |             Log::debug(sprintf( | 
					
						
							|  |  |  |                 'Account "%s", left on account "%s", saved so far "%s", left to save "%s", max amount "%s".', | 
					
						
							| 
									
										
										
										
											2025-06-02 20:32:58 +02:00
										 |  |  |                 $account->name, | 
					
						
							|  |  |  |                 $leftOnAccount, | 
					
						
							|  |  |  |                 $totalSaved, | 
					
						
							|  |  |  |                 $leftToSave, | 
					
						
							| 
									
										
										
										
											2025-06-03 19:32:21 +02:00
										 |  |  |                 $maxAmount, | 
					
						
							|  |  |  |             )); | 
					
						
							| 
									
										
										
										
											2025-06-02 20:32:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |             $accounts[]    = [ | 
					
						
							|  |  |  |                 'account'         => $account, | 
					
						
							|  |  |  |                 'left_on_account' => $leftOnAccount, | 
					
						
							| 
									
										
										
										
											2025-06-03 19:32:21 +02:00
										 |  |  |                 'total_saved'     => $totalSaved, | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |                 'left_to_save'    => $leftToSave, | 
					
						
							|  |  |  |                 'max_amount'      => $maxAmount, | 
					
						
							|  |  |  |             ]; | 
					
						
							|  |  |  |             $total         = bcadd($total, $leftOnAccount); | 
					
						
							| 
									
										
										
										
											2022-03-27 18:30:46 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-12-14 21:55:42 +01:00
										 |  |  |         $total      = (float) $total; // intentional float.
 | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |         return view('piggy-banks.add', compact('piggyBank', 'accounts', 'total')); | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Add money to piggy bank (for mobile devices). | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return Factory|View | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function addMobile(PiggyBank $piggyBank) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         /** @var Carbon $date */ | 
					
						
							| 
									
										
										
										
											2025-06-03 19:32:21 +02:00
										 |  |  |         $date       = session('end', today(config('app.timezone'))); | 
					
						
							|  |  |  |         $accounts   = []; | 
					
						
							|  |  |  |         $total      = '0'; | 
					
						
							| 
									
										
										
										
											2025-06-02 20:32:58 +02:00
										 |  |  |         $totalSaved = $this->piggyRepos->getCurrentAmount($piggyBank); | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |         foreach ($piggyBank->accounts as $account) { | 
					
						
							|  |  |  |             $leftOnAccount = $this->piggyRepos->leftOnAccount($piggyBank, $account, $date); | 
					
						
							| 
									
										
										
										
											2025-06-02 20:32:58 +02:00
										 |  |  |             $leftToSave    = bcsub($piggyBank->target_amount, $totalSaved); | 
					
						
							| 
									
										
										
										
											2025-02-01 19:06:02 +01:00
										 |  |  |             $maxAmount     = 0 === bccomp($piggyBank->target_amount, '0') ? $leftOnAccount : min($leftOnAccount, $leftToSave); | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |             $accounts[]    = [ | 
					
						
							|  |  |  |                 'account'         => $account, | 
					
						
							|  |  |  |                 'left_on_account' => $leftOnAccount, | 
					
						
							| 
									
										
										
										
											2025-06-03 19:32:21 +02:00
										 |  |  |                 'total_saved'     => $totalSaved, | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |                 'left_to_save'    => $leftToSave, | 
					
						
							| 
									
										
										
										
											2025-02-01 12:50:48 +01:00
										 |  |  |                 'max_amount'      => $maxAmount, | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |             ]; | 
					
						
							|  |  |  |             $total         = bcadd($total, $leftOnAccount); | 
					
						
							| 
									
										
										
										
											2022-03-27 18:30:46 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |         return view('piggy-banks.add-mobile', compact('piggyBank', 'total', 'accounts')); | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Add money to piggy bank. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function postAdd(Request $request, PiggyBank $piggyBank): RedirectResponse | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |         $data    = $request->all(); | 
					
						
							|  |  |  |         $amounts = $data['amount'] ?? []; | 
					
						
							|  |  |  |         $total   = '0'; | 
					
						
							|  |  |  |         Log::debug('Start with loop.'); | 
					
						
							| 
									
										
										
										
											2024-12-14 21:55:42 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |         /** @var Account $account */ | 
					
						
							|  |  |  |         foreach ($piggyBank->accounts as $account) { | 
					
						
							| 
									
										
										
										
											2024-12-14 21:55:42 +01:00
										 |  |  |             $amount        = (string) ($amounts[$account->id] ?? '0'); | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |             if ('' === $amount || 0 === bccomp($amount, '0')) { | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (-1 === bccomp($amount, '0')) { | 
					
						
							|  |  |  |                 $amount = bcmul($amount, '-1'); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // small check to see if the $amount is not more than the total "left to save" value
 | 
					
						
							|  |  |  |             $currentAmount = $this->piggyRepos->getCurrentAmount($piggyBank); | 
					
						
							|  |  |  |             $leftToSave    = 0 === bccomp($piggyBank->target_amount, '0') ? '0' : bcsub($piggyBank->target_amount, $currentAmount); | 
					
						
							|  |  |  |             if (bccomp($amount, $leftToSave) > 0 && 0 !== bccomp($leftToSave, '0')) { | 
					
						
							|  |  |  |                 Log::debug(sprintf('Amount "%s" is more than left to save "%s". Using left to save.', $amount, $leftToSave)); | 
					
						
							|  |  |  |                 $amount = $leftToSave; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-14 21:55:42 +01:00
										 |  |  |             $canAddAmount  = $this->piggyRepos->canAddAmount($piggyBank, $account, $amount); | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |             if ($canAddAmount) { | 
					
						
							|  |  |  |                 $this->piggyRepos->addAmount($piggyBank, $account, $amount); | 
					
						
							|  |  |  |                 $total = bcadd($total, $amount); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             $piggyBank->refresh(); | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |         if (0 !== bccomp($total, '0')) { | 
					
						
							|  |  |  |             session()->flash('success', (string) trans('firefly.added_amount_to_piggy', ['amount' => app('amount')->formatAnything($piggyBank->transactionCurrency, $total, false), 'name' => $piggyBank->name])); | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  |             app('preferences')->mark(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return redirect(route('piggy-banks.index')); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |         app('log')->error(sprintf('Cannot add %s because canAddAmount returned false.', $total)); | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  |         session()->flash( | 
					
						
							|  |  |  |             'error', | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |             (string) trans( | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  |                 'firefly.cannot_add_amount_piggy', | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |                 ['amount' => app('amount')->formatAnything($piggyBank->transactionCurrency, $total, false), 'name' => e($piggyBank->name)] | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  |             ) | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return redirect(route('piggy-banks.index')); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Remove money from piggy bank. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function postRemove(Request $request, PiggyBank $piggyBank): RedirectResponse | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |         $amounts = $request->get('amount') ?? []; | 
					
						
							|  |  |  |         if (!is_array($amounts)) { | 
					
						
							|  |  |  |             $amounts = []; | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-12-14 21:55:42 +01:00
										 |  |  |         $total   = '0'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |         /** @var Account $account */ | 
					
						
							|  |  |  |         foreach ($piggyBank->accounts as $account) { | 
					
						
							|  |  |  |             $amount = (string) ($amounts[$account->id] ?? '0'); | 
					
						
							|  |  |  |             if ('' === $amount || 0 === bccomp($amount, '0')) { | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (-1 === bccomp($amount, '0')) { | 
					
						
							|  |  |  |                 $amount = bcmul($amount, '-1'); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if ($this->piggyRepos->canRemoveAmount($piggyBank, $account, $amount)) { | 
					
						
							|  |  |  |                 $this->piggyRepos->removeAmount($piggyBank, $account, $amount); | 
					
						
							|  |  |  |                 $total = bcadd($total, $amount); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (0 !== bccomp($total, '0')) { | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  |             session()->flash( | 
					
						
							|  |  |  |                 'success', | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |                 (string) trans( | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  |                     'firefly.removed_amount_from_piggy', | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |                     ['amount' => app('amount')->formatAnything($piggyBank->transactionCurrency, $total, false), 'name' => $piggyBank->name] | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  |                 ) | 
					
						
							|  |  |  |             ); | 
					
						
							|  |  |  |             app('preferences')->mark(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return redirect(route('piggy-banks.index')); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         session()->flash( | 
					
						
							|  |  |  |             'error', | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |             (string) trans( | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  |                 'firefly.cannot_remove_from_piggy', | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |                 ['amount' => app('amount')->formatAnything($piggyBank->transactionCurrency, $total, false), 'name' => e($piggyBank->name)] | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  |             ) | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return redirect(route('piggy-banks.index')); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Remove money from piggy bank form. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return Factory|View | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function remove(PiggyBank $piggyBank) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |         $accounts = []; | 
					
						
							|  |  |  |         foreach ($piggyBank->accounts as $account) { | 
					
						
							|  |  |  |             $accounts[] = [ | 
					
						
							|  |  |  |                 'account'      => $account, | 
					
						
							|  |  |  |                 'saved_so_far' => $this->piggyRepos->getCurrentAmount($piggyBank, $account), | 
					
						
							|  |  |  |             ]; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-12-14 21:55:42 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |         return view('piggy-banks.remove', compact('piggyBank', 'accounts')); | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Remove money from piggy bank (for mobile devices). | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return Factory|View | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function removeMobile(PiggyBank $piggyBank) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |         $accounts = []; | 
					
						
							|  |  |  |         foreach ($piggyBank->accounts as $account) { | 
					
						
							|  |  |  |             $accounts[] = [ | 
					
						
							|  |  |  |                 'account'      => $account, | 
					
						
							|  |  |  |                 'saved_so_far' => $this->piggyRepos->getCurrentAmount($piggyBank, $account), | 
					
						
							|  |  |  |             ]; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-14 17:32:03 +01:00
										 |  |  |         return view('piggy-banks.remove-mobile', compact('piggyBank', 'accounts')); | 
					
						
							| 
									
										
										
										
											2020-06-07 11:30:02 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } |