| 
									
										
										
										
											2018-02-21 18:42:15 +01:00
										 |  |  | <?php | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * AccountDestroyService.php | 
					
						
							| 
									
										
										
										
											2020-02-16 13:56:35 +01:00
										 |  |  |  * Copyright (c) 2019 james@firefly-iii.org | 
					
						
							| 
									
										
										
										
											2018-02-21 18:42:15 +01:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-10-02 06:37:26 +02:00
										 |  |  |  * This file is part of Firefly III (https://github.com/firefly-iii). | 
					
						
							| 
									
										
										
										
											2018-02-21 18:42:15 +01: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. | 
					
						
							| 
									
										
										
										
											2018-02-21 18:42:15 +01:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-10-02 06:37:26 +02:00
										 |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							| 
									
										
										
										
											2018-02-21 18:42:15 +01: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. | 
					
						
							| 
									
										
										
										
											2018-02-21 18:42:15 +01: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/>. | 
					
						
							| 
									
										
										
										
											2018-02-21 18:42:15 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | declare(strict_types=1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace FireflyIII\Services\Internal\Destroy; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | use DB; | 
					
						
							|  |  |  | use FireflyIII\Models\Account; | 
					
						
							| 
									
										
										
										
											2018-10-17 05:04:26 +02:00
										 |  |  | use FireflyIII\Models\PiggyBank; | 
					
						
							| 
									
										
										
										
											2018-08-11 19:21:58 +02:00
										 |  |  | use FireflyIII\Models\RecurrenceTransaction; | 
					
						
							| 
									
										
										
										
											2018-02-21 18:42:15 +01:00
										 |  |  | use FireflyIII\Models\Transaction; | 
					
						
							| 
									
										
										
										
											2018-03-02 16:31:02 +01:00
										 |  |  | use FireflyIII\Models\TransactionJournal; | 
					
						
							| 
									
										
										
										
											2019-08-18 09:00:15 +02:00
										 |  |  | use FireflyIII\Models\TransactionType; | 
					
						
							| 
									
										
										
										
											2018-08-11 19:21:58 +02:00
										 |  |  | use Illuminate\Database\Eloquent\Builder; | 
					
						
							| 
									
										
										
										
											2023-04-01 07:04:42 +02:00
										 |  |  | use Illuminate\Support\Facades\Log; | 
					
						
							| 
									
										
										
										
											2021-05-24 08:54:58 +02:00
										 |  |  | use stdClass; | 
					
						
							| 
									
										
										
										
											2018-02-21 18:42:15 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Class AccountDestroyService | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class AccountDestroyService | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |      * @param  Account  $account | 
					
						
							|  |  |  |      * @param  Account|null  $moveTo | 
					
						
							| 
									
										
										
										
											2018-02-21 18:42:15 +01:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2018-03-25 09:01:43 +02:00
										 |  |  |      * @return void | 
					
						
							| 
									
										
										
										
											2018-02-21 18:42:15 +01:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2018-03-25 09:01:43 +02:00
										 |  |  |     public function destroy(Account $account, ?Account $moveTo): void | 
					
						
							| 
									
										
										
										
											2018-02-21 18:42:15 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-08-18 09:00:15 +02:00
										 |  |  |         // find and delete opening balance journal + opposing account
 | 
					
						
							|  |  |  |         $this->destroyOpeningBalance($account); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 18:42:15 +01:00
										 |  |  |         if (null !== $moveTo) { | 
					
						
							| 
									
										
										
										
											2019-07-31 16:53:09 +02:00
										 |  |  |             $this->moveTransactions($account, $moveTo); | 
					
						
							|  |  |  |             $this->updateRecurrences($account, $moveTo); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         $this->destroyJournals($account); | 
					
						
							| 
									
										
										
										
											2018-08-11 19:21:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-31 16:53:09 +02:00
										 |  |  |         // delete recurring transactions with this account:
 | 
					
						
							|  |  |  |         if (null === $moveTo) { | 
					
						
							|  |  |  |             $this->destroyRecurrences($account); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // delete piggy banks:
 | 
					
						
							|  |  |  |         PiggyBank::where('account_id', $account->id)->delete(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-18 09:00:15 +02:00
										 |  |  |         // delete account meta:
 | 
					
						
							|  |  |  |         $account->accountMeta()->delete(); | 
					
						
							| 
									
										
										
										
											2019-07-31 16:53:09 +02:00
										 |  |  |         // delete account.
 | 
					
						
							| 
									
										
										
										
											2022-12-30 20:25:04 +01:00
										 |  |  |         $account->delete(); | 
					
						
							| 
									
										
										
										
											2019-07-31 16:53:09 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-18 09:00:15 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |      * @param  Account  $account | 
					
						
							| 
									
										
										
										
											2019-08-18 09:00:15 +02:00
										 |  |  |      */ | 
					
						
							|  |  |  |     private function destroyOpeningBalance(Account $account): void | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         Log::debug(sprintf('Searching for opening balance for account #%d "%s"', $account->id, $account->name)); | 
					
						
							|  |  |  |         $set = $account->transactions() | 
					
						
							|  |  |  |                        ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') | 
					
						
							|  |  |  |                        ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') | 
					
						
							|  |  |  |                        ->where('transaction_types.type', TransactionType::OPENING_BALANCE) | 
					
						
							|  |  |  |                        ->get(['transactions.transaction_journal_id']); | 
					
						
							|  |  |  |         if ($set->count() > 0) { | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |             $journalId = (int)$set->first()->transaction_journal_id; | 
					
						
							| 
									
										
										
										
											2019-08-18 09:00:15 +02:00
										 |  |  |             Log::debug(sprintf('Found opening balance journal with ID #%d', $journalId)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // get transactions with this journal (should be just one):
 | 
					
						
							| 
									
										
										
										
											2022-10-30 14:24:37 +01:00
										 |  |  |             $transactions = Transaction::where('transaction_journal_id', $journalId) | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |                                        ->where('account_id', '!=', $account->id) | 
					
						
							|  |  |  |                                        ->get(); | 
					
						
							| 
									
										
										
										
											2019-08-18 09:00:15 +02:00
										 |  |  |             /** @var Transaction $transaction */ | 
					
						
							|  |  |  |             foreach ($transactions as $transaction) { | 
					
						
							|  |  |  |                 Log::debug(sprintf('Found transaction with ID #%d', $transaction->id)); | 
					
						
							|  |  |  |                 $ibAccount = $transaction->account; | 
					
						
							|  |  |  |                 Log::debug(sprintf('Connected to account #%d "%s"', $ibAccount->id, $ibAccount->name)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 $ibAccount->accountMeta()->delete(); | 
					
						
							|  |  |  |                 $transaction->delete(); | 
					
						
							|  |  |  |                 $ibAccount->delete(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             $journal = TransactionJournal::find($journalId); | 
					
						
							|  |  |  |             /** @var JournalDestroyService $service */ | 
					
						
							|  |  |  |             $service = app(JournalDestroyService::class); | 
					
						
							|  |  |  |             $service->destroy($journal); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-15 10:31:11 +01:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |      * @param  Account  $account | 
					
						
							|  |  |  |      * @param  Account  $moveTo | 
					
						
							| 
									
										
										
										
											2021-03-15 10:31:11 +01:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-04-03 13:56:45 +02:00
										 |  |  |     public function moveTransactions(Account $account, Account $moveTo): void | 
					
						
							| 
									
										
										
										
											2021-03-15 10:31:11 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-04-05 10:56:08 +02:00
										 |  |  |         Log::debug(sprintf('Move from account #%d to #%d', $account->id, $moveTo->id)); | 
					
						
							| 
									
										
										
										
											2021-03-15 10:31:11 +01:00
										 |  |  |         DB::table('transactions')->where('account_id', $account->id)->update(['account_id' => $moveTo->id]); | 
					
						
							| 
									
										
										
										
											2021-04-05 10:56:08 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $collection = Transaction::groupBy('transaction_journal_id', 'account_id') | 
					
						
							|  |  |  |                                  ->where('account_id', $moveTo->id) | 
					
						
							| 
									
										
										
										
											2022-10-31 05:53:36 +01:00
										 |  |  |                                  ->get(['transaction_journal_id', 'account_id', DB::raw('count(*) as the_count')]); | 
					
						
							| 
									
										
										
										
											2021-04-05 10:56:08 +02:00
										 |  |  |         if (0 === $collection->count()) { | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /** @var JournalDestroyService $service */ | 
					
						
							|  |  |  |         $service = app(JournalDestroyService::class); | 
					
						
							|  |  |  |         $user    = $account->user; | 
					
						
							| 
									
										
										
										
											2021-05-24 08:54:58 +02:00
										 |  |  |         /** @var stdClass $row */ | 
					
						
							| 
									
										
										
										
											2021-04-05 10:56:08 +02:00
										 |  |  |         foreach ($collection as $row) { | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |             if ((int)$row->the_count > 1) { | 
					
						
							|  |  |  |                 $journalId = (int)$row->transaction_journal_id; | 
					
						
							| 
									
										
										
										
											2021-04-05 10:56:08 +02:00
										 |  |  |                 $journal   = $user->transactionJournals()->find($journalId); | 
					
						
							|  |  |  |                 if (null !== $journal) { | 
					
						
							|  |  |  |                     Log::debug(sprintf('Deleted journal #%d because it has the same source as destination.', $journal->id)); | 
					
						
							|  |  |  |                     $service->destroy($journal); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-03-15 10:31:11 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |      * @param  Account  $account | 
					
						
							|  |  |  |      * @param  Account  $moveTo | 
					
						
							| 
									
										
										
										
											2021-03-15 10:31:11 +01:00
										 |  |  |      */ | 
					
						
							|  |  |  |     private function updateRecurrences(Account $account, Account $moveTo): void | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         DB::table('recurrences_transactions')->where('source_id', $account->id)->update(['source_id' => $moveTo->id]); | 
					
						
							|  |  |  |         DB::table('recurrences_transactions')->where('destination_id', $account->id)->update(['destination_id' => $moveTo->id]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |      * @param  Account  $account | 
					
						
							| 
									
										
										
										
											2021-03-15 10:31:11 +01:00
										 |  |  |      */ | 
					
						
							|  |  |  |     private function destroyJournals(Account $account): void | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         /** @var JournalDestroyService $service */ | 
					
						
							|  |  |  |         $service = app(JournalDestroyService::class); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |         Log::debug('Now trigger account delete response #'.$account->id); | 
					
						
							| 
									
										
										
										
											2021-03-15 10:31:11 +01:00
										 |  |  |         /** @var Transaction $transaction */ | 
					
						
							|  |  |  |         foreach ($account->transactions()->get() as $transaction) { | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |             Log::debug('Now at transaction #'.$transaction->id); | 
					
						
							| 
									
										
										
										
											2021-03-15 10:31:11 +01:00
										 |  |  |             /** @var TransactionJournal $journal */ | 
					
						
							|  |  |  |             $journal = $transaction->transactionJournal()->first(); | 
					
						
							|  |  |  |             if (null !== $journal) { | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |                 Log::debug('Call for deletion of journal #'.$journal->id); | 
					
						
							| 
									
										
										
										
											2021-03-15 10:31:11 +01:00
										 |  |  |                 $service->destroy($journal); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-31 16:53:09 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |      * @param  Account  $account | 
					
						
							| 
									
										
										
										
											2019-07-31 16:53:09 +02:00
										 |  |  |      */ | 
					
						
							|  |  |  |     private function destroyRecurrences(Account $account): void | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-10-30 14:24:37 +01:00
										 |  |  |         $recurrences = RecurrenceTransaction::where( | 
					
						
							| 
									
										
										
										
											2019-07-31 16:53:09 +02:00
										 |  |  |             static function (Builder $q) use ($account) { | 
					
						
							|  |  |  |                 $q->where('source_id', $account->id); | 
					
						
							|  |  |  |                 $q->orWhere('destination_id', $account->id); | 
					
						
							| 
									
										
										
										
											2018-08-11 19:21:58 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-07-31 16:53:09 +02:00
										 |  |  |         )->get(['recurrence_id'])->pluck('recurrence_id')->toArray(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /** @var RecurrenceDestroyService $destroyService */ | 
					
						
							|  |  |  |         $destroyService = app(RecurrenceDestroyService::class); | 
					
						
							|  |  |  |         foreach ($recurrences as $recurrenceId) { | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |             $destroyService->destroyById((int)$recurrenceId); | 
					
						
							| 
									
										
										
										
											2018-08-11 19:21:58 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-07-31 16:53:09 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-05 19:35:58 +01:00
										 |  |  | } |