add new action

This commit is contained in:
James Cole 2023-12-02 15:38:06 +01:00
commit 6df7f1f762
No known key found for this signature in database
GPG Key ID: B49A324B7EAD6D80
9 changed files with 252 additions and 4 deletions

View File

@ -0,0 +1,120 @@
<?php
/*
* SetDestinationToCashAccount.php
* Copyright (c) 2023 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 FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\User;
use DB;
/**
* Class SetDestinationToCashAccount
*/
class SetDestinationToCashAccount implements ActionInterface
{
private RuleAction $action;
/**
* TriggerInterface constructor.
*
* @param RuleAction $action
*/
public function __construct(RuleAction $action)
{
$this->action = $action;
}
/**
* @inheritDoc
*/
#[\Override] public function actOnArray(array $journal): bool
{
/** @var User $user */
$user = User::find($journal['user_id']);
/** @var TransactionJournal|null $object */
$object = $user->transactionJournals()->find((int)$journal['transaction_journal_id']);
$repository = app(AccountRepositoryInterface::class);
if (null === $object) {
app('log')->error('Could not find journal.');
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.no_such_journal')));
return false;
}
$type = $object->transactionType->type;
if (TransactionType::WITHDRAWAL !== $type) {
app('log')->error('Transaction must be withdrawal.');
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.not_withdrawal')));
return false;
}
// find cash account
$repository->setUser($user);
$cashAccount = $repository->getCashAccount();
// new destination account must be different from the current source account:
/** @var Transaction|null $source */
$source = $object->transactions()->where('amount', '<', 0)->first();
if (null === $source) {
app('log')->error('Could not find source transaction.');
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_source_transaction')));
return false;
}
// account must not be deleted (in the meantime):
if (null === $source->account) {
app('log')->error('Could not find source transaction account.');
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_source_transaction_account')));
return false;
}
if (null !== $cashAccount && $cashAccount->id === $source->account_id) {
app('log')->error(
sprintf(
'New destination account ID #%d and current source account ID #%d are the same. Do nothing.',
$cashAccount->id,
$source->account_id
)
);
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.already_has_destination', ['name' => $cashAccount->name])));
return false;
}
event(new TriggeredAuditLog($this->action->rule, $object, 'set_destination', null, $cashAccount->name));
// update destination transaction with new destination account:
DB::table('transactions')
->where('transaction_journal_id', '=', $object->id)
->where('amount', '>', 0)
->update(['account_id' => $cashAccount->id]);
app('log')->debug(sprintf('Updated journal #%d (group #%d) and gave it new destination account ID.', $object->id, $object->transaction_group_id));
return true;
}
}

View File

@ -0,0 +1,118 @@
<?php
/*
* SetsourceToCashAccount.php
* Copyright (c) 2023 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 FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\User;
use DB;
/**
* Class SetSourceToCashAccount
*/
class SetSourceToCashAccount implements ActionInterface
{
private RuleAction $action;
/**
* TriggerInterface constructor.
*
* @param RuleAction $action
*/
public function __construct(RuleAction $action)
{
$this->action = $action;
}
/**
* @inheritDoc
*/
#[\Override] public function actOnArray(array $journal): bool
{
/** @var User $user */
$user = User::find($journal['user_id']);
/** @var TransactionJournal|null $object */
$object = $user->transactionJournals()->find((int)$journal['transaction_journal_id']);
$repository = app(AccountRepositoryInterface::class);
if (null === $object) {
app('log')->error('Could not find journal.');
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.no_such_journal')));
return false;
}
$type = $object->transactionType->type;
if(TransactionType::DEPOSIT !== $type) {
app('log')->error('Transaction must be deposit.');
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.not_deposit')));
return false;
}
// find cash account
$repository->setUser($user);
$cashAccount = $repository->getCashAccount();
// new source account must be different from the current destination account:
/** @var Transaction|null $destination */
$destination = $object->transactions()->where('amount', '>', 0)->first();
if (null === $destination) {
app('log')->error('Could not find destination transaction.');
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_destination_transaction')));
return false;
}
// account must not be deleted (in the meantime):
if (null === $destination->account) {
app('log')->error('Could not find destination transaction account.');
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_destination_transaction_account')));
return false;
}
if (null !== $cashAccount && $cashAccount->id === $destination->account_id) {
app('log')->error(
sprintf(
'New source account ID #%d and current destination account ID #%d are the same. Do nothing.',
$cashAccount->id,
$destination->account_id
)
);
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.already_has_source', ['name' => $cashAccount->name])));
return false;
}
event(new TriggeredAuditLog($this->action->rule, $object, 'set_source', null, $cashAccount->name));
// update destination transaction with new destination account:
DB::table('transactions')
->where('transaction_journal_id', '=', $object->id)
->where('amount', '<', 0)
->update(['account_id' => $cashAccount->id]);
app('log')->debug(sprintf('Updated journal #%d (group #%d) and gave it new source account ID.', $object->id, $object->transaction_group_id));
return true;
}
}

