Add new action that can switch the source and destination account of a transfer

This commit is contained in:
James Cole 2023-08-11 06:16:40 +02:00
parent 2b829cb645
commit 939c636a74
No known key found for this signature in database
GPG Key ID: B49A324B7EAD6D80
4 changed files with 156 additions and 48 deletions

View File

@ -0,0 +1,97 @@
<?php
/**
* ConvertToWithdrawal.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* 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.
*
* This program 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 Affero General Public License for more details.
*
* 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/>.
*/
declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
use DB;
use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use Illuminate\Support\Facades\Log;
/**
*
* Class SwitchAccounts
*/
class SwitchAccounts implements ActionInterface
{
private RuleAction $action;
/**
* TriggerInterface constructor.
*
* @param RuleAction $action
*/
public function __construct(RuleAction $action)
{
$this->action = $action;
}
/**
* @inheritDoc
*/
public function actOnArray(array $journal): bool
{
// 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 switch accounts.', $journal['transaction_journal_id']));
return false;
}
$groupCount = TransactionJournal::where('transaction_group_id', $journal['transaction_group_id'])->count();
if ($groupCount > 1) {
Log::error(sprintf('Group #%d has more than one transaction in it, cannot switch accounts.', $journal['transaction_group_id']));
return false;
}
$type = $object->transactionType->type;
if (TransactionType::TRANSFER !== $type) {
Log::error(sprintf('Journal #%d is NOT a transfer (rule #%d), cannot switch accounts.', $journal['transaction_journal_id'], $this->action->rule_id));
return false;
}
/** @var Transaction $sourceTransaction */
$sourceTransaction = $object->transactions()->where('amount', '<', 0)->first();
/** @var Transaction $destTransaction */
$destTransaction = $object->transactions()->where('amount', '>', 0)->first();
if (null === $sourceTransaction || null === $destTransaction) {
Log::error(sprintf('Journal #%d has no source or destination transaction (rule #%d), cannot switch accounts.', $journal['transaction_journal_id'], $this->action->rule_id));
return false;
}
$sourceAccountId = (int)$sourceTransaction->account_id;
$destinationAccountId = $destTransaction->account_id;
$sourceTransaction->account_id = $destinationAccountId;
$destTransaction->account_id = $sourceAccountId;
$sourceTransaction->save();
$destTransaction->save();
event(new TriggeredAuditLog($this->action->rule, $object, 'switch_accounts', $sourceAccountId, $destinationAccountId));
return true;
}
}

View File

