Compare commits

...

50 Commits

Author SHA1 Message Date
Herculino Trotta
65c61f76ff feat(locale): add space-dot and space-comma number formatting options, where the thousand separator is a space 2025-08-10 12:34:29 -03:00
Herculino Trotta
66a5e6d613 fix(locale): get_format doesn't override number formatting if use_l10n is None 2025-08-10 12:23:41 -03:00
Herculino Trotta
20c6989ffb fix(insights:emergency-fund): hide untracked accounts 2025-08-09 03:45:16 -03:00
Herculino Trotta
c6cd525c49 fix(insights): display untracked accounts on sankey by account 2025-08-09 03:42:21 -03:00
Herculino Trotta
55c4b920ee feat(accounts): add option for untracking accounts on a per user basis 2025-08-09 03:35:39 -03:00
google-labs-jules[bot]
7f8261b9cc refactor: Style transaction items for untracked accounts
This commit extends the "Untrack Account" feature by applying a special style to transaction items that belong to an untracked account.

- The transaction item template is modified to apply a "dimmed" style to transactions from untracked accounts.
- The styling follows the precedence: Account (untracked) > Category (muted) > Transaction (hidden).
- The dropdown menu for transaction items now shows "Controlled by account" if the transaction's account is untracked.
2025-08-09 05:47:18 +00:00
Herculino Trotta
9102654eab Merge pull request #320
style(swal): move swal prompt over tooltips
2025-08-08 19:01:54 -03:00
Herculino Trotta
1ff49a8a04 style(swal): move swal prompt over tooltips 2025-08-08 19:01:35 -03:00
Herculino Trotta
846dd1fd73 Merge remote-tracking branch 'origin/main' 2025-08-08 16:49:54 -03:00
Herculino Trotta
9eed3b6692 style(transactions): remove menu vertical positioning on smaller screens 2025-08-08 16:49:37 -03:00
Dimitri Decrock
b7c53a3c2d locale(Dutch): update translation
Currently translated at 99.7% (673 of 675 strings)

Translation: WYGIWYH/App
Translate-URL: https://translations.herculino.com/projects/wygiwyh/app/nl/
2025-08-08 06:17:41 +00:00
Herculino Trotta
b378c8f6f7 locale(Portuguese (Brazil)): update translation
Currently translated at 100.0% (675 of 675 strings)

Translation: WYGIWYH/App
Translate-URL: https://translations.herculino.com/projects/wygiwyh/app/pt_BR/
2025-08-08 04:17:41 +00:00
Herculino Trotta
ccc4deb1d8 Merge branch 'main' of https://github.com/eitchtee/WYGIWYH 2025-08-07 23:48:45 -03:00
Herculino Trotta
d3ecf55375 Merge remote-tracking branch 'weblate/main' 2025-08-07 23:43:25 -03:00
eitchtee
580f3e7345 chore(locale): update translation files
[skip ci] Automatically generated by Django makemessages workflow
2025-08-08 02:41:32 +00:00
Herculino Trotta
0e5843094b Merge pull request #319
dev
2025-08-07 23:39:41 -03:00
Herculino Trotta
ed65945d19 feat(automatic-exchange-rates): rename automatic field 2025-08-07 23:39:21 -03:00
Herculino Trotta
18d8837c64 locale(Portuguese (Brazil)): update translation
Currently translated at 99.2% (671 of 676 strings)

Translation: WYGIWYH/App
Translate-URL: https://translations.herculino.com/projects/wygiwyh/app/pt_BR/
2025-08-08 02:37:06 +00:00
eitchtee
067d819077 chore(locale): update translation files
[skip ci] Automatically generated by Django makemessages workflow
2025-08-08 02:37:02 +00:00
Herculino Trotta
bbaae4746a Merge pull request #318
feat(transactions:recurring): try to create transactions on update
2025-08-07 23:36:12 -03:00
Herculino Trotta
d2e5c1d6b3 feat(transactions:recurring): try to create transactions on update 2025-08-07 23:35:57 -03:00
eitchtee
ffef61d514 chore(locale): update translation files
[skip ci] Automatically generated by Django makemessages workflow
2025-08-08 02:27:52 +00:00
Herculino Trotta
9020f6f972 Merge pull request #317
feat(automatic-exchange-rates): add "Single exchange rate" where only one exchange rate is added and updated to avoid db clutter
2025-08-07 23:26:10 -03:00
Herculino Trotta
540235c1b0 feat(automatic-exchange-rates): add "Single exchange rate" where only one exchange rate is added and updated to avoid db clutter 2025-08-07 23:25:51 -03:00
eitchtee
9070bc5705 chore(locale): update translation files
[skip ci] Automatically generated by Django makemessages workflow
2025-08-07 20:04:56 +00:00
Herculino Trotta
ba5a6c9772 Merge pull request #316 from eitchtee/dev
feat(transactions): add menu itens for quickly changing transaction date
2025-08-07 17:04:11 -03:00
Herculino Trotta
2f33b5989f feat(transactions): add menu itens for quickly changing transaction date 2025-08-07 15:30:42 -03:00
Herculino Trotta
5f24d05540 Merge pull request #315
style(login): make login button take full width as open id login
2025-08-07 12:03:02 -03:00
Herculino Trotta
31cf62e277 style(login): make login button take full width as open id login 2025-08-07 12:02:41 -03:00
Dimitri Decrock
15d990007e locale(Dutch): update translation
Currently translated at 100.0% (670 of 670 strings)

Translation: WYGIWYH/App
Translate-URL: https://translations.herculino.com/projects/wygiwyh/app/nl/
2025-08-07 06:17:41 +00:00
Herculino Trotta
3d5bc9cd3f Merge pull request #314
feat(tasks:check_for_updates): add env variable to disable checking
2025-08-06 16:59:15 -03:00
Herculino Trotta
a544dc4943 feat(tasks:check_for_updates): add env variable to disable checking 2025-08-06 16:58:58 -03:00
Herculino Trotta
b1178198e9 Merge remote-tracking branch 'origin/main' 2025-08-06 16:37:48 -03:00
Herculino Trotta
02a488bfff fix(sidebar): management menu gets hidden on my mobile by floating UI 2025-08-06 16:37:12 -03:00
Herculino Trotta
b05285947b locale(Portuguese (Brazil)): update translation
Currently translated at 100.0% (670 of 670 strings)

Translation: WYGIWYH/App
Translate-URL: https://translations.herculino.com/projects/wygiwyh/app/pt_BR/
2025-08-06 18:17:41 +00:00
eitchtee
d7b7dd28c7 chore(locale): update translation files
[skip ci] Automatically generated by Django makemessages workflow
2025-08-06 16:21:44 +00:00
Herculino Trotta
9353d498ef Merge pull request #313
feat(transactions:recurring): allow to set how many future instances of a recurring transaction to create in advance
2025-08-06 13:20:58 -03:00
Herculino Trotta
4f6903e8e4 feat(transactions:recurring): Allow to set how many future instances of a recurring transaction to create in advance 2025-08-06 13:13:59 -03:00
eitchtee
7d3d6ea2fc chore(locale): update translation files
[skip ci] Automatically generated by Django makemessages workflow
2025-08-06 14:48:14 +00:00
Herculino Trotta
cce9c7a7a5 Merge pull request #312
refactor(transactions:all): reduce screen state by moving filter to top
2025-08-06 11:46:06 -03:00
Herculino Trotta
df47ffc49c Merge pull request #311
refactor(yearly): convert into a single page instead of two
2025-08-06 11:45:07 -03:00
eitchtee
4f35647a22 chore(locale): update translation files
[skip ci] Automatically generated by Django makemessages workflow
2025-08-06 14:45:03 +00:00
Herculino Trotta
5a675f674d Merge pull request #310
refactor(networth): convert into a single page instead of two
2025-08-06 11:44:15 -03:00
Herculino Trotta
8c43365ec0 Merge pull request #309
fix: bulk delete not working
2025-08-06 11:42:24 -03:00
eitchtee
84852012f9 chore(locale): update translation files
[skip ci] Automatically generated by Django makemessages workflow
2025-08-06 14:36:50 +00:00
Herculino Trotta
edf0e2c66f Merge pull request #308
feat: replace navbar with sidebar
2025-08-06 11:35:58 -03:00
Herculino Trotta
57f98ba171 locale(Portuguese (Brazil)): update translation
Currently translated at 100.0% (669 of 669 strings)

Translation: WYGIWYH/App
Translate-URL: https://translations.herculino.com/projects/wygiwyh/app/pt_BR/
2025-08-03 16:17:41 +00:00
eitchtee
f2e93f7df9 chore(locale): update translation files
[skip ci] Automatically generated by Django makemessages workflow
2025-08-02 18:39:27 +00:00
Herculino Trotta
26cfa493b3 Merge pull request #305 from eitchtee/dev
fix(ui:transactions): transaction menu overflows screen on smaller screens
2025-08-02 15:37:30 -03:00
Herculino Trotta
c6e003ed86 fix(ui:transactions): transaction menu overflows screen on smaller screens 2025-08-02 15:36:57 -03:00
40 changed files with 2262 additions and 1469 deletions

View File

@@ -140,9 +140,10 @@ To create the first user, open the container's console using Unraid's UI, by cli
| ENABLE_SOFT_DELETE | true\|false | false | Whether to enable transactions soft delete, if enabled, deleted transactions will remain in the database. Useful for imports and avoiding duplicate entries. |
| KEEP_DELETED_TRANSACTIONS_FOR | int | 365 | Time in days to keep soft deleted transactions for. If 0, will keep all transactions indefinitely. Only works if ENABLE_SOFT_DELETE is true. |
| TASK_WORKERS | int | 1 | How many workers to have for async tasks. One should be enough for most use cases |
| DEMO | true\|false | false | If demo mode is enabled. |
| ADMIN_EMAIL | string | None | Automatically creates an admin account with this email. Must have `ADMIN_PASSWORD` also set. |
| ADMIN_PASSWORD | string | None | Automatically creates an admin account with this password. Must have `ADMIN_EMAIL` also set. |
| DEMO | true\|false | false | If demo mode is enabled. |
| ADMIN_EMAIL | string | None | Automatically creates an admin account with this email. Must have `ADMIN_PASSWORD` also set. |
| ADMIN_PASSWORD | string | None | Automatically creates an admin account with this password. Must have `ADMIN_EMAIL` also set. |
| CHECK_FOR_UPDATES | bool | true | Check and notify users about new versions. The check is done by doing a single query to Github's API every 12 hours. |
## OIDC Configuration

View File

@@ -537,6 +537,7 @@ PWA_APP_SCREENSHOTS = [
PWA_SERVICE_WORKER_PATH = BASE_DIR / "templates" / "pwa" / "serviceworker.js"
ENABLE_SOFT_DELETE = os.getenv("ENABLE_SOFT_DELETE", "false").lower() == "true"
CHECK_FOR_UPDATES = os.getenv("CHECK_FOR_UPDATES", "true").lower() == "true"
KEEP_DELETED_TRANSACTIONS_FOR = int(os.getenv("KEEP_DELETED_ENTRIES_FOR", "365"))
APP_VERSION = os.getenv("APP_VERSION", "unknown")
DEMO = os.getenv("DEMO", "false").lower() == "true"

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):
@@ -62,6 +62,11 @@ class Account(SharedObject):
verbose_name=_("Archived"),
help_text=_("Archived accounts don't show up nor count towards your net worth"),
)
untracked_by = models.ManyToManyField(
settings.AUTH_USER_MODEL,
blank=True,
related_name="untracked_accounts",
)
objects = SharedObjectManager()
all_objects = models.Manager() # Unfiltered manager
@@ -75,6 +80,10 @@ class Account(SharedObject):
def __str__(self):
return self.name
def is_untracked_by(self):
user = get_current_user()
return self.untracked_by.filter(pk=user.pk).exists()
def clean(self):
super().clean()
if self.exchange_currency == self.currency:

View File

@@ -31,6 +31,11 @@ urlpatterns = [
views.account_take_ownership,
name="account_take_ownership",
),
path(
"account/<int:pk>/toggle-untracked/",
views.account_toggle_untracked,
name="account_toggle_untracked",
),
path("account-groups/", views.account_groups_index, name="account_groups_index"),
path("account-groups/list/", views.account_groups_list, name="account_groups_list"),
path("account-groups/add/", views.account_group_add, name="account_group_add"),

View File

@@ -155,6 +155,26 @@ def account_delete(request, pk):
)
@only_htmx
@login_required
@require_http_methods(["GET"])
def account_toggle_untracked(request, pk):
account = get_object_or_404(Account, id=pk)
if account.is_untracked_by():
account.untracked_by.remove(request.user)
messages.success(request, _("Account is now tracked"))
else:
account.untracked_by.add(request.user)
messages.success(request, _("Account is now untracked"))
return HttpResponse(
status=204,
headers={
"HX-Trigger": "updated",
},
)
@only_htmx
@login_required
@require_http_methods(["GET"])

View File

@@ -138,6 +138,7 @@ class RecurringTransactionSerializer(serializers.ModelSerializer):
def update(self, instance, validated_data):
instance = super().update(instance, validated_data)
instance.update_unpaid_transactions()
instance.generate_upcoming_transactions()
return instance

View File

@@ -5,7 +5,12 @@ from django.utils.formats import get_format as original_get_format
def get_format(format_type=None, lang=None, use_l10n=None):
user = get_current_user()
if user and user.is_authenticated and hasattr(user, "settings") and use_l10n:
if (
user
and user.is_authenticated
and hasattr(user, "settings")
and use_l10n is not False
):
user_settings = user.settings
if format_type == "THOUSAND_SEPARATOR":
number_format = getattr(user_settings, "number_format", None)
@@ -13,11 +18,13 @@ def get_format(format_type=None, lang=None, use_l10n=None):
return "."
elif number_format == "CD":
return ","
elif number_format == "SD" or number_format == "SC":
return " "
elif format_type == "DECIMAL_SEPARATOR":
number_format = getattr(user_settings, "number_format", None)
if number_format == "DC":
if number_format == "DC" or number_format == "SC":
return ","
elif number_format == "CD":
elif number_format == "CD" or number_format == "SD":
return "."
elif format_type == "SHORT_DATE_FORMAT":
date_format = getattr(user_settings, "date_format", None)

View File

@@ -90,6 +90,9 @@ def reset_demo_data(timestamp=None):
name="check_for_updates",
)
def check_for_updates(timestamp=None):
if not settings.CHECK_FOR_UPDATES:
return "CHECK_FOR_UPDATES is disabled"
url = "https://api.github.com/repos/eitchtee/WYGIWYH/releases/latest"
try:

