feat(accounts): add option for untracking accounts on a per user basis

This commit is contained in:
Herculino Trotta
2025-08-09 03:35:39 -03:00
parent 7f8261b9cc
commit 55c4b920ee
7 changed files with 48 additions and 22 deletions

View File

@@ -0,0 +1,20 @@
# Generated by Django 5.2.4 on 2025-08-09 05:52
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0015_alter_account_owner_alter_account_shared_with_and_more'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AddField(
model_name='account',
name='untracked_by',
field=models.ManyToManyField(blank=True, related_name='untracked_accounts', to=settings.AUTH_USER_MODEL),
),
]

View File

@@ -1,11 +1,11 @@
from django.conf import settings
from django.core.exceptions import ValidationError
from django.db import models
from django.db.models import Q
from django.utils.translation import gettext_lazy as _
from apps.transactions.models import Transaction
from apps.common.middleware.thread_local import get_current_user
from apps.common.models import SharedObject, SharedObjectManager
from apps.transactions.models import Transaction
class AccountGroup(SharedObject):
@@ -80,7 +80,8 @@ class Account(SharedObject):
def __str__(self):
return self.name
def is_untracked_by(self, user):
def is_untracked_by(self):
user = get_current_user()
return self.untracked_by.filter(pk=user.pk).exists()
def clean(self):

View File

@@ -157,15 +157,15 @@ def account_delete(request, pk):
@only_htmx
@login_required
@require_http_methods(["POST"])
@require_http_methods(["GET"])
def account_toggle_untracked(request, pk):
account = get_object_or_404(Account, id=pk)
if account.is_untracked_by(request.user):
if account.is_untracked_by():
account.untracked_by.remove(request.user)
messages.success(request, _("Account is now tracked."))
messages.success(request, _("Account is now tracked"))
else:
account.untracked_by.add(request.user)
messages.success(request, _("Account is now untracked."))
messages.success(request, _("Account is now untracked"))
return HttpResponse(
status=204,

View File

@@ -171,10 +171,14 @@ def monthly_account_summary(request, month: int, year: int):
@require_http_methods(["GET"])
def monthly_currency_summary(request, month: int, year: int):
# Base queryset with all required filters
base_queryset = Transaction.objects.filter(
reference_date__year=year,
reference_date__month=month,
).exclude(Q(Q(category__mute=True) & ~Q(category=None)) | Q(mute=True))
base_queryset = (
Transaction.objects.filter(
reference_date__year=year,
reference_date__month=month,
)
.exclude(Q(Q(category__mute=True) & ~Q(category=None)) | Q(mute=True))
.exclude(account__in=request.user.untracked_accounts.all())
)
currency_data = calculate_currency_totals(base_queryset.all(), ignore_empty=True)
currency_percentages = calculate_percentage_distribution(currency_data)

View File

@@ -589,7 +589,10 @@ def transaction_all_currency_summary(request):
f = TransactionsFilter(request.GET, queryset=transactions)
currency_data = calculate_currency_totals(f.qs.all(), ignore_empty=True)
currency_data = calculate_currency_totals(
f.qs.exclude(account__in=request.user.untracked_accounts.all()),
ignore_empty=True,
)
currency_percentages = calculate_percentage_distribution(currency_data)
context = {

View File

@@ -73,15 +73,13 @@
{% endif %}
<a class="btn btn-secondary btn-sm"
role="button"
hx-post="{% url 'account_toggle_untracked' pk=account.id %}"
hx-trigger='updated from:body'
hx-swap="none"
hx-get="{% url 'account_toggle_untracked' pk=account.id %}"
data-bs-toggle="tooltip"
data-bs-title="{% if account.is_untracked_by user %}{% translate "Track" %}{% else %}{% translate "Untrack" %}{% endif %}">
{% if account.is_untracked_by user %}
<i class="fa-solid fa-eye-slash fa-fw"></i>
{% else %}
data-bs-title="{% if account.is_untracked_by %}{% translate "Track" %}{% else %}{% translate "Untrack" %}{% endif %}">
{% if account.is_untracked_by %}
<i class="fa-solid fa-eye fa-fw"></i>
{% else %}
<i class="fa-solid fa-eye-slash fa-fw"></i>
{% endif %}
</a>
</div>

View File

@@ -33,7 +33,7 @@
</div>
{% endif %}
</div>
<div class="col-lg col-12 {% if transaction.account.is_untracked_by user or transaction.category.mute or transaction.mute %}tw:brightness-80{% endif %}">
<div class="col-lg col-12 {% if transaction.account.is_untracked_by or transaction.category.mute or transaction.mute %}tw:brightness-80{% endif %}">
{# Date#}
<div class="row mb-2 mb-lg-1 tw:text-gray-400">
<div class="col-auto pe-1"><i class="fa-solid fa-calendar fa-fw me-1 fa-xs"></i></div>
@@ -91,7 +91,7 @@
{% endwith %}
</div>
</div>
<div class="col-lg-auto col-12 text-lg-end align-self-end {% if transaction.account.is_untracked_by user or transaction.category.mute or transaction.mute %}tw:brightness-80{% endif %}">
<div class="col-lg-auto col-12 text-lg-end align-self-end {% if transaction.account.is_untracked_by or transaction.category.mute or transaction.mute %}tw:brightness-80{% endif %}">
<div class="main-amount mb-2 mb-lg-0">
<c-amount.display
:amount="transaction.amount"
@@ -146,7 +146,7 @@
<i class="fa-solid fa-ellipsis fa-fw"></i>
</button>
<ul class="dropdown-menu dropdown-menu-end dropdown-menu-md-start">
{% if transaction.account.is_untracked_by user %}
{% if transaction.account.is_untracked_by %}
<li>
<a class="dropdown-item disabled d-flex align-items-center" aria-disabled="true">
<i class="fa-solid fa-eye fa-fw me-2"></i>