| 
									
										
										
										
											2018-09-15 13:43:57 +02:00
										 |  |  | <?php | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * ConvertToTransfer.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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  | use DB; | 
					
						
							| 
									
										
										
										
											2023-08-12 20:57:51 +02:00
										 |  |  | use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray; | 
					
						
							| 
									
										
										
										
											2023-08-13 15:01:12 +02:00
										 |  |  | use FireflyIII\Events\Model\Rule\RuleActionFailedOnObject; | 
					
						
							| 
									
										
										
										
											2022-10-02 06:23:31 +02:00
										 |  |  | use FireflyIII\Events\TriggeredAuditLog; | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  | use FireflyIII\Exceptions\FireflyException; | 
					
						
							| 
									
										
										
										
											2018-09-15 13:43:57 +02:00
										 |  |  | use FireflyIII\Models\Account; | 
					
						
							|  |  |  | 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; | 
					
						
							|  |  |  | use FireflyIII\Repositories\Account\AccountRepositoryInterface; | 
					
						
							| 
									
										
										
										
											2023-04-01 07:04:42 +02:00
										 |  |  | use Illuminate\Support\Facades\Log; | 
					
						
							| 
									
										
										
										
											2018-09-15 13:43:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Class ConvertToTransfer | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class ConvertToTransfer implements ActionInterface | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  |     private RuleAction $action; | 
					
						
							| 
									
										
										
										
											2018-09-15 13:43:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * TriggerInterface constructor. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |      * @param RuleAction $action | 
					
						
							| 
									
										
										
										
											2018-09-15 13:43:57 +02:00
										 |  |  |      */ | 
					
						
							|  |  |  |     public function __construct(RuleAction $action) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->action = $action; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @inheritDoc | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function actOnArray(array $journal): bool | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |         // make object from array (so the data is fresh).
 | 
					
						
							|  |  |  |         /** @var TransactionJournal|null $object */ | 
					
						
							|  |  |  |         $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']); | 
					
						
							|  |  |  |         if (null === $object) { | 
					
						
							|  |  |  |             Log::error(sprintf('Cannot find journal #%d, cannot convert to transfer.', $journal['transaction_journal_id'])); | 
					
						
							| 
									
										
										
										
											2023-08-12 20:57:51 +02:00
										 |  |  |             event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.journal_not_found'))); | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-06-25 14:36:53 +02:00
										 |  |  |         $groupCount = TransactionJournal::where('transaction_group_id', $journal['transaction_group_id'])->count(); | 
					
						
							| 
									
										
										
										
											2022-10-02 06:23:31 +02:00
										 |  |  |         if ($groupCount > 1) { | 
					
						
							| 
									
										
										
										
											2022-06-25 14:36:53 +02:00
										 |  |  |             Log::error(sprintf('Group #%d has more than one transaction in it, cannot convert to transfer.', $journal['transaction_group_id'])); | 
					
						
							| 
									
										
										
										
											2023-08-12 20:57:51 +02:00
										 |  |  |             event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.split_group'))); | 
					
						
							| 
									
										
										
										
											2022-06-25 14:36:53 +02:00
										 |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |         $type      = $object->transactionType->type; | 
					
						
							|  |  |  |         $user      = $object->user; | 
					
						
							|  |  |  |         $journalId = (int)$object->id; | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  |         if (TransactionType::TRANSFER === $type) { | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  |             Log::error( | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |                 sprintf('Journal #%d is already a transfer so cannot be converted (rule #%d).', $object->id, $this->action->rule_id) | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  |             ); | 
					
						
							| 
									
										
										
										
											2023-08-12 20:57:51 +02:00
										 |  |  |             event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.is_already_transfer'))); | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-08-13 15:01:12 +02:00
										 |  |  |         if (TransactionType::DEPOSIT !== $type && TransactionType::WITHDRAWAL !== $type) { | 
					
						
							|  |  |  |             event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.unsupported_transaction_type_transfer', ['type' => $type]))); | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // find the asset account in the action value.
 | 
					
						
							|  |  |  |         /** @var AccountRepositoryInterface $repository */ | 
					
						
							|  |  |  |         $repository = app(AccountRepositoryInterface::class); | 
					
						
							|  |  |  |         $repository->setUser($user); | 
					
						
							| 
									
										
										
										
											2023-03-25 13:42:26 +01:00
										 |  |  |         $expectedType = null; | 
					
						
							|  |  |  |         if (TransactionType::WITHDRAWAL === $type) { | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |             $expectedType = $this->getSourceType($journalId); | 
					
						
							| 
									
										
										
										
											2023-03-25 13:42:26 +01:00
										 |  |  |             // Withdrawal? Replace destination with account with same type as source.
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (TransactionType::DEPOSIT === $type) { | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |             $expectedType = $this->getDestinationType($journalId); | 
					
						
							| 
									
										
										
										
											2023-03-25 13:42:26 +01:00
										 |  |  |             // Deposit? Replace source with account with same type as destination.
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         $opposing = $repository->findByName($this->action->action_value, [$expectedType]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (null === $opposing) { | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  |             Log::error( | 
					
						
							|  |  |  |                 sprintf( | 
					
						
							| 
									
										
										
										
											2023-03-25 13:42:26 +01:00
										 |  |  |                     'Journal #%d cannot be converted because no valid %s account with name "%s" exists (rule #%d).', | 
					
						
							|  |  |  |                     $expectedType, | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |                     $journalId, | 
					
						
							| 
									
										
										
										
											2022-10-30 14:24:37 +01:00
										 |  |  |                     $this->action->action_value, | 
					
						
							|  |  |  |                     $this->action->rule_id | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  |                 ) | 
					
						
							|  |  |  |             ); | 
					
						
							| 
									
										
										
										
											2023-08-12 20:57:51 +02:00
										 |  |  |             event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.no_valid_opposing', ['name' => $this->action->action_value]))); | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  |         if (TransactionType::WITHDRAWAL === $type) { | 
					
						
							|  |  |  |             Log::debug('Going to transform a withdrawal to a transfer.'); | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |             try { | 
					
						
							|  |  |  |                 $res = $this->convertWithdrawalArray($object, $opposing); | 
					
						
							|  |  |  |             } catch (FireflyException $e) { | 
					
						
							|  |  |  |                 Log::debug('Could not convert withdrawal to transfer.'); | 
					
						
							|  |  |  |                 Log::error($e->getMessage()); | 
					
						
							| 
									
										
										
										
											2023-08-12 20:57:51 +02:00
										 |  |  |                 event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.complex_error'))); | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-08-13 15:01:12 +02:00
										 |  |  |             if (false !== $res) { | 
					
						
							|  |  |  |                 event(new TriggeredAuditLog($this->action->rule, $object, 'update_transaction_type', TransactionType::WITHDRAWAL, TransactionType::TRANSFER)); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |             return $res; | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (TransactionType::DEPOSIT === $type) { | 
					
						
							|  |  |  |             Log::debug('Going to transform a deposit to a transfer.'); | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |             try { | 
					
						
							|  |  |  |                 $res = $this->convertDepositArray($object, $opposing); | 
					
						
							|  |  |  |             } catch (FireflyException $e) { | 
					
						
							|  |  |  |                 Log::debug('Could not convert deposit to transfer.'); | 
					
						
							|  |  |  |                 Log::error($e->getMessage()); | 
					
						
							| 
									
										
										
										
											2023-08-12 20:57:51 +02:00
										 |  |  |                 event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.complex_error'))); | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-08-13 15:01:12 +02:00
										 |  |  |             if (false !== $res) { | 
					
						
							|  |  |  |                 event(new TriggeredAuditLog($this->action->rule, $object, 'update_transaction_type', TransactionType::DEPOSIT, TransactionType::TRANSFER)); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |             return $res; | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-08-13 15:01:12 +02:00
										 |  |  |         event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.unsupported_transaction_type_transfer', ['type' => $type]))); | 
					
						
							| 
									
										
										
										
											2021-09-18 10:26:12 +02:00
										 |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |      * @param int $journalId | 
					
						
							| 
									
										
										
										
											2023-07-15 16:02:42 +02:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |      * @return string | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private function getSourceType(int $journalId): string | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         /** @var TransactionJournal $journal */ | 
					
						
							|  |  |  |         $journal = TransactionJournal::find($journalId); | 
					
						
							|  |  |  |         if (null === $journal) { | 
					
						
							|  |  |  |             Log::error(sprintf('Journal #%d does not exist. Cannot convert to transfer.', $journalId)); | 
					
						
							|  |  |  |             return ''; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return (string)$journal->transactions()->where('amount', '<', 0)->first()?->account?->accountType?->type; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * @param int $journalId | 
					
						
							| 
									
										
										
										
											2023-07-15 16:02:42 +02:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |      * @return string | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private function getDestinationType(int $journalId): string | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         /** @var TransactionJournal $journal */ | 
					
						
							|  |  |  |         $journal = TransactionJournal::find($journalId); | 
					
						
							|  |  |  |         if (null === $journal) { | 
					
						
							|  |  |  |             Log::error(sprintf('Journal #%d does not exist. Cannot convert to transfer.', $journalId)); | 
					
						
							|  |  |  |             return ''; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return (string)$journal->transactions()->where('amount', '>', 0)->first()?->account?->accountType?->type; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * A withdrawal is from Asset to Expense. | 
					
						
							|  |  |  |      * We replace the Expense with another asset. | 
					
						
							|  |  |  |      * So this replaces the destination | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |      * @param TransactionJournal $journal | 
					
						
							|  |  |  |      * @param Account            $opposing | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  |      * @return bool | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |      * @throws FireflyException | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     private function convertWithdrawalArray(TransactionJournal $journal, Account $opposing): bool | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         $sourceAccount = $this->getSourceAccount($journal); | 
					
						
							|  |  |  |         if ((int)$sourceAccount->id === (int)$opposing->id) { | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  |             Log::error( | 
					
						
							|  |  |  |                 vsprintf( | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |                     'Journal #%d has already has "%s" as a source asset. ConvertToTransfer failed. (rule #%d).', | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |                     [$journal->id, $opposing->name, $this->action->rule_id] | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  |                 ) | 
					
						
							|  |  |  |             ); | 
					
						
							| 
									
										
										
										
											2023-08-13 15:01:12 +02:00
										 |  |  |             event(new RuleActionFailedOnObject($this->action, $journal, trans('rules.already_has_source_asset', ['name' => $opposing->name]))); | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         // update destination transaction:
 | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  |         DB::table('transactions') | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |           ->where('transaction_journal_id', '=', $journal->id) | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |           ->where('amount', '>', 0) | 
					
						
							| 
									
										
										
										
											2023-03-25 13:42:26 +01:00
										 |  |  |           ->update(['account_id' => $opposing->id]); | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // change transaction type of journal:
 | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  |         $newType = TransactionType::whereType(TransactionType::TRANSFER)->first(); | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         DB::table('transaction_journals') | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |           ->where('id', '=', $journal->id) | 
					
						
							| 
									
										
										
										
											2022-08-02 05:38:24 +02:00
										 |  |  |           ->update(['transaction_type_id' => $newType->id, 'bill_id' => null]); | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         Log::debug('Converted withdrawal to transfer.'); | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |      * @param TransactionJournal $journal | 
					
						
							| 
									
										
										
										
											2023-07-15 16:02:42 +02:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |      * @return Account | 
					
						
							|  |  |  |      * @throws FireflyException | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private function getSourceAccount(TransactionJournal $journal): Account | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         /** @var Transaction|null $sourceTransaction */ | 
					
						
							|  |  |  |         $sourceTransaction = $journal->transactions()->where('amount', '<', 0)->first(); | 
					
						
							|  |  |  |         if (null === $sourceTransaction) { | 
					
						
							|  |  |  |             throw new FireflyException(sprintf('Cannot find source transaction for journal #%d', $journal->id)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return $sourceTransaction->account; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * A deposit is from Revenue to Asset. | 
					
						
							|  |  |  |      * We replace the Revenue with another asset. | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |      * @param TransactionJournal $journal | 
					
						
							|  |  |  |      * @param Account            $opposing | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  |      * @return bool | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |      * @throws FireflyException | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     private function convertDepositArray(TransactionJournal $journal, Account $opposing): bool | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         $destAccount = $this->getDestinationAccount($journal); | 
					
						
							|  |  |  |         if ((int)$destAccount->id === (int)$opposing->id) { | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  |             Log::error( | 
					
						
							|  |  |  |                 vsprintf( | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |                     'Journal #%d has already has "%s" as a destination asset. ConvertToTransfer failed. (rule #%d).', | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |                     [$journal->id, $opposing->name, $this->action->rule_id] | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  |                 ) | 
					
						
							|  |  |  |             ); | 
					
						
							| 
									
										
										
										
											2023-08-13 15:01:12 +02:00
										 |  |  |             event(new RuleActionFailedOnObject($this->action, $journal, trans('rules.already_has_destination_asset', ['name' => $opposing->name]))); | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         // update source transaction:
 | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  |         DB::table('transactions') | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |           ->where('transaction_journal_id', '=', $journal->id) | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |           ->where('amount', '<', 0) | 
					
						
							| 
									
										
										
										
											2023-03-25 13:42:26 +01:00
										 |  |  |           ->update(['account_id' => $opposing->id]); | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // change transaction type of journal:
 | 
					
						
							| 
									
										
										
										
											2021-03-23 06:42:26 +01:00
										 |  |  |         $newType = TransactionType::whereType(TransactionType::TRANSFER)->first(); | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         DB::table('transaction_journals') | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |           ->where('id', '=', $journal->id) | 
					
						
							| 
									
										
										
										
											2022-08-02 05:38:24 +02:00
										 |  |  |           ->update(['transaction_type_id' => $newType->id, 'bill_id' => null]); | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         Log::debug('Converted deposit to transfer.'); | 
					
						
							| 
									
										
										
										
											2020-08-23 07:42:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-03-25 13:42:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |      * @param TransactionJournal $journal | 
					
						
							| 
									
										
										
										
											2023-07-15 16:02:42 +02:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2023-05-27 06:36:24 +02:00
										 |  |  |      * @return Account | 
					
						
							|  |  |  |      * @throws FireflyException | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private function getDestinationAccount(TransactionJournal $journal): Account | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         /** @var Transaction|null $destAccount */ | 
					
						
							|  |  |  |         $destAccount = $journal->transactions()->where('amount', '>', 0)->first(); | 
					
						
							|  |  |  |         if (null === $destAccount) { | 
					
						
							|  |  |  |             throw new FireflyException(sprintf('Cannot find destination transaction for journal #%d', $journal->id)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return $destAccount->account; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-12-31 07:48:23 +01:00
										 |  |  | } |