View File

@@ -35,8 +35,7 @@ class ArbitraryDecimalDisplayNumberInput(forms.TextInput):
self.attrs.update(
{
"x-data": "",
"x-mask:dynamic": f"$money($input, '{get_format('DECIMAL_SEPARATOR')}', "
f"'{get_format('THOUSAND_SEPARATOR')}', '30')",
"x-mask:dynamic": f"$money($input, '{get_format('DECIMAL_SEPARATOR')}', '{get_format('THOUSAND_SEPARATOR')}', '30')",
"x-on:keyup": "$el.dispatchEvent(new Event('input'))",
}
)

View File

@@ -203,21 +203,63 @@ class ExchangeRateFetcher:
if provider.rates_inverted:
# If rates are inverted, we need to swap currencies
ExchangeRate.objects.create(
from_currency=to_currency,
to_currency=from_currency,
rate=rate,
date=timezone.now(),
)
if service.singleton:
# Try to get the last automatically created exchange rate
exchange_rate = (
ExchangeRate.objects.filter(
automatic=True,
from_currency=to_currency,
to_currency=from_currency,
)
.order_by("-date")
.first()
)
else:
exchange_rate = None
if not exchange_rate:
ExchangeRate.objects.create(
automatic=True,
from_currency=to_currency,
to_currency=from_currency,
rate=rate,
date=timezone.now(),
)
else:
exchange_rate.rate = rate
exchange_rate.date = timezone.now()
exchange_rate.save()
processed_pairs.add((to_currency.id, from_currency.id))
else:
# If rates are not inverted, we can use them as is
ExchangeRate.objects.create(
from_currency=from_currency,
to_currency=to_currency,
rate=rate,
date=timezone.now(),
)
if service.singleton:
# Try to get the last automatically created exchange rate
exchange_rate = (
ExchangeRate.objects.filter(
automatic=True,
from_currency=from_currency,
to_currency=to_currency,
)
.order_by("-date")
.first()
)
else:
exchange_rate = None
if not exchange_rate:
ExchangeRate.objects.create(
automatic=True,
from_currency=from_currency,
to_currency=to_currency,
rate=rate,
date=timezone.now(),
)
else:
exchange_rate.rate = rate
exchange_rate.date = timezone.now()
exchange_rate.save()
processed_pairs.add((from_currency.id, to_currency.id))
service.last_fetch = timezone.now()

View File

@@ -114,6 +114,7 @@ class ExchangeRateServiceForm(forms.ModelForm):
"fetch_interval",
"target_currencies",
"target_accounts",
"singleton",
]
def __init__(self, *args, **kwargs):
@@ -126,6 +127,7 @@ class ExchangeRateServiceForm(forms.ModelForm):
"name",
"service_type",
Switch("is_active"),
Switch("singleton"),
"api_key",
Row(
Column("interval_type", css_class="form-group col-md-6"),

View File

@@ -0,0 +1,23 @@
# Generated by Django 5.2.4 on 2025-08-08 02:18
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('currencies', '0014_alter_currency_options'),
]
operations = [
migrations.AddField(
model_name='exchangerate',
name='automatic',
field=models.BooleanField(default=False, verbose_name='Automatic'),
),
migrations.AddField(
model_name='exchangerateservice',
name='singleton',
field=models.BooleanField(default=False, help_text='Create one exchange rate and keep updating it. Avoids database clutter.', verbose_name='Single exchange rate'),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.2.4 on 2025-08-08 02:38
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('currencies', '0015_exchangerate_automatic_exchangerateservice_singleton'),
]
operations = [
migrations.AlterField(
model_name='exchangerate',
name='automatic',
field=models.BooleanField(default=False, verbose_name='Auto'),
),
]

View File

@@ -70,6 +70,8 @@ class ExchangeRate(models.Model):
)
date = models.DateTimeField(verbose_name=_("Date and Time"))
automatic = models.BooleanField(verbose_name=_("Auto"), default=False)
class Meta:
verbose_name = _("Exchange Rate")
verbose_name_plural = _("Exchange Rates")
@@ -148,6 +150,14 @@ class ExchangeRateService(models.Model):
blank=True,
)
singleton = models.BooleanField(
verbose_name=_("Single exchange rate"),
default=False,
help_text=_(
"Create one exchange rate and keep updating it. Avoids database clutter."
),
)
class Meta:
verbose_name = _("Exchange Rate Service")
verbose_name_plural = _("Exchange Rate Services")

View File

@@ -13,7 +13,9 @@ from apps.insights.forms import (
)
def get_transactions(request, include_unpaid=True, include_silent=False):
def get_transactions(
request, include_unpaid=True, include_silent=False, include_untracked_accounts=False
):
transactions = Transaction.objects.all()
filter_type = request.GET.get("type", None)
@@ -95,4 +97,9 @@ def get_transactions(request, include_unpaid=True, include_silent=False):
Q(Q(category__mute=True) & ~Q(category=None)) | Q(mute=True)
)
if not include_untracked_accounts:
transactions = transactions.exclude(
account__in=request.user.untracked_accounts.all()
)
return transactions

View File

@@ -74,7 +74,7 @@ def index(request):
def sankey_by_account(request):
# Get filtered transactions
transactions = get_transactions(request)
transactions = get_transactions(request, include_untracked_accounts=True)
# Generate Sankey data
sankey_data = generate_sankey_data_by_account(transactions)
@@ -239,10 +239,14 @@ def late_transactions(request):
@login_required
@require_http_methods(["GET"])
def emergency_fund(request):
transactions_currency_queryset = Transaction.objects.filter(
is_paid=True, account__is_archived=False, account__is_asset=False
).order_by(
"account__currency__name",
transactions_currency_queryset = (
Transaction.objects.filter(
is_paid=True, account__is_archived=False, account__is_asset=False
)
.exclude(account__in=request.user.untracked_accounts.all())
.order_by(
"account__currency__name",
)
)
currency_net_worth = calculate_currency_totals(
transactions_queryset=transactions_currency_queryset, ignore_empty=False
@@ -262,6 +266,7 @@ def emergency_fund(request):
category__mute=False,
mute=False,
)
.exclude(account__in=request.user.untracked_accounts.all())
.values("reference_date", "account__currency")
.annotate(monthly_total=Sum("amount"))
)

View File

@@ -107,9 +107,15 @@ def transactions_list(request, month: int, year: int):
@require_http_methods(["GET"])
def monthly_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, account__is_asset=False
).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,
account__is_asset=False,
)
.exclude(Q(Q(category__mute=True) & ~Q(category=None)) | Q(mute=True))
.exclude(account__in=request.user.untracked_accounts.all())
)
data = calculate_currency_totals(base_queryset, ignore_empty=True)
percentages = calculate_percentage_distribution(data)
@@ -165,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