@ -86,6 +86,7 @@ use FireflyIII\TransactionRules\Actions\SetDescription;
use FireflyIII\TransactionRules\Actions\SetDestinationAccount; use FireflyIII\TransactionRules\Actions\SetDestinationAccount;
use FireflyIII\TransactionRules\Actions\SetNotes; use FireflyIII\TransactionRules\Actions\SetNotes;
use FireflyIII\TransactionRules\Actions\SetSourceAccount; use FireflyIII\TransactionRules\Actions\SetSourceAccount;
use FireflyIII\TransactionRules\Actions\SwitchAccounts;
use FireflyIII\TransactionRules\Actions\UpdatePiggybank; use FireflyIII\TransactionRules\Actions\UpdatePiggybank;
use FireflyIII\User; use FireflyIII\User;
@ -503,6 +504,7 @@ return [
'convert_withdrawal' => ConvertToWithdrawal::class, 'convert_withdrawal' => ConvertToWithdrawal::class,
'convert_deposit' => ConvertToDeposit::class, 'convert_deposit' => ConvertToDeposit::class,
'convert_transfer' => ConvertToTransfer::class, 'convert_transfer' => ConvertToTransfer::class,
'switch_accounts' => SwitchAccounts::class,
'update_piggy' => UpdatePiggybank::class, 'update_piggy' => UpdatePiggybank::class,
'delete_transaction' => DeleteTransaction::class, 'delete_transaction' => DeleteTransaction::class,
'append_descr_to_notes' => AppendDescriptionToNotes::class, 'append_descr_to_notes' => AppendDescriptionToNotes::class,

View File

@ -234,6 +234,7 @@ function updateActionInput(selectList) {
case 'clear_budget': case 'clear_budget':
case 'append_descr_to_notes': case 'append_descr_to_notes':
case 'append_notes_to_descr': case 'append_notes_to_descr':
case 'switch_accounts':
case 'move_descr_to_notes': case 'move_descr_to_notes':
case 'move_notes_to_descr': case 'move_notes_to_descr':
case 'clear_notes': case 'clear_notes':

View File

@ -904,10 +904,14 @@ return [
'rule_trigger_internal_reference_is' => 'Internal reference is ":trigger_value"', 'rule_trigger_internal_reference_is' => 'Internal reference is ":trigger_value"',
'rule_trigger_journal_id_choice' => 'Transaction journal ID is..', 'rule_trigger_journal_id_choice' => 'Transaction journal ID is..',
'rule_trigger_journal_id' => 'Transaction journal ID is ":trigger_value"', 'rule_trigger_journal_id' => 'Transaction journal ID is ":trigger_value"',
'rule_trigger_no_external_url' => 'Transaction has no external URL', 'rule_trigger_any_external_url' => 'Transaction has an (any) external URL',
'rule_trigger_any_external_url' => 'Transaction has an external URL', 'rule_trigger_any_external_url_choice' => 'Transaction has an (any) external URL',
'rule_trigger_any_external_url_choice' => 'Transaction has an external URL', 'rule_trigger_any_external_id' => 'Transaction has an (any) external ID',
'rule_trigger_any_external_id_choice' => 'Transaction has an (any) external ID',
'rule_trigger_no_external_url_choice' => 'Transaction has no external URL', 'rule_trigger_no_external_url_choice' => 'Transaction has no external URL',
'rule_trigger_no_external_url' => 'Transaction has no external URL',
'rule_trigger_no_external_id_choice' => 'Transaction has no external ID',
'rule_trigger_no_external_id' => 'Transaction has no external ID',
'rule_trigger_id_choice' => 'Transaction ID is..', 'rule_trigger_id_choice' => 'Transaction ID is..',
'rule_trigger_id' => 'Transaction ID is ":trigger_value"', 'rule_trigger_id' => 'Transaction ID is ":trigger_value"',
'rule_trigger_sepa_ct_is_choice' => 'SEPA CT is..', 'rule_trigger_sepa_ct_is_choice' => 'SEPA CT is..',
@ -1178,6 +1182,7 @@ return [
// Ignore this comment // Ignore this comment
// actions // actions
// set, clear, add, remove, append/prepend
'rule_action_delete_transaction_choice' => 'DELETE transaction(!)', 'rule_action_delete_transaction_choice' => 'DELETE transaction(!)',
'rule_action_delete_transaction' => 'DELETE transaction(!)', 'rule_action_delete_transaction' => 'DELETE transaction(!)',
'rule_action_set_category' => 'Set category to ":action_value"', 'rule_action_set_category' => 'Set category to ":action_value"',
@ -1215,6 +1220,8 @@ return [
'rule_action_set_notes_choice' => 'Set notes to ..', 'rule_action_set_notes_choice' => 'Set notes to ..',
'rule_action_link_to_bill_choice' => 'Link to a bill ..', 'rule_action_link_to_bill_choice' => 'Link to a bill ..',
'rule_action_link_to_bill' => 'Link to bill ":action_value"', 'rule_action_link_to_bill' => 'Link to bill ":action_value"',
'rule_action_switch_accounts_choice' => 'Switch source and destination accounts (transfers only!)',
'rule_action_switch_accounts' => 'Switch source and destination ',
'rule_action_set_notes' => 'Set notes to ":action_value"', 'rule_action_set_notes' => 'Set notes to ":action_value"',
'rule_action_convert_deposit_choice' => 'Convert the transaction to a deposit', 'rule_action_convert_deposit_choice' => 'Convert the transaction to a deposit',
'rule_action_convert_deposit' => 'Convert the transaction to a deposit from ":action_value"', 'rule_action_convert_deposit' => 'Convert the transaction to a deposit from ":action_value"',
@ -2603,6 +2610,7 @@ return [
'ale_action_clear_tag' => 'Cleared tag', 'ale_action_clear_tag' => 'Cleared tag',
'ale_action_clear_all_tags' => 'Cleared all tags', 'ale_action_clear_all_tags' => 'Cleared all tags',
'ale_action_set_bill' => 'Linked to bill', 'ale_action_set_bill' => 'Linked to bill',
'ale_action_switch_accounts' => 'Switched source and destination account',
'ale_action_set_budget' => 'Set budget', 'ale_action_set_budget' => 'Set budget',
'ale_action_set_category' => 'Set category', 'ale_action_set_category' => 'Set category',
'ale_action_set_source' => 'Set source account', 'ale_action_set_source' => 'Set source account',