| 
									
										
										
										
											2015-02-09 07:23:39 +01:00
										 |  |  | <?php | 
					
						
							| 
									
										
										
										
											2016-05-20 12:41:23 +02:00
										 |  |  | /** | 
					
						
							|  |  |  |  * AccountRepository.php | 
					
						
							| 
									
										
										
										
											2017-10-21 08:40:00 +02:00
										 |  |  |  * Copyright (c) 2017 thegrumpydictator@gmail.com | 
					
						
							| 
									
										
										
										
											2016-05-20 12:41:23 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2017-10-21 08:40:00 +02:00
										 |  |  |  * This file is part of Firefly III. | 
					
						
							| 
									
										
										
										
											2016-10-05 06:52:15 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2017-10-21 08:40:00 +02:00
										 |  |  |  * Firefly III is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  |  * the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  |  * (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Firefly III 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 General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							| 
									
										
										
										
											2017-12-17 14:44:05 +01:00
										 |  |  |  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							| 
									
										
										
										
											2016-05-20 12:41:23 +02:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-04-09 07:44:22 +02:00
										 |  |  | declare(strict_types=1); | 
					
						
							| 
									
										
										
										
											2016-05-20 08:57:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-09 07:23:39 +01:00
										 |  |  | namespace FireflyIII\Repositories\Account; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-21 12:16:41 +01:00
										 |  |  | use Carbon\Carbon; | 
					
						
							| 
									
										
										
										
											2015-04-13 20:43:58 +02:00
										 |  |  | use DB; | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  | use FireflyIII\Exceptions\FireflyException; | 
					
						
							| 
									
										
										
										
											2015-02-09 07:23:39 +01:00
										 |  |  | use FireflyIII\Models\Account; | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  | use FireflyIII\Models\AccountMeta; | 
					
						
							|  |  |  | use FireflyIII\Models\AccountType; | 
					
						
							| 
									
										
										
										
											2017-11-24 21:51:07 +01:00
										 |  |  | use FireflyIII\Models\Category; | 
					
						
							| 
									
										
										
										
											2017-12-30 21:04:04 +01:00
										 |  |  | use FireflyIII\Models\Note; | 
					
						
							| 
									
										
										
										
											2017-11-24 21:51:07 +01:00
										 |  |  | use FireflyIII\Models\Tag; | 
					
						
							| 
									
										
										
										
											2015-02-09 07:56:24 +01:00
										 |  |  | use FireflyIII\Models\Transaction; | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  | use FireflyIII\Models\TransactionJournal; | 
					
						
							|  |  |  | use FireflyIII\Models\TransactionType; | 
					
						
							| 
									
										
										
										
											2017-11-24 21:51:07 +01:00
										 |  |  | use FireflyIII\Repositories\Tag\TagRepositoryInterface; | 
					
						
							| 
									
										
										
										
											2016-03-20 11:47:10 +01:00
										 |  |  | use FireflyIII\User; | 
					
						
							| 
									
										
										
										
											2016-10-10 07:20:49 +02:00
										 |  |  | use Log; | 
					
						
							| 
									
										
										
										
											2017-07-14 17:57:20 +02:00
										 |  |  | use Validator; | 
					
						
							| 
									
										
										
										
											2015-02-09 07:23:39 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |  * Class AccountRepository. | 
					
						
							| 
									
										
										
										
											2015-02-09 07:23:39 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | class AccountRepository implements AccountRepositoryInterface | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-03-20 11:47:10 +01:00
										 |  |  |     /** @var User */ | 
					
						
							|  |  |  |     private $user; | 
					
						
							| 
									
										
										
										
											2017-11-24 21:51:07 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     use FindAccountsTrait; | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |     /** @var array */ | 
					
						
							| 
									
										
										
										
											2016-11-28 18:55:56 +01:00
										 |  |  |     private $validFields = ['accountRole', 'ccMonthlyPaymentDate', 'ccType', 'accountNumber', 'currency_id', 'BIC']; | 
					
						
							| 
									
										
										
										
											2016-03-30 17:47:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-09 08:18:47 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |      * Moved here from account CRUD. | 
					
						
							| 
									
										
										
										
											2016-10-09 08:18:47 +02:00
										 |  |  |      * | 
					
						
							|  |  |  |      * @param array $types | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return int | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-11-28 18:55:56 +01:00
										 |  |  |     public function count(array $types): int | 
					
						
							| 
									
										
										
										
											2016-10-09 08:18:47 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         $count = $this->user->accounts()->accountTypeIn($types)->count(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $count; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-09 08:20:29 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Moved here from account CRUD. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param Account $account | 
					
						
							|  |  |  |      * @param Account $moveTo | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return bool | 
					
						
							| 
									
										
										
										
											2017-12-22 18:32:43 +01:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2017-12-17 14:30:53 +01:00
										 |  |  |      * @throws \Exception | 
					
						
							| 
									
										
										
										
											2016-10-09 08:20:29 +02:00
										 |  |  |      */ | 
					
						
							|  |  |  |     public function destroy(Account $account, Account $moveTo): bool | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |         if (null !== $moveTo->id) { | 
					
						
							| 
									
										
										
										
											2016-10-09 08:20:29 +02:00
										 |  |  |             DB::table('transactions')->where('account_id', $account->id)->update(['account_id' => $moveTo->id]); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |         if (null !== $account) { | 
					
						
							| 
									
										
										
										
											2016-10-09 08:20:29 +02:00
										 |  |  |             $account->delete(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-31 10:40:27 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @param Account $account | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return Note|null | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getNote(Account $account): ?Note | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return $account->notes()->first(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-08 14:50:18 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2016-11-21 20:23:25 +01:00
										 |  |  |      * Returns the date of the very last transaction in this account. | 
					
						
							| 
									
										
										
										
											2016-04-08 14:50:18 +02:00
										 |  |  |      * | 
					
						
							|  |  |  |      * @param Account $account | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return Carbon | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-11-21 20:23:25 +01:00
										 |  |  |     public function newestJournalDate(Account $account): Carbon | 
					
						
							| 
									
										
										
										
											2016-04-08 14:50:18 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-11-21 20:23:25 +01:00
										 |  |  |         $last = new Carbon; | 
					
						
							| 
									
										
										
										
											2016-10-09 10:57:06 +02:00
										 |  |  |         $date = $account->transactions() | 
					
						
							|  |  |  |                         ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') | 
					
						
							| 
									
										
										
										
											2016-11-21 20:23:25 +01:00
										 |  |  |                         ->orderBy('transaction_journals.date', 'DESC') | 
					
						
							|  |  |  |                         ->orderBy('transaction_journals.order', 'ASC') | 
					
						
							|  |  |  |                         ->orderBy('transaction_journals.id', 'DESC') | 
					
						
							| 
									
										
										
										
											2016-10-09 10:57:06 +02:00
										 |  |  |                         ->first(['transaction_journals.date']); | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |         if (null !== $date) { | 
					
						
							| 
									
										
										
										
											2016-11-21 20:23:25 +01:00
										 |  |  |             $last = new Carbon($date->date); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $last; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Returns the date of the very first transaction in this account. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param Account $account | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2017-01-19 21:54:27 +01:00
										 |  |  |      * @return TransactionJournal | 
					
						
							| 
									
										
										
										
											2016-11-21 20:23:25 +01:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2017-01-19 21:54:27 +01:00
										 |  |  |     public function oldestJournal(Account $account): TransactionJournal | 
					
						
							| 
									
										
										
										
											2016-11-21 20:23:25 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-01-19 21:54:27 +01:00
										 |  |  |         $first = $account->transactions() | 
					
						
							| 
									
										
										
										
											2016-11-21 20:23:25 +01:00
										 |  |  |                          ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') | 
					
						
							|  |  |  |                          ->orderBy('transaction_journals.date', 'ASC') | 
					
						
							|  |  |  |                          ->orderBy('transaction_journals.order', 'DESC') | 
					
						
							| 
									
										
										
										
											2017-01-19 21:54:27 +01:00
										 |  |  |                          ->where('transaction_journals.user_id', $this->user->id) | 
					
						
							| 
									
										
										
										
											2016-11-21 20:23:25 +01:00
										 |  |  |                          ->orderBy('transaction_journals.id', 'ASC') | 
					
						
							| 
									
										
										
										
											2017-01-19 21:54:27 +01:00
										 |  |  |                          ->first(['transaction_journals.id']); | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |         if (null !== $first) { | 
					
						
							| 
									
										
										
										
											2017-01-19 21:54:27 +01:00
										 |  |  |             return TransactionJournal::find(intval($first->id)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return new TransactionJournal(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Returns the date of the very first transaction in this account. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param Account $account | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return Carbon | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function oldestJournalDate(Account $account): Carbon | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $journal = $this->oldestJournal($account); | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |         if (null === $journal->id) { | 
					
						
							| 
									
										
										
										
											2017-01-19 21:54:27 +01:00
										 |  |  |             return new Carbon; | 
					
						
							| 
									
										
										
										
											2016-04-08 14:50:18 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-19 21:54:27 +01:00
										 |  |  |         return $journal->date; | 
					
						
							| 
									
										
										
										
											2016-04-08 14:50:18 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-30 16:42:58 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @param User $user | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function setUser(User $user) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->user = $user; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @param array $data | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return Account | 
					
						
							| 
									
										
										
										
											2017-12-22 18:32:43 +01:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2017-12-10 12:00:08 +01:00
										 |  |  |      * @throws FireflyException | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |      */ | 
					
						
							|  |  |  |     public function store(array $data): Account | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $newAccount = $this->storeAccount($data); | 
					
						
							|  |  |  |         $this->updateMetadata($newAccount, $data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($this->validOpeningBalanceData($data)) { | 
					
						
							|  |  |  |             $this->updateInitialBalance($newAccount, $data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return $newAccount; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         $this->deleteInitialBalance($newAccount); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-30 21:04:04 +01:00
										 |  |  |         // update note:
 | 
					
						
							|  |  |  |         if (isset($data['notes'])) { | 
					
						
							|  |  |  |             $this->updateNote($newAccount, $data['notes']); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |         return $newAccount; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * @param Account $account | 
					
						
							|  |  |  |      * @param array   $data | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return Account | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function update(Account $account, array $data): Account | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // update the account:
 | 
					
						
							|  |  |  |         $account->name            = $data['name']; | 
					
						
							| 
									
										
										
										
											2017-07-25 21:01:25 +02:00
										 |  |  |         $account->active          = $data['active']; | 
					
						
							| 
									
										
										
										
											2017-12-29 09:05:35 +01:00
										 |  |  |         $account->virtual_balance = trim($data['virtualBalance']) === '' ? '0' : $data['virtualBalance']; | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |         $account->iban            = $data['iban']; | 
					
						
							|  |  |  |         $account->save(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $this->updateMetadata($account, $data); | 
					
						
							| 
									
										
										
										
											2016-12-24 17:36:51 +01:00
										 |  |  |         if ($this->validOpeningBalanceData($data)) { | 
					
						
							|  |  |  |             $this->updateInitialBalance($account, $data); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-30 21:04:04 +01:00
										 |  |  |         // update note:
 | 
					
						
							|  |  |  |         if (isset($data['notes']) && null !== $data['notes']) { | 
					
						
							|  |  |  |             $this->updateNote($account, strval($data['notes'])); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |         return $account; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-24 21:51:07 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @param TransactionJournal $journal | 
					
						
							|  |  |  |      * @param array              $data | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return TransactionJournal | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function updateReconciliation(TransactionJournal $journal, array $data): TransactionJournal | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // update journal
 | 
					
						
							|  |  |  |         // update actual journal:
 | 
					
						
							|  |  |  |         $data['amount'] = strval($data['amount']); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // unlink all categories, recreate them:
 | 
					
						
							|  |  |  |         $journal->categories()->detach(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $this->storeCategoryWithJournal($journal, strval($data['category'])); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // update amounts
 | 
					
						
							|  |  |  |         /** @var Transaction $transaction */ | 
					
						
							|  |  |  |         foreach ($journal->transactions as $transaction) { | 
					
						
							|  |  |  |             $transaction->amount = bcmul($data['amount'], '-1'); | 
					
						
							| 
									
										
										
										
											2017-12-22 18:32:43 +01:00
										 |  |  |             if (AccountType::ASSET === $transaction->account->accountType->type) { | 
					
						
							| 
									
										
										
										
											2017-11-24 21:51:07 +01:00
										 |  |  |                 $transaction->amount = $data['amount']; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             $transaction->save(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $journal->save(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // update tags:
 | 
					
						
							|  |  |  |         if (isset($data['tags']) && is_array($data['tags'])) { | 
					
						
							|  |  |  |             $this->updateTags($journal, $data['tags']); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $journal; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @param Account $account | 
					
						
							| 
									
										
										
										
											2017-12-17 14:30:53 +01:00
										 |  |  |      * | 
					
						
							|  |  |  |      * @throws \Exception | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |      */ | 
					
						
							|  |  |  |     protected function deleteInitialBalance(Account $account) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $journal = $this->openingBalanceTransaction($account); | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |         if (null !== $journal->id) { | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |             $journal->delete(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * @param Account $account | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return TransactionJournal|null | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function openingBalanceTransaction(Account $account): TransactionJournal | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-11-01 19:30:13 +01:00
										 |  |  |         $journal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') | 
					
						
							| 
									
										
										
										
											2016-12-04 18:02:19 +01:00
										 |  |  |                                      ->where('transactions.account_id', $account->id) | 
					
						
							|  |  |  |                                      ->transactionTypes([TransactionType::OPENING_BALANCE]) | 
					
						
							|  |  |  |                                      ->first(['transaction_journals.*']); | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |         if (null === $journal) { | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |             Log::debug('Could not find a opening balance journal, return empty one.'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return new TransactionJournal; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         Log::debug(sprintf('Found opening balance: journal #%d.', $journal->id)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $journal; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * @param array $data | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return Account | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |      * @throws FireflyException | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function storeAccount(array $data): Account | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $data['accountType'] = $data['accountType'] ?? 'invalid'; | 
					
						
							|  |  |  |         $type                = config('firefly.accountTypeByIdentifier.' . $data['accountType']); | 
					
						
							|  |  |  |         $accountType         = AccountType::whereType($type)->first(); | 
					
						
							| 
									
										
										
										
											2017-07-14 17:57:20 +02:00
										 |  |  |         $data['iban']        = $this->filterIban($data['iban']); | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |         // verify account type
 | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |         if (null === $accountType) { | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |             throw new FireflyException(sprintf('Account type "%s" is invalid. Cannot create account.', $data['accountType'])); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // account may exist already:
 | 
					
						
							| 
									
										
										
										
											2017-06-20 21:04:25 +02:00
										 |  |  |         $existingAccount = $this->findByName($data['name'], [$type]); | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |         if (null !== $existingAccount->id) { | 
					
						
							| 
									
										
										
										
											2017-06-20 21:04:25 +02:00
										 |  |  |             Log::warning(sprintf('There already is an account named "%s" of type "%s".', $data['name'], $type)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return $existingAccount; | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // create it:
 | 
					
						
							| 
									
										
										
										
											2017-07-14 17:57:20 +02:00
										 |  |  |         $databaseData | 
					
						
							|  |  |  |                     = [ | 
					
						
							|  |  |  |             'user_id'         => $this->user->id, | 
					
						
							|  |  |  |             'account_type_id' => $accountType->id, | 
					
						
							|  |  |  |             'name'            => $data['name'], | 
					
						
							| 
									
										
										
										
											2017-12-26 08:32:00 +01:00
										 |  |  |             'virtual_balance' => strlen(strval($data['virtualBalance'])) === 0 ? '0' : $data['virtualBalance'], | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |             'active'          => true === $data['active'] ? true : false, | 
					
						
							| 
									
										
										
										
											2017-07-14 17:57:20 +02:00
										 |  |  |             'iban'            => $data['iban'], | 
					
						
							|  |  |  |         ]; | 
					
						
							|  |  |  |         $newAccount = new Account($databaseData); | 
					
						
							|  |  |  |         Log::debug('Final account creation dataset', $databaseData); | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |         $newAccount->save(); | 
					
						
							|  |  |  |         // verify its creation:
 | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |         if (null === $newAccount->id) { | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |             Log::error( | 
					
						
							| 
									
										
										
										
											2017-11-15 10:52:29 +01:00
										 |  |  |                 sprintf('Could not create account "%s" (%d error(s))', $data['name'], $newAccount->getErrors()->count()), | 
					
						
							|  |  |  |                 $newAccount->getErrors()->toArray() | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |             ); | 
					
						
							|  |  |  |             throw new FireflyException(sprintf('Tried to create account named "%s" but failed. The logs have more details.', $data['name'])); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-06-20 21:04:25 +02:00
										 |  |  |         Log::debug(sprintf('Created new account #%d named "%s" of type %s.', $newAccount->id, $newAccount->name, $accountType->type)); | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return $newAccount; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-24 21:51:07 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @param TransactionJournal $journal | 
					
						
							|  |  |  |      * @param string             $category | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function storeCategoryWithJournal(TransactionJournal $journal, string $category) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (strlen($category) > 0) { | 
					
						
							|  |  |  |             $category = Category::firstOrCreateEncrypted(['name' => $category, 'user_id' => $journal->user_id]); | 
					
						
							|  |  |  |             $journal->categories()->save($category); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2017-11-01 19:30:13 +01:00
										 |  |  |      * At this point strlen of amount > 0. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |      * @param Account $account | 
					
						
							|  |  |  |      * @param array   $data | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return TransactionJournal | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function storeInitialBalance(Account $account, array $data): TransactionJournal | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-02 13:00:24 +02:00
										 |  |  |         $amount = strval($data['openingBalance']); | 
					
						
							| 
									
										
										
										
											2017-11-05 19:49:20 +01:00
										 |  |  |         Log::debug(sprintf('Submitted amount is %s', $amount)); | 
					
						
							| 
									
										
										
										
											2017-06-02 13:00:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |         if (0 === bccomp($amount, '0')) { | 
					
						
							| 
									
										
										
										
											2017-06-02 13:00:24 +02:00
										 |  |  |             return new TransactionJournal; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |         $name            = $data['name']; | 
					
						
							| 
									
										
										
										
											2017-04-14 07:32:30 +02:00
										 |  |  |         $currencyId      = $data['currency_id']; | 
					
						
							| 
									
										
										
										
											2016-12-21 20:31:44 +01:00
										 |  |  |         $opposing        = $this->storeOpposingAccount($name); | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |         $transactionType = TransactionType::whereType(TransactionType::OPENING_BALANCE)->first(); | 
					
						
							| 
									
										
										
										
											2017-02-25 05:57:01 +01:00
										 |  |  |         /** @var TransactionJournal $journal */ | 
					
						
							|  |  |  |         $journal = TransactionJournal::create( | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |             [ | 
					
						
							| 
									
										
										
										
											2016-10-23 12:19:32 +02:00
										 |  |  |                 'user_id'                 => $this->user->id, | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |                 'transaction_type_id'     => $transactionType->id, | 
					
						
							| 
									
										
										
										
											2017-04-14 07:32:30 +02:00
										 |  |  |                 'transaction_currency_id' => $currencyId, | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |                 'description'             => 'Initial balance for "' . $account->name . '"', | 
					
						
							|  |  |  |                 'completed'               => true, | 
					
						
							|  |  |  |                 'date'                    => $data['openingBalanceDate'], | 
					
						
							|  |  |  |             ] | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2017-12-10 12:00:08 +01:00
										 |  |  |         Log::notice(sprintf('Created new opening balance journal: #%d', $journal->id)); | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $firstAccount  = $account; | 
					
						
							|  |  |  |         $secondAccount = $opposing; | 
					
						
							|  |  |  |         $firstAmount   = $amount; | 
					
						
							| 
									
										
										
										
											2017-06-02 13:00:24 +02:00
										 |  |  |         $secondAmount  = bcmul($amount, '-1'); | 
					
						
							| 
									
										
										
										
											2017-12-10 12:00:08 +01:00
										 |  |  |         Log::notice(sprintf('First amount is %s, second amount is %s', $firstAmount, $secondAmount)); | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-05 19:49:20 +01:00
										 |  |  |         if (bccomp($amount, '0') === -1) { | 
					
						
							| 
									
										
										
										
											2017-11-01 19:30:13 +01:00
										 |  |  |             Log::debug(sprintf('%s is a negative number.', $amount)); | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |             $firstAccount  = $opposing; | 
					
						
							|  |  |  |             $secondAccount = $account; | 
					
						
							| 
									
										
										
										
											2017-06-02 13:00:24 +02:00
										 |  |  |             $firstAmount   = bcmul($amount, '-1'); | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |             $secondAmount  = $amount; | 
					
						
							| 
									
										
										
										
											2017-12-10 12:00:08 +01:00
										 |  |  |             Log::notice(sprintf('First amount is %s, second amount is %s', $firstAmount, $secondAmount)); | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-04 23:39:26 +02:00
										 |  |  |         $one = new Transaction( | 
					
						
							|  |  |  |             [ | 
					
						
							|  |  |  |                 'account_id'              => $firstAccount->id, | 
					
						
							|  |  |  |                 'transaction_journal_id'  => $journal->id, | 
					
						
							|  |  |  |                 'amount'                  => $firstAmount, | 
					
						
							|  |  |  |                 'transaction_currency_id' => $currencyId, | 
					
						
							|  |  |  |             ] | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |         $one->save(); // first transaction: from
 | 
					
						
							| 
									
										
										
										
											2017-06-04 23:39:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $two = new Transaction( | 
					
						
							|  |  |  |             [ | 
					
						
							|  |  |  |                 'account_id'              => $secondAccount->id, | 
					
						
							|  |  |  |                 'transaction_journal_id'  => $journal->id, | 
					
						
							|  |  |  |                 'amount'                  => $secondAmount, | 
					
						
							|  |  |  |                 'transaction_currency_id' => $currencyId,] | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |         $two->save(); // second transaction: to
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-10 12:00:08 +01:00
										 |  |  |         Log::notice(sprintf('Stored two transactions for new account, #%d and #%d', $one->id, $two->id)); | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return $journal; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * @param string $name | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return Account | 
					
						
							| 
									
										
										
										
											2017-12-22 18:32:43 +01:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2017-12-17 14:30:53 +01:00
										 |  |  |      * @throws FireflyException | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-12-21 20:31:44 +01:00
										 |  |  |     protected function storeOpposingAccount(string $name): Account | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         $opposingData = [ | 
					
						
							| 
									
										
										
										
											2016-12-21 20:31:44 +01:00
										 |  |  |             'accountType'    => 'initial', | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |             'name'           => $name . ' initial balance', | 
					
						
							|  |  |  |             'active'         => false, | 
					
						
							|  |  |  |             'iban'           => '', | 
					
						
							| 
									
										
										
										
											2017-12-28 18:28:22 +01:00
										 |  |  |             'virtualBalance' => '0', | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |         ]; | 
					
						
							| 
									
										
										
										
											2016-12-21 20:31:44 +01:00
										 |  |  |         Log::debug('Going to create an opening balance opposing account.'); | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return $this->storeAccount($opposingData); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * @param Account $account | 
					
						
							|  |  |  |      * @param array   $data | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return bool | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function updateInitialBalance(Account $account, array $data): bool | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-11-01 19:30:13 +01:00
										 |  |  |         Log::debug(sprintf('updateInitialBalance() for account #%d', $account->id)); | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |         $openingBalance = $this->openingBalanceTransaction($account); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // no opening balance journal? create it:
 | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |         if (null === $openingBalance->id) { | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |             Log::debug('No opening balance journal yet, create journal.'); | 
					
						
							|  |  |  |             $this->storeInitialBalance($account, $data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         // opening balance data? update it!
 | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |         if (null !== $openingBalance->id) { | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |             Log::debug('Opening balance journal found, update journal.'); | 
					
						
							| 
									
										
										
										
											2017-04-14 07:11:30 +02:00
										 |  |  |             $this->updateOpeningBalanceJournal($account, $openingBalance, $data); | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * @param Account $account | 
					
						
							|  |  |  |      * @param array   $data | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function updateMetadata(Account $account, array $data) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         foreach ($this->validFields as $field) { | 
					
						
							|  |  |  |             /** @var AccountMeta $entry */ | 
					
						
							|  |  |  |             $entry = $account->accountMeta()->where('name', $field)->first(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // if $data has field and $entry is null, create new one:
 | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |             if (isset($data[$field]) && null === $entry) { | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |                 Log::debug( | 
					
						
							|  |  |  |                     sprintf( | 
					
						
							|  |  |  |                         'Created meta-field "%s":"%s" for account #%d ("%s") ', | 
					
						
							| 
									
										
										
										
											2017-11-15 10:52:29 +01:00
										 |  |  |                         $field, | 
					
						
							|  |  |  |                         $data[$field], | 
					
						
							|  |  |  |                         $account->id, | 
					
						
							|  |  |  |                         $account->name | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |                     ) | 
					
						
							|  |  |  |                 ); | 
					
						
							|  |  |  |                 AccountMeta::create( | 
					
						
							|  |  |  |                     [ | 
					
						
							|  |  |  |                         'account_id' => $account->id, | 
					
						
							|  |  |  |                         'name'       => $field, | 
					
						
							|  |  |  |                         'data'       => $data[$field], | 
					
						
							|  |  |  |                     ] | 
					
						
							|  |  |  |                 ); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // if $data has field and $entry is not null, update $entry:
 | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |             if (isset($data[$field]) && null !== $entry) { | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |                 $entry->data = $data[$field]; | 
					
						
							|  |  |  |                 $entry->save(); | 
					
						
							|  |  |  |                 Log::debug( | 
					
						
							|  |  |  |                     sprintf( | 
					
						
							|  |  |  |                         'Updated meta-field "%s":"%s" for account #%d ("%s") ', | 
					
						
							| 
									
										
										
										
											2017-11-15 10:52:29 +01:00
										 |  |  |                         $field, | 
					
						
							|  |  |  |                         $data[$field], | 
					
						
							|  |  |  |                         $account->id, | 
					
						
							|  |  |  |                         $account->name | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |                     ) | 
					
						
							|  |  |  |                 ); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-30 21:04:04 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @param Account $account | 
					
						
							|  |  |  |      * @param string  $note | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return bool | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function updateNote(Account $account, string $note): bool | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (0 === strlen($note)) { | 
					
						
							|  |  |  |             $dbNote = $account->notes()->first(); | 
					
						
							|  |  |  |             if (null !== $dbNote) { | 
					
						
							|  |  |  |                 $dbNote->delete(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         $dbNote = $account->notes()->first(); | 
					
						
							|  |  |  |         if (null === $dbNote) { | 
					
						
							|  |  |  |             $dbNote = new Note(); | 
					
						
							|  |  |  |             $dbNote->noteable()->associate($account); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         $dbNote->text = trim($note); | 
					
						
							|  |  |  |         $dbNote->save(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @param Account            $account | 
					
						
							|  |  |  |      * @param TransactionJournal $journal | 
					
						
							| 
									
										
										
										
											2017-04-14 07:11:30 +02:00
										 |  |  |      * @param array              $data | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |      * | 
					
						
							|  |  |  |      * @return bool | 
					
						
							| 
									
										
										
										
											2017-12-22 18:32:43 +01:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2017-12-17 14:30:53 +01:00
										 |  |  |      * @throws \Exception | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2017-04-14 07:11:30 +02:00
										 |  |  |     protected function updateOpeningBalanceJournal(Account $account, TransactionJournal $journal, array $data): bool | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-01-04 22:44:47 +01:00
										 |  |  |         $date           = $data['openingBalanceDate']; | 
					
						
							|  |  |  |         $amount         = strval($data['openingBalance']); | 
					
						
							|  |  |  |         $negativeAmount = bcmul($amount, '-1'); | 
					
						
							|  |  |  |         $currencyId     = intval($data['currency_id']); | 
					
						
							| 
									
										
										
										
											2017-04-14 07:11:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-04 22:44:47 +01:00
										 |  |  |         Log::debug(sprintf('Submitted amount for opening balance to update is "%s"', $amount)); | 
					
						
							| 
									
										
										
										
											2017-11-01 19:30:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |         if (0 === bccomp($amount, '0')) { | 
					
						
							| 
									
										
										
										
											2018-01-04 22:44:47 +01:00
										 |  |  |             Log::notice(sprintf('Amount "%s" is zero, delete opening balance.', $amount)); | 
					
						
							| 
									
										
										
										
											2017-06-02 13:00:24 +02:00
										 |  |  |             $journal->delete(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |         // update date:
 | 
					
						
							| 
									
										
										
										
											2017-04-14 07:11:30 +02:00
										 |  |  |         $journal->date                    = $date; | 
					
						
							|  |  |  |         $journal->transaction_currency_id = $currencyId; | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |         $journal->save(); | 
					
						
							| 
									
										
										
										
											2018-01-04 22:44:47 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |         // update transactions:
 | 
					
						
							|  |  |  |         /** @var Transaction $transaction */ | 
					
						
							|  |  |  |         foreach ($journal->transactions()->get() as $transaction) { | 
					
						
							| 
									
										
										
										
											2018-01-04 22:44:47 +01:00
										 |  |  |             if (intval($account->id) === intval($transaction->account_id)) { | 
					
						
							|  |  |  |                 Log::debug(sprintf('Will (eq) change transaction #%d amount from "%s" to "%s"', $transaction->id, $transaction->amount, $amount)); | 
					
						
							| 
									
										
										
										
											2017-06-04 23:39:26 +02:00
										 |  |  |                 $transaction->amount                  = $amount; | 
					
						
							|  |  |  |                 $transaction->transaction_currency_id = $currencyId; | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |                 $transaction->save(); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-01-04 22:44:47 +01:00
										 |  |  |             if (!(intval($account->id) === intval($transaction->account_id))) { | 
					
						
							|  |  |  |                 Log::debug(sprintf('Will (neq) change transaction #%d amount from "%s" to "%s"', $transaction->id, $transaction->amount, $negativeAmount)); | 
					
						
							| 
									
										
										
										
											2017-11-01 19:30:13 +01:00
										 |  |  |                 $transaction->amount                  = $negativeAmount; | 
					
						
							| 
									
										
										
										
											2017-06-04 23:39:26 +02:00
										 |  |  |                 $transaction->transaction_currency_id = $currencyId; | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |                 $transaction->save(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         Log::debug('Updated opening balance journal.'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-24 21:51:07 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @param TransactionJournal $journal | 
					
						
							|  |  |  |      * @param array              $array | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return bool | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function updateTags(TransactionJournal $journal, array $array): bool | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // create tag repository
 | 
					
						
							|  |  |  |         /** @var TagRepositoryInterface $tagRepository */ | 
					
						
							|  |  |  |         $tagRepository = app(TagRepositoryInterface::class); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 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 (0 === count($ids)) { | 
					
						
							|  |  |  |             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) { | 
					
						
							|  |  |  |             Log::debug(sprintf('Will try to connect tag #%d to journal #%d.', $tag->id, $journal->id)); | 
					
						
							|  |  |  |             $tagRepository->connect($journal, $tag); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @param array $data | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return bool | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function validOpeningBalanceData(array $data): bool | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-11-01 20:04:25 +01:00
										 |  |  |         $data['openingBalance'] = strval($data['openingBalance'] ?? ''); | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |         if (isset($data['openingBalance']) && null !== $data['openingBalance'] && strlen($data['openingBalance']) > 0 | 
					
						
							| 
									
										
										
										
											2017-11-05 19:49:20 +01:00
										 |  |  |             && isset($data['openingBalanceDate'])) { | 
					
						
							| 
									
										
										
										
											2016-10-10 08:03:03 +02:00
										 |  |  |             Log::debug('Array has valid opening balance data.'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         Log::debug('Array does not have valid opening balance data.'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-07-14 17:57:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2017-07-23 08:16:11 +02:00
										 |  |  |      * @param null|string $iban | 
					
						
							| 
									
										
										
										
											2017-07-14 17:57:20 +02:00
										 |  |  |      * | 
					
						
							|  |  |  |      * @return null|string | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2017-07-23 19:06:24 +02:00
										 |  |  |     private function filterIban(?string $iban) | 
					
						
							| 
									
										
										
										
											2017-07-14 17:57:20 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |         if (null === $iban) { | 
					
						
							| 
									
										
										
										
											2017-07-14 17:57:20 +02:00
										 |  |  |             return null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         $data      = ['iban' => $iban]; | 
					
						
							|  |  |  |         $rules     = ['iban' => 'required|iban']; | 
					
						
							|  |  |  |         $validator = Validator::make($data, $rules); | 
					
						
							|  |  |  |         if ($validator->fails()) { | 
					
						
							|  |  |  |             Log::error(sprintf('Detected invalid IBAN ("%s"). Return NULL instead.', $iban)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $iban; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-03-29 08:14:32 +02:00
										 |  |  | } |