View File

@ -86,8 +86,10 @@ use FireflyIII\TransactionRules\Actions\SetBudget;
use FireflyIII\TransactionRules\Actions\SetCategory;
use FireflyIII\TransactionRules\Actions\SetDescription;
use FireflyIII\TransactionRules\Actions\SetDestinationAccount;
use FireflyIII\TransactionRules\Actions\SetDestinationToCashAccount;
use FireflyIII\TransactionRules\Actions\SetNotes;
use FireflyIII\TransactionRules\Actions\SetSourceAccount;
use FireflyIII\TransactionRules\Actions\SetSourceToCashAccount;
use FireflyIII\TransactionRules\Actions\SwitchAccounts;
use FireflyIII\TransactionRules\Actions\UpdatePiggybank;
use FireflyIII\User;
@ -516,6 +518,8 @@ return [
'append_notes_to_descr' => AppendNotesToDescription::class,
'move_descr_to_notes' => MoveDescriptionToNotes::class,
'move_notes_to_descr' => MoveNotesToDescription::class,
'set_source_to_cash' => SetSourceToCashAccount::class,
'set_destination_to_cash' => SetDestinationToCashAccount::class,
],
'context-rule-actions' => [
'set_category',

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -239,6 +239,8 @@ function updateActionInput(selectList) {
case 'move_notes_to_descr':
case 'clear_notes':
case 'delete_transaction':
case 'set_source_to_cash':
case 'set_destination_to_cash':
case 'remove_all_tags':
console.log('Select list value is ' + selectList.val() + ', so input needs to be disabled.');
inputResult.prop('disabled', true);

View File

@ -665,7 +665,7 @@ export default {
sourceId = null;
}
// parse amount if has exactly one comma:
// parse amount, if amount has exactly one comma:
// solves issues with some locales.
if (1 === (String(row.amount).match(/\,/g) || []).length) {
row.amount = String(row.amount).replace(',', '.');
@ -721,7 +721,7 @@ export default {
if (parseInt(row.piggy_bank) > 0) {
currentArray.piggy_bank_id = parseInt(row.piggy_bank);
}
if(this.isReconciled) {
if(this.isReconciled && !this.storeAsNew) {
// drop content from array:
delete currentArray.source_id;
delete currentArray.source_name;

View File

@ -1238,6 +1238,8 @@ return [
'rule_action_append_notes_to_descr' => 'Append notes to description',
'rule_action_move_descr_to_notes' => 'Replace notes with description',
'rule_action_move_notes_to_descr' => 'Replace description with notes',
'rule_action_set_destination_to_cash_choice' => 'Set destination account to (cash)',
'rule_action_set_source_to_cash_choice' => 'Set source account to (cash)',
'rulegroup_for_bills_title' => 'Rule group for bills',
'rulegroup_for_bills_description' => 'A special rule group for all the rules that involve bills.',
'rule_for_bill_title' => 'Auto-generated rule for bill ":name"',

View File

@ -56,6 +56,8 @@ return [
'cannot_find_subscription' => 'Firefly III can\'t find subscription ":name"',
'no_notes_to_move' => 'The transaction has no notes to move to the description field',
'no_tags_to_remove' => 'The transaction has no tags to remove',
'not_withdrawal' => 'The transaction is not a withdrawal',
'not_deposit' => 'The transaction is not a deposit',
'cannot_find_tag' => 'Firefly III can\'t find tag ":tag"',
'cannot_find_asset' => 'Firefly III can\'t find asset account ":name"',
'cannot_find_accounts' => 'Firefly III can\'t find the source or destination account',