From a9f2741282ecd77bf2d971527e1ccfc2efe2291b Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 24 Sep 2022 17:43:49 +0200 Subject: [PATCH] Add ability to move stuff around, fix spelling. --- app/Helpers/Collector/GroupCollector.php | 9 +++ .../Collector/GroupCollectorInterface.php | 5 ++ app/Support/Search/OperatorQuerySearch.php | 5 +- app/Support/Steam.php | 3 + .../Actions/AppendDescriptionToNotes.php | 57 +++++++++++++++++ .../Actions/AppendNotesToDescription.php | 64 +++++++++++++++++++ .../Actions/MoveDescriptionToNotes.php | 63 ++++++++++++++++++ .../Actions/MoveNotesToDescription.php | 59 +++++++++++++++++ .../Engine/SearchRuleEngine.php | 4 +- config/firefly.php | 8 +++ config/search.php | 1 + public/v1/js/ff/rules/create-edit.js | 55 +++++++++------- resources/lang/en_US/firefly.php | 62 ++++++++++-------- resources/lang/en_US/validation.php | 2 +- 14 files changed, 344 insertions(+), 53 deletions(-) create mode 100644 app/TransactionRules/Actions/AppendDescriptionToNotes.php create mode 100644 app/TransactionRules/Actions/AppendNotesToDescription.php create mode 100644 app/TransactionRules/Actions/MoveDescriptionToNotes.php create mode 100644 app/TransactionRules/Actions/MoveNotesToDescription.php diff --git a/app/Helpers/Collector/GroupCollector.php b/app/Helpers/Collector/GroupCollector.php index 5748f439de..667204ad36 100644 --- a/app/Helpers/Collector/GroupCollector.php +++ b/app/Helpers/Collector/GroupCollector.php @@ -841,4 +841,13 @@ class GroupCollector implements GroupCollectorInterface $this->query->where('source.reconciled', 1)->where('destination.reconciled', 1); return $this; } + + /** + * @inheritDoc + */ + public function exists(): GroupCollectorInterface + { + $this->query->whereNull('transaction_groups.deleted_at'); + return $this; + } } diff --git a/app/Helpers/Collector/GroupCollectorInterface.php b/app/Helpers/Collector/GroupCollectorInterface.php index 7129940f96..b24aa90703 100644 --- a/app/Helpers/Collector/GroupCollectorInterface.php +++ b/app/Helpers/Collector/GroupCollectorInterface.php @@ -56,6 +56,11 @@ interface GroupCollectorInterface */ public function isReconciled(): GroupCollectorInterface; + /** + * @return GroupCollectorInterface + */ + public function exists(): GroupCollectorInterface; + /** * Get transactions where the amount is less than. * diff --git a/app/Support/Search/OperatorQuerySearch.php b/app/Support/Search/OperatorQuerySearch.php index 3ff0601ebc..3ddf291adb 100644 --- a/app/Support/Search/OperatorQuerySearch.php +++ b/app/Support/Search/OperatorQuerySearch.php @@ -619,7 +619,7 @@ class OperatorQuerySearch implements SearchInterface case 'amount_is': // strip comma's, make dots. Log::debug(sprintf('Original value "%s"', $value)); - $value = str_replace(',', '.', (string) $value); + $value = str_replace(',', '.', (string) $value); $amount = app('steam')->positive($value); Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount)); $this->collector->amountIs($amount); @@ -866,6 +866,9 @@ class OperatorQuerySearch implements SearchInterface case 'attachment_notes_ends': $this->collector->attachmentNotesEnds($value); break; + case 'exists': + $this->collector->exists(); + break; } diff --git a/app/Support/Steam.php b/app/Support/Steam.php index 658ec843b4..fa6718cd9d 100644 --- a/app/Support/Steam.php +++ b/app/Support/Steam.php @@ -399,6 +399,9 @@ class Steam "\x20", // plain old normal space ]; + // clear zalgo text + $string = preg_replace('/\pM/u', '', $string); + return str_replace($search, '', $string); } diff --git a/app/TransactionRules/Actions/AppendDescriptionToNotes.php b/app/TransactionRules/Actions/AppendDescriptionToNotes.php new file mode 100644 index 0000000000..7ce4e37a5d --- /dev/null +++ b/app/TransactionRules/Actions/AppendDescriptionToNotes.php @@ -0,0 +1,57 @@ +. + */ + +namespace FireflyIII\TransactionRules\Actions; + +use FireflyIII\Models\Note; +use FireflyIII\Models\TransactionJournal; +use Illuminate\Support\Facades\Log; + +class AppendDescriptionToNotes implements ActionInterface +{ + /** + * @inheritDoc + */ + public function actOnArray(array $journal): bool + { + /** @var TransactionJournal $journal */ + $journal = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']); + if (null === $journal) { + Log::error(sprintf('No journal #%d belongs to user #%d.', $journal['transaction_journal_id'], $journal['user_id'])); + return false; + } + $note = $journal->notes()->first(); + if (null === $note) { + $note = new Note; + $note->noteable()->associate($journal); + $note->text = ''; + } + if ('' !== $note->text) { + $note->text = trim(sprintf("%s \n%s", $note->text, $journal->description)); + } + if ('' === $note->text) { + $note->text = (string) $journal->description; + } + + $note->save(); + return true; + } +} diff --git a/app/TransactionRules/Actions/AppendNotesToDescription.php b/app/TransactionRules/Actions/AppendNotesToDescription.php new file mode 100644 index 0000000000..53a4d1db24 --- /dev/null +++ b/app/TransactionRules/Actions/AppendNotesToDescription.php @@ -0,0 +1,64 @@ +. + */ + +namespace FireflyIII\TransactionRules\Actions; + +use FireflyIII\Models\Note; +use FireflyIII\Models\TransactionJournal; +use FireflyIII\Support\Request\ConvertsDataTypes; +use FireflyIII\Support\Steam; +use Illuminate\Support\Facades\Log; + +/** + * Class AppendNotesToDescription + */ +class AppendNotesToDescription implements ActionInterface +{ + use ConvertsDataTypes; + /** + * @inheritDoc + */ + public function actOnArray(array $journal): bool + { + Log::debug('Now in AppendNotesToDescription'); + /** @var TransactionJournal $journal */ + $journal = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']); + if (null === $journal) { + Log::error(sprintf('No journal #%d belongs to user #%d.', $journal['transaction_journal_id'], $journal['user_id'])); + return false; + } + $note = $journal->notes()->first(); + if (null === $note) { + Log::debug('Journal has no notes.'); + $note = new Note; + $note->noteable()->associate($journal); + $note->text = ''; + } + // only append if there is something to append + if ('' !== $note->text) { + $journal->description = trim(sprintf("%s %s", $journal->description, (string) $this->clearString($note->text, false))); + $journal->save(); + Log::debug(sprintf('Journal description is updated to "%s".', $journal->description)); + return true; + } + return false; + } +} diff --git a/app/TransactionRules/Actions/MoveDescriptionToNotes.php b/app/TransactionRules/Actions/MoveDescriptionToNotes.php new file mode 100644 index 0000000000..cbad52ed07 --- /dev/null +++ b/app/TransactionRules/Actions/MoveDescriptionToNotes.php @@ -0,0 +1,63 @@ +. + */ + +namespace FireflyIII\TransactionRules\Actions; + +use FireflyIII\Models\Note; +use FireflyIII\Models\TransactionJournal; +use Illuminate\Support\Facades\Log; + +/** + * Class MoveDescriptionToNotes + */ +class MoveDescriptionToNotes implements ActionInterface +{ + /** + * @inheritDoc + */ + public function actOnArray(array $journal): bool + { + /** @var TransactionJournal $journal */ + $journal = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']); + if (null === $journal) { + Log::error(sprintf('No journal #%d belongs to user #%d.', $journal['transaction_journal_id'], $journal['user_id'])); + return false; + } + $note = $journal->notes()->first(); + if (null === $note) { + $note = new Note; + $note->noteable()->associate($journal); + $note->text = ''; + } + if ('' !== $note->text) { + $note->text = trim(sprintf("%s \n%s", $note->text, $journal->description)); + $journal->description = '(no description)'; + } + if ('' === $note->text) { + $note->text = (string) $journal->description; + $journal->description = '(no description)'; + } + + $note->save(); + $journal->save(); + return true; + } +} diff --git a/app/TransactionRules/Actions/MoveNotesToDescription.php b/app/TransactionRules/Actions/MoveNotesToDescription.php new file mode 100644 index 0000000000..f261d44c7a --- /dev/null +++ b/app/TransactionRules/Actions/MoveNotesToDescription.php @@ -0,0 +1,59 @@ +. + */ + +namespace FireflyIII\TransactionRules\Actions; + +use FireflyIII\Models\TransactionJournal; +use FireflyIII\Support\Request\ConvertsDataTypes; +use Illuminate\Support\Facades\Log; + +class MoveNotesToDescription implements ActionInterface +{ + use ConvertsDataTypes; + + /** + * @inheritDoc + */ + public function actOnArray(array $journal): bool + { + /** @var TransactionJournal $journal */ + $journal = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']); + if (null === $journal) { + Log::error(sprintf('No journal #%d belongs to user #%d.', $journal['transaction_journal_id'], $journal['user_id'])); + return false; + } + $note = $journal->notes()->first(); + if (null === $note) { + // nothing to move, return null + return false; + } + if ('' === $note->text) { + // nothing to move, return null + $note->delete(); + return false; + } + $journal->description = (string) $this->clearString($note->text, false); + $journal->save(); + $note->delete(); + + return true; + } +} diff --git a/app/TransactionRules/Engine/SearchRuleEngine.php b/app/TransactionRules/Engine/SearchRuleEngine.php index 8afcae7b81..3ca0cd33cb 100644 --- a/app/TransactionRules/Engine/SearchRuleEngine.php +++ b/app/TransactionRules/Engine/SearchRuleEngine.php @@ -99,7 +99,7 @@ class SearchRuleEngine implements RuleEngineInterface $searchArray = []; /** @var Collection $triggers */ - $triggers = $rule->ruleTriggers; + $triggers = $rule->ruleTriggers()->orderBy('order', 'ASC')->get(); /** @var RuleTrigger $ruleTrigger */ foreach ($triggers as $ruleTrigger) { @@ -409,7 +409,7 @@ class SearchRuleEngine implements RuleEngineInterface private function processTransactionJournal(Rule $rule, array $transaction): void { Log::debug(sprintf('SearchRuleEngine:: Will now execute actions on transaction journal #%d', $transaction['transaction_journal_id'])); - $actions = $rule->ruleActions()->get(); + $actions = $rule->ruleActions()->orderBy('order', 'ASC')->get(); /** @var RuleAction $ruleAction */ foreach ($actions as $ruleAction) { if (false === $ruleAction->active) { diff --git a/config/firefly.php b/config/firefly.php index da5c219273..c2f00c93cc 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -61,7 +61,9 @@ use FireflyIII\Support\Binder\TagList; use FireflyIII\Support\Binder\TagOrId; use FireflyIII\TransactionRules\Actions\AddTag; use FireflyIII\TransactionRules\Actions\AppendDescription; +use FireflyIII\TransactionRules\Actions\AppendDescriptionToNotes; use FireflyIII\TransactionRules\Actions\AppendNotes; +use FireflyIII\TransactionRules\Actions\AppendNotesToDescription; use FireflyIII\TransactionRules\Actions\ClearBudget; use FireflyIII\TransactionRules\Actions\ClearCategory; use FireflyIII\TransactionRules\Actions\ClearNotes; @@ -70,6 +72,8 @@ use FireflyIII\TransactionRules\Actions\ConvertToTransfer; use FireflyIII\TransactionRules\Actions\ConvertToWithdrawal; use FireflyIII\TransactionRules\Actions\DeleteTransaction; use FireflyIII\TransactionRules\Actions\LinkToBill; +use FireflyIII\TransactionRules\Actions\MoveDescriptionToNotes; +use FireflyIII\TransactionRules\Actions\MoveNotesToDescription; use FireflyIII\TransactionRules\Actions\PrependDescription; use FireflyIII\TransactionRules\Actions\PrependNotes; use FireflyIII\TransactionRules\Actions\RemoveAllTags; @@ -481,6 +485,10 @@ return [ 'convert_transfer' => ConvertToTransfer::class, 'update_piggy' => UpdatePiggybank::class, 'delete_transaction' => DeleteTransaction::class, + 'append_descr_to_notes' => AppendDescriptionToNotes::class, + 'append_notes_to_descr' => AppendNotesToDescription::class, + 'move_descr_to_notes' => MoveDescriptionToNotes::class, + 'move_notes_to_descr' => MoveNotesToDescription::class, ], 'context-rule-actions' => [ 'set_category', diff --git a/config/search.php b/config/search.php index a2d4cac75d..ef7dd639ba 100644 --- a/config/search.php +++ b/config/search.php @@ -230,5 +230,6 @@ return [ 'attachment_notes_start' => ['alias' => true, 'alias_for' => 'attachment_notes_starts', 'needs_context' => true], 'attachment_notes_ends' => ['alias' => false, 'needs_context' => true], 'attachment_notes_end' => ['alias' => true, 'alias_for' => 'attachment_notes_ends', 'needs_context' => true], + 'exists' => ['alias' => false, 'needs_context' => false,], ], ]; diff --git a/public/v1/js/ff/rules/create-edit.js b/public/v1/js/ff/rules/create-edit.js index f454473eac..b9d2299b56 100644 --- a/public/v1/js/ff/rules/create-edit.js +++ b/public/v1/js/ff/rules/create-edit.js @@ -232,11 +232,16 @@ function updateActionInput(selectList) { break; case 'clear_category': case 'clear_budget': + case 'append_descr_to_notes': + case 'append_notes_to_descr': + case 'move_descr_to_notes': + case 'move_notes_to_descr': case 'clear_notes': case 'delete_transaction': case 'remove_all_tags': console.log('Select list value is ' + selectList.val() + ', so input needs to be disabled.'); - inputResult.attr('disabled', 'disabled'); + inputResult.prop('disabled', true); + inputResult.typeahead('destroy'); break; case 'set_budget': console.log('Select list value is ' + selectList.val() + ', so input needs auto complete.'); @@ -343,6 +348,8 @@ function updateTriggerInput(selectList) { case 'has_no_tag': case 'no_notes': case 'any_notes': + case 'exists': + case 'reconciled': case 'has_any_tag': case 'has_attachments': case 'source_is_cash': @@ -364,7 +371,7 @@ function updateTriggerInput(selectList) { case 'amount_exactly': console.log('Set value to type=number'); inputResult.prop('type', 'number'); - inputResult.prop('step','any'); + inputResult.prop('step', 'any'); break; default: console.log('Select list value is ' + selectList.val() + ', destroy auto complete, do nothing else.'); @@ -383,32 +390,32 @@ function createAutoComplete(input, URL) { input.typeahead('destroy'); // append URL: - var lastChar = URL[URL.length -1]; + var lastChar = URL[URL.length - 1]; var urlParamSplit = '?'; - if('&' === lastChar) { + if ('&' === lastChar) { urlParamSplit = ''; } var source = new Bloodhound({ - datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'), - queryTokenizer: Bloodhound.tokenizers.whitespace, - prefetch: { - url: URL + urlParamSplit + 'uid=' + uid, - filter: function (list) { - return $.map(list, function (item) { - return {name: item.name}; - }); - } - }, - remote: { - url: URL + urlParamSplit + 'query=%QUERY&uid=' + uid, - wildcard: '%QUERY', - filter: function (list) { - return $.map(list, function (item) { - return {name: item.name}; - }); - } - } - }); + datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'), + queryTokenizer: Bloodhound.tokenizers.whitespace, + prefetch: { + url: URL + urlParamSplit + 'uid=' + uid, + filter: function (list) { + return $.map(list, function (item) { + return {name: item.name}; + }); + } + }, + remote: { + url: URL + urlParamSplit + 'query=%QUERY&uid=' + uid, + wildcard: '%QUERY', + filter: function (list) { + return $.map(list, function (item) { + return {name: item.name}; + }); + } + } + }); source.initialize(); input.typeahead({hint: true, highlight: true,}, {source: source, displayKey: 'name', autoSelect: false}); } diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index 97d39d4b18..6c2bd336fd 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -761,8 +761,8 @@ return [ // new values: 'rule_trigger_user_action_choice' => 'User action is ":trigger_value"', - 'rule_trigger_tag_is_not_choice' => 'No tag is ":trigger_value"', - 'rule_trigger_tag_is_not' => 'No tag is..', + 'rule_trigger_tag_is_not_choice' => 'No tag is..', + 'rule_trigger_tag_is_not' => 'No tag is ":trigger_value"', 'rule_trigger_account_is_choice' => 'Either account is exactly..', 'rule_trigger_account_is' => 'Either account is exactly ":trigger_value"', 'rule_trigger_account_contains_choice' => 'Either account contains..', @@ -887,10 +887,14 @@ return [ 'rule_trigger_attachment_notes_starts' => 'Any attachment\'s notes start with ":trigger_value"', 'rule_trigger_attachment_notes_ends_choice' => 'Any attachment\'s notes end with..', 'rule_trigger_attachment_notes_ends' => 'Any attachment\'s notes end with ":trigger_value"', + 'rule_trigger_reconciled_choice' => 'Transaction is reconciled', + 'rule_trigger_reconciled' => 'Transaction is reconciled', + 'rule_trigger_exists_choice' => 'Any transaction matches(!)', + 'rule_trigger_exists' => 'Any transaction matches', // actions - 'rule_action_delete_transaction_choice' => 'DELETE transaction (!)', - 'rule_action_delete_transaction' => 'DELETE transaction (!)', + 'rule_action_delete_transaction_choice' => 'DELETE transaction(!)', + 'rule_action_delete_transaction' => 'DELETE transaction(!)', 'rule_action_set_category' => 'Set category to ":action_value"', 'rule_action_clear_category' => 'Clear category', 'rule_action_set_budget' => 'Set budget to ":action_value"', @@ -901,30 +905,30 @@ return [ 'rule_action_set_description' => 'Set description to ":action_value"', 'rule_action_append_description' => 'Append description with ":action_value"', 'rule_action_prepend_description' => 'Prepend description with ":action_value"', - 'rule_action_set_category_choice' => 'Set category to..', + 'rule_action_set_category_choice' => 'Set category to ..', 'rule_action_clear_category_choice' => 'Clear any category', - 'rule_action_set_budget_choice' => 'Set budget to..', + 'rule_action_set_budget_choice' => 'Set budget to ..', 'rule_action_clear_budget_choice' => 'Clear any budget', - 'rule_action_add_tag_choice' => 'Add tag..', - 'rule_action_remove_tag_choice' => 'Remove tag..', + 'rule_action_add_tag_choice' => 'Add tag ..', + 'rule_action_remove_tag_choice' => 'Remove tag ..', 'rule_action_remove_all_tags_choice' => 'Remove all tags', - 'rule_action_set_description_choice' => 'Set description to..', - 'rule_action_update_piggy_choice' => 'Add/remove transaction amount in piggy bank..', - 'rule_action_update_piggy' => 'Add/remove transaction amount in piggy bank ":action_value"', - 'rule_action_append_description_choice' => 'Append description with..', - 'rule_action_prepend_description_choice' => 'Prepend description with..', - 'rule_action_set_source_account_choice' => 'Set source account to..', + 'rule_action_set_description_choice' => 'Set description to ..', + 'rule_action_update_piggy_choice' => 'Add / remove transaction amount in piggy bank ..', + 'rule_action_update_piggy' => 'Add / remove transaction amount in piggy bank ":action_value"', + 'rule_action_append_description_choice' => 'Append description with ..', + 'rule_action_prepend_description_choice' => 'Prepend description with ..', + 'rule_action_set_source_account_choice' => 'Set source account to ..', 'rule_action_set_source_account' => 'Set source account to :action_value', - 'rule_action_set_destination_account_choice' => 'Set destination account to..', + 'rule_action_set_destination_account_choice' => 'Set destination account to ..', 'rule_action_set_destination_account' => 'Set destination account to :action_value', - 'rule_action_append_notes_choice' => 'Append notes with..', + 'rule_action_append_notes_choice' => 'Append notes with ..', 'rule_action_append_notes' => 'Append notes with ":action_value"', - 'rule_action_prepend_notes_choice' => 'Prepend notes with..', + 'rule_action_prepend_notes_choice' => 'Prepend notes with ..', 'rule_action_prepend_notes' => 'Prepend notes with ":action_value"', 'rule_action_clear_notes_choice' => 'Remove any notes', 'rule_action_clear_notes' => 'Remove any notes', - 'rule_action_set_notes_choice' => 'Set notes to..', - 'rule_action_link_to_bill_choice' => 'Link to a bill..', + 'rule_action_set_notes_choice' => 'Set notes to ..', + 'rule_action_link_to_bill_choice' => 'Link to a bill ..', 'rule_action_link_to_bill' => 'Link to bill ":action_value"', 'rule_action_set_notes' => 'Set notes to ":action_value"', 'rule_action_convert_deposit_choice' => 'Convert the transaction to a deposit', @@ -933,15 +937,23 @@ return [ 'rule_action_convert_withdrawal' => 'Convert the transaction to a withdrawal to ":action_value"', 'rule_action_convert_transfer_choice' => 'Convert the transaction to a transfer', 'rule_action_convert_transfer' => 'Convert the transaction to a transfer with ":action_value"', + 'rule_action_append_descr_to_notes_choice' => 'Append the description to the transaction notes', + 'rule_action_append_notes_to_descr_choice' => 'Append the transaction notes to the description', + 'rule_action_move_descr_to_notes_choice' => 'Replace the current transaction notes with the description', + 'rule_action_move_notes_to_descr_choice' => 'Replace the current description with the transaction notes', + 'rule_action_append_descr_to_notes' => 'Append description to notes', + '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', - 'rules_have_read_warning' => 'Have you read the warning?', - 'apply_rule_warning' => 'Warning: running a rule(group) on a large selection of transactions could take ages, and it could time-out. If it does, the rule(group) will only be applied to an unknown subset of your transactions. This might leave your financial administration in tatters. Please be careful.', + 'rules_have_read_warning' => 'Have you read the warning ? ', + 'apply_rule_warning' => 'Warning: running a rule(group) on a large selection of transactions could take ages, and it could time - out . if it does, the rule(group) will only be applied to an unknown subset of your transactions . This might leave your financial administration in tatters . Please be careful . ', '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"', - 'rule_for_bill_description' => 'This rule is auto-generated to try to match bill ":name".', + '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"', + 'rule_for_bill_description' => 'This rule is auto - generated to try to match bill ":name" . ', 'create_rule_for_bill' => 'Create a new rule for bill ":name"', - 'create_rule_for_bill_txt' => 'You have just created a new bill called ":name", congratulations! Firefly III can automagically match new withdrawals to this bill. For example, whenever you pay your rent, the bill "rent" will be linked to the expense. This way, Firefly III can accurately show you which bills are due and which ones aren\'t. In order to do so, a new rule must be created. Firefly III has filled in some sensible defaults for you. Please make sure these are correct. If these values are correct, Firefly III will automatically link the correct withdrawal to the correct bill. Please check out the triggers to see if they are correct, and add some if they\'re wrong.', + 'create_rule_for_bill_txt' => 'You have just created a new bill called ":name", congratulations!Firefly III can automagically match new withdrawals to this bill . for example, whenever you pay your rent, the bill "rent" will be linked to the expense . This way, Firefly III can accurately show you which bills are due and which ones aren\'t. In order to do so, a new rule must be created. Firefly III has filled in some sensible defaults for you. Please make sure these are correct. If these values are correct, Firefly III will automatically link the correct withdrawal to the correct bill. Please check out the triggers to see if they are correct, and add some if they\'re wrong.', 'new_rule_for_bill_title' => 'Rule for bill ":name"', 'new_rule_for_bill_description' => 'This rule marks transactions for bill ":name".', diff --git a/resources/lang/en_US/validation.php b/resources/lang/en_US/validation.php index e3c07f5369..0f0eb75744 100644 --- a/resources/lang/en_US/validation.php +++ b/resources/lang/en_US/validation.php @@ -142,7 +142,7 @@ return [ 'unique_object_group' => 'The group name must be unique', 'starts_with' => 'The value must start with :values.', 'unique_webhook' => 'You already have a webhook with this combination of URL, trigger, response and delivery.', - 'unique_existing_webhook' => 'You already have another webhook this combination of URL, trigger, response and delivery.', + 'unique_existing_webhook' => 'You already have another webhook with this combination of URL, trigger, response and delivery.', 'same_account_type' => 'Both accounts must be of the same account type', 'same_account_currency' => 'Both accounts must have the same currency setting',