@@ -27,10 +27,12 @@ def net_worth(request):
view_type = request.session.get("networth_view_type", "current")
if view_type == "current":
transactions_currency_queryset = Transaction.objects.filter(
is_paid=True, account__is_archived=False
).order_by(
"account__currency__name",
transactions_currency_queryset = (
Transaction.objects.filter(is_paid=True, account__is_archived=False)
.order_by(
"account__currency__name",
)
.exclude(account__in=request.user.untracked_accounts.all())
)
transactions_account_queryset = Transaction.objects.filter(
is_paid=True, account__is_archived=False
@@ -39,10 +41,12 @@ def net_worth(request):
"account__name",
)
else:
transactions_currency_queryset = Transaction.objects.filter(
account__is_archived=False
).order_by(
"account__currency__name",
transactions_currency_queryset = (
Transaction.objects.filter(account__is_archived=False)
.order_by(
"account__currency__name",
)
.exclude(account__in=request.user.untracked_accounts.all())
)
transactions_account_queryset = Transaction.objects.filter(
account__is_archived=False

View File

@@ -1,5 +1,5 @@
from crispy_bootstrap5.bootstrap5 import Switch, BS5Accordion
from crispy_forms.bootstrap import FormActions, AccordionGroup
from crispy_forms.bootstrap import FormActions, AccordionGroup, AppendedText
from crispy_forms.helper import FormHelper
from crispy_forms.layout import (
Layout,
@@ -963,6 +963,7 @@ class RecurringTransactionForm(forms.ModelForm):
"notes",
"add_notes_to_transaction",
"entities",
"keep_at_most",
]
widgets = {
"reference_date": AirMonthYearPickerInput(),
@@ -1042,6 +1043,7 @@ class RecurringTransactionForm(forms.ModelForm):
Column("end_date", css_class="form-group col-md-4 mb-0"),
css_class="form-row",
),
AppendedText("keep_at_most", _("future transactions")),
)
self.fields["amount"].widget = ArbitraryDecimalDisplayNumberInput()
@@ -1083,5 +1085,6 @@ class RecurringTransactionForm(forms.ModelForm):
instance.create_upcoming_transactions()
else:
instance.update_unpaid_transactions()
instance.generate_upcoming_transactions()
return instance

View File

@@ -0,0 +1,19 @@
# Generated by Django 5.2.4 on 2025-08-06 14:51
import django.core.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('transactions', '0047_alter_transactioncategory_owner_and_more'),
]
operations = [
migrations.AddField(
model_name='recurringtransaction',
name='keep_at_most',
field=models.PositiveIntegerField(default=6, validators=[django.core.validators.MinValueValidator(1)], verbose_name='Keep at most'),
),
]

View File

@@ -722,6 +722,9 @@ class RecurringTransaction(models.Model):
recurrence_interval = models.PositiveIntegerField(
verbose_name=_("Recurrence Interval"),
)
keep_at_most = models.PositiveIntegerField(
verbose_name=_("Keep at most"), default=6, validators=[MinValueValidator(1)]
)
last_generated_date = models.DateField(
verbose_name=_("Last Generated Date"), null=True, blank=True
@@ -759,8 +762,10 @@ class RecurringTransaction(models.Model):
current_date = self.start_date
reference_date = self.reference_date
end_date = min(
self.end_date or timezone.now().date() + (self.get_recurrence_delta() * 5),
timezone.now().date() + (self.get_recurrence_delta() * 5),
self.end_date
or timezone.now().date()
+ (self.get_recurrence_delta() * self.keep_at_most),
timezone.now().date() + (self.get_recurrence_delta() * self.keep_at_most),
)
while current_date <= end_date:
@@ -837,8 +842,16 @@ class RecurringTransaction(models.Model):
current_date = start_date
end_date = min(
recurring_transaction.end_date
or today + (recurring_transaction.get_recurrence_delta() * 6),
today + (recurring_transaction.get_recurrence_delta() * 6),
or today
+ (
recurring_transaction.get_recurrence_delta()
* recurring_transaction.keep_at_most
),
today
+ (
recurring_transaction.get_recurrence_delta()
* recurring_transaction.keep_at_most
),
)
logger.info(f"End date: {end_date}")

View File

@@ -28,23 +28,18 @@ def generate_recurring_transactions(timestamp=None):
@app.periodic(cron="10 1 * * *")
@app.task(name="cleanup_deleted_transactions")
def cleanup_deleted_transactions(timestamp=None):
with cachalot_disabled():
if settings.ENABLE_SOFT_DELETE and settings.KEEP_DELETED_TRANSACTIONS_FOR == 0:
return "KEEP_DELETED_TRANSACTIONS_FOR is 0, no cleanup performed."
if settings.ENABLE_SOFT_DELETE and settings.KEEP_DELETED_TRANSACTIONS_FOR == 0:
return "KEEP_DELETED_TRANSACTIONS_FOR is 0, no cleanup performed."
if not settings.ENABLE_SOFT_DELETE:
# Hard delete all soft-deleted transactions
deleted_count, _ = Transaction.userless_deleted_objects.all().hard_delete()
return (
f"Hard deleted {deleted_count} transactions (soft deletion disabled)."
)
if not settings.ENABLE_SOFT_DELETE:
# Hard delete all soft-deleted transactions
deleted_count, _ = Transaction.userless_deleted_objects.all().hard_delete()
return f"Hard deleted {deleted_count} transactions (soft deletion disabled)."
# Calculate the cutoff date
cutoff_date = timezone.now() - timedelta(
days=settings.KEEP_DELETED_TRANSACTIONS_FOR
)
invalidate()
# Calculate the cutoff date
cutoff_date = timezone.now() - timedelta(
days=settings.KEEP_DELETED_TRANSACTIONS_FOR
)
# Hard delete soft-deleted transactions older than the cutoff date
old_transactions = Transaction.userless_deleted_objects.filter(

View File

@@ -71,6 +71,16 @@ urlpatterns = [
views.transaction_mute,
name="transaction_mute",
),
path(
"transaction/<int:transaction_id>/change-month/<str:change_type>/",
views.transaction_change_month,
name="transaction_change_month",
),
path(
"transaction/<int:transaction_id>/move-to-today/",
views.transaction_move_to_today,
name="transaction_move_to_today",
),
path(
"transaction/<int:transaction_id>/delete/",
views.transaction_delete,

View File

@@ -1,6 +1,7 @@
import datetime
from copy import deepcopy
from dateutil.relativedelta import relativedelta
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator
@@ -408,6 +409,47 @@ def transaction_mute(request, transaction_id):
return response
@only_htmx
@login_required
@require_http_methods(["GET"])
def transaction_change_month(request, transaction_id, change_type):
transaction: Transaction = get_object_or_404(Transaction, pk=transaction_id)
if change_type == "next":
transaction.reference_date = transaction.reference_date + relativedelta(
months=1
)
transaction.save()
transaction_updated.send(sender=transaction)
elif change_type == "previous":
transaction.reference_date = transaction.reference_date - relativedelta(
months=1
)
transaction.save()
transaction_updated.send(sender=transaction)
return HttpResponse(
status=204,
headers={"HX-Trigger": "updated"},
)
@only_htmx
@login_required
@require_http_methods(["GET"])
def transaction_move_to_today(request, transaction_id):
transaction: Transaction = get_object_or_404(Transaction, pk=transaction_id)
transaction.date = timezone.localdate(timezone.now())
transaction.save()
transaction_updated.send(sender=transaction)
return HttpResponse(
status=204,
headers={"HX-Trigger": "updated"},
)
@login_required
@require_http_methods(["GET"])
def transaction_all_index(request):
@@ -547,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

@@ -45,7 +45,7 @@ class LoginForm(AuthenticationForm):
self.helper.layout = Layout(
"username",
"password",
Submit("Submit", "Login"),
Submit("Submit", "Login", css_class="btn btn-primary w-100"),
)
@@ -89,6 +89,8 @@ class UserSettingsForm(forms.ModelForm):
("AA", _("Default")),
("DC", "1.234,50"),
("CD", "1,234.50"),
("SD", "1 234.50"),
("SC", "1 234,50"),
]
date_format = forms.ChoiceField(

View File

@@ -95,6 +95,7 @@ def yearly_overview_by_currency(request, year: int):
transactions = (
Transaction.objects.filter(**filter_params)
.exclude(Q(Q(category__mute=True) & ~Q(category=None)) | Q(mute=True))
.exclude(account__in=request.user.untracked_accounts.all())
.order_by("account__currency__name")
)

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-07-28 02:21+0000\n"
"POT-Creation-Date: 2025-08-08 02:41+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -24,26 +24,26 @@ msgstr ""
#: apps/accounts/forms.py:40 apps/accounts/forms.py:98
#: apps/currencies/forms.py:53 apps/currencies/forms.py:91
#: apps/currencies/forms.py:142 apps/dca/forms.py:49 apps/dca/forms.py:224
#: apps/currencies/forms.py:144 apps/dca/forms.py:49 apps/dca/forms.py:224
#: apps/import_app/forms.py:34 apps/rules/forms.py:51 apps/rules/forms.py:93
#: apps/rules/forms.py:365 apps/transactions/forms.py:204
#: apps/transactions/forms.py:374 apps/transactions/forms.py:421
#: apps/transactions/forms.py:793 apps/transactions/forms.py:836
#: apps/transactions/forms.py:868 apps/transactions/forms.py:903
#: apps/transactions/forms.py:1055 apps/users/forms.py:215
#: apps/transactions/forms.py:1057 apps/users/forms.py:215
#: apps/users/forms.py:377
msgid "Update"
msgstr ""
#: apps/accounts/forms.py:48 apps/accounts/forms.py:106
#: apps/common/widgets/tom_select.py:13 apps/currencies/forms.py:61
#: apps/currencies/forms.py:99 apps/currencies/forms.py:150
#: apps/currencies/forms.py:99 apps/currencies/forms.py:152
#: apps/dca/forms.py:57 apps/dca/forms.py:232 apps/import_app/forms.py:42
#: apps/rules/forms.py:59 apps/rules/forms.py:101 apps/rules/forms.py:373
#: apps/transactions/forms.py:189 apps/transactions/forms.py:213
#: apps/transactions/forms.py:383 apps/transactions/forms.py:801
#: apps/transactions/forms.py:844 apps/transactions/forms.py:876
#: apps/transactions/forms.py:911 apps/transactions/forms.py:1063
#: apps/transactions/forms.py:911 apps/transactions/forms.py:1065
#: apps/users/forms.py:223 apps/users/forms.py:385
#: templates/account_groups/fragments/list.html:9
#: templates/accounts/fragments/list.html:9
@@ -80,9 +80,9 @@ msgstr ""
#: apps/transactions/forms.py:455 apps/transactions/forms.py:462
#: apps/transactions/forms.py:674 apps/transactions/forms.py:935
#: apps/transactions/models.py:318 apps/transactions/models.py:501
#: apps/transactions/models.py:701 apps/transactions/models.py:938
#: apps/transactions/models.py:701 apps/transactions/models.py:951
#: templates/insights/fragments/category_overview/index.html:63
#: templates/insights/fragments/category_overview/index.html:420
#: templates/insights/fragments/category_overview/index.html:419
msgid "Category"
msgstr ""
@@ -94,8 +94,8 @@ msgstr ""
#: apps/transactions/forms.py:471 apps/transactions/forms.py:479
#: apps/transactions/forms.py:667 apps/transactions/forms.py:928
#: apps/transactions/models.py:324 apps/transactions/models.py:503
#: apps/transactions/models.py:705 apps/transactions/models.py:944
#: templates/includes/navbar.html:111
#: apps/transactions/models.py:705 apps/transactions/models.py:957
#: templates/includes/navbar.html:111 templates/includes/sidebar.html:168
#: templates/insights/fragments/category_overview/index.html:35
#: templates/tags/fragments/list.html:5 templates/tags/pages/index.html:4
msgid "Tags"
@@ -104,7 +104,7 @@ msgstr ""
#: apps/accounts/models.py:12 apps/accounts/models.py:29 apps/dca/models.py:13
#: apps/import_app/models.py:14 apps/rules/models.py:13
#: apps/transactions/models.py:210 apps/transactions/models.py:235
#: apps/transactions/models.py:259 apps/transactions/models.py:906
#: apps/transactions/models.py:259 apps/transactions/models.py:919
#: templates/account_groups/fragments/list.html:25
#: templates/accounts/fragments/list.html:25
#: templates/categories/fragments/table.html:16
@@ -127,12 +127,14 @@ msgstr ""
#: apps/accounts/models.py:19 templates/account_groups/fragments/list.html:5
#: templates/account_groups/pages/index.html:4
#: templates/includes/navbar.html:121
#: templates/includes/navbar.html:121 templates/includes/sidebar.html:188
msgid "Account Groups"
msgstr ""
#: apps/accounts/models.py:39 apps/currencies/models.py:39
#: templates/accounts/fragments/list.html:27
#: templates/yearly_overview/pages/overview_by_account.html:18
#: templates/yearly_overview/pages/overview_by_currency.html:20
msgid "Currency"
msgstr ""
@@ -170,10 +172,12 @@ msgstr ""
#: apps/transactions/forms.py:62 apps/transactions/forms.py:276
#: apps/transactions/forms.py:659 apps/transactions/forms.py:920
#: apps/transactions/models.py:290 apps/transactions/models.py:461
#: apps/transactions/models.py:683 apps/transactions/models.py:912
#: apps/transactions/models.py:683 apps/transactions/models.py:925
#: templates/installment_plans/fragments/table.html:17
#: templates/quick_transactions/fragments/list.html:14
#: templates/recurring_transactions/fragments/table.html:19
#: templates/yearly_overview/pages/overview_by_account.html:22
#: templates/yearly_overview/pages/overview_by_currency.html:24
msgid "Account"
msgstr ""
@@ -181,10 +185,11 @@ msgstr ""
#: apps/export_app/forms.py:132 apps/transactions/filters.py:53
#: templates/accounts/fragments/list.html:5
#: templates/accounts/pages/index.html:4 templates/includes/navbar.html:117
#: templates/includes/navbar.html:119
#: templates/includes/navbar.html:119 templates/includes/sidebar.html:180
#: templates/includes/sidebar.html:182
#: templates/monthly_overview/pages/overview.html:94
#: templates/transactions/fragments/summary.html:12
#: templates/transactions/pages/transactions.html:72
#: templates/transactions/pages/transactions.html:81
msgid "Accounts"
msgstr ""
@@ -281,7 +286,7 @@ msgstr ""
msgid "Invalid entity data. Provide an ID or name."
msgstr ""
#: apps/api/serializers/transactions.py:191
#: apps/api/serializers/transactions.py:192
msgid "Either 'date' or 'reference_date' must be provided."
msgstr ""
@@ -454,7 +459,7 @@ msgstr ""
#: apps/common/widgets/tom_select.py:15
#: templates/mini_tools/unit_price_calculator.html:174
#: templates/monthly_overview/pages/overview.html:172
#: templates/transactions/pages/transactions.html:17
#: templates/transactions/pages/transactions.html:47
msgid "Clear"
msgstr ""
@@ -496,10 +501,11 @@ msgstr ""
#: apps/export_app/forms.py:133 apps/transactions/filters.py:60
#: templates/currencies/fragments/list.html:5
#: templates/currencies/pages/index.html:4 templates/includes/navbar.html:125
#: templates/includes/navbar.html:127
#: templates/includes/navbar.html:127 templates/includes/sidebar.html:194
#: templates/includes/sidebar.html:196
#: templates/monthly_overview/pages/overview.html:81
#: templates/transactions/fragments/summary.html:8
#: templates/transactions/pages/transactions.html:59
#: templates/transactions/pages/transactions.html:68
msgid "Currencies"
msgstr ""
@@ -515,7 +521,7 @@ msgstr ""
msgid "To Currency"
msgstr ""
#: apps/currencies/models.py:69 apps/currencies/models.py:74
#: apps/currencies/models.py:69 apps/currencies/models.py:76
msgid "Exchange Rate"
msgstr ""
@@ -523,38 +529,43 @@ msgstr ""
msgid "Date and Time"
msgstr ""
#: apps/currencies/models.py:75 apps/export_app/forms.py:68
#: apps/currencies/models.py:73 apps/users/models.py:12
#: apps/users/models.py:497
msgid "Auto"
msgstr ""
#: apps/currencies/models.py:77 apps/export_app/forms.py:68
#: apps/export_app/forms.py:145 templates/exchange_rates/fragments/list.html:6
#: templates/exchange_rates/pages/index.html:4
#: templates/includes/navbar.html:129
#: templates/includes/navbar.html:129 templates/includes/sidebar.html:202
msgid "Exchange Rates"
msgstr ""
#: apps/currencies/models.py:87
#: apps/currencies/models.py:89
msgid "From and To currencies cannot be the same."
msgstr ""
#: apps/currencies/models.py:102
#: apps/currencies/models.py:104
msgid "On"
msgstr ""
#: apps/currencies/models.py:103
#: apps/currencies/models.py:105
msgid "Every X hours"
msgstr ""
#: apps/currencies/models.py:104
#: apps/currencies/models.py:106
msgid "Not on"
msgstr ""
#: apps/currencies/models.py:106
#: apps/currencies/models.py:108
msgid "Service Name"
msgstr ""
#: apps/currencies/models.py:108
#: apps/currencies/models.py:110
msgid "Service Type"
msgstr ""
#: apps/currencies/models.py:110 apps/transactions/models.py:214
#: apps/currencies/models.py:112 apps/transactions/models.py:214
#: apps/transactions/models.py:238 apps/transactions/models.py:262
#: templates/categories/fragments/list.html:21
#: templates/entities/fragments/list.html:21
@@ -563,69 +574,77 @@ msgstr ""
msgid "Active"
msgstr ""
#: apps/currencies/models.py:115
#: apps/currencies/models.py:117
msgid "API Key"
msgstr ""
#: apps/currencies/models.py:116
#: apps/currencies/models.py:118
msgid "API key for the service (if required)"
msgstr ""
#: apps/currencies/models.py:121
#: apps/currencies/models.py:123
msgid "Interval Type"
msgstr ""
#: apps/currencies/models.py:125
#: apps/currencies/models.py:127
msgid "Interval"
msgstr ""
#: apps/currencies/models.py:128
#: apps/currencies/models.py:130
msgid "Last Successful Fetch"
msgstr ""
#: apps/currencies/models.py:133
#: apps/currencies/models.py:135
msgid "Target Currencies"
msgstr ""
#: apps/currencies/models.py:135
#: apps/currencies/models.py:137
msgid ""
"Select currencies to fetch exchange rates for. Rates will be fetched for "
"each currency against their set exchange currency."
msgstr ""
#: apps/currencies/models.py:143
#: apps/currencies/models.py:145
msgid "Target Accounts"
msgstr ""
#: apps/currencies/models.py:145
#: apps/currencies/models.py:147
msgid ""
"Select accounts to fetch exchange rates for. Rates will be fetched for each "
"account's currency against their set exchange currency."
msgstr ""
#: apps/currencies/models.py:152
#: apps/currencies/models.py:154
msgid "Single exchange rate"
msgstr ""
#: apps/currencies/models.py:157
msgid "Create one exchange rate and keep updating it. Avoids database clutter."
msgstr ""
#: apps/currencies/models.py:162
msgid "Exchange Rate Service"
msgstr ""
#: apps/currencies/models.py:153
#: apps/currencies/models.py:163
msgid "Exchange Rate Services"
msgstr ""
#: apps/currencies/models.py:205
#: apps/currencies/models.py:215
msgid "'Every X hours' interval type requires a positive integer."
msgstr ""
#: apps/currencies/models.py:214
#: apps/currencies/models.py:224
msgid "'Every X hours' interval must be between 1 and 24."
msgstr ""
#: apps/currencies/models.py:228
#: apps/currencies/models.py:238
msgid ""
"Invalid hour format. Use comma-separated hours (0-23) and/or ranges (e.g., "
"'1-5,8,10-12')."
msgstr ""
#: apps/currencies/models.py:239
#: apps/currencies/models.py:249
msgid ""
"Invalid format. Please check the requirements for your selected interval "
"type."
@@ -725,7 +744,7 @@ msgstr ""
#: apps/rules/forms.py:188 apps/rules/models.py:37 apps/rules/models.py:270
#: apps/transactions/forms.py:499 apps/transactions/models.py:314
#: apps/transactions/models.py:510 apps/transactions/models.py:711
#: apps/transactions/models.py:934
#: apps/transactions/models.py:947
msgid "Notes"
msgstr ""
@@ -782,14 +801,15 @@ msgid "Entry deleted successfully"
msgstr ""
#: apps/export_app/forms.py:14 apps/export_app/forms.py:131
#: templates/includes/navbar.html:150 templates/users/fragments/list.html:6
#: templates/users/pages/index.html:4
#: templates/includes/navbar.html:150 templates/includes/sidebar.html:239
#: templates/users/fragments/list.html:6 templates/users/pages/index.html:4
msgid "Users"
msgstr ""
#: apps/export_app/forms.py:32 apps/export_app/forms.py:137
#: apps/transactions/models.py:375 templates/includes/navbar.html:58
#: templates/includes/navbar.html:107
#: templates/includes/navbar.html:107 templates/includes/sidebar.html:66
#: templates/includes/sidebar.html:160
#: templates/recurring_transactions/fragments/list_transactions.html:5
#: templates/recurring_transactions/fragments/table.html:39
#: templates/transactions/pages/transactions.html:5
@@ -799,6 +819,7 @@ msgstr ""
#: apps/export_app/forms.py:38 apps/export_app/forms.py:134
#: apps/transactions/filters.py:67 templates/categories/fragments/list.html:5
#: templates/categories/pages/index.html:4 templates/includes/navbar.html:109
#: templates/includes/sidebar.html:162
msgid "Categories"
msgstr ""
@@ -809,13 +830,15 @@ msgstr ""
#: apps/transactions/forms.py:682 apps/transactions/forms.py:943
#: apps/transactions/models.py:273 apps/transactions/models.py:329
#: apps/transactions/models.py:506 apps/transactions/models.py:708
#: apps/transactions/models.py:949 templates/entities/fragments/list.html:5
#: apps/transactions/models.py:962 templates/entities/fragments/list.html:5
#: templates/entities/pages/index.html:4 templates/includes/navbar.html:113
#: templates/includes/sidebar.html:174
msgid "Entities"
msgstr ""
#: apps/export_app/forms.py:56 apps/export_app/forms.py:140
#: apps/transactions/models.py:745 templates/includes/navbar.html:77
#: apps/transactions/models.py:748 templates/includes/navbar.html:77
#: templates/includes/sidebar.html:95
#: templates/recurring_transactions/fragments/list.html:5
#: templates/recurring_transactions/pages/index.html:4
msgid "Recurring Transactions"
@@ -823,6 +846,7 @@ msgstr ""
#: apps/export_app/forms.py:62 apps/export_app/forms.py:138
#: apps/transactions/models.py:524 templates/includes/navbar.html:75
#: templates/includes/sidebar.html:89
#: templates/installment_plans/fragments/list.html:5
#: templates/installment_plans/pages/index.html:4
msgid "Installment Plans"
@@ -831,12 +855,13 @@ msgstr ""
#: apps/export_app/forms.py:74 apps/export_app/forms.py:143
#: templates/exchange_rates_services/fragments/list.html:6
#: templates/exchange_rates_services/pages/index.html:4
#: templates/includes/navbar.html:143
#: templates/includes/navbar.html:143 templates/includes/sidebar.html:230
msgid "Automatic Exchange Rates"
msgstr ""
#: apps/export_app/forms.py:80 templates/includes/navbar.html:135
#: templates/rules/fragments/list.html:5 templates/rules/pages/index.html:4
#: templates/includes/sidebar.html:210 templates/rules/fragments/list.html:5
#: templates/rules/pages/index.html:4
msgid "Rules"
msgstr ""
@@ -875,7 +900,7 @@ msgstr ""
msgid "Update or create transaction actions"
msgstr ""
#: apps/export_app/forms.py:185 templates/cotton/transaction/item.html:172
#: apps/export_app/forms.py:185 templates/cotton/transaction/item.html:176
#: templates/cotton/ui/deleted_transactions_action_bar.html:47
#: templates/export_app/fragments/restore.html:5
#: templates/export_app/pages/index.html:24
@@ -905,7 +930,7 @@ msgstr ""
#: apps/import_app/forms.py:61
#: templates/import_app/fragments/profiles/list.html:62
#: templates/includes/navbar.html:137
#: templates/includes/navbar.html:137 templates/includes/sidebar.html:216
msgid "Import"
msgstr ""
@@ -976,8 +1001,8 @@ msgstr ""
#: apps/insights/forms.py:119 apps/insights/utils/sankey.py:36
#: apps/insights/utils/sankey.py:167
#: templates/insights/fragments/category_overview/index.html:73
#: templates/insights/fragments/category_overview/index.html:285
#: templates/insights/fragments/category_overview/index.html:314
#: templates/insights/fragments/category_overview/index.html:284
#: templates/insights/fragments/category_overview/index.html:313
msgid "Uncategorized"
msgstr ""
@@ -1061,13 +1086,13 @@ msgstr ""
#: apps/rules/forms.py:167 apps/rules/forms.py:180 apps/rules/models.py:31
#: apps/rules/models.py:246 apps/transactions/models.py:297
#: apps/transactions/models.py:466 apps/transactions/models.py:689
#: apps/transactions/models.py:919
#: apps/transactions/models.py:932
msgid "Type"
msgstr ""
#: apps/rules/forms.py:168 apps/rules/forms.py:181 apps/rules/models.py:32
#: apps/rules/models.py:250 apps/transactions/filters.py:23
#: apps/transactions/models.py:299 apps/transactions/models.py:921
#: apps/transactions/models.py:299 apps/transactions/models.py:934
#: templates/cotton/transaction/item.html:20
#: templates/cotton/transaction/item.html:30
#: templates/transactions/widgets/paid_toggle_button.html:12
@@ -1085,7 +1110,7 @@ msgstr ""
#: apps/rules/forms.py:171 apps/rules/forms.py:184 apps/rules/models.py:35
#: apps/rules/models.py:262 apps/transactions/models.py:307
#: apps/transactions/models.py:694 apps/transactions/models.py:927
#: apps/transactions/models.py:694 apps/transactions/models.py:940
#: templates/insights/fragments/sankey.html:95
#: templates/installment_plans/fragments/table.html:18
#: templates/quick_transactions/fragments/list.html:15
@@ -1097,17 +1122,17 @@ msgstr ""
#: apps/rules/models.py:36 apps/rules/models.py:266
#: apps/transactions/forms.py:490 apps/transactions/models.py:312
#: apps/transactions/models.py:468 apps/transactions/models.py:697
#: apps/transactions/models.py:932
#: apps/transactions/models.py:945
msgid "Description"
msgstr ""
#: apps/rules/forms.py:175 apps/rules/forms.py:190 apps/rules/models.py:274
#: apps/transactions/models.py:351 apps/transactions/models.py:954
#: apps/transactions/models.py:351 apps/transactions/models.py:967
msgid "Internal Note"
msgstr ""
#: apps/rules/forms.py:176 apps/rules/forms.py:191 apps/rules/models.py:278
#: apps/transactions/models.py:353 apps/transactions/models.py:956
#: apps/transactions/models.py:353 apps/transactions/models.py:969
msgid "Internal ID"
msgstr ""
@@ -1179,7 +1204,7 @@ msgstr ""
msgid "less than or equal"
msgstr ""
#: apps/rules/models.py:88 templates/transactions/pages/transactions.html:15
#: apps/rules/models.py:88
msgid "Filter"
msgstr ""
@@ -1236,6 +1261,7 @@ msgstr ""
#: apps/transactions/filters.py:24 templates/cotton/transaction/item.html:20
#: templates/cotton/transaction/item.html:30 templates/includes/navbar.html:47
#: templates/insights/fragments/category_overview/index.html:46
#: templates/net_worth/net_worth.html:32
#: templates/transactions/widgets/paid_toggle_button.html:8
#: templates/transactions/widgets/unselectable_paid_toggle_button.html:12
msgid "Projected"
@@ -1294,7 +1320,7 @@ msgid "To Amount"
msgstr ""
#: apps/transactions/forms.py:503 apps/transactions/models.py:211
#: apps/transactions/models.py:302 apps/transactions/models.py:922
#: apps/transactions/models.py:302 apps/transactions/models.py:935
msgid "Mute"
msgstr ""
@@ -1320,7 +1346,11 @@ msgstr ""
msgid "Muted categories won't be displayed on monthly summaries"
msgstr ""
#: apps/transactions/forms.py:1074
#: apps/transactions/forms.py:1046
msgid "future transactions"
msgstr ""
#: apps/transactions/forms.py:1076
msgid "End date should be after the start date"
msgstr ""
@@ -1357,7 +1387,7 @@ msgstr ""
msgid "Entity"
msgstr ""
#: apps/transactions/models.py:284 apps/transactions/models.py:899
#: apps/transactions/models.py:284 apps/transactions/models.py:912
#: templates/calendar_view/fragments/list.html:42
#: templates/calendar_view/fragments/list.html:44
#: templates/calendar_view/fragments/list.html:52
@@ -1369,7 +1399,7 @@ msgstr ""
msgid "Income"
msgstr ""
#: apps/transactions/models.py:285 apps/transactions/models.py:900
#: apps/transactions/models.py:285 apps/transactions/models.py:913
#: templates/calendar_view/fragments/list.html:46
#: templates/calendar_view/fragments/list.html:48
#: templates/calendar_view/fragments/list.html:56
@@ -1384,7 +1414,7 @@ msgstr ""
msgid "Installment Plan"
msgstr ""
#: apps/transactions/models.py:349 apps/transactions/models.py:744
#: apps/transactions/models.py:349 apps/transactions/models.py:747
msgid "Recurring Transaction"
msgstr ""
@@ -1412,12 +1442,12 @@ msgstr ""
msgid "No description"
msgstr ""
#: apps/transactions/models.py:455
#: apps/transactions/models.py:455 templates/includes/sidebar.html:42
msgid "Yearly"
msgstr ""
#: apps/transactions/models.py:456 apps/users/models.py:464
#: templates/includes/navbar.html:27
#: templates/includes/navbar.html:27 templates/includes/sidebar.html:36
msgid "Monthly"
msgstr ""
@@ -1457,11 +1487,11 @@ msgstr ""
msgid "Installment Amount"
msgstr ""
#: apps/transactions/models.py:513 apps/transactions/models.py:734
#: apps/transactions/models.py:513 apps/transactions/models.py:737
msgid "Add description to transactions"
msgstr ""
#: apps/transactions/models.py:516 apps/transactions/models.py:737
#: apps/transactions/models.py:516 apps/transactions/models.py:740
msgid "Add notes to transactions"
msgstr ""
@@ -1494,15 +1524,19 @@ msgstr ""
msgid "Recurrence Interval"
msgstr ""
#: apps/transactions/models.py:727
msgid "Last Generated Date"
#: apps/transactions/models.py:726
msgid "Keep at most"
msgstr ""
#: apps/transactions/models.py:730
msgid "Last Generated Date"
msgstr ""
#: apps/transactions/models.py:733
msgid "Last Generated Reference Date"
msgstr ""
#: apps/transactions/models.py:966
#: apps/transactions/models.py:979
#: apps/transactions/views/quick_transactions.py:177
#: apps/transactions/views/quick_transactions.py:186
#: apps/transactions/views/quick_transactions.py:188
@@ -1511,7 +1545,8 @@ msgstr ""
msgid "Quick Transaction"
msgstr ""
#: apps/transactions/models.py:967 templates/includes/navbar.html:73
#: apps/transactions/models.py:980 templates/includes/navbar.html:73
#: templates/includes/sidebar.html:83
#: templates/quick_transactions/pages/index.html:5
#: templates/quick_transactions/pages/index.html:11
msgid "Quick Transactions"
@@ -1616,8 +1651,8 @@ msgid "Item deleted successfully"
msgstr ""
#: apps/transactions/views/quick_transactions.py:155
#: apps/transactions/views/transactions.py:52
#: apps/transactions/views/transactions.py:148
#: apps/transactions/views/transactions.py:53
#: apps/transactions/views/transactions.py:149
msgid "Transaction added successfully"
msgstr ""
@@ -1657,30 +1692,30 @@ msgstr ""
msgid "Tag deleted successfully"
msgstr ""
#: apps/transactions/views/transactions.py:182
#: apps/transactions/views/transactions.py:183
msgid "Transaction updated successfully"
msgstr ""
#: apps/transactions/views/transactions.py:232
#: apps/transactions/views/transactions.py:233
#, python-format
msgid "%(count)s transaction updated successfully"
msgid_plural "%(count)s transactions updated successfully"
msgstr[0] ""
msgstr[1] ""
#: apps/transactions/views/transactions.py:268
#: apps/transactions/views/transactions.py:269
msgid "Transaction duplicated successfully"
msgstr ""
#: apps/transactions/views/transactions.py:310
#: apps/transactions/views/transactions.py:311
msgid "Transaction deleted successfully"
msgstr ""
#: apps/transactions/views/transactions.py:328
#: apps/transactions/views/transactions.py:329
msgid "Transaction restored successfully"
msgstr ""
#: apps/transactions/views/transactions.py:354
#: apps/transactions/views/transactions.py:355
msgid "Transfer added successfully"
msgstr ""
@@ -1723,7 +1758,7 @@ msgstr ""
#: apps/users/forms.py:54 apps/users/forms.py:67 apps/users/forms.py:89
#: templates/monthly_overview/pages/overview.html:153
#: templates/transactions/pages/transactions.html:35
#: templates/transactions/pages/transactions.html:28
msgid "Default"
msgstr ""
@@ -1803,10 +1838,6 @@ msgstr ""
msgid "A user with this email address already exists."
msgstr ""
#: apps/users/models.py:12 apps/users/models.py:497
msgid "Auto"
msgstr ""
#: apps/users/models.py:465 templates/includes/navbar.html:29
msgid "Yearly by currency"
msgstr ""
@@ -1828,6 +1859,7 @@ msgid "All Transactions"
msgstr ""
#: apps/users/models.py:470 templates/includes/navbar.html:33
#: templates/includes/sidebar.html:48
msgid "Calendar"
msgstr ""
@@ -1922,9 +1954,9 @@ msgstr ""
#: templates/accounts/fragments/list.html:48
#: templates/categories/fragments/table.html:36
#: templates/cotton/transaction/item.html:136
#: templates/cotton/transaction/item.html:178
#: templates/cotton/transaction/item.html:182
#: templates/cotton/ui/deleted_transactions_action_bar.html:55
#: templates/cotton/ui/transactions_action_bar.html:89
#: templates/cotton/ui/transactions_action_bar.html:90
#: templates/currencies/fragments/list.html:44
#: templates/dca/fragments/strategy/details.html:75
#: templates/dca/fragments/strategy/list.html:44
@@ -1949,9 +1981,9 @@ msgstr ""
#: templates/accounts/fragments/list.html:52
#: templates/categories/fragments/table.html:41
#: templates/cotton/transaction/item.html:140
#: templates/cotton/transaction/item.html:182
#: templates/cotton/transaction/item.html:186
#: templates/cotton/ui/deleted_transactions_action_bar.html:57
#: templates/cotton/ui/transactions_action_bar.html:91
#: templates/cotton/ui/transactions_action_bar.html:92
#: templates/currencies/fragments/list.html:48
#: templates/dca/fragments/strategy/details.html:80
#: templates/dca/fragments/strategy/list.html:48
@@ -1979,9 +2011,9 @@ msgstr ""
#: templates/accounts/fragments/list.html:53
#: templates/categories/fragments/table.html:42
#: templates/cotton/transaction/item.html:141
#: templates/cotton/transaction/item.html:183
#: templates/cotton/transaction/item.html:187
#: templates/cotton/ui/deleted_transactions_action_bar.html:58
#: templates/cotton/ui/transactions_action_bar.html:92
#: templates/cotton/ui/transactions_action_bar.html:93
#: templates/currencies/fragments/list.html:49
#: templates/dca/fragments/strategy/details.html:81
#: templates/dca/fragments/strategy/list.html:49
@@ -2001,7 +2033,7 @@ msgstr ""
#: templates/accounts/fragments/list.html:54
#: templates/categories/fragments/table.html:43
#: templates/cotton/transaction/item.html:142
#: templates/cotton/transaction/item.html:184
#: templates/cotton/transaction/item.html:188
#: templates/currencies/fragments/list.html:50
#: templates/dca/fragments/strategy/details.html:82
#: templates/dca/fragments/strategy/list.html:50
@@ -2140,7 +2172,7 @@ msgid "Muted"
msgstr ""
#: templates/categories/fragments/table.html:75
#: templates/insights/fragments/category_overview/index.html:430
#: templates/insights/fragments/category_overview/index.html:429
msgid "No categories"
msgstr ""
@@ -2149,6 +2181,7 @@ msgid "Pick a month"
msgstr ""
#: templates/common/fragments/toasts.html:15 templates/extends/offcanvas.html:5
#: templates/includes/sidebar.html:28
msgid "Close"
msgstr ""
@@ -2180,7 +2213,19 @@ msgid "Add as quick transaction"
msgstr ""
#: templates/cotton/transaction/item.html:166
#: templates/cotton/ui/transactions_action_bar.html:81
msgid "Move to previous month"
msgstr ""
#: templates/cotton/transaction/item.html:167
msgid "Move to next month"
msgstr ""
#: templates/cotton/transaction/item.html:168
msgid "Move to today"
msgstr ""
#: templates/cotton/transaction/item.html:170
#: templates/cotton/ui/transactions_action_bar.html:82
msgid "Duplicate"
msgstr ""
@@ -2230,7 +2275,7 @@ msgid "Unselect All"
msgstr ""
#: templates/cotton/ui/deleted_transactions_action_bar.html:59
#: templates/cotton/ui/transactions_action_bar.html:93
#: templates/cotton/ui/transactions_action_bar.html:94
msgid "Yes, delete them!"
msgstr ""
@@ -2241,49 +2286,49 @@ msgstr ""
#: templates/cotton/ui/deleted_transactions_action_bar.html:189
#: templates/cotton/ui/deleted_transactions_action_bar.html:209
#: templates/cotton/ui/deleted_transactions_action_bar.html:229
#: templates/cotton/ui/transactions_action_bar.html:139
#: templates/cotton/ui/transactions_action_bar.html:163
#: templates/cotton/ui/transactions_action_bar.html:183
#: templates/cotton/ui/transactions_action_bar.html:203
#: templates/cotton/ui/transactions_action_bar.html:223
#: templates/cotton/ui/transactions_action_bar.html:243
#: templates/cotton/ui/transactions_action_bar.html:263
#: templates/cotton/ui/transactions_action_bar.html:140
#: templates/cotton/ui/transactions_action_bar.html:165
#: templates/cotton/ui/transactions_action_bar.html:185
#: templates/cotton/ui/transactions_action_bar.html:205
#: templates/cotton/ui/transactions_action_bar.html:225
#: templates/cotton/ui/transactions_action_bar.html:245
#: templates/cotton/ui/transactions_action_bar.html:265
msgid "copied!"
msgstr ""
#: templates/cotton/ui/deleted_transactions_action_bar.html:114
#: templates/cotton/ui/transactions_action_bar.html:57
#: templates/cotton/ui/transactions_action_bar.html:148
#: templates/cotton/ui/transactions_action_bar.html:58
#: templates/cotton/ui/transactions_action_bar.html:150
msgid "Toggle Dropdown"
msgstr ""
#: templates/cotton/ui/deleted_transactions_action_bar.html:122
#: templates/cotton/ui/transactions_action_bar.html:156
#: templates/cotton/ui/transactions_action_bar.html:158
msgid "Flat Total"
msgstr ""
#: templates/cotton/ui/deleted_transactions_action_bar.html:142
#: templates/cotton/ui/transactions_action_bar.html:176
#: templates/cotton/ui/transactions_action_bar.html:178
msgid "Real Total"
msgstr ""
#: templates/cotton/ui/deleted_transactions_action_bar.html:162
#: templates/cotton/ui/transactions_action_bar.html:196
#: templates/cotton/ui/transactions_action_bar.html:198
msgid "Mean"
msgstr ""
#: templates/cotton/ui/deleted_transactions_action_bar.html:182
#: templates/cotton/ui/transactions_action_bar.html:216
#: templates/cotton/ui/transactions_action_bar.html:218
msgid "Max"
msgstr ""
#: templates/cotton/ui/deleted_transactions_action_bar.html:202
#: templates/cotton/ui/transactions_action_bar.html:236
#: templates/cotton/ui/transactions_action_bar.html:238
msgid "Min"
msgstr ""
#: templates/cotton/ui/deleted_transactions_action_bar.html:222
#: templates/cotton/ui/transactions_action_bar.html:256
#: templates/cotton/ui/transactions_action_bar.html:258
msgid "Count"
msgstr ""
@@ -2302,11 +2347,11 @@ msgstr ""
msgid "Balance"
msgstr ""
#: templates/cotton/ui/transactions_action_bar.html:65
#: templates/cotton/ui/transactions_action_bar.html:66
msgid "Mark as unpaid"
msgstr ""
#: templates/cotton/ui/transactions_action_bar.html:72
#: templates/cotton/ui/transactions_action_bar.html:73
msgid "Mark as paid"
msgstr ""
@@ -2462,10 +2507,10 @@ msgid "Edit exchange rate"
msgstr ""
#: templates/exchange_rates/fragments/list.html:25
#: templates/includes/navbar.html:62
#: templates/includes/navbar.html:62 templates/includes/sidebar.html:68
#: templates/installment_plans/fragments/list.html:21
#: templates/yearly_overview/pages/overview_by_account.html:94
#: templates/yearly_overview/pages/overview_by_currency.html:96
#: templates/yearly_overview/pages/overview_by_account.html:105
#: templates/yearly_overview/pages/overview_by_currency.html:107
msgid "All"
msgstr ""
@@ -2519,6 +2564,7 @@ msgid "No services configured"
msgstr ""
#: templates/export_app/pages/index.html:4 templates/includes/navbar.html:140
#: templates/includes/sidebar.html:223
msgid "Export and Restore"
msgstr ""
@@ -2606,7 +2652,7 @@ msgstr ""
msgid "Logs for"
msgstr ""
#: templates/includes/navbar.html:12
#: templates/includes/mobile_navbar.html:12 templates/includes/navbar.html:12
msgid "Toggle navigation"
msgstr ""
@@ -2614,88 +2660,88 @@ msgstr ""
msgid "Overview"
msgstr ""
#: templates/includes/navbar.html:41
#: templates/includes/navbar.html:41 templates/includes/sidebar.html:60
msgid "Net Worth"
msgstr ""
#: templates/includes/navbar.html:45
#: templates/insights/fragments/category_overview/index.html:50
#: templates/net_worth/net_worth.html:22
msgid "Current"
msgstr ""
#: templates/includes/navbar.html:51 templates/insights/pages/index.html:5
#: templates/includes/navbar.html:51 templates/includes/sidebar.html:54
#: templates/insights/pages/index.html:5
msgid "Insights"
msgstr ""
#: templates/includes/navbar.html:67
#: templates/includes/navbar.html:67 templates/includes/sidebar.html:76
msgid "Trash Can"
msgstr ""
#: templates/includes/navbar.html:85
#: templates/includes/navbar.html:85 templates/includes/sidebar.html:101
msgid "Tools"
msgstr ""
#: templates/includes/navbar.html:89
#: templates/includes/navbar.html:89 templates/includes/sidebar.html:103
msgid "Dollar Cost Average Tracker"
msgstr ""
#: templates/includes/navbar.html:92
#: templates/includes/navbar.html:92 templates/includes/sidebar.html:109
#: templates/mini_tools/unit_price_calculator.html:5
#: templates/mini_tools/unit_price_calculator.html:10
msgid "Unit Price Calculator"
msgstr ""
#: templates/includes/navbar.html:95
#: templates/includes/navbar.html:95 templates/includes/sidebar.html:115
#: templates/mini_tools/currency_converter/currency_converter.html:8
#: templates/mini_tools/currency_converter/currency_converter.html:15
msgid "Currency Converter"
msgstr ""
#: templates/includes/navbar.html:104
#: templates/includes/navbar.html:104 templates/includes/sidebar.html:134
#: templates/includes/sidebar.html:147
msgid "Management"
msgstr ""
#: templates/includes/navbar.html:133
#: templates/includes/navbar.html:133 templates/includes/sidebar.html:208
msgid "Automation"
msgstr ""
#: templates/includes/navbar.html:148
#: templates/includes/navbar.html:148 templates/includes/sidebar.html:237
msgid "Admin"
msgstr ""
#: templates/includes/navbar.html:157
#: templates/includes/navbar.html:157 templates/includes/sidebar.html:246
msgid "Only use this if you know what you're doing"
msgstr ""
#: templates/includes/navbar.html:158
#: templates/includes/navbar.html:158 templates/includes/sidebar.html:245
msgid "Django Admin"
msgstr ""
#: templates/includes/navbar.html:169
#: templates/includes/navbar.html:169 templates/includes/sidebar.html:260
msgid "is available"
msgstr ""
#: templates/includes/navbar.html:174 templates/includes/navbar.html:177
#: templates/includes/sidebar.html:266
msgid "Calculator"
msgstr ""
#: templates/includes/navbar/user_menu.html:6
msgid "Profile"
msgstr ""
#: templates/includes/navbar/user_menu.html:15
#: templates/includes/navbar/user_menu.html:12
msgid "Settings"
msgstr ""
#: templates/includes/navbar/user_menu.html:20
#: templates/includes/navbar/user_menu.html:17
msgid "Edit profile"
msgstr ""
#: templates/includes/navbar/user_menu.html:47
#: templates/includes/navbar/user_menu.html:44
msgid "Clear cache"
msgstr ""
#: templates/includes/navbar/user_menu.html:51
#: templates/includes/navbar/user_menu.html:48
msgid "Logout"
msgstr ""
@@ -2772,7 +2818,7 @@ msgstr ""
msgid "Untagged"
msgstr ""
#: templates/insights/fragments/category_overview/index.html:407
#: templates/insights/fragments/category_overview/index.html:406
msgid "Final Total"
msgstr ""
@@ -2825,8 +2871,8 @@ msgid "Month"
msgstr ""
#: templates/insights/pages/index.html:40
#: templates/yearly_overview/pages/overview_by_account.html:62
#: templates/yearly_overview/pages/overview_by_currency.html:64
#: templates/yearly_overview/pages/overview_by_account.html:73
#: templates/yearly_overview/pages/overview_by_currency.html:75
msgid "Year"
msgstr ""
@@ -2905,11 +2951,11 @@ msgstr ""
msgid "No installment plans"
msgstr ""
#: templates/layouts/base.html:40
#: templates/layouts/base.html:43
msgid "This is a demo!"
msgstr ""
#: templates/layouts/base.html:40
#: templates/layouts/base.html:43
msgid "Any data you add here will be wiped in 24hrs or less"
msgstr ""
@@ -2978,43 +3024,44 @@ msgid "Summary"
msgstr ""
#: templates/monthly_overview/pages/overview.html:142
#: templates/transactions/pages/transactions.html:17
msgid "Filter transactions"
msgstr ""
#: templates/monthly_overview/pages/overview.html:148
#: templates/transactions/pages/transactions.html:33
#: templates/transactions/pages/transactions.html:23
msgid "Order by"
msgstr ""
#: templates/monthly_overview/pages/overview.html:155
#: templates/transactions/pages/transactions.html:36
#: templates/transactions/pages/transactions.html:30
msgid "Oldest first"
msgstr ""
#: templates/monthly_overview/pages/overview.html:157
#: templates/transactions/pages/transactions.html:37
#: templates/transactions/pages/transactions.html:32
msgid "Newest first"
msgstr ""
#: templates/net_worth/net_worth.html:18
#: templates/net_worth/net_worth.html:40
#: templates/yearly_overview/pages/overview_by_currency.html:9
msgid "By currency"
msgstr ""
#: templates/net_worth/net_worth.html:53
#: templates/net_worth/net_worth.html:75
msgid "Consolidated"
msgstr ""
#: templates/net_worth/net_worth.html:82
#: templates/net_worth/net_worth.html:104
#: templates/yearly_overview/pages/overview_by_account.html:7
msgid "By account"
msgstr ""
#: templates/net_worth/net_worth.html:189
#: templates/net_worth/net_worth.html:211
msgid "Evolution by currency"
msgstr ""
#: templates/net_worth/net_worth.html:253
#: templates/net_worth/net_worth.html:275
msgid "Evolution by account"
msgstr ""

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

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-07-28 02:21+0000\n"
"POT-Creation-Date: 2025-08-08 02:41+0000\n"
"PO-Revision-Date: 2025-04-14 06:16+0000\n"
"Last-Translator: Emil <emil.bjorkroth@gmail.com>\n"
"Language-Team: Swedish <https://translations.herculino.com/projects/wygiwyh/"
@@ -25,26 +25,26 @@ msgstr ""
#: apps/accounts/forms.py:40 apps/accounts/forms.py:98
#: apps/currencies/forms.py:53 apps/currencies/forms.py:91
#: apps/currencies/forms.py:142 apps/dca/forms.py:49 apps/dca/forms.py:224
#: apps/currencies/forms.py:144 apps/dca/forms.py:49 apps/dca/forms.py:224
#: apps/import_app/forms.py:34 apps/rules/forms.py:51 apps/rules/forms.py:93
#: apps/rules/forms.py:365 apps/transactions/forms.py:204
#: apps/transactions/forms.py:374 apps/transactions/forms.py:421
#: apps/transactions/forms.py:793 apps/transactions/forms.py:836
#: apps/transactions/forms.py:868 apps/transactions/forms.py:903
#: apps/transactions/forms.py:1055 apps/users/forms.py:215
#: apps/transactions/forms.py:1057 apps/users/forms.py:215
#: apps/users/forms.py:377
msgid "Update"
msgstr "Uppdatera"
#: apps/accounts/forms.py:48 apps/accounts/forms.py:106
#: apps/common/widgets/tom_select.py:13 apps/currencies/forms.py:61
#: apps/currencies/forms.py:99 apps/currencies/forms.py:150
#: apps/currencies/forms.py:99 apps/currencies/forms.py:152
#: apps/dca/forms.py:57 apps/dca/forms.py:232 apps/import_app/forms.py:42
#: apps/rules/forms.py:59 apps/rules/forms.py:101 apps/rules/forms.py:373
#: apps/transactions/forms.py:189 apps/transactions/forms.py:213
#: apps/transactions/forms.py:383 apps/transactions/forms.py:801
#: apps/transactions/forms.py:844 apps/transactions/forms.py:876
#: apps/transactions/forms.py:911 apps/transactions/forms.py:1063
#: apps/transactions/forms.py:911 apps/transactions/forms.py:1065
#: apps/users/forms.py:223 apps/users/forms.py:385
#: templates/account_groups/fragments/list.html:9
#: templates/accounts/fragments/list.html:9
@@ -81,9 +81,9 @@ msgstr ""
#: apps/transactions/forms.py:455 apps/transactions/forms.py:462
#: apps/transactions/forms.py:674 apps/transactions/forms.py:935
#: apps/transactions/models.py:318 apps/transactions/models.py:501
#: apps/transactions/models.py:701 apps/transactions/models.py:938
#: apps/transactions/models.py:701 apps/transactions/models.py:951
#: templates/insights/fragments/category_overview/index.html:63
#: templates/insights/fragments/category_overview/index.html:420
#: templates/insights/fragments/category_overview/index.html:419
msgid "Category"
msgstr ""
@@ -95,8 +95,8 @@ msgstr ""
#: apps/transactions/forms.py:471 apps/transactions/forms.py:479
#: apps/transactions/forms.py:667 apps/transactions/forms.py:928
#: apps/transactions/models.py:324 apps/transactions/models.py:503
#: apps/transactions/models.py:705 apps/transactions/models.py:944
#: templates/includes/navbar.html:111
#: apps/transactions/models.py:705 apps/transactions/models.py:957
#: templates/includes/navbar.html:111 templates/includes/sidebar.html:168
#: templates/insights/fragments/category_overview/index.html:35
#: templates/tags/fragments/list.html:5 templates/tags/pages/index.html:4
msgid "Tags"
@@ -105,7 +105,7 @@ msgstr ""
#: apps/accounts/models.py:12 apps/accounts/models.py:29 apps/dca/models.py:13
#: apps/import_app/models.py:14 apps/rules/models.py:13
#: apps/transactions/models.py:210 apps/transactions/models.py:235
#: apps/transactions/models.py:259 apps/transactions/models.py:906
#: apps/transactions/models.py:259 apps/transactions/models.py:919
#: templates/account_groups/fragments/list.html:25
#: templates/accounts/fragments/list.html:25
#: templates/categories/fragments/table.html:16
@@ -128,12 +128,14 @@ msgstr ""
#: apps/accounts/models.py:19 templates/account_groups/fragments/list.html:5
#: templates/account_groups/pages/index.html:4
#: templates/includes/navbar.html:121
#: templates/includes/navbar.html:121 templates/includes/sidebar.html:188
msgid "Account Groups"
msgstr ""
#: apps/accounts/models.py:39 apps/currencies/models.py:39
#: templates/accounts/fragments/list.html:27
#: templates/yearly_overview/pages/overview_by_account.html:18
#: templates/yearly_overview/pages/overview_by_currency.html:20
msgid "Currency"
msgstr ""
@@ -171,10 +173,12 @@ msgstr ""
#: apps/transactions/forms.py:62 apps/transactions/forms.py:276
#: apps/transactions/forms.py:659 apps/transactions/forms.py:920
#: apps/transactions/models.py:290 apps/transactions/models.py:461
#: apps/transactions/models.py:683 apps/transactions/models.py:912
#: apps/transactions/models.py:683 apps/transactions/models.py:925
#: templates/installment_plans/fragments/table.html:17
#: templates/quick_transactions/fragments/list.html:14
#: templates/recurring_transactions/fragments/table.html:19
#: templates/yearly_overview/pages/overview_by_account.html:22
#: templates/yearly_overview/pages/overview_by_currency.html:24
msgid "Account"
msgstr ""
@@ -182,10 +186,11 @@ msgstr ""
#: apps/export_app/forms.py:132 apps/transactions/filters.py:53
#: templates/accounts/fragments/list.html:5
#: templates/accounts/pages/index.html:4 templates/includes/navbar.html:117
#: templates/includes/navbar.html:119
#: templates/includes/navbar.html:119 templates/includes/sidebar.html:180
#: templates/includes/sidebar.html:182
#: templates/monthly_overview/pages/overview.html:94
#: templates/transactions/fragments/summary.html:12
#: templates/transactions/pages/transactions.html:72
#: templates/transactions/pages/transactions.html:81
msgid "Accounts"
msgstr ""
@@ -282,7 +287,7 @@ msgstr ""
msgid "Invalid entity data. Provide an ID or name."
msgstr ""
#: apps/api/serializers/transactions.py:191
#: apps/api/serializers/transactions.py:192
msgid "Either 'date' or 'reference_date' must be provided."
msgstr ""
@@ -455,7 +460,7 @@ msgstr ""
#: apps/common/widgets/tom_select.py:15
#: templates/mini_tools/unit_price_calculator.html:174
#: templates/monthly_overview/pages/overview.html:172
#: templates/transactions/pages/transactions.html:17
#: templates/transactions/pages/transactions.html:47
msgid "Clear"
msgstr ""
@@ -497,10 +502,11 @@ msgstr ""
#: apps/export_app/forms.py:133 apps/transactions/filters.py:60
#: templates/currencies/fragments/list.html:5
#: templates/currencies/pages/index.html:4 templates/includes/navbar.html:125
#: templates/includes/navbar.html:127
#: templates/includes/navbar.html:127 templates/includes/sidebar.html:194
#: templates/includes/sidebar.html:196
#: templates/monthly_overview/pages/overview.html:81
#: templates/transactions/fragments/summary.html:8
#: templates/transactions/pages/transactions.html:59
#: templates/transactions/pages/transactions.html:68
msgid "Currencies"
msgstr ""
@@ -516,7 +522,7 @@ msgstr ""
msgid "To Currency"
msgstr ""
#: apps/currencies/models.py:69 apps/currencies/models.py:74
#: apps/currencies/models.py:69 apps/currencies/models.py:76
msgid "Exchange Rate"
msgstr ""
@@ -524,38 +530,43 @@ msgstr ""
msgid "Date and Time"
msgstr ""
#: apps/currencies/models.py:75 apps/export_app/forms.py:68
#: apps/currencies/models.py:73 apps/users/models.py:12
#: apps/users/models.py:497
msgid "Auto"
msgstr ""
#: apps/currencies/models.py:77 apps/export_app/forms.py:68
#: apps/export_app/forms.py:145 templates/exchange_rates/fragments/list.html:6
#: templates/exchange_rates/pages/index.html:4
#: templates/includes/navbar.html:129
#: templates/includes/navbar.html:129 templates/includes/sidebar.html:202
msgid "Exchange Rates"
msgstr ""
#: apps/currencies/models.py:87
#: apps/currencies/models.py:89
msgid "From and To currencies cannot be the same."
msgstr ""
#: apps/currencies/models.py:102
#: apps/currencies/models.py:104
msgid "On"
msgstr ""
#: apps/currencies/models.py:103
#: apps/currencies/models.py:105
msgid "Every X hours"
msgstr ""
#: apps/currencies/models.py:104
#: apps/currencies/models.py:106
msgid "Not on"
msgstr ""
#: apps/currencies/models.py:106
#: apps/currencies/models.py:108
msgid "Service Name"
msgstr ""
#: apps/currencies/models.py:108
#: apps/currencies/models.py:110
msgid "Service Type"
msgstr ""
#: apps/currencies/models.py:110 apps/transactions/models.py:214
#: apps/currencies/models.py:112 apps/transactions/models.py:214
#: apps/transactions/models.py:238 apps/transactions/models.py:262
#: templates/categories/fragments/list.html:21
#: templates/entities/fragments/list.html:21
@@ -564,69 +575,77 @@ msgstr ""
msgid "Active"
msgstr ""
#: apps/currencies/models.py:115
#: apps/currencies/models.py:117
msgid "API Key"
msgstr ""
#: apps/currencies/models.py:116
#: apps/currencies/models.py:118
msgid "API key for the service (if required)"
msgstr ""
#: apps/currencies/models.py:121
#: apps/currencies/models.py:123
msgid "Interval Type"
msgstr ""
#: apps/currencies/models.py:125
#: apps/currencies/models.py:127
msgid "Interval"
msgstr ""
#: apps/currencies/models.py:128
#: apps/currencies/models.py:130
msgid "Last Successful Fetch"
msgstr ""
#: apps/currencies/models.py:133
#: apps/currencies/models.py:135
msgid "Target Currencies"
msgstr ""
#: apps/currencies/models.py:135
#: apps/currencies/models.py:137
msgid ""
"Select currencies to fetch exchange rates for. Rates will be fetched for "
"each currency against their set exchange currency."
msgstr ""
#: apps/currencies/models.py:143
#: apps/currencies/models.py:145
msgid "Target Accounts"
msgstr ""
#: apps/currencies/models.py:145
#: apps/currencies/models.py:147
msgid ""
"Select accounts to fetch exchange rates for. Rates will be fetched for each "
"account's currency against their set exchange currency."
msgstr ""
#: apps/currencies/models.py:152
#: apps/currencies/models.py:154
msgid "Single exchange rate"
msgstr ""
#: apps/currencies/models.py:157
msgid "Create one exchange rate and keep updating it. Avoids database clutter."
msgstr ""
#: apps/currencies/models.py:162
msgid "Exchange Rate Service"
msgstr ""
#: apps/currencies/models.py:153
#: apps/currencies/models.py:163
msgid "Exchange Rate Services"
msgstr ""
#: apps/currencies/models.py:205
#: apps/currencies/models.py:215
msgid "'Every X hours' interval type requires a positive integer."
msgstr ""
#: apps/currencies/models.py:214
#: apps/currencies/models.py:224
msgid "'Every X hours' interval must be between 1 and 24."
msgstr ""
#: apps/currencies/models.py:228
#: apps/currencies/models.py:238
msgid ""
"Invalid hour format. Use comma-separated hours (0-23) and/or ranges (e.g., "
"'1-5,8,10-12')."
msgstr ""
#: apps/currencies/models.py:239
#: apps/currencies/models.py:249
msgid ""
"Invalid format. Please check the requirements for your selected interval "
"type."
@@ -726,7 +745,7 @@ msgstr ""
#: apps/rules/forms.py:188 apps/rules/models.py:37 apps/rules/models.py:270
#: apps/transactions/forms.py:499 apps/transactions/models.py:314
#: apps/transactions/models.py:510 apps/transactions/models.py:711
#: apps/transactions/models.py:934
#: apps/transactions/models.py:947
msgid "Notes"
msgstr ""
@@ -783,14 +802,15 @@ msgid "Entry deleted successfully"
msgstr ""
#: apps/export_app/forms.py:14 apps/export_app/forms.py:131
#: templates/includes/navbar.html:150 templates/users/fragments/list.html:6
#: templates/users/pages/index.html:4
#: templates/includes/navbar.html:150 templates/includes/sidebar.html:239
#: templates/users/fragments/list.html:6 templates/users/pages/index.html:4
msgid "Users"
msgstr ""
#: apps/export_app/forms.py:32 apps/export_app/forms.py:137
#: apps/transactions/models.py:375 templates/includes/navbar.html:58
#: templates/includes/navbar.html:107
#: templates/includes/navbar.html:107 templates/includes/sidebar.html:66
#: templates/includes/sidebar.html:160
#: templates/recurring_transactions/fragments/list_transactions.html:5
#: templates/recurring_transactions/fragments/table.html:39
#: templates/transactions/pages/transactions.html:5
@@ -800,6 +820,7 @@ msgstr ""
#: apps/export_app/forms.py:38 apps/export_app/forms.py:134
#: apps/transactions/filters.py:67 templates/categories/fragments/list.html:5
#: templates/categories/pages/index.html:4 templates/includes/navbar.html:109
#: templates/includes/sidebar.html:162
msgid "Categories"
msgstr ""
@@ -810,13 +831,15 @@ msgstr ""
#: apps/transactions/forms.py:682 apps/transactions/forms.py:943
#: apps/transactions/models.py:273 apps/transactions/models.py:329
#: apps/transactions/models.py:506 apps/transactions/models.py:708
#: apps/transactions/models.py:949 templates/entities/fragments/list.html:5
#: apps/transactions/models.py:962 templates/entities/fragments/list.html:5
#: templates/entities/pages/index.html:4 templates/includes/navbar.html:113
#: templates/includes/sidebar.html:174
msgid "Entities"
msgstr ""
#: apps/export_app/forms.py:56 apps/export_app/forms.py:140
#: apps/transactions/models.py:745 templates/includes/navbar.html:77
#: apps/transactions/models.py:748 templates/includes/navbar.html:77
#: templates/includes/sidebar.html:95
#: templates/recurring_transactions/fragments/list.html:5
#: templates/recurring_transactions/pages/index.html:4
msgid "Recurring Transactions"
@@ -824,6 +847,7 @@ msgstr ""
#: apps/export_app/forms.py:62 apps/export_app/forms.py:138
#: apps/transactions/models.py:524 templates/includes/navbar.html:75
#: templates/includes/sidebar.html:89
#: templates/installment_plans/fragments/list.html:5
#: templates/installment_plans/pages/index.html:4
msgid "Installment Plans"
@@ -832,12 +856,13 @@ msgstr ""
#: apps/export_app/forms.py:74 apps/export_app/forms.py:143
#: templates/exchange_rates_services/fragments/list.html:6
#: templates/exchange_rates_services/pages/index.html:4
#: templates/includes/navbar.html:143
#: templates/includes/navbar.html:143 templates/includes/sidebar.html:230
msgid "Automatic Exchange Rates"
msgstr ""
#: apps/export_app/forms.py:80 templates/includes/navbar.html:135
#: templates/rules/fragments/list.html:5 templates/rules/pages/index.html:4
#: templates/includes/sidebar.html:210 templates/rules/fragments/list.html:5
#: templates/rules/pages/index.html:4
msgid "Rules"
msgstr ""
@@ -876,7 +901,7 @@ msgstr ""
msgid "Update or create transaction actions"
msgstr ""
#: apps/export_app/forms.py:185 templates/cotton/transaction/item.html:172
#: apps/export_app/forms.py:185 templates/cotton/transaction/item.html:176
#: templates/cotton/ui/deleted_transactions_action_bar.html:47
#: templates/export_app/fragments/restore.html:5
#: templates/export_app/pages/index.html:24
@@ -906,7 +931,7 @@ msgstr ""
#: apps/import_app/forms.py:61
#: templates/import_app/fragments/profiles/list.html:62
#: templates/includes/navbar.html:137
#: templates/includes/navbar.html:137 templates/includes/sidebar.html:216
msgid "Import"
msgstr ""
@@ -977,8 +1002,8 @@ msgstr ""
#: apps/insights/forms.py:119 apps/insights/utils/sankey.py:36
#: apps/insights/utils/sankey.py:167
#: templates/insights/fragments/category_overview/index.html:73
#: templates/insights/fragments/category_overview/index.html:285
#: templates/insights/fragments/category_overview/index.html:314
#: templates/insights/fragments/category_overview/index.html:284
#: templates/insights/fragments/category_overview/index.html:313
msgid "Uncategorized"
msgstr ""
@@ -1062,13 +1087,13 @@ msgstr ""
#: apps/rules/forms.py:167 apps/rules/forms.py:180 apps/rules/models.py:31
#: apps/rules/models.py:246 apps/transactions/models.py:297
#: apps/transactions/models.py:466 apps/transactions/models.py:689
#: apps/transactions/models.py:919
#: apps/transactions/models.py:932
msgid "Type"
msgstr ""
#: apps/rules/forms.py:168 apps/rules/forms.py:181 apps/rules/models.py:32
#: apps/rules/models.py:250 apps/transactions/filters.py:23
#: apps/transactions/models.py:299 apps/transactions/models.py:921
#: apps/transactions/models.py:299 apps/transactions/models.py:934
#: templates/cotton/transaction/item.html:20
#: templates/cotton/transaction/item.html:30
#: templates/transactions/widgets/paid_toggle_button.html:12
@@ -1086,7 +1111,7 @@ msgstr ""
#: apps/rules/forms.py:171 apps/rules/forms.py:184 apps/rules/models.py:35
#: apps/rules/models.py:262 apps/transactions/models.py:307
#: apps/transactions/models.py:694 apps/transactions/models.py:927
#: apps/transactions/models.py:694 apps/transactions/models.py:940
#: templates/insights/fragments/sankey.html:95
#: templates/installment_plans/fragments/table.html:18
#: templates/quick_transactions/fragments/list.html:15
@@ -1098,17 +1123,17 @@ msgstr ""
#: apps/rules/models.py:36 apps/rules/models.py:266
#: apps/transactions/forms.py:490 apps/transactions/models.py:312
#: apps/transactions/models.py:468 apps/transactions/models.py:697
#: apps/transactions/models.py:932
#: apps/transactions/models.py:945
msgid "Description"
msgstr ""
#: apps/rules/forms.py:175 apps/rules/forms.py:190 apps/rules/models.py:274
#: apps/transactions/models.py:351 apps/transactions/models.py:954
#: apps/transactions/models.py:351 apps/transactions/models.py:967
msgid "Internal Note"
msgstr ""
#: apps/rules/forms.py:176 apps/rules/forms.py:191 apps/rules/models.py:278
#: apps/transactions/models.py:353 apps/transactions/models.py:956
#: apps/transactions/models.py:353 apps/transactions/models.py:969
msgid "Internal ID"
msgstr ""
@@ -1180,7 +1205,7 @@ msgstr ""
msgid "less than or equal"
msgstr ""
#: apps/rules/models.py:88 templates/transactions/pages/transactions.html:15
#: apps/rules/models.py:88
msgid "Filter"
msgstr ""
@@ -1237,6 +1262,7 @@ msgstr ""
#: apps/transactions/filters.py:24 templates/cotton/transaction/item.html:20
#: templates/cotton/transaction/item.html:30 templates/includes/navbar.html:47
#: templates/insights/fragments/category_overview/index.html:46
#: templates/net_worth/net_worth.html:32
#: templates/transactions/widgets/paid_toggle_button.html:8
#: templates/transactions/widgets/unselectable_paid_toggle_button.html:12
msgid "Projected"
@@ -1295,7 +1321,7 @@ msgid "To Amount"
msgstr ""
#: apps/transactions/forms.py:503 apps/transactions/models.py:211
#: apps/transactions/models.py:302 apps/transactions/models.py:922
#: apps/transactions/models.py:302 apps/transactions/models.py:935
msgid "Mute"
msgstr ""
@@ -1321,7 +1347,11 @@ msgstr ""
msgid "Muted categories won't be displayed on monthly summaries"
msgstr ""
#: apps/transactions/forms.py:1074
#: apps/transactions/forms.py:1046
msgid "future transactions"
msgstr ""
#: apps/transactions/forms.py:1076
msgid "End date should be after the start date"
msgstr ""
@@ -1358,7 +1388,7 @@ msgstr ""
msgid "Entity"
msgstr ""
#: apps/transactions/models.py:284 apps/transactions/models.py:899
#: apps/transactions/models.py:284 apps/transactions/models.py:912
#: templates/calendar_view/fragments/list.html:42
#: templates/calendar_view/fragments/list.html:44
#: templates/calendar_view/fragments/list.html:52
@@ -1370,7 +1400,7 @@ msgstr ""
msgid "Income"
msgstr ""
#: apps/transactions/models.py:285 apps/transactions/models.py:900
#: apps/transactions/models.py:285 apps/transactions/models.py:913
#: templates/calendar_view/fragments/list.html:46
#: templates/calendar_view/fragments/list.html:48
#: templates/calendar_view/fragments/list.html:56
@@ -1385,7 +1415,7 @@ msgstr ""
msgid "Installment Plan"
msgstr ""
#: apps/transactions/models.py:349 apps/transactions/models.py:744
#: apps/transactions/models.py:349 apps/transactions/models.py:747
msgid "Recurring Transaction"
msgstr ""
@@ -1413,12 +1443,12 @@ msgstr ""
msgid "No description"
msgstr ""
#: apps/transactions/models.py:455
#: apps/transactions/models.py:455 templates/includes/sidebar.html:42
msgid "Yearly"
msgstr ""
#: apps/transactions/models.py:456 apps/users/models.py:464
#: templates/includes/navbar.html:27
#: templates/includes/navbar.html:27 templates/includes/sidebar.html:36
msgid "Monthly"
msgstr ""
@@ -1458,11 +1488,11 @@ msgstr ""
msgid "Installment Amount"
msgstr ""
#: apps/transactions/models.py:513 apps/transactions/models.py:734
#: apps/transactions/models.py:513 apps/transactions/models.py:737
msgid "Add description to transactions"
msgstr ""
#: apps/transactions/models.py:516 apps/transactions/models.py:737
#: apps/transactions/models.py:516 apps/transactions/models.py:740
msgid "Add notes to transactions"
msgstr ""
@@ -1495,15 +1525,19 @@ msgstr ""
msgid "Recurrence Interval"
msgstr ""
#: apps/transactions/models.py:727
msgid "Last Generated Date"
#: apps/transactions/models.py:726
msgid "Keep at most"
msgstr ""
#: apps/transactions/models.py:730
msgid "Last Generated Date"
msgstr ""
#: apps/transactions/models.py:733
msgid "Last Generated Reference Date"
msgstr ""
#: apps/transactions/models.py:966
#: apps/transactions/models.py:979
#: apps/transactions/views/quick_transactions.py:177
#: apps/transactions/views/quick_transactions.py:186
#: apps/transactions/views/quick_transactions.py:188
@@ -1512,7 +1546,8 @@ msgstr ""
msgid "Quick Transaction"
msgstr ""
#: apps/transactions/models.py:967 templates/includes/navbar.html:73
#: apps/transactions/models.py:980 templates/includes/navbar.html:73
#: templates/includes/sidebar.html:83
#: templates/quick_transactions/pages/index.html:5
#: templates/quick_transactions/pages/index.html:11
msgid "Quick Transactions"
@@ -1617,8 +1652,8 @@ msgid "Item deleted successfully"
msgstr ""
#: apps/transactions/views/quick_transactions.py:155
#: apps/transactions/views/transactions.py:52
#: apps/transactions/views/transactions.py:148
#: apps/transactions/views/transactions.py:53
#: apps/transactions/views/transactions.py:149
msgid "Transaction added successfully"
msgstr ""
@@ -1658,30 +1693,30 @@ msgstr ""
msgid "Tag deleted successfully"
msgstr ""
#: apps/transactions/views/transactions.py:182
#: apps/transactions/views/transactions.py:183
msgid "Transaction updated successfully"
msgstr ""
#: apps/transactions/views/transactions.py:232
#: apps/transactions/views/transactions.py:233
#, python-format
msgid "%(count)s transaction updated successfully"
msgid_plural "%(count)s transactions updated successfully"
msgstr[0] ""
msgstr[1] ""
#: apps/transactions/views/transactions.py:268
#: apps/transactions/views/transactions.py:269
msgid "Transaction duplicated successfully"
msgstr ""
#: apps/transactions/views/transactions.py:310
#: apps/transactions/views/transactions.py:311
msgid "Transaction deleted successfully"
msgstr ""
#: apps/transactions/views/transactions.py:328
#: apps/transactions/views/transactions.py:329
msgid "Transaction restored successfully"
msgstr ""
#: apps/transactions/views/transactions.py:354
#: apps/transactions/views/transactions.py:355
msgid "Transfer added successfully"
msgstr ""
@@ -1724,7 +1759,7 @@ msgstr ""
#: apps/users/forms.py:54 apps/users/forms.py:67 apps/users/forms.py:89
#: templates/monthly_overview/pages/overview.html:153
#: templates/transactions/pages/transactions.html:35
#: templates/transactions/pages/transactions.html:28
msgid "Default"
msgstr ""
@@ -1804,10 +1839,6 @@ msgstr ""
msgid "A user with this email address already exists."
msgstr ""
#: apps/users/models.py:12 apps/users/models.py:497
msgid "Auto"
msgstr ""
#: apps/users/models.py:465 templates/includes/navbar.html:29
msgid "Yearly by currency"
msgstr ""
@@ -1829,6 +1860,7 @@ msgid "All Transactions"
msgstr ""
#: apps/users/models.py:470 templates/includes/navbar.html:33
#: templates/includes/sidebar.html:48
msgid "Calendar"
msgstr ""
@@ -1923,9 +1955,9 @@ msgstr ""
#: templates/accounts/fragments/list.html:48
#: templates/categories/fragments/table.html:36
#: templates/cotton/transaction/item.html:136
#: templates/cotton/transaction/item.html:178
#: templates/cotton/transaction/item.html:182
#: templates/cotton/ui/deleted_transactions_action_bar.html:55
#: templates/cotton/ui/transactions_action_bar.html:89
#: templates/cotton/ui/transactions_action_bar.html:90
#: templates/currencies/fragments/list.html:44
#: templates/dca/fragments/strategy/details.html:75
#: templates/dca/fragments/strategy/list.html:44
@@ -1950,9 +1982,9 @@ msgstr ""
#: templates/accounts/fragments/list.html:52
#: templates/categories/fragments/table.html:41
#: templates/cotton/transaction/item.html:140
#: templates/cotton/transaction/item.html:182
#: templates/cotton/transaction/item.html:186
#: templates/cotton/ui/deleted_transactions_action_bar.html:57
#: templates/cotton/ui/transactions_action_bar.html:91
#: templates/cotton/ui/transactions_action_bar.html:92
#: templates/currencies/fragments/list.html:48
#: templates/dca/fragments/strategy/details.html:80
#: templates/dca/fragments/strategy/list.html:48
@@ -1980,9 +2012,9 @@ msgstr ""
#: templates/accounts/fragments/list.html:53
#: templates/categories/fragments/table.html:42
#: templates/cotton/transaction/item.html:141
#: templates/cotton/transaction/item.html:183
#: templates/cotton/transaction/item.html:187
#: templates/cotton/ui/deleted_transactions_action_bar.html:58
#: templates/cotton/ui/transactions_action_bar.html:92
#: templates/cotton/ui/transactions_action_bar.html:93
#: templates/currencies/fragments/list.html:49
#: templates/dca/fragments/strategy/details.html:81
#: templates/dca/fragments/strategy/list.html:49
@@ -2002,7 +2034,7 @@ msgstr ""
#: templates/accounts/fragments/list.html:54
#: templates/categories/fragments/table.html:43
#: templates/cotton/transaction/item.html:142
#: templates/cotton/transaction/item.html:184
#: templates/cotton/transaction/item.html:188
#: templates/currencies/fragments/list.html:50
#: templates/dca/fragments/strategy/details.html:82
#: templates/dca/fragments/strategy/list.html:50
@@ -2141,7 +2173,7 @@ msgid "Muted"
msgstr ""
#: templates/categories/fragments/table.html:75
#: templates/insights/fragments/category_overview/index.html:430
#: templates/insights/fragments/category_overview/index.html:429
msgid "No categories"
msgstr ""
@@ -2150,6 +2182,7 @@ msgid "Pick a month"
msgstr ""
#: templates/common/fragments/toasts.html:15 templates/extends/offcanvas.html:5
#: templates/includes/sidebar.html:28
msgid "Close"
msgstr ""
@@ -2181,7 +2214,19 @@ msgid "Add as quick transaction"
msgstr ""
#: templates/cotton/transaction/item.html:166
#: templates/cotton/ui/transactions_action_bar.html:81
msgid "Move to previous month"
msgstr ""
#: templates/cotton/transaction/item.html:167
msgid "Move to next month"
msgstr ""
#: templates/cotton/transaction/item.html:168
msgid "Move to today"
msgstr ""
#: templates/cotton/transaction/item.html:170
#: templates/cotton/ui/transactions_action_bar.html:82
msgid "Duplicate"
msgstr ""
@@ -2231,7 +2276,7 @@ msgid "Unselect All"
msgstr ""
#: templates/cotton/ui/deleted_transactions_action_bar.html:59
#: templates/cotton/ui/transactions_action_bar.html:93
#: templates/cotton/ui/transactions_action_bar.html:94
msgid "Yes, delete them!"
msgstr ""
@@ -2242,49 +2287,49 @@ msgstr ""
#: templates/cotton/ui/deleted_transactions_action_bar.html:189
#: templates/cotton/ui/deleted_transactions_action_bar.html:209
#: templates/cotton/ui/deleted_transactions_action_bar.html:229
#: templates/cotton/ui/transactions_action_bar.html:139
#: templates/cotton/ui/transactions_action_bar.html:163
#: templates/cotton/ui/transactions_action_bar.html:183
#: templates/cotton/ui/transactions_action_bar.html:203
#: templates/cotton/ui/transactions_action_bar.html:223
#: templates/cotton/ui/transactions_action_bar.html:243
#: templates/cotton/ui/transactions_action_bar.html:263
#: templates/cotton/ui/transactions_action_bar.html:140
#: templates/cotton/ui/transactions_action_bar.html:165
#: templates/cotton/ui/transactions_action_bar.html:185
#: templates/cotton/ui/transactions_action_bar.html:205
#: templates/cotton/ui/transactions_action_bar.html:225
#: templates/cotton/ui/transactions_action_bar.html:245
#: templates/cotton/ui/transactions_action_bar.html:265
msgid "copied!"
msgstr ""
#: templates/cotton/ui/deleted_transactions_action_bar.html:114
#: templates/cotton/ui/transactions_action_bar.html:57
#: templates/cotton/ui/transactions_action_bar.html:148
#: templates/cotton/ui/transactions_action_bar.html:58
#: templates/cotton/ui/transactions_action_bar.html:150
msgid "Toggle Dropdown"
msgstr ""
#: templates/cotton/ui/deleted_transactions_action_bar.html:122
#: templates/cotton/ui/transactions_action_bar.html:156
#: templates/cotton/ui/transactions_action_bar.html:158
msgid "Flat Total"
msgstr ""
#: templates/cotton/ui/deleted_transactions_action_bar.html:142
#: templates/cotton/ui/transactions_action_bar.html:176
#: templates/cotton/ui/transactions_action_bar.html:178
msgid "Real Total"
msgstr ""
#: templates/cotton/ui/deleted_transactions_action_bar.html:162
#: templates/cotton/ui/transactions_action_bar.html:196
#: templates/cotton/ui/transactions_action_bar.html:198
msgid "Mean"
msgstr ""
#: templates/cotton/ui/deleted_transactions_action_bar.html:182
#: templates/cotton/ui/transactions_action_bar.html:216
#: templates/cotton/ui/transactions_action_bar.html:218
msgid "Max"
msgstr ""
#: templates/cotton/ui/deleted_transactions_action_bar.html:202
#: templates/cotton/ui/transactions_action_bar.html:236
#: templates/cotton/ui/transactions_action_bar.html:238
msgid "Min"
msgstr ""
#: templates/cotton/ui/deleted_transactions_action_bar.html:222
#: templates/cotton/ui/transactions_action_bar.html:256
#: templates/cotton/ui/transactions_action_bar.html:258
msgid "Count"
msgstr ""
@@ -2303,11 +2348,11 @@ msgstr ""
msgid "Balance"
msgstr ""
#: templates/cotton/ui/transactions_action_bar.html:65
#: templates/cotton/ui/transactions_action_bar.html:66
msgid "Mark as unpaid"
msgstr ""
#: templates/cotton/ui/transactions_action_bar.html:72
#: templates/cotton/ui/transactions_action_bar.html:73
msgid "Mark as paid"
msgstr ""
@@ -2463,10 +2508,10 @@ msgid "Edit exchange rate"
msgstr ""
#: templates/exchange_rates/fragments/list.html:25
#: templates/includes/navbar.html:62
#: templates/includes/navbar.html:62 templates/includes/sidebar.html:68
#: templates/installment_plans/fragments/list.html:21
#: templates/yearly_overview/pages/overview_by_account.html:94
#: templates/yearly_overview/pages/overview_by_currency.html:96
#: templates/yearly_overview/pages/overview_by_account.html:105
#: templates/yearly_overview/pages/overview_by_currency.html:107
msgid "All"
msgstr ""
@@ -2520,6 +2565,7 @@ msgid "No services configured"
msgstr ""
#: templates/export_app/pages/index.html:4 templates/includes/navbar.html:140
#: templates/includes/sidebar.html:223
msgid "Export and Restore"
msgstr ""
@@ -2607,7 +2653,7 @@ msgstr ""
msgid "Logs for"
msgstr ""
#: templates/includes/navbar.html:12
#: templates/includes/mobile_navbar.html:12 templates/includes/navbar.html:12
msgid "Toggle navigation"
msgstr ""
@@ -2615,88 +2661,88 @@ msgstr ""
msgid "Overview"
msgstr ""
#: templates/includes/navbar.html:41
#: templates/includes/navbar.html:41 templates/includes/sidebar.html:60
msgid "Net Worth"
msgstr ""
#: templates/includes/navbar.html:45
#: templates/insights/fragments/category_overview/index.html:50
#: templates/net_worth/net_worth.html:22
msgid "Current"
msgstr ""
#: templates/includes/navbar.html:51 templates/insights/pages/index.html:5
#: templates/includes/navbar.html:51 templates/includes/sidebar.html:54
#: templates/insights/pages/index.html:5
msgid "Insights"
msgstr ""
#: templates/includes/navbar.html:67
#: templates/includes/navbar.html:67 templates/includes/sidebar.html:76
msgid "Trash Can"
msgstr ""
#: templates/includes/navbar.html:85
#: templates/includes/navbar.html:85 templates/includes/sidebar.html:101
msgid "Tools"
msgstr ""
#: templates/includes/navbar.html:89
#: templates/includes/navbar.html:89 templates/includes/sidebar.html:103
msgid "Dollar Cost Average Tracker"
msgstr ""
#: templates/includes/navbar.html:92
#: templates/includes/navbar.html:92 templates/includes/sidebar.html:109
#: templates/mini_tools/unit_price_calculator.html:5
#: templates/mini_tools/unit_price_calculator.html:10
msgid "Unit Price Calculator"
msgstr ""
#: templates/includes/navbar.html:95
#: templates/includes/navbar.html:95 templates/includes/sidebar.html:115
#: templates/mini_tools/currency_converter/currency_converter.html:8
#: templates/mini_tools/currency_converter/currency_converter.html:15
msgid "Currency Converter"
msgstr ""
#: templates/includes/navbar.html:104
#: templates/includes/navbar.html:104 templates/includes/sidebar.html:134
#: templates/includes/sidebar.html:147
msgid "Management"
msgstr ""
#: templates/includes/navbar.html:133
#: templates/includes/navbar.html:133 templates/includes/sidebar.html:208
msgid "Automation"
msgstr ""
#: templates/includes/navbar.html:148
#: templates/includes/navbar.html:148 templates/includes/sidebar.html:237
msgid "Admin"
msgstr ""
#: templates/includes/navbar.html:157
#: templates/includes/navbar.html:157 templates/includes/sidebar.html:246
msgid "Only use this if you know what you're doing"
msgstr ""
#: templates/includes/navbar.html:158
#: templates/includes/navbar.html:158 templates/includes/sidebar.html:245
msgid "Django Admin"
msgstr ""
#: templates/includes/navbar.html:169
#: templates/includes/navbar.html:169 templates/includes/sidebar.html:260
msgid "is available"
msgstr ""
#: templates/includes/navbar.html:174 templates/includes/navbar.html:177
#: templates/includes/sidebar.html:266
msgid "Calculator"
msgstr ""
#: templates/includes/navbar/user_menu.html:6
msgid "Profile"
msgstr ""
#: templates/includes/navbar/user_menu.html:15
#: templates/includes/navbar/user_menu.html:12
msgid "Settings"
msgstr ""
#: templates/includes/navbar/user_menu.html:20
#: templates/includes/navbar/user_menu.html:17
msgid "Edit profile"
msgstr ""
#: templates/includes/navbar/user_menu.html:47
#: templates/includes/navbar/user_menu.html:44
msgid "Clear cache"
msgstr ""
#: templates/includes/navbar/user_menu.html:51
#: templates/includes/navbar/user_menu.html:48
msgid "Logout"
msgstr ""
@@ -2773,7 +2819,7 @@ msgstr ""
msgid "Untagged"
msgstr ""
#: templates/insights/fragments/category_overview/index.html:407
#: templates/insights/fragments/category_overview/index.html:406
msgid "Final Total"
msgstr ""
@@ -2826,8 +2872,8 @@ msgid "Month"
msgstr ""
#: templates/insights/pages/index.html:40
#: templates/yearly_overview/pages/overview_by_account.html:62
#: templates/yearly_overview/pages/overview_by_currency.html:64
#: templates/yearly_overview/pages/overview_by_account.html:73
#: templates/yearly_overview/pages/overview_by_currency.html:75
msgid "Year"
msgstr ""
@@ -2906,11 +2952,11 @@ msgstr ""
msgid "No installment plans"
msgstr ""
#: templates/layouts/base.html:40
#: templates/layouts/base.html:43
msgid "This is a demo!"
msgstr ""
#: templates/layouts/base.html:40
#: templates/layouts/base.html:43
msgid "Any data you add here will be wiped in 24hrs or less"
msgstr ""
@@ -2979,43 +3025,44 @@ msgid "Summary"
msgstr ""
#: templates/monthly_overview/pages/overview.html:142
#: templates/transactions/pages/transactions.html:17
msgid "Filter transactions"
msgstr ""
#: templates/monthly_overview/pages/overview.html:148
#: templates/transactions/pages/transactions.html:33
#: templates/transactions/pages/transactions.html:23
msgid "Order by"
msgstr ""
#: templates/monthly_overview/pages/overview.html:155
#: templates/transactions/pages/transactions.html:36
#: templates/transactions/pages/transactions.html:30
msgid "Oldest first"
msgstr ""
#: templates/monthly_overview/pages/overview.html:157
#: templates/transactions/pages/transactions.html:37
#: templates/transactions/pages/transactions.html:32
msgid "Newest first"
msgstr ""
#: templates/net_worth/net_worth.html:18
#: templates/net_worth/net_worth.html:40
#: templates/yearly_overview/pages/overview_by_currency.html:9
msgid "By currency"
msgstr ""
#: templates/net_worth/net_worth.html:53
#: templates/net_worth/net_worth.html:75
msgid "Consolidated"
msgstr ""
#: templates/net_worth/net_worth.html:82
#: templates/net_worth/net_worth.html:104
#: templates/yearly_overview/pages/overview_by_account.html:7
msgid "By account"
msgstr ""
#: templates/net_worth/net_worth.html:189
#: templates/net_worth/net_worth.html:211
msgid "Evolution by currency"
msgstr ""
#: templates/net_worth/net_worth.html:253
#: templates/net_worth/net_worth.html:275
msgid "Evolution by account"
msgstr ""

File diff suppressed because it is too large Load Diff

View File

@@ -71,6 +71,17 @@
hx-get="{% url 'account_share_settings' pk=account.id %}">
<i class="fa-solid fa-share fa-fw"></i></a>
{% endif %}
<a class="btn btn-secondary btn-sm"
role="button"
hx-get="{% url 'account_toggle_untracked' pk=account.id %}"
data-bs-toggle="tooltip"
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>
</td>
<td class="col">{{ account.name }}</td>

View File

@@ -33,7 +33,7 @@
</div>
{% endif %}
</div>
<div class="col-lg col-12 {% if 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.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"
@@ -121,7 +121,7 @@
{# Item actions#}
<div
class="transaction-actions tw:absolute! tw:left-1/2 tw:top-0 tw:-translate-x-1/2 tw:-translate-y-1/2 tw:invisible tw:group-hover/transaction:visible d-flex flex-row card">
<div class="card-body p-1 shadow-lg">
<div class="card-body p-1 shadow-lg d-flex flex-row gap-1">
{% if not transaction.deleted %}
<a class="btn btn-secondary btn-sm transaction-action"
role="button"
@@ -145,17 +145,27 @@
<button class="btn btn-secondary btn-sm transaction-action" type="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="fa-solid fa-ellipsis fa-fw"></i>
</button>
<ul class="dropdown-menu">
{% if transaction.category.mute %}
<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>
<div>
{% translate 'Show on summaries' %}
<div class="d-block text-body-secondary tw:text-xs tw:font-medium">{% translate 'Controlled by category' %}</div>
</div>
</a>
</li>
<ul class="dropdown-menu dropdown-menu-end dropdown-menu-md-start">
{% 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>
<div>
{% translate 'Show on summaries' %}
<div class="d-block text-body-secondary tw:text-xs tw:font-medium">{% translate 'Controlled by account' %}</div>
</div>
</a>
</li>
{% elif transaction.category.mute %}
<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>
<div>
{% translate 'Show on summaries' %}
<div class="d-block text-body-secondary tw:text-xs tw:font-medium">{% translate 'Controlled by category' %}</div>
</div>
</a>
</li>
{% elif transaction.mute %}
<li><a class="dropdown-item" href="#" hx-get="{% url 'transaction_mute' transaction_id=transaction.id %}" hx-target="closest .transaction" hx-swap="outerHTML"><i class="fa-solid fa-eye fa-fw me-2"></i>{% translate 'Show on summaries' %}</a></li>
{% else %}
@@ -163,6 +173,10 @@
{% endif %}
<li><a class="dropdown-item" href="#" hx-get="{% url 'quick_transaction_add_as_quick_transaction' transaction_id=transaction.id %}"><i class="fa-solid fa-person-running fa-fw me-2"></i>{% translate 'Add as quick transaction' %}</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#" hx-get="{% url 'transaction_change_month' transaction_id=transaction.id change_type='previous' %}"><i class="fa-solid fa-calendar-minus fa-fw me-2"></i>{% translate 'Move to previous month' %}</a></li>
<li><a class="dropdown-item" href="#" hx-get="{% url 'transaction_change_month' transaction_id=transaction.id change_type='next' %}"><i class="fa-solid fa-calendar-plus fa-fw me-2"></i>{% translate 'Move to next month' %}</a></li>
<li><a class="dropdown-item" href="#" hx-get="{% url 'transaction_move_to_today' transaction_id=transaction.id %}"><i class="fa-solid fa-calendar-day fa-fw me-2"></i>{% translate 'Move to today' %}</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#" hx-get="{% url 'transaction_clone' transaction_id=transaction.id %}"><i class="fa-solid fa-clone fa-fw me-2"></i>{% translate 'Duplicate' %}</a></li>
</ul>
{% else %}

View File

@@ -138,8 +138,8 @@
<div class="mt-auto p-2 w-100">
<div id="collapsible-panel"
class="p-0 collapse tw:absolute tw:bottom-0 tw:left-0 tw:w-full tw:z-30 tw:group-hover:lg:overflow-y-auto tw:lg:overflow-y-hidden tw:max-h-screen">
<div class="tw:h-screen tw:backdrop-blur-3xl">
class="p-0 collapse tw:absolute tw:bottom-0 tw:left-0 tw:w-full tw:z-30 tw:group-hover:lg:overflow-y-auto tw:lg:overflow-y-hidden tw:max-h-dvh">
<div class="tw:h-dvh tw:backdrop-blur-3xl">
<!-- Header -->
<div
class="tw:flex tw:justify-between tw:items-center tw:p-4 tw:border-b tw:border-gray-600 tw:lg:hidden tw:lg:group-hover:flex">

View File

@@ -85,3 +85,7 @@ select[multiple] {
[data-bs-toggle="collapse"][aria-expanded="true"] .fa-chevron-down {
transform: rotate(-180deg);
}
div:where(.swal2-container) {
z-index: 1100 !important;
}