Compare commits

..

2 Commits

Author SHA1 Message Date
Herculino Trotta
64b32316ca fix(accounts): unable to update accounts
due to wrong currency queryset
2025-09-08 09:19:17 -03:00
Herculino Trotta
efe020efb3 fix(rules): duplicating transactions when ran outside of test mode 2025-09-07 22:14:40 -03:00
13 changed files with 2780 additions and 3398 deletions

View File

@@ -82,22 +82,16 @@ class AccountForm(forms.ModelForm):
self.fields["group"].queryset = AccountGroup.objects.all()
if self.instance.id:
self.fields["currency"].queryset = Currency.objects.filter(
Q(is_archived=False) | Q(accounts=self.instance.id),
)
self.fields["exchange_currency"].queryset = Currency.objects.filter(
qs = Currency.objects.filter(
Q(is_archived=False) | Q(accounts=self.instance.id)
)
).distinct()
self.fields["currency"].queryset = qs
self.fields["exchange_currency"].queryset = qs
else:
self.fields["currency"].queryset = Currency.objects.filter(
Q(is_archived=False),
)
self.fields["exchange_currency"].queryset = Currency.objects.filter(
Q(is_archived=False)
)
qs = Currency.objects.filter(Q(is_archived=False))
self.fields["currency"].queryset = qs
self.fields["exchange_currency"].queryset = qs
self.helper = FormHelper()
self.helper.form_tag = False

View File

@@ -36,7 +36,7 @@ class ArbitraryDecimalDisplayNumberInput(forms.TextInput):
{
"x-data": "",
"x-mask:dynamic": f"$money($input, '{get_format('DECIMAL_SEPARATOR')}', '{get_format('THOUSAND_SEPARATOR')}', '30')",
"x-on:keyup": "if (!['Control', 'Shift', 'Alt', 'Meta'].includes($event.key) && !(($event.ctrlKey || $event.metaKey) && $event.key.toLowerCase() === 'a')) $el.dispatchEvent(new Event('input'))",
"x-on:keyup": "$el.dispatchEvent(new Event('input'))",
}
)

View File

@@ -1,6 +1,7 @@
import decimal
import logging
import traceback
from copy import deepcopy
from datetime import datetime, date
from decimal import Decimal
from itertools import chain
@@ -33,14 +34,25 @@ logger = logging.getLogger(__name__)
class DryRunResults:
def __init__(self):
def __init__(self, dry_run: bool):
self.results = []
self.dry_run = dry_run
def header(self, header: str, action):
if not self.dry_run:
return
result = {"type": "header", "header_type": header, "action": action}
self.results.append(result)
def triggering_transaction(self, instance):
if not self.dry_run:
return
if isinstance(instance, Transaction):
instance = instance.deepcopy()
elif isinstance(instance, dict):
instance = deepcopy(instance)
result = {
"type": "triggering_transaction",
"transaction": instance,
@@ -50,9 +62,16 @@ class DryRunResults:
def edit_transaction(
self, instance, action, old_value, new_value, field, tags, entities
):
if not self.dry_run:
return
if isinstance(instance, Transaction):
instance = instance.deepcopy()
elif isinstance(instance, dict):
instance = deepcopy(instance)
result = {
"type": "edit_transaction",
"transaction": instance.deepcopy(),
"transaction": instance,
"action": action,
"old_value": old_value,
"new_value": new_value,
@@ -72,6 +91,14 @@ class DryRunResults:
start_instance=None,
end_instance=None,
):
if not self.dry_run:
return
if isinstance(end_instance, Transaction):
start_instance = end_instance.deepcopy()
elif isinstance(end_instance, dict):
start_instance = deepcopy(end_instance)
result = {
"type": "update_or_create_transaction",
"start_transaction": start_instance,
@@ -85,6 +112,9 @@ class DryRunResults:
self.results.append(result)
def error(self, error, level: Literal["error", "warning", "info"] = "error"):
if not self.dry_run:
return
result = {
"type": "error",
"error": error,
@@ -247,7 +277,10 @@ def check_for_transaction_rules(
if searched_transactions.exists():
transaction = searched_transactions.first()
existing = True
starting_instance = transaction.deepcopy()
if dry_run:
starting_instance = transaction.deepcopy()
_log("Found at least one matching transaction, using latest:")
_log("{}".format(pformat(model_to_dict(transaction))))
else:
@@ -376,7 +409,7 @@ def check_for_transaction_rules(
dry_run_results.update_or_create_transaction(
start_instance=starting_instance,
end_instance=transaction.deepcopy(),
end_instance=transaction,
updated=existing,
action=processed_action,
query=search_query,
@@ -473,7 +506,7 @@ def check_for_transaction_rules(
)
dry_run_results.edit_transaction(
instance=transaction.deepcopy(),
instance=transaction,
action=processed_action,
old_value=original_value,
new_value=new_value,
@@ -489,7 +522,7 @@ def check_for_transaction_rules(
user = get_user_model().objects.get(id=user_id)
write_current_user(user)
logs = [] if dry_run else None
dry_run_results = DryRunResults()
dry_run_results = DryRunResults(dry_run=dry_run)
if dry_run and not rule_id:
raise Exception("Cannot dry run without a rule id")
@@ -507,7 +540,7 @@ def check_for_transaction_rules(
# Regular transaction processing for creates and updates
instance = Transaction.objects.get(id=instance_id)
dry_run_results.triggering_transaction(instance.deepcopy())
dry_run_results.triggering_transaction(instance)
functions = {
"relativedelta": relativedelta,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff