From aeaa0450580f7b3f9a5b0589971a329c32086cde Mon Sep 17 00:00:00 2001 From: Herculino Trotta Date: Tue, 2 Sep 2025 22:21:43 -0300 Subject: [PATCH] Updated Transaction Rules (markdown) --- Transaction-Rules.md | 46 +++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/Transaction-Rules.md b/Transaction-Rules.md index 5c616ed..f23a1f9 100644 --- a/Transaction-Rules.md +++ b/Transaction-Rules.md @@ -1,10 +1,10 @@ -### Transaction Rules +# Transaction Rules Transaction Rules are a powerful feature in WYGIWYH that allow for the automatic execution of actions based on transaction events. This can be used to modify the transaction that triggered the event, or to create/update other transactions, helping you save time and ensure consistency in your financial tracking. A rule is composed of a **Trigger** and one or more **Actions**. -#### Rule Configuration +## Rule Configuration Each rule has the following configuration options: @@ -17,7 +17,7 @@ Each rule has the following configuration options: * **Sequenced**: A sequenced rule will update its [variables](#available-variables) between each rule execution, meaning that the next action will have access to the values of the previous action instead of the originating transaction. * **Trigger**: A condition that must evaluate to `True` for the rule's actions to be executed. -#### Actions +## Actions When a rule's trigger condition is met, it will execute one or more actions. There are two types of actions: @@ -34,7 +34,7 @@ Since v.0.17, each action has an `Order` field (a number, defaulting to 0). Ther --- -### 1. Edit Transaction Action +## Edit Transaction Action This action modifies the fields of the transaction that triggered the rule. @@ -68,7 +68,7 @@ Unlike other interfaces, rules **do not create inexistent objects** like categor --- -### 2. Update or Create Transaction Action +## Update or Create Transaction Action This action is more advanced. It allows you to define search criteria to find a specific transaction. @@ -82,17 +82,17 @@ This action has three main parts: * **Set Values**: The new values for the fields of the found or created transaction. If a field is left blank, it will not be changed on an update (it will be left empty on creation). -### The Evaluation Engine +## The Evaluation Engine The `Trigger`, action `Value`s, and `Filter` fields all use a limited subset of Python for their expressions, powered by [SimpleEval](https://github.com/danthedeckie/simpleeval). You can use variables and functions to create dynamic logic. -#### Caveats +## Caveats - Since you're writing Python, make sure to quote your strings (e.g. `"My account"` instead of just `My account`) - You are creating big one-liners of python code, you can't define variables or call functions outside the available scope. -#### Available Variables +## Available Variables The following variables are available, referring to the transaction that triggered the rule. @@ -124,12 +124,22 @@ The following variables are available, referring to the transaction that trigger | `is_deleted` | `True` if the transaction is soft-deleted. | | `is_muted` | `True` if the transaction is muted. | +**Always-available Variables** + +These variables are always available + +| Variable | Description | +| ---------------------- | ------------------------------------------------------------ | +| `is_on_create` | If the running rule has been triggered by a `create` event | +| `is_on_update` | If the running rule has been triggered by an `update` event | +| `is_on_delete` | If the running rule has been triggered by a `delete` event | + **Context-Specific Variables:** * **On Update (`on_update`)**: When a rule is triggered by an update, you can access the previous values of the transaction using the `old_` prefix (e.g., `old_amount`, `old_description`). * **Inside "Update or Create" Actions**: Within the `Set Values` and `Filter` fields of an "Update or Create" action, you can access the fields of the transaction that was *found* by the search criteria using the `my_` prefix (e.g., `my_amount`, `my_description`). -#### Available Functions +## Available Functions | Function | Description | |----------------------------------|---------------------------------------------------------------------------------------------------| @@ -138,7 +148,7 @@ The following variables are available, referring to the transaction that trigger | `str`, `int`, `float`, `Decimal` | Standard Python functions for type casting. | | `transactions()` | A special function to query other transactions. Returns a `TransactionsGetter` object. | | `abs(x)` | Returns the absolute value of x | -| `random()` | Return the next random floating-point number in the range 0.0 <= X < 1.0 | +| `random()` | Return the next random floating-point number in the range 0.0 <= X < 1.0 | | `randint(a, b)` | Return a random integer N such that a <= N <= b | > [!NOTE] @@ -160,10 +170,16 @@ The returned object has the following properties: Example: `transactions(account_id=account_id, date__month=date.month).sum` returns the sum of all transactions in the same account and month as the triggering transaction. +## Testing -### Examples +You can test your rule by clicking on the `Test` button. Testing works by running the current rule against an existing transaction, all changes and updates are ran on the database and then rolled back (using an atomic transaction). -#### Example 1: Add a tag for investment income +### Known Issues +- Since we're creating the transactions even if rolling them back afterwards, the **transactions()** function may return incorrect data during testing, on normal execution it should work correctly. + +## Examples + +### Example 1: Add a tag for investment income Add the "Yield" tag to any income transaction in an investment account. @@ -172,7 +188,7 @@ Add the "Yield" tag to any income transaction in an investment account. * **Set field**: `Tags` * **To value**: `tag_names + ["Yield"]` -#### Example 2: Adjust credit card reference date +### Example 2: Adjust credit card reference date Move credit card transactions to the next month's budget if they occur after the statement's cutoff date (e.g., the 26th). @@ -181,7 +197,7 @@ Move credit card transactions to the next month's budget if they occur after the * **Set field**: `Reference Date` * **To value**: `(reference_date + relativedelta(months=1)).replace(day=1)` -#### Example 3: Create a fee transaction when a specific transaction is deleted +### Example 3: Create a fee transaction when a specific transaction is deleted When a "Subscription A" transaction is deleted, create a new "Cancellation Fee" transaction for $5. @@ -196,7 +212,7 @@ When a "Subscription A" transaction is deleted, create a new "Cancellation Fee" * `Amount`: `Decimal("5.00")` * `Type`: `'EX'` (Expense) -#### Example 4: Update a "Goal" transaction +### Example 4: Update a "Goal" transaction Imagine you have a recurring transaction for a savings goal. When you add a manual contribution, you want to update the goal transaction's notes.