| 
									
										
										
										
											2018-09-15 13:43:57 +02:00
										 |  |  | <?php | 
					
						
							| 
									
										
										
										
											2024-11-25 04:18:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-15 13:43:57 +02:00
										 |  |  | /** | 
					
						
							|  |  |  |  * ConvertToWithdrawal.php | 
					
						
							| 
									
										
										
										
											2020-02-16 13:57:05 +01:00
										 |  |  |  * Copyright (c) 2019 james@firefly-iii.org | 
					
						
							| 
									
										
										
										
											2018-09-15 13:43:57 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-10-02 06:37:26 +02:00
										 |  |  |  * This file is part of Firefly III (https://github.com/firefly-iii). | 
					
						
							| 
									
										
										
										
											2018-09-15 13:43:57 +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. | 
					
						
							| 
									
										
										
										
											2018-09-15 13:43:57 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-10-02 06:37:26 +02:00
										 |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							| 
									
										
										
										
											2018-09-15 13:43:57 +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. | 
					
						
							| 
									
										
										
										
											2018-09-15 13:43:57 +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/>. | 
					
						
							| 
									
										
										
										
											2018-09-15 13:43:57 +02:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | declare(strict_types=1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace FireflyIII\TransactionRules\Actions; | 
					
						
							| 
									
										
										
										
											2021-04-05 22:12:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-03 09:15:52 +01:00
										 |  |  | use FireflyIII\Enums\AccountTypeEnum; | 
					
						
							| 
									
										
										
										
											2025-01-03 09:05:19 +01:00
										 |  |  | use FireflyIII\Enums\TransactionTypeEnum; | 
					
						
							| 
									
										
										
										
											2023-08-13 15:01:12 +02:00
										 |  |  | use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray; | 
					
						
							| 
									
										
										
										
											2022-10-02 06:23:31 +02:00
										 |  |  | use FireflyIII\Events\TriggeredAuditLog; | 
					
						
							| 
									
										
										
										
											2019-08-17 10:47:29 +02:00
										 |  |  | use FireflyIII\Exceptions\FireflyException; | 
					
						
							| 
									
										
										
										
											2018-09-15 13:43:57 +02:00
										 |  |  | use FireflyIII\Factory\AccountFactory; | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  | use FireflyIII\Models\Account; | 
					
						
							| 
									
										
										
										
											2018-09-15 13:43:57 +02:00
										 |  |  | use FireflyIII\Models\RuleAction; | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  | use FireflyIII\Models\Transaction; | 
					
						
							| 
									
										
										
										
											2022-06-25 14:36:53 +02:00
										 |  |  | use FireflyIII\Models\TransactionJournal; | 
					
						
							| 
									
										
										
										
											2018-09-15 13:43:57 +02:00
										 |  |  | use FireflyIII\Models\TransactionType; | 
					
						
							| 
									
										
										
										
											2023-03-25 13:42:26 +01:00
										 |  |  | use FireflyIII\Repositories\Account\AccountRepositoryInterface; | 
					
						
							| 
									
										
										
										
											2025-02-23 12:47:04 +01:00
										 |  |  | use Illuminate\Support\Facades\DB; | 
					
						
							| 
									
										
										
										
											2018-09-15 13:43:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Class ConvertToWithdrawal | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class ConvertToWithdrawal implements ActionInterface | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * TriggerInterface constructor. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2025-05-04 13:55:42 +02:00
										 |  |  |     public function __construct(private readonly RuleAction $action) {} | 
					
						
							| 
									
										
										
										
											2018-09-15 13:43:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  |     public function actOnArray(array $journal): bool | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-03-07 17:18:46 -05:00
										 |  |  |         $actionValue = $this->action->getValue($journal); | 
					
						
							| 
									
										
										
										
											2024-03-06 20:54:50 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |         // make object from array (so the data is fresh).
 | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  |         /** @var null|TransactionJournal $object */ | 
					
						
							| 
									
										
										
										
											2024-03-07 17:18:46 -05:00
										 |  |  |         $object      = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']); | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |         if (null === $object) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:32:00 +01:00
										 |  |  |             app('log')->error(sprintf('Cannot find journal #%d, cannot convert to withdrawal.', $journal['transaction_journal_id'])); | 
					
						
							| 
									
										
										
										
											2023-08-13 15:01:12 +02:00
										 |  |  |             event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.journal_not_found'))); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-03-07 17:18:46 -05:00
										 |  |  |         $groupCount  = TransactionJournal::where('transaction_group_id', $journal['transaction_group_id'])->count(); | 
					
						
							| 
									
										
										
										
											2022-10-02 06:23:31 +02:00
										 |  |  |         if ($groupCount > 1) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:32:00 +01:00
										 |  |  |             app('log')->error(sprintf('Group #%d has more than one transaction in it, cannot convert to withdrawal.', $journal['transaction_group_id'])); | 
					
						
							| 
									
										
										
										
											2023-08-13 15:01:12 +02:00
										 |  |  |             event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.split_group'))); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-25 14:36:53 +02:00
										 |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-07 17:18:46 -05:00
										 |  |  |         $type        = $object->transactionType->type; | 
					
						
							| 
									
										
										
										
											2025-01-03 09:05:19 +01:00
										 |  |  |         if (TransactionTypeEnum::WITHDRAWAL->value === $type) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:32:00 +01:00
										 |  |  |             app('log')->error(sprintf('Journal #%d is already a withdrawal (rule #%d).', $journal['transaction_journal_id'], $this->action->rule_id)); | 
					
						
							| 
									
										
										
										
											2023-08-13 15:01:12 +02:00
										 |  |  |             event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.is_already_withdrawal'))); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-13 15:01:12 +02:00
										 |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-01-03 09:09:15 +01:00
										 |  |  |         if (TransactionTypeEnum::DEPOSIT->value !== $type && TransactionTypeEnum::TRANSFER->value !== $type) { | 
					
						
							| 
									
										
										
										
											2023-08-13 15:01:12 +02:00
										 |  |  |             event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.unsupported_transaction_type_withdrawal', ['type' => $type]))); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-23 08:03:28 +02:00
										 |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-01-03 09:09:15 +01:00
										 |  |  |         if (TransactionTypeEnum::DEPOSIT->value === $type) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug('Going to transform a deposit to a withdrawal.'); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |             try { | 
					
						
							| 
									
										
										
										
											2024-03-06 20:54:50 -05:00
										 |  |  |                 $res = $this->convertDepositArray($object, $actionValue); | 
					
						
							| 
									
										
										
										
											2023-12-21 04:59:23 +01:00
										 |  |  |             } catch (FireflyException $e) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |                 app('log')->debug('Could not convert transfer to deposit.'); | 
					
						
							| 
									
										
										
										
											2023-10-29 06:32:00 +01:00
										 |  |  |                 app('log')->error($e->getMessage()); | 
					
						
							| 
									
										
										
										
											2023-08-13 15:01:12 +02:00
										 |  |  |                 event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.complex_error'))); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-01-03 09:09:15 +01:00
										 |  |  |             event(new TriggeredAuditLog($this->action->rule, $object, 'update_transaction_type', TransactionTypeEnum::DEPOSIT->value, TransactionTypeEnum::WITHDRAWAL->value)); | 
					
						
							| 
									
										
										
										
											2020-08-23 08:03:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |             return $res; | 
					
						
							| 
									
										
										
										
											2020-08-23 08:03:28 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-11-04 07:18:03 +01:00
										 |  |  |         // can only be transfer at this point.
 | 
					
						
							|  |  |  |         app('log')->debug('Going to transform a transfer to a withdrawal.'); | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-04 07:18:03 +01:00
										 |  |  |         try { | 
					
						
							| 
									
										
										
										
											2024-03-06 21:38:40 -05:00
										 |  |  |             $res = $this->convertTransferArray($object, $actionValue); | 
					
						
							| 
									
										
										
										
											2023-12-21 04:59:23 +01:00
										 |  |  |         } catch (FireflyException $e) { | 
					
						
							| 
									
										
										
										
											2023-11-04 07:18:03 +01:00
										 |  |  |             app('log')->debug('Could not convert transfer to deposit.'); | 
					
						
							|  |  |  |             app('log')->error($e->getMessage()); | 
					
						
							|  |  |  |             event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.complex_error'))); | 
					
						
							| 
									
										
										
										
											2020-08-23 08:03:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-04 07:18:03 +01:00
										 |  |  |             return false; | 
					
						
							| 
									
										
										
										
											2020-08-23 08:03:28 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-01-03 09:05:56 +01:00
										 |  |  |         event(new TriggeredAuditLog($this->action->rule, $object, 'update_transaction_type', TransactionTypeEnum::TRANSFER->value, TransactionTypeEnum::WITHDRAWAL->value)); | 
					
						
							| 
									
										
										
										
											2023-11-04 07:18:03 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return $res; | 
					
						
							| 
									
										
										
										
											2020-08-23 08:03:28 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-25 13:42:26 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @throws FireflyException | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2024-03-07 17:18:46 -05:00
										 |  |  |     private function convertDepositArray(TransactionJournal $journal, string $actionValue = ''): bool | 
					
						
							| 
									
										
										
										
											2020-08-23 08:03:28 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $user            = $journal->user; | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-23 08:03:28 +02:00
										 |  |  |         /** @var AccountFactory $factory */ | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $factory         = app(AccountFactory::class); | 
					
						
							| 
									
										
										
										
											2020-08-23 08:03:28 +02:00
										 |  |  |         $factory->setUser($user); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $repository      = app(AccountRepositoryInterface::class); | 
					
						
							| 
									
										
										
										
											2023-03-25 13:42:26 +01:00
										 |  |  |         $repository->setUser($user); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $sourceAccount   = $this->getSourceAccount($journal); | 
					
						
							|  |  |  |         $destAccount     = $this->getDestinationAccount($journal); | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-25 13:42:26 +01:00
										 |  |  |         // get the action value, or use the original source name in case the action value is empty:
 | 
					
						
							|  |  |  |         // this becomes a new or existing (expense) account, which is the destination of the new withdrawal.
 | 
					
						
							| 
									
										
										
										
											2024-03-07 17:18:46 -05:00
										 |  |  |         $opposingName    = '' === $actionValue ? $sourceAccount->name : $actionValue; | 
					
						
							| 
									
										
										
										
											2023-03-25 13:42:26 +01:00
										 |  |  |         // we check all possible source account types if one exists:
 | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |         $validTypes      = config('firefly.expected_source_types.destination.Withdrawal'); | 
					
						
							|  |  |  |         $opposingAccount = $repository->findByName($opposingName, $validTypes); | 
					
						
							| 
									
										
										
										
											2023-03-25 13:42:26 +01:00
										 |  |  |         if (null === $opposingAccount) { | 
					
						
							| 
									
										
										
										
											2025-01-03 09:15:52 +01:00
										 |  |  |             $opposingAccount = $factory->findOrCreate($opposingName, AccountTypeEnum::EXPENSE->value); | 
					
						
							| 
									
										
										
										
											2023-03-25 13:42:26 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-06 21:38:40 -05:00
										 |  |  |         app('log')->debug(sprintf('ConvertToWithdrawal. Action value is "%s", expense name is "%s"', $actionValue, $opposingName)); | 
					
						
							| 
									
										
										
										
											2020-08-23 08:03:28 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // update source transaction(s) to be the original destination account
 | 
					
						
							| 
									
										
										
										
											2025-02-23 12:47:04 +01:00
										 |  |  |         DB::table('transactions') | 
					
						
							| 
									
										
										
										
											2024-03-06 20:54:50 -05:00
										 |  |  |             ->where('transaction_journal_id', '=', $journal->id) | 
					
						
							|  |  |  |             ->where('amount', '<', 0) | 
					
						
							| 
									
										
										
										
											2024-03-07 17:18:46 -05:00
										 |  |  |             ->update(['account_id' => $destAccount->id]) | 
					
						
							|  |  |  |         ; | 
					
						
							| 
									
										
										
										
											2020-08-23 08:03:28 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // update destination transaction(s) to be new expense account.
 | 
					
						
							| 
									
										
										
										
											2025-02-23 12:47:04 +01:00
										 |  |  |         DB::table('transactions') | 
					
						
							| 
									
										
										
										
											2024-03-06 20:54:50 -05:00
										 |  |  |             ->where('transaction_journal_id', '=', $journal->id) | 
					
						
							|  |  |  |             ->where('amount', '>', 0) | 
					
						
							| 
									
										
										
										
											2024-03-07 17:18:46 -05:00
										 |  |  |             ->update(['account_id' => $opposingAccount->id]) | 
					
						
							|  |  |  |         ; | 
					
						
							| 
									
										
										
										
											2020-08-23 08:03:28 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // change transaction type of journal:
 | 
					
						
							| 
									
										
										
										
											2025-01-03 09:05:19 +01:00
										 |  |  |         $newType         = TransactionType::whereType(TransactionTypeEnum::WITHDRAWAL->value)->first(); | 
					
						
							| 
									
										
										
										
											2025-02-23 12:47:04 +01:00
										 |  |  |         DB::table('transaction_journals') | 
					
						
							| 
									
										
										
										
											2024-03-06 20:54:50 -05:00
										 |  |  |             ->where('id', '=', $journal->id) | 
					
						
							| 
									
										
										
										
											2024-03-07 17:18:46 -05:00
										 |  |  |             ->update(['transaction_type_id' => $newType->id]) | 
					
						
							|  |  |  |         ; | 
					
						
							| 
									
										
										
										
											2020-08-23 08:03:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |         app('log')->debug('Converted deposit to withdrawal.'); | 
					
						
							| 
									
										
										
										
											2020-08-23 08:03:28 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @throws FireflyException | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private function getSourceAccount(TransactionJournal $journal): Account | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  |         /** @var null|Transaction $sourceTransaction */ | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         $sourceTransaction = $journal->transactions()->where('amount', '<', 0)->first(); | 
					
						
							|  |  |  |         if (null === $sourceTransaction) { | 
					
						
							|  |  |  |             throw new FireflyException(sprintf('Cannot find source transaction for journal #%d', $journal->id)); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         return $sourceTransaction->account; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * @throws FireflyException | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private function getDestinationAccount(TransactionJournal $journal): Account | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  |         /** @var null|Transaction $destAccount */ | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         $destAccount = $journal->transactions()->where('amount', '>', 0)->first(); | 
					
						
							|  |  |  |         if (null === $destAccount) { | 
					
						
							|  |  |  |             throw new FireflyException(sprintf('Cannot find destination transaction for journal #%d', $journal->id)); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         return $destAccount->account; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Input is a transfer from A to B. | 
					
						
							|  |  |  |      * Output is a withdrawal from A to C. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @throws FireflyException | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2024-03-07 17:18:46 -05:00
										 |  |  |     private function convertTransferArray(TransactionJournal $journal, string $actionValue = ''): bool | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  |     { | 
					
						
							|  |  |  |         // find or create expense account.
 | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $user            = $journal->user; | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  |         /** @var AccountFactory $factory */ | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $factory         = app(AccountFactory::class); | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  |         $factory->setUser($user); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $repository      = app(AccountRepositoryInterface::class); | 
					
						
							| 
									
										
										
										
											2023-03-25 13:42:26 +01:00
										 |  |  |         $repository->setUser($user); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $destAccount     = $this->getDestinationAccount($journal); | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-25 13:42:26 +01:00
										 |  |  |         // get the action value, or use the original source name in case the action value is empty:
 | 
					
						
							|  |  |  |         // this becomes a new or existing (expense) account, which is the destination of the new withdrawal.
 | 
					
						
							| 
									
										
										
										
											2024-03-06 21:38:40 -05:00
										 |  |  |         $opposingName    = '' === $actionValue ? $destAccount->name : $actionValue; | 
					
						
							| 
									
										
										
										
											2023-03-25 13:42:26 +01:00
										 |  |  |         // we check all possible source account types if one exists:
 | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |         $validTypes      = config('firefly.expected_source_types.destination.Withdrawal'); | 
					
						
							|  |  |  |         $opposingAccount = $repository->findByName($opposingName, $validTypes); | 
					
						
							| 
									
										
										
										
											2023-03-25 13:42:26 +01:00
										 |  |  |         if (null === $opposingAccount) { | 
					
						
							| 
									
										
										
										
											2025-01-03 09:15:52 +01:00
										 |  |  |             $opposingAccount = $factory->findOrCreate($opposingName, AccountTypeEnum::EXPENSE->value); | 
					
						
							| 
									
										
										
										
											2023-03-25 13:42:26 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-06 21:38:40 -05:00
										 |  |  |         app('log')->debug(sprintf('ConvertToWithdrawal. Action value is "%s", destination name is "%s"', $actionValue, $opposingName)); | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // update destination transaction(s) to be new expense account.
 | 
					
						
							| 
									
										
										
										
											2025-02-23 12:47:04 +01:00
										 |  |  |         DB::table('transactions') | 
					
						
							| 
									
										
										
										
											2024-03-06 20:54:50 -05:00
										 |  |  |             ->where('transaction_journal_id', '=', $journal->id) | 
					
						
							|  |  |  |             ->where('amount', '>', 0) | 
					
						
							| 
									
										
										
										
											2024-03-07 17:18:46 -05:00
										 |  |  |             ->update(['account_id' => $opposingAccount->id]) | 
					
						
							|  |  |  |         ; | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // change transaction type of journal:
 | 
					
						
							| 
									
										
										
										
											2025-01-03 09:05:19 +01:00
										 |  |  |         $newType         = TransactionType::whereType(TransactionTypeEnum::WITHDRAWAL->value)->first(); | 
					
						
							| 
									
										
										
										
											2025-02-23 12:47:04 +01:00
										 |  |  |         DB::table('transaction_journals') | 
					
						
							| 
									
										
										
										
											2024-03-06 20:54:50 -05:00
										 |  |  |             ->where('id', '=', $journal->id) | 
					
						
							| 
									
										
										
										
											2024-03-07 17:18:46 -05:00
										 |  |  |             ->update(['transaction_type_id' => $newType->id]) | 
					
						
							|  |  |  |         ; | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |         app('log')->debug('Converted transfer to withdrawal.'); | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-12-31 07:48:23 +01:00
										 |  |  | } |