mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Refresh notes in various actions.
This commit is contained in:
parent
0b45c1aa76
commit
3413b9b5b5
@ -105,8 +105,8 @@ class StoreRequest extends FormRequest
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$validTriggers = $this->getTriggers();
|
||||
$validActions = array_keys(config('firefly.rule-actions'));
|
||||
$validTriggers = $this->getTriggers();
|
||||
$validActions = array_keys(config('firefly.rule-actions'));
|
||||
|
||||
// some triggers and actions require text:
|
||||
$contextTriggers = implode(',', $this->getTriggersWithContext());
|
||||
@ -118,11 +118,11 @@ class StoreRequest extends FormRequest
|
||||
'rule_group_id' => 'belongsToUser:rule_groups|required_without:rule_group_title',
|
||||
'rule_group_title' => 'nullable|min:1|max:255|required_without:rule_group_id|belongsToUser:rule_groups,title',
|
||||
'trigger' => 'required|in:store-journal,update-journal',
|
||||
'triggers.*.type' => 'required|in:' . implode(',', $validTriggers),
|
||||
'triggers.*.value' => 'required_if:actions.*.type,' . $contextTriggers . '|min:1|ruleTriggerValue|max:1024',
|
||||
'triggers.*.type' => 'required|in:'.implode(',', $validTriggers),
|
||||
'triggers.*.value' => 'required_if:actions.*.type,'.$contextTriggers.'|min:1|ruleTriggerValue|max:1024',
|
||||
'triggers.*.stop_processing' => [new IsBoolean()],
|
||||
'triggers.*.active' => [new IsBoolean()],
|
||||
'actions.*.type' => 'required|in:' . implode(',', $validActions),
|
||||
'actions.*.type' => 'required|in:'.implode(',', $validActions),
|
||||
'actions.*.value' => [sprintf('required_if:actions.*.type,%s', $contextActions), new IsValidActionExpression(), 'ruleActionValue'],
|
||||
'actions.*.stop_processing' => [new IsBoolean()],
|
||||
'actions.*.active' => [new IsBoolean()],
|
||||
@ -181,10 +181,10 @@ class StoreRequest extends FormRequest
|
||||
*/
|
||||
protected function atLeastOneActiveTrigger(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$data = $validator->getData();
|
||||
|
||||
/** @var null|array|int|string $triggers */
|
||||
$triggers = $data['triggers'] ?? [];
|
||||
$triggers = $data['triggers'] ?? [];
|
||||
// need at least one trigger
|
||||
if (!is_countable($triggers) || 0 === count($triggers)) {
|
||||
return;
|
||||
@ -210,10 +210,10 @@ class StoreRequest extends FormRequest
|
||||
*/
|
||||
protected function atLeastOneActiveAction(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$data = $validator->getData();
|
||||
|
||||
/** @var null|array|int|string $actions */
|
||||
$actions = $data['actions'] ?? [];
|
||||
$actions = $data['actions'] ?? [];
|
||||
// need at least one trigger
|
||||
if (!is_countable($actions) || 0 === count($actions)) {
|
||||
return;
|
||||
|
@ -141,7 +141,7 @@ class UpdateRequest extends FormRequest
|
||||
'triggers.*.stop_processing' => [new IsBoolean()],
|
||||
'triggers.*.active' => [new IsBoolean()],
|
||||
'actions.*.type' => 'required|in:'.implode(',', $validActions),
|
||||
'actions.*.value' => [sprintf('required_if:actions.*.type,%s',$contextActions), new IsValidActionExpression(), 'ruleActionValue'],
|
||||
'actions.*.value' => [sprintf('required_if:actions.*.type,%s', $contextActions), new IsValidActionExpression(), 'ruleActionValue'],
|
||||
'actions.*.stop_processing' => [new IsBoolean()],
|
||||
'actions.*.active' => [new IsBoolean()],
|
||||
'strict' => [new IsBoolean()],
|
||||
|
@ -26,9 +26,7 @@ namespace FireflyIII\Api\V1\Requests\Models\Rule;
|
||||
|
||||
use FireflyIII\Rules\IsValidActionExpression;
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use Illuminate\Contracts\Validation\Validator;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
/**
|
||||
* Class ValidateExpressionRequest
|
||||
@ -41,6 +39,4 @@ class ValidateExpressionRequest extends FormRequest
|
||||
{
|
||||
return ['expression' => ['required', new IsValidActionExpression()]];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -31,7 +31,6 @@ use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* FireflyIII\Models\RuleAction
|
||||
@ -67,7 +66,7 @@ class RuleAction extends Model
|
||||
use ReturnsIntegerIdTrait;
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'active' => 'boolean',
|
||||
@ -80,12 +79,14 @@ class RuleAction extends Model
|
||||
public function getValue(array $journal): string
|
||||
{
|
||||
if (false === config('firefly.feature_flags.expression_engine')) {
|
||||
Log::debug('Expression engine is disabled, returning action value as string.');
|
||||
\Log::debug('Expression engine is disabled, returning action value as string.');
|
||||
|
||||
return (string)$this->action_value;
|
||||
}
|
||||
$expr = new ActionExpression($this->action_value);
|
||||
$result = $expr->evaluate($journal);
|
||||
Log::debug(sprintf('Expression engine is enabled, result of expression "%s" is "%s".', $this->action_value, $result));
|
||||
\Log::debug(sprintf('Expression engine is enabled, result of expression "%s" is "%s".', $this->action_value, $result));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
@ -97,14 +98,14 @@ class RuleAction extends Model
|
||||
protected function order(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: static fn($value) => (int)$value,
|
||||
get: static fn ($value) => (int)$value,
|
||||
);
|
||||
}
|
||||
|
||||
protected function ruleId(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: static fn($value) => (int)$value,
|
||||
get: static fn ($value) => (int)$value,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ class IsValidActionExpression implements ValidationRule
|
||||
return;
|
||||
}
|
||||
$value ??= '';
|
||||
$expr = new ActionExpression($value);
|
||||
$expr = new ActionExpression($value);
|
||||
|
||||
if (!$expr->isValid()) {
|
||||
$fail('validation.rule_action_expression')->translate(
|
||||
|
@ -34,8 +34,8 @@ use FireflyIII\TransactionRules\Traits\RefreshNotesTrait;
|
||||
*/
|
||||
class AppendDescription implements ActionInterface
|
||||
{
|
||||
private RuleAction $action;
|
||||
use RefreshNotesTrait;
|
||||
private RuleAction $action;
|
||||
|
||||
/**
|
||||
* TriggerInterface constructor.
|
||||
|
@ -51,6 +51,7 @@ class AppendDescriptionToNotes implements ActionInterface
|
||||
public function actOnArray(array $journal): bool
|
||||
{
|
||||
$this->refreshNotes($journal);
|
||||
|
||||
/** @var null|TransactionJournal $object */
|
||||
$object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
|
||||
if (null === $object) {
|
||||
|
@ -27,6 +27,7 @@ use FireflyIII\Events\TriggeredAuditLog;
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\RuleAction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\TransactionRules\Traits\RefreshNotesTrait;
|
||||
|
||||
/**
|
||||
* Class AppendNotes.
|
||||
@ -34,6 +35,7 @@ use FireflyIII\Models\TransactionJournal;
|
||||
*/
|
||||
class AppendNotes implements ActionInterface
|
||||
{
|
||||
use RefreshNotesTrait;
|
||||
private RuleAction $action;
|
||||
|
||||
/**
|
||||
@ -46,6 +48,7 @@ class AppendNotes implements ActionInterface
|
||||
|
||||
public function actOnArray(array $journal): bool
|
||||
{
|
||||
$this->refreshNotes($journal);
|
||||
$dbNote = Note::where('noteable_id', (int)$journal['transaction_journal_id'])
|
||||
->where('noteable_type', TransactionJournal::class)
|
||||
->first(['notes.*'])
|
||||
|
@ -30,6 +30,7 @@ use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\RuleAction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use FireflyIII\TransactionRules\Traits\RefreshNotesTrait;
|
||||
|
||||
/**
|
||||
* Class AppendNotesToDescription
|
||||
@ -38,7 +39,7 @@ use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
class AppendNotesToDescription implements ActionInterface
|
||||
{
|
||||
use ConvertsDataTypes;
|
||||
|
||||
use RefreshNotesTrait;
|
||||
private RuleAction $action;
|
||||
|
||||
/**
|
||||
@ -52,6 +53,7 @@ class AppendNotesToDescription implements ActionInterface
|
||||
public function actOnArray(array $journal): bool
|
||||
{
|
||||
app('log')->debug('Now in AppendNotesToDescription');
|
||||
$this->refreshNotes($journal);
|
||||
|
||||
/** @var null|TransactionJournal $object */
|
||||
$object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
|
||||
|
@ -26,12 +26,14 @@ namespace FireflyIII\TransactionRules\Actions;
|
||||
use FireflyIII\Events\TriggeredAuditLog;
|
||||
use FireflyIII\Models\RuleAction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\TransactionRules\Traits\RefreshNotesTrait;
|
||||
|
||||
/**
|
||||
* Class SetDescription.
|
||||
*/
|
||||
class SetDescription implements ActionInterface
|
||||
{
|
||||
use RefreshNotesTrait;
|
||||
private RuleAction $action;
|
||||
|
||||
/**
|
||||
@ -44,6 +46,8 @@ class SetDescription implements ActionInterface
|
||||
|
||||
public function actOnArray(array $journal): bool
|
||||
{
|
||||
$this->refreshNotes($journal);
|
||||
|
||||
/** @var TransactionJournal $object */
|
||||
$object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
|
||||
$before = $object->description;
|
||||
|
@ -53,10 +53,10 @@ class SearchRuleEngine implements RuleEngineInterface
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->rules = new Collection();
|
||||
$this->groups = new Collection();
|
||||
$this->operators = [];
|
||||
$this->resultCount = [];
|
||||
$this->rules = new Collection();
|
||||
$this->groups = new Collection();
|
||||
$this->operators = [];
|
||||
$this->resultCount = [];
|
||||
|
||||
// always collect the triggers from the database, unless indicated otherwise.
|
||||
$this->refreshTriggers = true;
|
||||
@ -73,7 +73,7 @@ class SearchRuleEngine implements RuleEngineInterface
|
||||
app('log')->debug('SearchRuleEngine::find()');
|
||||
$collection = new Collection();
|
||||
foreach ($this->rules as $rule) {
|
||||
$found = new Collection();
|
||||
$found = new Collection();
|
||||
if (true === $rule->strict) {
|
||||
$found = $this->findStrictRule($rule);
|
||||
}
|
||||
@ -82,8 +82,9 @@ class SearchRuleEngine implements RuleEngineInterface
|
||||
}
|
||||
$collection = $collection->merge($found);
|
||||
}
|
||||
$result = $collection->unique();
|
||||
$result = $collection->unique();
|
||||
app('log')->debug(sprintf('SearchRuleEngine::find() returns %d unique transactions.', $result->count()));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
@ -93,8 +94,8 @@ class SearchRuleEngine implements RuleEngineInterface
|
||||
private function findStrictRule(Rule $rule): Collection
|
||||
{
|
||||
app('log')->debug(sprintf('Now in findStrictRule(#%d)', $rule->id ?? 0));
|
||||
$searchArray = [];
|
||||
$triggers = [];
|
||||
$searchArray = [];
|
||||
$triggers = [];
|
||||
if ($this->refreshTriggers) {
|
||||
$triggers = $rule->ruleTriggers()->orderBy('order', 'ASC')->get();
|
||||
}
|
||||
@ -125,7 +126,7 @@ class SearchRuleEngine implements RuleEngineInterface
|
||||
app('log')->debug(sprintf('SearchRuleEngine:: add local added operator: %s:"%s"', $operator['type'], $operator['value']));
|
||||
$searchArray[$operator['type']][] = sprintf('"%s"', $operator['value']);
|
||||
}
|
||||
$date = today(config('app.timezone'));
|
||||
$date = today(config('app.timezone'));
|
||||
if ($this->hasSpecificJournalTrigger($searchArray)) {
|
||||
$date = $this->setDateFromJournalTrigger($searchArray);
|
||||
}
|
||||
@ -145,7 +146,7 @@ class SearchRuleEngine implements RuleEngineInterface
|
||||
}
|
||||
}
|
||||
|
||||
$result = $searchEngine->searchTransactions();
|
||||
$result = $searchEngine->searchTransactions();
|
||||
|
||||
return $result->getCollection();
|
||||
}
|
||||
@ -170,7 +171,7 @@ class SearchRuleEngine implements RuleEngineInterface
|
||||
$dateTrigger = true;
|
||||
}
|
||||
}
|
||||
$result = $journalTrigger && $dateTrigger;
|
||||
$result = $journalTrigger && $dateTrigger;
|
||||
app('log')->debug(sprintf('Result of hasSpecificJournalTrigger is %s.', var_export($result, true)));
|
||||
|
||||
return $result;
|
||||
@ -189,7 +190,7 @@ class SearchRuleEngine implements RuleEngineInterface
|
||||
if (0 !== $journalId) {
|
||||
$repository = app(JournalRepositoryInterface::class);
|
||||
$repository->setUser($this->user);
|
||||
$journal = $repository->find($journalId);
|
||||
$journal = $repository->find($journalId);
|
||||
if (null !== $journal) {
|
||||
$date = $journal->date;
|
||||
app('log')->debug(sprintf('Found journal #%d with date %s.', $journal->id, $journal->date->format('Y-m-d')));
|
||||
@ -265,10 +266,10 @@ class SearchRuleEngine implements RuleEngineInterface
|
||||
$searchEngine->parseQuery(sprintf('%s:%s', $type, $value));
|
||||
}
|
||||
|
||||
$result = $searchEngine->searchTransactions();
|
||||
$collection = $result->getCollection();
|
||||
$result = $searchEngine->searchTransactions();
|
||||
$collection = $result->getCollection();
|
||||
app('log')->debug(sprintf('Found in this run, %d transactions', $collection->count()));
|
||||
$total = $total->merge($collection);
|
||||
$total = $total->merge($collection);
|
||||
app('log')->debug(sprintf('Total collection is now %d transactions', $total->count()));
|
||||
++$count;
|
||||
// if trigger says stop processing, do so.
|
||||
@ -282,7 +283,7 @@ class SearchRuleEngine implements RuleEngineInterface
|
||||
app('log')->debug(sprintf('Done running %d trigger(s)', $count));
|
||||
|
||||
// make collection unique
|
||||
$unique = $total->unique(
|
||||
$unique = $total->unique(
|
||||
static function (array $group) {
|
||||
$str = '';
|
||||
foreach ($group['transactions'] as $transaction) {
|
||||
@ -373,7 +374,7 @@ class SearchRuleEngine implements RuleEngineInterface
|
||||
$this->processResults($rule, $collection);
|
||||
app('log')->debug(sprintf('SearchRuleEngine:: done processing strict rule #%d', $rule->id));
|
||||
|
||||
$result = $collection->count() > 0;
|
||||
$result = $collection->count() > 0;
|
||||
if (true === $result) {
|
||||
app('log')->debug(sprintf('SearchRuleEngine:: rule #%d was triggered (on %d transaction(s)).', $rule->id, $collection->count()));
|
||||
|
||||
@ -546,6 +547,7 @@ class SearchRuleEngine implements RuleEngineInterface
|
||||
$transaction['notes'] = $dbNote->text;
|
||||
}
|
||||
Log::debug(sprintf('Notes of journal #%d filled in.', $transaction['transaction_journal_id']));
|
||||
|
||||
return $transaction;
|
||||
}
|
||||
}
|
||||
|
@ -31,26 +31,24 @@ class ActionExpressionLanguageProvider implements ExpressionFunctionProviderInte
|
||||
{
|
||||
public function getFunctions(): array
|
||||
{
|
||||
|
||||
return [
|
||||
|
||||
new ExpressionFunction('constant', function ($str): string {
|
||||
return sprintf('(is_string(%1$s) ? strtolower(%1$s) : %1$s)', $str . '!');
|
||||
return sprintf('(is_string(%1$s) ? strtolower(%1$s) : %1$s)', $str.'!');
|
||||
}, function ($arguments, $str): string {
|
||||
if (!is_string($str)) {
|
||||
return $str;
|
||||
}
|
||||
|
||||
return strtolower($str . '!');
|
||||
return strtolower($str.'!');
|
||||
}),
|
||||
new ExpressionFunction('enum', function ($str): string {
|
||||
return sprintf('(is_string(%1$s) ? strtolower(%1$s) : %1$s)', $str . '?');
|
||||
return sprintf('(is_string(%1$s) ? strtolower(%1$s) : %1$s)', $str.'?');
|
||||
}, function ($arguments, $str): string {
|
||||
if (!is_string($str)) {
|
||||
return $str;
|
||||
}
|
||||
|
||||
return strtolower($str) . '?';
|
||||
return strtolower($str).'?';
|
||||
}),
|
||||
|
||||
ExpressionFunction::fromPhp('substr'),
|
||||
|
@ -29,11 +29,6 @@ use Illuminate\Support\Facades\Log;
|
||||
|
||||
trait RefreshNotesTrait
|
||||
{
|
||||
/**
|
||||
* @param array $transaction
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
final protected function refreshNotes(array $transaction): array
|
||||
{
|
||||
$transaction['notes'] = '';
|
||||
@ -42,7 +37,7 @@ trait RefreshNotesTrait
|
||||
$transaction['notes'] = $dbNote->text;
|
||||
}
|
||||
Log::debug(sprintf('Notes of journal #%d refreshed.', $transaction['transaction_journal_id']));
|
||||
|
||||
return $transaction;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -607,7 +607,6 @@ Route::group(
|
||||
Route::put('{rule}', ['uses' => 'UpdateController@update', 'as' => 'update']);
|
||||
Route::delete('{rule}', ['uses' => 'DestroyController@destroy', 'as' => 'delete']);
|
||||
|
||||
|
||||
Route::get('{rule}/test', ['uses' => 'TriggerController@testRule', 'as' => 'test']);
|
||||
// TODO give results back
|
||||
Route::post('{rule}/trigger', ['uses' => 'TriggerController@triggerRule', 'as' => 'trigger']);
|
||||
|
Loading…
Reference in New Issue
Block a user