| 
									
										
										
										
											2015-02-25 19:32:33 +01:00
										 |  |  | <?php | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-20 12:41:23 +02:00
										 |  |  | /** | 
					
						
							|  |  |  |  * PiggyBankRepository.php | 
					
						
							| 
									
										
										
										
											2020-02-16 14:00:57 +01:00
										 |  |  |  * Copyright (c) 2019 james@firefly-iii.org | 
					
						
							| 
									
										
										
										
											2016-05-20 12:41:23 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-10-02 06:37:26 +02:00
										 |  |  |  * This file is part of Firefly III (https://github.com/firefly-iii). | 
					
						
							| 
									
										
										
										
											2016-10-05 06:52:15 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-10-02 06:37:26 +02:00
										 |  |  |  * 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. | 
					
						
							| 
									
										
										
										
											2017-10-21 08:40:00 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-10-02 06:37:26 +02:00
										 |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							| 
									
										
										
										
											2017-10-21 08:40:00 +02:00
										 |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							| 
									
										
										
										
											2019-10-02 06:37:26 +02:00
										 |  |  |  * GNU Affero General Public License for more details. | 
					
						
							| 
									
										
										
										
											2017-10-21 08:40:00 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-10-02 06:37:26 +02:00
										 |  |  |  * 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/>. | 
					
						
							| 
									
										
										
										
											2016-05-20 12:41:23 +02:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-04-09 07:44:22 +02:00
										 |  |  | declare(strict_types=1); | 
					
						
							| 
									
										
										
										
											2015-02-25 19:32:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace FireflyIII\Repositories\PiggyBank; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-20 21:57:20 +02:00
										 |  |  | use Carbon\Carbon; | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  | use FireflyIII\Exceptions\FireflyException; | 
					
						
							| 
									
										
										
										
											2020-05-07 06:44:01 +02:00
										 |  |  | use FireflyIII\Models\Attachment; | 
					
						
							| 
									
										
										
										
											2016-10-22 10:13:49 +02:00
										 |  |  | use FireflyIII\Models\Note; | 
					
						
							| 
									
										
										
										
											2015-02-25 19:32:33 +01:00
										 |  |  | use FireflyIII\Models\PiggyBank; | 
					
						
							| 
									
										
										
										
											2017-04-28 07:51:09 +02:00
										 |  |  | use FireflyIII\Models\PiggyBankRepetition; | 
					
						
							| 
									
										
										
										
											2019-09-14 18:02:24 +02:00
										 |  |  | use FireflyIII\Models\Transaction; | 
					
						
							| 
									
										
										
										
											2017-04-28 07:51:09 +02:00
										 |  |  | use FireflyIII\Models\TransactionJournal; | 
					
						
							| 
									
										
										
										
											2019-09-14 18:02:24 +02:00
										 |  |  | use FireflyIII\Repositories\Account\AccountRepositoryInterface; | 
					
						
							| 
									
										
										
										
											2018-02-25 19:09:05 +01:00
										 |  |  | use FireflyIII\Repositories\Journal\JournalRepositoryInterface; | 
					
						
							| 
									
										
										
										
											2016-03-03 08:58:15 +01:00
										 |  |  | use FireflyIII\User; | 
					
						
							| 
									
										
										
										
											2015-02-27 11:02:08 +01:00
										 |  |  | use Illuminate\Support\Collection; | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  | use JsonException; | 
					
						
							| 
									
										
										
										
											2017-04-28 07:51:09 +02:00
										 |  |  | use Log; | 
					
						
							| 
									
										
										
										
											2020-05-07 06:44:01 +02:00
										 |  |  | use Storage; | 
					
						
							| 
									
										
										
										
											2015-02-25 19:32:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |  * Class PiggyBankRepository. | 
					
						
							| 
									
										
										
										
											2018-07-25 19:43:02 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2015-02-25 19:32:33 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | class PiggyBankRepository implements PiggyBankRepositoryInterface | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-03-21 14:20:40 +01:00
										 |  |  |     use ModifiesPiggyBanks; | 
					
						
							| 
									
										
										
										
											2020-09-07 13:03:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-23 19:11:25 +02:00
										 |  |  |     private User $user; | 
					
						
							| 
									
										
										
										
											2015-04-20 21:57:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-12 06:20:01 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @inheritDoc | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function destroyAll(): void | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->user->piggyBanks()->delete(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-17 17:05:16 +01:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |      * @param  int|null  $piggyBankId | 
					
						
							|  |  |  |      * @param  string|null  $piggyBankName | 
					
						
							| 
									
										
										
										
											2019-03-17 17:05:16 +01:00
										 |  |  |      * | 
					
						
							|  |  |  |      * @return PiggyBank|null | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2019-06-16 13:16:04 +02:00
										 |  |  |     public function findPiggyBank(?int $piggyBankId, ?string $piggyBankName): ?PiggyBank | 
					
						
							| 
									
										
										
										
											2019-03-17 17:05:16 +01:00
										 |  |  |     { | 
					
						
							|  |  |  |         Log::debug('Searching for piggy information.'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (null !== $piggyBankId) { | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |             $searchResult = $this->find((int)$piggyBankId); | 
					
						
							| 
									
										
										
										
											2019-03-17 17:05:16 +01:00
										 |  |  |             if (null !== $searchResult) { | 
					
						
							|  |  |  |                 Log::debug(sprintf('Found piggy based on #%d, will return it.', $piggyBankId)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 return $searchResult; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (null !== $piggyBankName) { | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |             $searchResult = $this->findByName((string)$piggyBankName); | 
					
						
							| 
									
										
										
										
											2019-03-17 17:05:16 +01:00
										 |  |  |             if (null !== $searchResult) { | 
					
						
							|  |  |  |                 Log::debug(sprintf('Found piggy based on "%s", will return it.', $piggyBankName)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 return $searchResult; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         Log::debug('Found nothing'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return null; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-29 14:59:58 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |      * @param  int  $piggyBankId | 
					
						
							| 
									
										
										
										
											2022-03-29 14:59:58 +02:00
										 |  |  |      * | 
					
						
							|  |  |  |      * @return PiggyBank|null | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function find(int $piggyBankId): ?PiggyBank | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-12-31 15:54:55 +01:00
										 |  |  |         // phpstan doesn't get the Model.
 | 
					
						
							|  |  |  |         return $this->user->piggyBanks()->find($piggyBankId); // @phpstan-ignore-line
 | 
					
						
							| 
									
										
										
										
											2022-03-29 14:59:58 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Find by name or return NULL. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |      * @param  string  $name | 
					
						
							| 
									
										
										
										
											2022-03-29 14:59:58 +02:00
										 |  |  |      * | 
					
						
							|  |  |  |      * @return PiggyBank|null | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function findByName(string $name): ?PiggyBank | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return $this->user->piggyBanks()->where('piggy_banks.name', $name)->first(['piggy_banks.*']); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-12 06:20:01 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @inheritDoc | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getAttachments(PiggyBank $piggyBank): Collection | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $set = $piggyBank->attachments()->get(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /** @var Storage $disk */ | 
					
						
							|  |  |  |         $disk = Storage::disk('upload'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $set->each( | 
					
						
							|  |  |  |             static function (Attachment $attachment) use ($disk) { | 
					
						
							|  |  |  |                 $notes                   = $attachment->notes()->first(); | 
					
						
							|  |  |  |                 $attachment->file_exists = $disk->exists($attachment->fileName()); | 
					
						
							| 
									
										
										
										
											2022-12-31 15:54:55 +01:00
										 |  |  |                 $attachment->notes       = $notes ? $notes->text : ''; // TODO setting the text to the 'notes' field doesn't work.
 | 
					
						
							| 
									
										
										
										
											2021-03-12 06:20:01 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 return $attachment; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-17 10:47:32 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get current amount saved in piggy bank. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |      * @param  PiggyBank  $piggyBank | 
					
						
							| 
									
										
										
										
											2018-02-17 10:47:32 +01:00
										 |  |  |      * | 
					
						
							|  |  |  |      * @return string | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getCurrentAmount(PiggyBank $piggyBank): string | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-04-21 23:48:54 +02:00
										 |  |  |         $rep = $this->getRepetition($piggyBank); | 
					
						
							| 
									
										
										
										
											2018-02-17 10:47:32 +01:00
										 |  |  |         if (null === $rep) { | 
					
						
							|  |  |  |             return '0'; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |         return (string)$rep->currentamount; | 
					
						
							| 
									
										
										
										
											2022-03-29 14:59:58 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |      * @param  PiggyBank  $piggyBank | 
					
						
							| 
									
										
										
										
											2022-03-29 14:59:58 +02:00
										 |  |  |      * | 
					
						
							|  |  |  |      * @return PiggyBankRepetition|null | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getRepetition(PiggyBank $piggyBank): ?PiggyBankRepetition | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return $piggyBank->piggyBankRepetitions()->first(); | 
					
						
							| 
									
										
										
										
											2018-02-17 10:47:32 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-20 21:57:20 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |      * @param  PiggyBank  $piggyBank | 
					
						
							| 
									
										
										
										
											2015-04-20 21:57:20 +02:00
										 |  |  |      * | 
					
						
							|  |  |  |      * @return Collection | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-04-06 09:27:45 +02:00
										 |  |  |     public function getEvents(PiggyBank $piggyBank): Collection | 
					
						
							| 
									
										
										
										
											2015-04-20 21:57:20 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         return $piggyBank->piggyBankEvents()->orderBy('date', 'DESC')->orderBy('id', 'DESC')->get(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-04-13 20:43:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-28 07:51:09 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Used for connecting to a piggy bank. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |      * @param  PiggyBank  $piggyBank | 
					
						
							|  |  |  |      * @param  PiggyBankRepetition  $repetition | 
					
						
							|  |  |  |      * @param  TransactionJournal  $journal | 
					
						
							| 
									
										
										
										
											2017-04-28 07:51:09 +02:00
										 |  |  |      * | 
					
						
							|  |  |  |      * @return string | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |      * @throws FireflyException | 
					
						
							|  |  |  |      * @throws JsonException | 
					
						
							| 
									
										
										
										
											2017-04-28 07:51:09 +02:00
										 |  |  |      */ | 
					
						
							|  |  |  |     public function getExactAmount(PiggyBank $piggyBank, PiggyBankRepetition $repetition, TransactionJournal $journal): string | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-09-14 18:02:24 +02:00
										 |  |  |         Log::debug(sprintf('Now in getExactAmount(%d, %d, %d)', $piggyBank->id, $repetition->id, $journal->id)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $operator = null; | 
					
						
							| 
									
										
										
										
											2020-09-07 13:03:10 +02:00
										 |  |  |         $currency = null; | 
					
						
							| 
									
										
										
										
											2019-09-14 18:02:24 +02:00
										 |  |  |         /** @var JournalRepositoryInterface $journalRepost */ | 
					
						
							|  |  |  |         $journalRepost = app(JournalRepositoryInterface::class); | 
					
						
							|  |  |  |         $journalRepost->setUser($this->user); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /** @var AccountRepositoryInterface $accountRepos */ | 
					
						
							|  |  |  |         $accountRepos = app(AccountRepositoryInterface::class); | 
					
						
							|  |  |  |         $accountRepos->setUser($this->user); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-12 06:20:01 +01:00
										 |  |  |         $defaultCurrency   = app('amount')->getDefaultCurrencyByUser($this->user); | 
					
						
							| 
									
										
										
										
											2019-09-14 18:02:24 +02:00
										 |  |  |         $piggyBankCurrency = $accountRepos->getAccountCurrency($piggyBank->account) ?? $defaultCurrency; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Log::debug(sprintf('Piggy bank #%d currency is %s', $piggyBank->id, $piggyBankCurrency->code)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /** @var Transaction $source */ | 
					
						
							| 
									
										
										
										
											2020-09-07 13:03:10 +02:00
										 |  |  |         $source = $journal->transactions()->with(['account'])->where('amount', '<', 0)->first(); | 
					
						
							| 
									
										
										
										
											2019-09-14 18:02:24 +02:00
										 |  |  |         /** @var Transaction $destination */ | 
					
						
							| 
									
										
										
										
											2020-09-07 13:03:10 +02:00
										 |  |  |         $destination = $journal->transactions()->with(['account'])->where('amount', '>', 0)->first(); | 
					
						
							| 
									
										
										
										
											2019-09-14 18:02:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // matches source, which means amount will be removed from piggy:
 | 
					
						
							|  |  |  |         if ($source->account_id === $piggyBank->account_id) { | 
					
						
							|  |  |  |             $operator = 'negative'; | 
					
						
							|  |  |  |             $currency = $accountRepos->getAccountCurrency($source->account) ?? $defaultCurrency; | 
					
						
							|  |  |  |             Log::debug(sprintf('Currency will draw money out of piggy bank. Source currency is %s', $currency->code)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // matches destination, which means amount will be added to piggy.
 | 
					
						
							|  |  |  |         if ($destination->account_id === $piggyBank->account_id) { | 
					
						
							|  |  |  |             $operator = 'positive'; | 
					
						
							|  |  |  |             $currency = $accountRepos->getAccountCurrency($destination->account) ?? $defaultCurrency; | 
					
						
							|  |  |  |             Log::debug(sprintf('Currency will add money to piggy bank. Destination currency is %s', $currency->code)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (null === $operator || null === $currency) { | 
					
						
							| 
									
										
										
										
											2020-09-07 13:03:10 +02:00
										 |  |  |             Log::debug('Currency is NULL and operator is NULL, return "0".'); | 
					
						
							| 
									
										
										
										
											2021-03-12 06:20:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-14 18:02:24 +02:00
										 |  |  |             return '0'; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         // currency of the account + the piggy bank currency are almost the same.
 | 
					
						
							|  |  |  |         // which amount from the transaction matches?
 | 
					
						
							|  |  |  |         $amount = null; | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |         if ((int)$source->transaction_currency_id === (int)$currency->id) { | 
					
						
							| 
									
										
										
										
											2019-09-14 18:02:24 +02:00
										 |  |  |             Log::debug('Use normal amount'); | 
					
						
							|  |  |  |             $amount = app('steam')->$operator($source->amount); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |         if ((int)$source->foreign_currency_id === (int)$currency->id) { | 
					
						
							| 
									
										
										
										
											2019-09-14 18:02:24 +02:00
										 |  |  |             Log::debug('Use foreign amount'); | 
					
						
							|  |  |  |             $amount = app('steam')->$operator($source->foreign_amount); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (null === $amount) { | 
					
						
							| 
									
										
										
										
											2020-09-07 13:03:10 +02:00
										 |  |  |             Log::debug('No match on currency, so amount remains null, return "0".'); | 
					
						
							| 
									
										
										
										
											2021-03-12 06:20:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-14 18:02:24 +02:00
										 |  |  |             return '0'; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Log::debug(sprintf('The currency is %s and the amount is %s', $currency->code, $amount)); | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |         $room    = bcsub((string)$piggyBank->targetamount, (string)$repetition->currentamount); | 
					
						
							| 
									
										
										
										
											2017-04-28 07:51:09 +02:00
										 |  |  |         $compare = bcmul($repetition->currentamount, '-1'); | 
					
						
							| 
									
										
										
										
											2022-05-04 20:27:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |         if (bccomp((string)$piggyBank->targetamount, '0') === 0) { | 
					
						
							| 
									
										
										
										
											2022-05-04 20:27:18 +02:00
										 |  |  |             // amount is zero? then the "room" is positive amount of we wish to add or remove.
 | 
					
						
							|  |  |  |             $room = app('steam')->positive($amount); | 
					
						
							|  |  |  |             Log::debug(sprintf('Room is now %s', $room)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-28 07:51:09 +02:00
										 |  |  |         Log::debug(sprintf('Will add/remove %f to piggy bank #%d ("%s")', $amount, $piggyBank->id, $piggyBank->name)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // if the amount is positive, make sure it fits in piggy bank:
 | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |         if (1 === bccomp($amount, '0') && bccomp($room, $amount) === -1) { | 
					
						
							| 
									
										
										
										
											2017-04-28 07:51:09 +02:00
										 |  |  |             // amount is positive and $room is smaller than $amount
 | 
					
						
							|  |  |  |             Log::debug(sprintf('Room in piggy bank for extra money is %f', $room)); | 
					
						
							|  |  |  |             Log::debug(sprintf('There is NO room to add %f to piggy bank #%d ("%s")', $amount, $piggyBank->id, $piggyBank->name)); | 
					
						
							|  |  |  |             Log::debug(sprintf('New amount is %f', $room)); | 
					
						
							| 
									
										
										
										
											2021-03-12 06:20:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-28 07:51:09 +02:00
										 |  |  |             return $room; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // amount is negative and $currentamount is smaller than $amount
 | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |         if (bccomp($amount, '0') === -1 && 1 === bccomp($compare, $amount)) { | 
					
						
							| 
									
										
										
										
											2017-04-28 07:51:09 +02:00
										 |  |  |             Log::debug(sprintf('Max amount to remove is %f', $repetition->currentamount)); | 
					
						
							|  |  |  |             Log::debug(sprintf('Cannot remove %f from piggy bank #%d ("%s")', $amount, $piggyBank->id, $piggyBank->name)); | 
					
						
							|  |  |  |             Log::debug(sprintf('New amount is %f', $compare)); | 
					
						
							| 
									
										
										
										
											2021-03-12 06:20:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-28 07:51:09 +02:00
										 |  |  |             return $compare; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |         return (string)$amount; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * @param  User  $user | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function setUser(User $user): void | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->user = $user; | 
					
						
							| 
									
										
										
										
											2017-04-28 07:51:09 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-24 20:38:58 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @return int | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-04-06 09:27:45 +02:00
										 |  |  |     public function getMaxOrder(): int | 
					
						
							| 
									
										
										
										
											2016-01-24 20:38:58 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |         return (int)$this->user->piggyBanks()->max('piggy_banks.order'); | 
					
						
							| 
									
										
										
										
											2016-01-24 20:38:58 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 05:46:05 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Return note for piggy bank. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |      * @param  PiggyBank  $piggyBank | 
					
						
							| 
									
										
										
										
											2018-12-20 05:46:05 +01:00
										 |  |  |      * | 
					
						
							|  |  |  |      * @return string | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getNoteText(PiggyBank $piggyBank): string | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         /** @var Note $note */ | 
					
						
							|  |  |  |         $note = $piggyBank->notes()->first(); | 
					
						
							|  |  |  |         if (null === $note) { | 
					
						
							|  |  |  |             return ''; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $note->text; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-15 12:08:41 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Also add amount in name. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return Collection | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-12-04 18:02:19 +01:00
										 |  |  |     public function getPiggyBanksWithAmount(): Collection | 
					
						
							| 
									
										
										
										
											2016-05-15 12:08:41 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-10-05 11:49:06 +02:00
										 |  |  |         $currency = app('amount')->getDefaultCurrency(); | 
					
						
							| 
									
										
										
										
											2017-06-04 23:39:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-24 21:12:48 +02:00
										 |  |  |         $set = $this->getPiggyBanks(); | 
					
						
							| 
									
										
										
										
											2020-06-27 13:08:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-24 21:12:48 +02:00
										 |  |  |         /** @var PiggyBank $piggy */ | 
					
						
							|  |  |  |         foreach ($set as $piggy) { | 
					
						
							|  |  |  |             $currentAmount = $this->getRepetition($piggy)->currentamount ?? '0'; | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |             $piggy->name   = $piggy->name.' ('.app('amount')->formatAnything($currency, $currentAmount, false).')'; | 
					
						
							| 
									
										
										
										
											2016-05-15 12:08:41 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-09-18 10:26:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-15 12:08:41 +02:00
										 |  |  |         return $set; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-28 07:51:09 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2022-03-29 14:59:58 +02:00
										 |  |  |      * @return Collection | 
					
						
							| 
									
										
										
										
											2018-04-21 23:48:54 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2022-03-29 14:59:58 +02:00
										 |  |  |     public function getPiggyBanks(): Collection | 
					
						
							| 
									
										
										
										
											2018-04-21 23:48:54 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-12-31 15:54:55 +01:00
										 |  |  |         return $this->user  // @phpstan-ignore-line (phpstan does not recognize objectGroups)
 | 
					
						
							| 
									
										
										
										
											2022-12-31 13:32:42 +01:00
										 |  |  |             ->piggyBanks() | 
					
						
							|  |  |  |             ->with( | 
					
						
							|  |  |  |                 ['account', | 
					
						
							| 
									
										
										
										
											2023-01-02 16:18:17 +01:00
										 |  |  |                  'objectGroups'] | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2022-12-31 13:32:42 +01:00
										 |  |  |             ->orderBy('order', 'ASC')->get(); | 
					
						
							| 
									
										
										
										
											2018-04-21 23:48:54 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-26 07:48:49 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Returns the suggested amount the user should save per month, or "". | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |      * @param  PiggyBank  $piggyBank | 
					
						
							| 
									
										
										
										
											2018-05-26 07:48:49 +02:00
										 |  |  |      * | 
					
						
							|  |  |  |      * @return string | 
					
						
							| 
									
										
										
										
											2019-08-17 10:47:29 +02:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2018-05-26 07:48:49 +02:00
										 |  |  |      */ | 
					
						
							|  |  |  |     public function getSuggestedMonthlyAmount(PiggyBank $piggyBank): string | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $savePerMonth = '0'; | 
					
						
							| 
									
										
										
										
											2021-03-12 06:20:01 +01:00
										 |  |  |         $repetition   = $this->getRepetition($piggyBank); | 
					
						
							| 
									
										
										
										
											2018-06-06 21:23:00 +02:00
										 |  |  |         if (null === $repetition) { | 
					
						
							| 
									
										
										
										
											2018-05-26 07:48:49 +02:00
										 |  |  |             return $savePerMonth; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (null !== $piggyBank->targetdate && $repetition->currentamount < $piggyBank->targetamount) { | 
					
						
							| 
									
										
										
										
											2023-02-11 07:36:45 +01:00
										 |  |  |             $now             = today(config('app.timezone')); | 
					
						
							| 
									
										
										
										
											2022-07-22 19:57:40 +10:00
										 |  |  |             $startDate       = null !== $piggyBank->startdate && $piggyBank->startdate->gte($now) ? $piggyBank->startdate : $now; | 
					
						
							|  |  |  |             $diffInMonths    = $startDate->diffInMonths($piggyBank->targetdate, false); | 
					
						
							| 
									
										
										
										
											2018-05-26 07:48:49 +02:00
										 |  |  |             $remainingAmount = bcsub($piggyBank->targetamount, $repetition->currentamount); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // more than 1 month to go and still need money to save:
 | 
					
						
							|  |  |  |             if ($diffInMonths > 0 && 1 === bccomp($remainingAmount, '0')) { | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |                 $savePerMonth = bcdiv($remainingAmount, (string)$diffInMonths); | 
					
						
							| 
									
										
										
										
											2018-05-26 07:48:49 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // less than 1 month to go but still need money to save:
 | 
					
						
							|  |  |  |             if (0 === $diffInMonths && 1 === bccomp($remainingAmount, '0')) { | 
					
						
							|  |  |  |                 $savePerMonth = $remainingAmount; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $savePerMonth; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-21 23:48:54 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get for piggy account what is left to put in piggies. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |      * @param  PiggyBank  $piggyBank | 
					
						
							|  |  |  |      * @param  Carbon  $date | 
					
						
							| 
									
										
										
										
											2017-04-28 07:51:09 +02:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2018-04-21 23:48:54 +02:00
										 |  |  |      * @return string | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |      * @throws JsonException | 
					
						
							| 
									
										
										
										
											2017-04-28 07:51:09 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2018-04-21 23:48:54 +02:00
										 |  |  |     public function leftOnAccount(PiggyBank $piggyBank, Carbon $date): string | 
					
						
							| 
									
										
										
										
											2017-04-28 07:51:09 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-04-21 23:48:54 +02:00
										 |  |  |         $balance = app('steam')->balanceIgnoreVirtual($piggyBank->account, $date); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /** @var Collection $piggies */ | 
					
						
							|  |  |  |         $piggies = $piggyBank->account->piggyBanks; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /** @var PiggyBank $current */ | 
					
						
							|  |  |  |         foreach ($piggies as $current) { | 
					
						
							|  |  |  |             $repetition = $this->getRepetition($current); | 
					
						
							| 
									
										
										
										
											2018-04-28 21:54:48 +02:00
										 |  |  |             if (null !== $repetition) { | 
					
						
							| 
									
										
										
										
											2018-04-21 23:48:54 +02:00
										 |  |  |                 $balance = bcsub($balance, $repetition->currentamount); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2017-04-28 07:51:09 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-21 23:48:54 +02:00
										 |  |  |         return $balance; | 
					
						
							| 
									
										
										
										
											2017-04-28 07:51:09 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-22 20:17:20 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @inheritDoc | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function searchPiggyBank(string $query, int $limit): Collection | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $search = $this->user->piggyBanks(); | 
					
						
							|  |  |  |         if ('' !== $query) { | 
					
						
							|  |  |  |             $search->where('piggy_banks.name', 'LIKE', sprintf('%%%s%%', $query)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         $search->orderBy('piggy_banks.order', 'ASC') | 
					
						
							| 
									
										
										
										
											2021-03-12 06:20:01 +01:00
										 |  |  |                ->orderBy('piggy_banks.name', 'ASC'); | 
					
						
							| 
									
										
										
										
											2020-07-22 20:17:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return $search->take($limit)->get(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-03-29 08:14:32 +02:00
										 |  |  | } |