mirror of
https://github.com/eitchtee/WYGIWYH.git
synced 2026-02-25 08:54:52 +01:00
Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b62122ed23 | ||
|
|
f74946cba7 | ||
|
|
585652064a | ||
|
|
ea6f61d5e4 | ||
|
|
e986f7d802 | ||
|
|
26b218ae51 | ||
|
|
19f0bc1034 | ||
|
|
47d34f3c27 | ||
|
|
046e02d506 | ||
|
|
92c7a29b6a | ||
|
|
d95e5f71cc | ||
|
|
992c518dab | ||
|
|
29aa1c9d2b | ||
|
|
1b3b7a583d | ||
|
|
2d22f961ad | ||
|
|
71551d7651 | ||
|
|
62d58d1be3 | ||
|
|
21917437f2 | ||
|
|
59acb14d05 | ||
|
|
050f794f2b | ||
|
|
a5958c0937 | ||
|
|
ee73ada5ae | ||
|
|
736a116685 | ||
|
|
6c03c7b4eb | ||
|
|
960e537709 | ||
|
|
e32285ce75 | ||
|
|
73e8fdbf04 | ||
|
|
d4c15da051 | ||
|
|
187b3174d2 | ||
|
|
c90ea7ef16 | ||
|
|
54713ecfe2 | ||
|
|
cf693aa0c3 | ||
|
|
3580f1b132 | ||
|
|
febd9a8ae7 | ||
|
|
3809f82b60 | ||
|
|
3c6b52462a |
@@ -10,6 +10,11 @@ SECRET_KEY=<GENERATE A SAFE SECRET KEY AND PLACE IT HERE>
|
||||
DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]
|
||||
OUTBOUND_PORT=9005
|
||||
|
||||
# Uncomment these variables to automatically create an admin account using these credentials on startup.
|
||||
# After your first successfull login you can remove these variables from your file for safety reasons.
|
||||
#ADMIN_EMAIL=<ENTER YOUR EMAIL>
|
||||
#ADMIN_PASSWORD=<YOUR SAFE PASSWORD>
|
||||
|
||||
SQL_DATABASE=wygiwyh
|
||||
SQL_USER=wygiwyh
|
||||
SQL_PASSWORD=<INSERT A SAFE PASSWORD HERE>
|
||||
|
||||
@@ -76,7 +76,7 @@ $ nano .env # or any other editor you want to use
|
||||
# Run the app
|
||||
$ docker compose up -d
|
||||
|
||||
# Create the first admin account
|
||||
# Create the first admin account. This isn't required if you set the enviroment variables: ADMIN_EMAIL and ADMIN_PASSWORD.
|
||||
$ docker compose exec -it web python manage.py createsuperuser
|
||||
```
|
||||
|
||||
@@ -117,7 +117,7 @@ To create the first user, open the container's console using Unraid's UI, by cli
|
||||
|-------------------------------|-------------|-----------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| DJANGO_ALLOWED_HOSTS | string | localhost 127.0.0.1 | A list of space separated domains and IPs representing the host/domain names that WYGIWYH site can serve. [Click here](https://docs.djangoproject.com/en/5.1/ref/settings/#allowed-hosts) for more details |
|
||||
| HTTPS_ENABLED | true\|false | false | Whether to use secure cookies. If this is set to true, the cookie will be marked as “secure”, which means browsers may ensure that the cookie is only sent under an HTTPS connection |
|
||||
| URL | string | http://localhost http://127.0.0.1 | A list of space separated domains and IPs (with the protocol) representing the trusted origins for unsafe requests (e.g. POST). [Click here](https://docs.djangoproject.com/en/5.1/ref/settings/#csrf-trusted-origins ) for more details |
|
||||
| URL | string | http://localhost http://127.0.0.1 | A list of space separated domains and IPs (with the protocol) representing the trusted origins for unsafe requests (e.g. POST). [Click here](https://docs.djangoproject.com/en/5.1/ref/settings/#csrf-trusted-origins ) for more details |
|
||||
| SECRET_KEY | string | "" | This is used to provide cryptographic signing, and should be set to a unique, unpredictable value. |
|
||||
| DEBUG | true\|false | false | Turns DEBUG mode on or off, this is useful to gather more data about possible errors you're having. Don't use in production. |
|
||||
| SQL_DATABASE | string | None *required | The name of your postgres database |
|
||||
@@ -129,6 +129,9 @@ 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. |
|
||||
|
||||
# How it works
|
||||
|
||||
|
||||
@@ -261,7 +261,10 @@ if DEBUG:
|
||||
REST_FRAMEWORK = {
|
||||
# Use Django's standard `django.contrib.auth` permissions,
|
||||
# or allow read-only access for unauthenticated users.
|
||||
"DEFAULT_PERMISSION_CLASSES": ["rest_framework.permissions.DjangoModelPermissions"],
|
||||
"DEFAULT_PERMISSION_CLASSES": [
|
||||
"apps.api.permissions.NotInDemoMode",
|
||||
"rest_framework.permissions.DjangoModelPermissions",
|
||||
],
|
||||
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
|
||||
"PAGE_SIZE": 10,
|
||||
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
|
||||
@@ -394,3 +397,4 @@ PWA_SERVICE_WORKER_PATH = BASE_DIR / "templates" / "pwa" / "serviceworker.js"
|
||||
ENABLE_SOFT_DELETE = os.getenv("ENABLE_SOFT_DELETE", "false").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"
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# Generated by Django 5.1.7 on 2025-03-09 21:54
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('accounts', '0013_alter_account_visibility_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='account',
|
||||
options={'ordering': ['name', 'id'], 'verbose_name': 'Account', 'verbose_name_plural': 'Accounts'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='accountgroup',
|
||||
options={'ordering': ['name', 'id'], 'verbose_name': 'Account Group', 'verbose_name_plural': 'Account Groups'},
|
||||
),
|
||||
]
|
||||
@@ -19,6 +19,7 @@ class AccountGroup(SharedObject):
|
||||
verbose_name_plural = _("Account Groups")
|
||||
db_table = "account_groups"
|
||||
unique_together = (("owner", "name"),)
|
||||
ordering = ["name", "id"]
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
@@ -69,6 +70,7 @@ class Account(SharedObject):
|
||||
verbose_name = _("Account")
|
||||
verbose_name_plural = _("Accounts")
|
||||
unique_together = (("owner", "name"),)
|
||||
ordering = ["name", "id"]
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
10
app/apps/api/permissions.py
Normal file
10
app/apps/api/permissions.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from rest_framework.permissions import BasePermission
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
class NotInDemoMode(BasePermission):
|
||||
def has_permission(self, request, view):
|
||||
if settings.DEMO and not request.user.is_superuser:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
15
app/apps/common/decorators/demo.py
Normal file
15
app/apps/common/decorators/demo.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from functools import wraps
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import PermissionDenied
|
||||
|
||||
|
||||
def disabled_on_demo(view):
|
||||
@wraps(view)
|
||||
def _view(request, *args, **kwargs):
|
||||
if settings.DEMO and not request.user.is_superuser:
|
||||
raise PermissionDenied
|
||||
|
||||
return view(request, *args, **kwargs)
|
||||
|
||||
return _view
|
||||
0
app/apps/common/management/__init__.py
Normal file
0
app/apps/common/management/__init__.py
Normal file
0
app/apps/common/management/commands/__init__.py
Normal file
0
app/apps/common/management/commands/__init__.py
Normal file
137
app/apps/common/management/commands/setup_users.py
Normal file
137
app/apps/common/management/commands/setup_users.py
Normal file
@@ -0,0 +1,137 @@
|
||||
import os
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.conf import settings
|
||||
from django.db import IntegrityError
|
||||
|
||||
# Get the custom User model if defined, otherwise the default User model
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = (
|
||||
"Creates a superuser from environment variables (ADMIN_EMAIL, ADMIN_PASSWORD) "
|
||||
"and optionally creates a demo user (demo@demo.com) if settings.DEMO is True."
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
self.stdout.write("Starting user setup...")
|
||||
|
||||
# --- Create Superuser ---
|
||||
admin_email = os.environ.get("ADMIN_EMAIL")
|
||||
admin_password = os.environ.get("ADMIN_PASSWORD")
|
||||
|
||||
if admin_email and admin_password:
|
||||
self.stdout.write(f"Attempting to create superuser: {admin_email}")
|
||||
# Use email as username for simplicity, requires USERNAME_FIELD='email'
|
||||
# or adapt if your USERNAME_FIELD is different.
|
||||
# If USERNAME_FIELD is 'username', you might need ADMIN_USERNAME env var.
|
||||
username_field = User.USERNAME_FIELD # Get the actual username field name
|
||||
|
||||
# Check if the user already exists by email or username
|
||||
user_exists_kwargs = {"email": admin_email}
|
||||
if username_field != "email":
|
||||
# Assume username should also be the email if not explicitly provided
|
||||
user_exists_kwargs[username_field] = admin_email
|
||||
|
||||
if User.objects.filter(**user_exists_kwargs).exists():
|
||||
self.stdout.write(
|
||||
self.style.WARNING(
|
||||
f"Superuser with email '{admin_email}' (or corresponding username) already exists. Skipping creation."
|
||||
)
|
||||
)
|
||||
else:
|
||||
try:
|
||||
create_kwargs = {
|
||||
username_field: admin_email, # Use email as username by default
|
||||
"email": admin_email,
|
||||
"password": admin_password,
|
||||
}
|
||||
User.objects.create_superuser(**create_kwargs)
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(
|
||||
f"Superuser '{admin_email}' created successfully."
|
||||
)
|
||||
)
|
||||
except IntegrityError as e:
|
||||
self.stdout.write(
|
||||
self.style.ERROR(
|
||||
f"Failed to create superuser '{admin_email}'. IntegrityError: {e}"
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
self.stdout.write(
|
||||
self.style.ERROR(
|
||||
f"An unexpected error occurred creating superuser '{admin_email}': {e}"
|
||||
)
|
||||
)
|
||||
else:
|
||||
self.stdout.write(
|
||||
self.style.NOTICE(
|
||||
"ADMIN_EMAIL or ADMIN_PASSWORD environment variables not set. Skipping superuser creation."
|
||||
)
|
||||
)
|
||||
|
||||
self.stdout.write("---") # Separator
|
||||
|
||||
# --- Create Demo User ---
|
||||
# Use getattr to safely check for the DEMO setting, default to False if not present
|
||||
create_demo_user = getattr(settings, "DEMO", False)
|
||||
|
||||
if create_demo_user:
|
||||
demo_email = "demo@demo.com"
|
||||
demo_password = (
|
||||
"wygiwyhdemo" # Consider making this an env var too for security
|
||||
)
|
||||
demo_username = demo_email # Using email as username for consistency
|
||||
|
||||
self.stdout.write(
|
||||
f"DEMO setting is True. Attempting to create demo user: {demo_email}"
|
||||
)
|
||||
|
||||
username_field = User.USERNAME_FIELD # Get the actual username field name
|
||||
|
||||
# Check if the user already exists by email or username
|
||||
user_exists_kwargs = {"email": demo_email}
|
||||
if username_field != "email":
|
||||
user_exists_kwargs[username_field] = demo_username
|
||||
|
||||
if User.objects.filter(**user_exists_kwargs).exists():
|
||||
self.stdout.write(
|
||||
self.style.WARNING(
|
||||
f"Demo user with email '{demo_email}' (or corresponding username) already exists. Skipping creation."
|
||||
)
|
||||
)
|
||||
else:
|
||||
try:
|
||||
create_kwargs = {
|
||||
username_field: demo_username,
|
||||
"email": demo_email,
|
||||
"password": demo_password,
|
||||
}
|
||||
User.objects.create_user(**create_kwargs)
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(
|
||||
f"Demo user '{demo_email}' created successfully."
|
||||
)
|
||||
)
|
||||
except IntegrityError as e:
|
||||
self.stdout.write(
|
||||
self.style.ERROR(
|
||||
f"Failed to create demo user '{demo_email}'. IntegrityError: {e}"
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
self.stdout.write(
|
||||
self.style.ERROR(
|
||||
f"An unexpected error occurred creating demo user '{demo_email}': {e}"
|
||||
)
|
||||
)
|
||||
else:
|
||||
self.stdout.write(
|
||||
self.style.NOTICE(
|
||||
"DEMO setting is not True (or not set). Skipping demo user creation."
|
||||
)
|
||||
)
|
||||
|
||||
self.stdout.write(self.style.SUCCESS("User setup command finished."))
|
||||
@@ -1,7 +1,9 @@
|
||||
import logging
|
||||
|
||||
from asgiref.sync import sync_to_async
|
||||
from django.conf import settings
|
||||
from django.core import management
|
||||
from django.db import DEFAULT_DB_ALIAS
|
||||
|
||||
from procrastinate import builtin_tasks
|
||||
from procrastinate.contrib.django import app
|
||||
@@ -40,3 +42,39 @@ async def remove_expired_sessions(timestamp=None):
|
||||
"Error while executing 'remove_expired_sessions' task",
|
||||
exc_info=True,
|
||||
)
|
||||
|
||||
|
||||
@app.periodic(cron="0 6 * * *")
|
||||
@app.task(name="reset_demo_data")
|
||||
def reset_demo_data():
|
||||
"""
|
||||
Wipes the database and loads fresh demo data if DEMO mode is active.
|
||||
Runs daily at 6:00 AM.
|
||||
"""
|
||||
if not settings.DEMO:
|
||||
return # Exit if not in demo mode
|
||||
|
||||
logger.info("Demo mode active. Starting daily data reset...")
|
||||
|
||||
try:
|
||||
# 1. Flush the database (wipe all data)
|
||||
logger.info("Flushing the database...")
|
||||
# Using --noinput prevents prompts. Specify database if not default.
|
||||
management.call_command(
|
||||
"flush", "--noinput", database=DEFAULT_DB_ALIAS, verbosity=1
|
||||
)
|
||||
logger.info("Database flushed successfully.")
|
||||
|
||||
# 2. Load data from the fixture
|
||||
fixture_name = "fixtures/demo_data.json"
|
||||
logger.info(f"Loading data from fixture: {fixture_name}...")
|
||||
management.call_command(
|
||||
"loaddata", fixture_name, database=DEFAULT_DB_ALIAS, verbosity=1
|
||||
)
|
||||
logger.info(f"Data loaded successfully from {fixture_name}.")
|
||||
|
||||
logger.info("Daily demo data reset completed.")
|
||||
|
||||
except Exception as e:
|
||||
logger.exception(f"Error during daily demo data reset: {e}")
|
||||
raise
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# Generated by Django 5.1.7 on 2025-03-09 21:54
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('currencies', '0013_alter_exchangerateservice_service_type'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='currency',
|
||||
options={'ordering': ['name', 'id'], 'verbose_name': 'Currency', 'verbose_name_plural': 'Currencies'},
|
||||
),
|
||||
]
|
||||
@@ -38,6 +38,7 @@ class Currency(models.Model):
|
||||
class Meta:
|
||||
verbose_name = _("Currency")
|
||||
verbose_name_plural = _("Currencies")
|
||||
ordering = ["name", "id"]
|
||||
|
||||
def clean(self):
|
||||
super().clean()
|
||||
|
||||
@@ -11,9 +11,11 @@ from apps.common.decorators.htmx import only_htmx
|
||||
from apps.currencies.forms import ExchangeRateForm, ExchangeRateServiceForm
|
||||
from apps.currencies.models import ExchangeRate, ExchangeRateService
|
||||
from apps.currencies.tasks import manual_fetch_exchange_rates
|
||||
from apps.common.decorators.demo import disabled_on_demo
|
||||
|
||||
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET"])
|
||||
def exchange_rates_services_index(request):
|
||||
return render(
|
||||
@@ -24,6 +26,7 @@ def exchange_rates_services_index(request):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET"])
|
||||
def exchange_rates_services_list(request):
|
||||
services = ExchangeRateService.objects.all()
|
||||
@@ -37,6 +40,7 @@ def exchange_rates_services_list(request):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def exchange_rate_service_add(request):
|
||||
if request.method == "POST":
|
||||
@@ -63,6 +67,7 @@ def exchange_rate_service_add(request):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def exchange_rate_service_edit(request, pk):
|
||||
service = get_object_or_404(ExchangeRateService, id=pk)
|
||||
@@ -91,6 +96,7 @@ def exchange_rate_service_edit(request, pk):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["DELETE"])
|
||||
def exchange_rate_service_delete(request, pk):
|
||||
service = get_object_or_404(ExchangeRateService, id=pk)
|
||||
@@ -109,6 +115,7 @@ def exchange_rate_service_delete(request, pk):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET"])
|
||||
def exchange_rate_service_force_fetch(request):
|
||||
manual_fetch_exchange_rates.defer()
|
||||
|
||||
@@ -41,11 +41,13 @@ from apps.export_app.resources.transactions import (
|
||||
RecurringTransactionResource,
|
||||
)
|
||||
from apps.export_app.resources.users import UserResource
|
||||
from apps.common.decorators.demo import disabled_on_demo
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@user_passes_test(lambda u: u.is_superuser)
|
||||
@require_http_methods(["GET"])
|
||||
def export_index(request):
|
||||
@@ -53,6 +55,7 @@ def export_index(request):
|
||||
|
||||
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@user_passes_test(lambda u: u.is_superuser)
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def export_form(request):
|
||||
@@ -182,6 +185,7 @@ def export_form(request):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@user_passes_test(lambda u: u.is_superuser)
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def import_form(request):
|
||||
|
||||
@@ -13,9 +13,11 @@ from apps.import_app.forms import ImportRunFileUploadForm, ImportProfileForm
|
||||
from apps.import_app.models import ImportRun, ImportProfile
|
||||
from apps.import_app.services import PresetService
|
||||
from apps.import_app.tasks import process_import
|
||||
from apps.common.decorators.demo import disabled_on_demo
|
||||
|
||||
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET"])
|
||||
def import_presets_list(request):
|
||||
presets = PresetService.get_all_presets()
|
||||
@@ -27,6 +29,7 @@ def import_presets_list(request):
|
||||
|
||||
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def import_profile_index(request):
|
||||
return render(
|
||||
@@ -37,6 +40,7 @@ def import_profile_index(request):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def import_profile_list(request):
|
||||
profiles = ImportProfile.objects.all()
|
||||
@@ -50,6 +54,7 @@ def import_profile_list(request):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def import_profile_add(request):
|
||||
message = request.POST.get("message", None)
|
||||
@@ -85,6 +90,7 @@ def import_profile_add(request):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def import_profile_edit(request, profile_id):
|
||||
profile = get_object_or_404(ImportProfile, id=profile_id)
|
||||
@@ -114,6 +120,7 @@ def import_profile_edit(request, profile_id):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["DELETE"])
|
||||
def import_profile_delete(request, profile_id):
|
||||
profile = ImportProfile.objects.get(id=profile_id)
|
||||
@@ -132,6 +139,7 @@ def import_profile_delete(request, profile_id):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def import_runs_list(request, profile_id):
|
||||
profile = ImportProfile.objects.get(id=profile_id)
|
||||
@@ -147,6 +155,7 @@ def import_runs_list(request, profile_id):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def import_run_log(request, profile_id, run_id):
|
||||
run = ImportRun.objects.get(profile__id=profile_id, id=run_id)
|
||||
@@ -160,6 +169,7 @@ def import_run_log(request, profile_id, run_id):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def import_run_add(request, profile_id):
|
||||
profile = ImportProfile.objects.get(id=profile_id)
|
||||
@@ -202,6 +212,7 @@ def import_run_add(request, profile_id):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["DELETE"])
|
||||
def import_run_delete(request, profile_id, run_id):
|
||||
run = ImportRun.objects.get(profile__id=profile_id, id=run_id)
|
||||
|
||||
@@ -117,13 +117,15 @@ class CategoryForm(forms.Form):
|
||||
required=False,
|
||||
label=_("Category"),
|
||||
empty_label=_("Uncategorized"),
|
||||
queryset=TransactionCategory.objects.filter(active=True),
|
||||
queryset=TransactionCategory.objects.all(),
|
||||
widget=TomSelect(clear_button=True),
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.fields["category"].queryset = TransactionCategory.objects.all()
|
||||
|
||||
self.helper = FormHelper()
|
||||
self.helper.form_tag = False
|
||||
self.helper.disable_csrf = True
|
||||
|
||||
@@ -40,8 +40,8 @@ def get_currency_exchange_map(date=None) -> Dict[str, dict]:
|
||||
date_diff=Func(Extract(F("date") - Value(date), "epoch"), function="ABS"),
|
||||
effective_rate=F("rate"),
|
||||
)
|
||||
.order_by("from_currency", "to_currency", "date_diff")
|
||||
.distinct("from_currency", "to_currency")
|
||||
.order_by("from_currency", "to_currency", "-date_diff")
|
||||
.distinct()
|
||||
)
|
||||
|
||||
# Initialize the result dictionary
|
||||
|
||||
@@ -2,25 +2,38 @@ from collections import OrderedDict, defaultdict
|
||||
from decimal import Decimal
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from django.db.models import Sum, Min, Max, Case, When, F, Value, DecimalField
|
||||
from django.db.models import Sum, Min, Max, Case, When, F, Value, DecimalField, Q
|
||||
from django.db.models.functions import TruncMonth
|
||||
from django.template.defaultfilters import date as date_filter
|
||||
from django.utils import timezone
|
||||
|
||||
from apps.accounts.models import Account
|
||||
from apps.common.middleware.thread_local import get_current_user
|
||||
from apps.currencies.models import Currency
|
||||
from apps.transactions.models import Transaction
|
||||
|
||||
|
||||
def calculate_historical_currency_net_worth(is_paid=True):
|
||||
transactions_params = {**{k: v for k, v in [("is_paid", True)] if is_paid}}
|
||||
|
||||
def calculate_historical_currency_net_worth(queryset):
|
||||
# Get all currencies and date range in a single query
|
||||
aggregates = Transaction.objects.aggregate(
|
||||
aggregates = queryset.aggregate(
|
||||
min_date=Min("reference_date"),
|
||||
max_date=Max("reference_date"),
|
||||
)
|
||||
currencies = list(Currency.objects.values_list("name", flat=True))
|
||||
|
||||
user = get_current_user()
|
||||
|
||||
currencies = list(
|
||||
Currency.objects.filter(
|
||||
Q(accounts__visibility="public")
|
||||
| Q(accounts__owner=user)
|
||||
| Q(accounts__shared_with=user)
|
||||
| Q(accounts__visibility="private", accounts__owner=None),
|
||||
accounts__is_archived=False,
|
||||
accounts__isnull=False,
|
||||
)
|
||||
.values_list("name", flat=True)
|
||||
.distinct()
|
||||
)
|
||||
|
||||
if not aggregates.get("min_date"):
|
||||
start_date = timezone.localdate(timezone.now())
|
||||
@@ -34,8 +47,7 @@ def calculate_historical_currency_net_worth(is_paid=True):
|
||||
|
||||
# Calculate cumulative balances for each account, currency, and month
|
||||
cumulative_balances = (
|
||||
Transaction.objects.filter(**transactions_params)
|
||||
.annotate(month=TruncMonth("reference_date"))
|
||||
queryset.annotate(month=TruncMonth("reference_date"))
|
||||
.values("account__currency__name", "month")
|
||||
.annotate(
|
||||
balance=Sum(
|
||||
@@ -94,15 +106,14 @@ def calculate_historical_currency_net_worth(is_paid=True):
|
||||
return historical_net_worth
|
||||
|
||||
|
||||
def calculate_historical_account_balance(is_paid=True):
|
||||
transactions_params = {**{k: v for k, v in [("is_paid", True)] if is_paid}}
|
||||
def calculate_historical_account_balance(queryset):
|
||||
# Get all accounts
|
||||
accounts = Account.objects.filter(
|
||||
is_archived=False,
|
||||
)
|
||||
|
||||
# Get the date range
|
||||
date_range = Transaction.objects.filter(**transactions_params).aggregate(
|
||||
date_range = queryset.aggregate(
|
||||
min_date=Min("reference_date"), max_date=Max("reference_date")
|
||||
)
|
||||
|
||||
@@ -118,8 +129,7 @@ def calculate_historical_account_balance(is_paid=True):
|
||||
|
||||
# Calculate balances for each account and month
|
||||
balances = (
|
||||
Transaction.objects.filter(**transactions_params)
|
||||
.annotate(month=TruncMonth("reference_date"))
|
||||
queryset.annotate(month=TruncMonth("reference_date"))
|
||||
.values("account", "month")
|
||||
.annotate(
|
||||
balance=Sum(
|
||||
|
||||
@@ -38,7 +38,9 @@ def net_worth_current(request):
|
||||
transactions_queryset=transactions_account_queryset
|
||||
)
|
||||
|
||||
historical_currency_net_worth = calculate_historical_currency_net_worth()
|
||||
historical_currency_net_worth = calculate_historical_currency_net_worth(
|
||||
queryset=transactions_currency_queryset
|
||||
)
|
||||
|
||||
labels = (
|
||||
list(historical_currency_net_worth.keys())
|
||||
@@ -71,7 +73,9 @@ def net_worth_current(request):
|
||||
|
||||
chart_data_currency_json = json.dumps(chart_data_currency, cls=DjangoJSONEncoder)
|
||||
|
||||
historical_account_balance = calculate_historical_account_balance()
|
||||
historical_account_balance = calculate_historical_account_balance(
|
||||
queryset=transactions_account_queryset
|
||||
)
|
||||
|
||||
labels = (
|
||||
list(historical_account_balance.keys()) if historical_account_balance else []
|
||||
@@ -140,7 +144,7 @@ def net_worth_projected(request):
|
||||
)
|
||||
|
||||
historical_currency_net_worth = calculate_historical_currency_net_worth(
|
||||
is_paid=False
|
||||
queryset=transactions_currency_queryset
|
||||
)
|
||||
|
||||
labels = (
|
||||
@@ -174,7 +178,9 @@ def net_worth_projected(request):
|
||||
|
||||
chart_data_currency_json = json.dumps(chart_data_currency, cls=DjangoJSONEncoder)
|
||||
|
||||
historical_account_balance = calculate_historical_account_balance(is_paid=False)
|
||||
historical_account_balance = calculate_historical_account_balance(
|
||||
queryset=transactions_account_queryset
|
||||
)
|
||||
|
||||
labels = (
|
||||
list(historical_account_balance.keys()) if historical_account_balance else []
|
||||
|
||||
@@ -18,9 +18,11 @@ from apps.rules.models import (
|
||||
)
|
||||
from apps.common.models import SharedObject
|
||||
from apps.common.forms import SharedObjectForm
|
||||
from apps.common.decorators.demo import disabled_on_demo
|
||||
|
||||
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET"])
|
||||
def rules_index(request):
|
||||
return render(
|
||||
@@ -31,6 +33,7 @@ def rules_index(request):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET"])
|
||||
def rules_list(request):
|
||||
transaction_rules = TransactionRule.objects.all().order_by("id")
|
||||
@@ -43,6 +46,7 @@ def rules_list(request):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def transaction_rule_toggle_activity(request, transaction_rule_id, **kwargs):
|
||||
transaction_rule = get_object_or_404(TransactionRule, id=transaction_rule_id)
|
||||
@@ -65,6 +69,7 @@ def transaction_rule_toggle_activity(request, transaction_rule_id, **kwargs):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def transaction_rule_add(request, **kwargs):
|
||||
if request.method == "POST":
|
||||
@@ -91,6 +96,7 @@ def transaction_rule_add(request, **kwargs):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def transaction_rule_edit(request, transaction_rule_id):
|
||||
transaction_rule = get_object_or_404(TransactionRule, id=transaction_rule_id)
|
||||
@@ -129,6 +135,7 @@ def transaction_rule_edit(request, transaction_rule_id):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def transaction_rule_view(request, transaction_rule_id):
|
||||
transaction_rule = get_object_or_404(TransactionRule, id=transaction_rule_id)
|
||||
@@ -142,6 +149,7 @@ def transaction_rule_view(request, transaction_rule_id):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["DELETE"])
|
||||
def transaction_rule_delete(request, transaction_rule_id):
|
||||
transaction_rule = get_object_or_404(TransactionRule, id=transaction_rule_id)
|
||||
@@ -166,6 +174,7 @@ def transaction_rule_delete(request, transaction_rule_id):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET"])
|
||||
def transaction_rule_take_ownership(request, transaction_rule_id):
|
||||
transaction_rule = get_object_or_404(TransactionRule, id=transaction_rule_id)
|
||||
@@ -187,6 +196,7 @@ def transaction_rule_take_ownership(request, transaction_rule_id):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def transaction_rule_share(request, pk):
|
||||
obj = get_object_or_404(TransactionRule, id=pk)
|
||||
@@ -225,6 +235,7 @@ def transaction_rule_share(request, pk):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def transaction_rule_action_add(request, transaction_rule_id):
|
||||
transaction_rule = get_object_or_404(TransactionRule, id=transaction_rule_id)
|
||||
@@ -252,6 +263,7 @@ def transaction_rule_action_add(request, transaction_rule_id):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def transaction_rule_action_edit(request, transaction_rule_action_id):
|
||||
transaction_rule_action = get_object_or_404(
|
||||
@@ -289,6 +301,7 @@ def transaction_rule_action_edit(request, transaction_rule_action_id):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["DELETE"])
|
||||
def transaction_rule_action_delete(request, transaction_rule_action_id):
|
||||
transaction_rule_action = get_object_or_404(
|
||||
@@ -309,6 +322,7 @@ def transaction_rule_action_delete(request, transaction_rule_action_id):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def update_or_create_transaction_rule_action_add(request, transaction_rule_id):
|
||||
transaction_rule = get_object_or_404(TransactionRule, id=transaction_rule_id)
|
||||
@@ -340,6 +354,7 @@ def update_or_create_transaction_rule_action_add(request, transaction_rule_id):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def update_or_create_transaction_rule_action_edit(request, pk):
|
||||
linked_action = get_object_or_404(UpdateOrCreateTransactionRuleAction, id=pk)
|
||||
@@ -374,6 +389,7 @@ def update_or_create_transaction_rule_action_edit(request, pk):
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@disabled_on_demo
|
||||
@require_http_methods(["DELETE"])
|
||||
def update_or_create_transaction_rule_action_delete(request, pk):
|
||||
linked_action = get_object_or_404(UpdateOrCreateTransactionRuleAction, id=pk)
|
||||
|
||||
@@ -334,7 +334,9 @@ class TransferForm(forms.Form):
|
||||
widget=AirMonthYearPickerInput(), label=_("Reference Date"), required=False
|
||||
)
|
||||
|
||||
description = forms.CharField(max_length=500, label=_("Description"))
|
||||
description = forms.CharField(
|
||||
max_length=500, label=_("Description"), required=False
|
||||
)
|
||||
notes = forms.CharField(
|
||||
required=False,
|
||||
widget=forms.Textarea(
|
||||
@@ -538,6 +540,8 @@ class InstallmentPlanForm(forms.ModelForm):
|
||||
"notes",
|
||||
"installment_start",
|
||||
"entities",
|
||||
"add_description_to_transaction",
|
||||
"add_notes_to_transaction",
|
||||
]
|
||||
widgets = {
|
||||
"account": TomSelect(),
|
||||
@@ -593,7 +597,9 @@ class InstallmentPlanForm(forms.ModelForm):
|
||||
css_class="form-row",
|
||||
),
|
||||
"description",
|
||||
Switch("add_description_to_transaction"),
|
||||
"notes",
|
||||
Switch("add_notes_to_transaction"),
|
||||
Row(
|
||||
Column("number_of_installments", css_class="form-group col-md-6 mb-0"),
|
||||
Column("installment_start", css_class="form-group col-md-6 mb-0"),
|
||||
@@ -782,6 +788,7 @@ class RecurringTransactionForm(forms.ModelForm):
|
||||
"type",
|
||||
"amount",
|
||||
"description",
|
||||
"add_description_to_transaction",
|
||||
"category",
|
||||
"tags",
|
||||
"start_date",
|
||||
@@ -790,6 +797,7 @@ class RecurringTransactionForm(forms.ModelForm):
|
||||
"recurrence_type",
|
||||
"recurrence_interval",
|
||||
"notes",
|
||||
"add_notes_to_transaction",
|
||||
"entities",
|
||||
]
|
||||
widgets = {
|
||||
@@ -850,6 +858,7 @@ class RecurringTransactionForm(forms.ModelForm):
|
||||
css_class="form-row",
|
||||
),
|
||||
"description",
|
||||
Switch("add_description_to_transaction"),
|
||||
"amount",
|
||||
Row(
|
||||
Column("category", css_class="form-group col-md-6 mb-0"),
|
||||
@@ -857,6 +866,7 @@ class RecurringTransactionForm(forms.ModelForm):
|
||||
css_class="form-row",
|
||||
),
|
||||
"notes",
|
||||
Switch("add_notes_to_transaction"),
|
||||
Row(
|
||||
Column("start_date", css_class="form-group col-md-6 mb-0"),
|
||||
Column("reference_date", css_class="form-group col-md-6 mb-0"),
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
# Generated by Django 5.1.7 on 2025-03-09 20:22
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('transactions', '0040_alter_transaction_unique_together_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='installmentplan',
|
||||
name='add_description_to_transaction',
|
||||
field=models.BooleanField(default=True, verbose_name='Add description to transactions'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='installmentplan',
|
||||
name='add_notes_to_transaction',
|
||||
field=models.BooleanField(default=True, verbose_name='Add notes to transactions'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='recurringtransaction',
|
||||
name='add_description_to_transaction',
|
||||
field=models.BooleanField(default=True, verbose_name='Add description to transactions'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='recurringtransaction',
|
||||
name='add_notes_to_transaction',
|
||||
field=models.BooleanField(default=True, verbose_name='Add notes to transactions'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,25 @@
|
||||
# Generated by Django 5.1.7 on 2025-03-09 21:54
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('transactions', '0041_installmentplan_add_description_to_transaction_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='transactioncategory',
|
||||
options={'ordering': ['name', 'id'], 'verbose_name': 'Transaction Category', 'verbose_name_plural': 'Transaction Categories'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='transactionentity',
|
||||
options={'ordering': ['name', 'id'], 'verbose_name': 'Entity', 'verbose_name_plural': 'Entities'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='transactiontag',
|
||||
options={'ordering': ['name', 'id'], 'verbose_name': 'Transaction Tags', 'verbose_name_plural': 'Transaction Tags'},
|
||||
),
|
||||
]
|
||||
@@ -213,6 +213,7 @@ class TransactionCategory(SharedObject):
|
||||
verbose_name_plural = _("Transaction Categories")
|
||||
db_table = "t_categories"
|
||||
unique_together = (("owner", "name"),)
|
||||
ordering = ["name", "id"]
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
@@ -236,6 +237,7 @@ class TransactionTag(SharedObject):
|
||||
verbose_name_plural = _("Transaction Tags")
|
||||
db_table = "tags"
|
||||
unique_together = (("owner", "name"),)
|
||||
ordering = ["name", "id"]
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
@@ -259,6 +261,7 @@ class TransactionEntity(SharedObject):
|
||||
verbose_name_plural = _("Entities")
|
||||
db_table = "entities"
|
||||
unique_together = (("owner", "name"),)
|
||||
ordering = ["name", "id"]
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
@@ -493,6 +496,13 @@ class InstallmentPlan(models.Model):
|
||||
|
||||
notes = models.TextField(blank=True, verbose_name=_("Notes"))
|
||||
|
||||
add_description_to_transaction = models.BooleanField(
|
||||
default=True, verbose_name=_("Add description to transactions")
|
||||
)
|
||||
add_notes_to_transaction = models.BooleanField(
|
||||
default=True, verbose_name=_("Add notes to transactions")
|
||||
)
|
||||
|
||||
all_objects = models.Manager() # Unfiltered manager
|
||||
objects = GenericAccountOwnerManager() # Default filtered manager
|
||||
|
||||
@@ -557,11 +567,13 @@ class InstallmentPlan(models.Model):
|
||||
is_paid=False,
|
||||
reference_date=transaction_reference_date,
|
||||
amount=self.installment_amount,
|
||||
description=self.description,
|
||||
description=(
|
||||
self.description if self.add_description_to_transaction else ""
|
||||
),
|
||||
category=self.category,
|
||||
installment_plan=self,
|
||||
installment_id=i,
|
||||
notes=self.notes,
|
||||
notes=self.notes if self.add_notes_to_transaction else "",
|
||||
)
|
||||
new_transaction.tags.set(self.tags.all())
|
||||
new_transaction.entities.set(self.entities.all())
|
||||
@@ -594,9 +606,13 @@ class InstallmentPlan(models.Model):
|
||||
existing_transaction.type = self.type
|
||||
existing_transaction.date = transaction_date
|
||||
existing_transaction.reference_date = transaction_reference_date
|
||||
existing_transaction.description = self.description
|
||||
existing_transaction.description = (
|
||||
self.description if self.add_description_to_transaction else ""
|
||||
)
|
||||
existing_transaction.category = self.category
|
||||
existing_transaction.notes = self.notes
|
||||
existing_transaction.notes = (
|
||||
self.notes if self.add_notes_to_transaction else ""
|
||||
)
|
||||
|
||||
if (
|
||||
not existing_transaction.is_paid
|
||||
@@ -617,11 +633,13 @@ class InstallmentPlan(models.Model):
|
||||
is_paid=False,
|
||||
reference_date=transaction_reference_date,
|
||||
amount=self.installment_amount,
|
||||
description=self.description,
|
||||
description=(
|
||||
self.description if self.add_description_to_transaction else ""
|
||||
),
|
||||
category=self.category,
|
||||
installment_plan=self,
|
||||
installment_id=i,
|
||||
notes=self.notes,
|
||||
notes=self.notes if self.add_notes_to_transaction else "",
|
||||
)
|
||||
new_transaction.tags.set(self.tags.all())
|
||||
new_transaction.entities.set(self.entities.all())
|
||||
@@ -697,6 +715,13 @@ class RecurringTransaction(models.Model):
|
||||
verbose_name=_("Last Generated Reference Date"), null=True, blank=True
|
||||
)
|
||||
|
||||
add_description_to_transaction = models.BooleanField(
|
||||
default=True, verbose_name=_("Add description to transactions")
|
||||
)
|
||||
add_notes_to_transaction = models.BooleanField(
|
||||
default=True, verbose_name=_("Add notes to transactions")
|
||||
)
|
||||
|
||||
all_objects = models.Manager() # Unfiltered manager
|
||||
objects = GenericAccountOwnerManager() # Default filtered manager
|
||||
|
||||
@@ -743,11 +768,13 @@ class RecurringTransaction(models.Model):
|
||||
date=date,
|
||||
reference_date=reference_date.replace(day=1),
|
||||
amount=self.amount,
|
||||
description=self.description,
|
||||
description=(
|
||||
self.description if self.add_description_to_transaction else ""
|
||||
),
|
||||
category=self.category,
|
||||
is_paid=False,
|
||||
recurring_transaction=self,
|
||||
notes=self.notes,
|
||||
notes=self.notes if self.add_notes_to_transaction else "",
|
||||
)
|
||||
if self.tags.exists():
|
||||
created_transaction.tags.set(self.tags.all())
|
||||
@@ -821,9 +848,13 @@ class RecurringTransaction(models.Model):
|
||||
for existing_transaction in unpaid_transactions:
|
||||
# Update fields based on RecurringTransaction
|
||||
existing_transaction.amount = self.amount
|
||||
existing_transaction.description = self.description
|
||||
existing_transaction.description = (
|
||||
self.description if self.add_description_to_transaction else ""
|
||||
)
|
||||
existing_transaction.category = self.category
|
||||
existing_transaction.notes = self.notes
|
||||
existing_transaction.notes = (
|
||||
self.notes if self.add_notes_to_transaction else ""
|
||||
)
|
||||
|
||||
# Update many-to-many relationships
|
||||
existing_transaction.tags.set(self.tags.all())
|
||||
|
||||
34
app/fixtures/demo_data.json
Normal file
34
app/fixtures/demo_data.json
Normal file
@@ -0,0 +1,34 @@
|
||||
[
|
||||
{
|
||||
"model": "users.user",
|
||||
"pk": 1,
|
||||
"fields": {
|
||||
"password": "pbkdf2_sha256$870000$kUmqeqdenjc2yFS8qbniwS$7qOMXzKG+yFmezdjhptkwuMJlqlZnQHXgAnonWurpBk=",
|
||||
"last_login": "2025-03-31T03:22:25Z",
|
||||
"is_superuser": false,
|
||||
"first_name": "Demo",
|
||||
"last_name": "User",
|
||||
"is_staff": false,
|
||||
"is_active": true,
|
||||
"date_joined": "2025-03-31T03:21:04Z",
|
||||
"email": "demo@demo.com",
|
||||
"groups": [],
|
||||
"user_permissions": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "users.usersettings",
|
||||
"pk": 1,
|
||||
"fields": {
|
||||
"user": 1,
|
||||
"hide_amounts": false,
|
||||
"mute_sounds": false,
|
||||
"date_format": "SHORT_DATE_FORMAT",
|
||||
"datetime_format": "SHORT_DATETIME_FORMAT",
|
||||
"number_format": "AA",
|
||||
"language": "auto",
|
||||
"timezone": "auto",
|
||||
"start_page": "MONTHLY_OVERVIEW"
|
||||
}
|
||||
}
|
||||
]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-03-09 04:55+0000\n"
|
||||
"POT-Creation-Date: 2025-03-31 05:30+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"
|
||||
@@ -27,9 +27,9 @@ msgstr ""
|
||||
#: apps/currencies/forms.py:142 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:202
|
||||
#: apps/transactions/forms.py:269 apps/transactions/forms.py:623
|
||||
#: apps/transactions/forms.py:666 apps/transactions/forms.py:698
|
||||
#: apps/transactions/forms.py:733 apps/transactions/forms.py:881
|
||||
#: apps/transactions/forms.py:269 apps/transactions/forms.py:629
|
||||
#: apps/transactions/forms.py:672 apps/transactions/forms.py:704
|
||||
#: apps/transactions/forms.py:739 apps/transactions/forms.py:891
|
||||
msgid "Update"
|
||||
msgstr ""
|
||||
|
||||
@@ -39,9 +39,9 @@ msgstr ""
|
||||
#: 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:187 apps/transactions/forms.py:211
|
||||
#: apps/transactions/forms.py:631 apps/transactions/forms.py:674
|
||||
#: apps/transactions/forms.py:706 apps/transactions/forms.py:741
|
||||
#: apps/transactions/forms.py:889
|
||||
#: apps/transactions/forms.py:637 apps/transactions/forms.py:680
|
||||
#: apps/transactions/forms.py:712 apps/transactions/forms.py:747
|
||||
#: apps/transactions/forms.py:899
|
||||
#: templates/account_groups/fragments/list.html:9
|
||||
#: templates/accounts/fragments/list.html:9
|
||||
#: templates/categories/fragments/list.html:9
|
||||
@@ -72,9 +72,9 @@ msgstr ""
|
||||
#: apps/insights/forms.py:118 apps/rules/forms.py:174 apps/rules/forms.py:189
|
||||
#: apps/rules/models.py:38 apps/rules/models.py:286
|
||||
#: apps/transactions/forms.py:40 apps/transactions/forms.py:303
|
||||
#: apps/transactions/forms.py:310 apps/transactions/forms.py:508
|
||||
#: apps/transactions/forms.py:765 apps/transactions/models.py:302
|
||||
#: apps/transactions/models.py:485 apps/transactions/models.py:668
|
||||
#: apps/transactions/forms.py:310 apps/transactions/forms.py:510
|
||||
#: apps/transactions/forms.py:771 apps/transactions/models.py:305
|
||||
#: apps/transactions/models.py:488 apps/transactions/models.py:686
|
||||
#: templates/insights/fragments/category_overview/index.html:9
|
||||
msgid "Category"
|
||||
msgstr ""
|
||||
@@ -84,18 +84,18 @@ msgstr ""
|
||||
#: apps/rules/forms.py:177 apps/rules/forms.py:186 apps/rules/models.py:39
|
||||
#: apps/rules/models.py:290 apps/transactions/filters.py:74
|
||||
#: apps/transactions/forms.py:48 apps/transactions/forms.py:319
|
||||
#: apps/transactions/forms.py:327 apps/transactions/forms.py:501
|
||||
#: apps/transactions/forms.py:758 apps/transactions/models.py:308
|
||||
#: apps/transactions/models.py:487 apps/transactions/models.py:672
|
||||
#: apps/transactions/forms.py:327 apps/transactions/forms.py:503
|
||||
#: apps/transactions/forms.py:764 apps/transactions/models.py:311
|
||||
#: apps/transactions/models.py:490 apps/transactions/models.py:690
|
||||
#: templates/includes/navbar.html:108 templates/tags/fragments/list.html:5
|
||||
#: templates/tags/pages/index.html:4
|
||||
msgid "Tags"
|
||||
msgstr ""
|
||||
|
||||
#: apps/accounts/models.py:12 apps/accounts/models.py:28 apps/dca/models.py:13
|
||||
#: 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:198 apps/transactions/models.py:222
|
||||
#: apps/transactions/models.py:245
|
||||
#: apps/transactions/models.py:198 apps/transactions/models.py:223
|
||||
#: apps/transactions/models.py:247
|
||||
#: templates/account_groups/fragments/list.html:25
|
||||
#: templates/accounts/fragments/list.html:25
|
||||
#: templates/categories/fragments/table.html:16
|
||||
@@ -110,7 +110,7 @@ msgstr ""
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#: apps/accounts/models.py:18 apps/accounts/models.py:32
|
||||
#: apps/accounts/models.py:18 apps/accounts/models.py:33
|
||||
msgid "Account Group"
|
||||
msgstr ""
|
||||
|
||||
@@ -120,49 +120,49 @@ msgstr ""
|
||||
msgid "Account Groups"
|
||||
msgstr ""
|
||||
|
||||
#: apps/accounts/models.py:38 apps/currencies/models.py:39
|
||||
#: apps/accounts/models.py:39 apps/currencies/models.py:39
|
||||
#: templates/accounts/fragments/list.html:27
|
||||
msgid "Currency"
|
||||
msgstr ""
|
||||
|
||||
#: apps/accounts/models.py:44 apps/currencies/models.py:27
|
||||
#: apps/accounts/models.py:45 apps/currencies/models.py:27
|
||||
#: templates/accounts/fragments/list.html:28
|
||||
msgid "Exchange Currency"
|
||||
msgstr ""
|
||||
|
||||
#: apps/accounts/models.py:49 apps/currencies/models.py:32
|
||||
#: apps/accounts/models.py:50 apps/currencies/models.py:32
|
||||
msgid "Default currency for exchange calculations"
|
||||
msgstr ""
|
||||
|
||||
#: apps/accounts/models.py:54
|
||||
#: apps/accounts/models.py:55
|
||||
msgid "Asset account"
|
||||
msgstr ""
|
||||
|
||||
#: apps/accounts/models.py:56
|
||||
#: apps/accounts/models.py:57
|
||||
msgid ""
|
||||
"Asset accounts count towards your Net Worth, but not towards your month."
|
||||
msgstr ""
|
||||
|
||||
#: apps/accounts/models.py:61 templates/accounts/fragments/list.html:30
|
||||
#: apps/accounts/models.py:62 templates/accounts/fragments/list.html:30
|
||||
#: templates/categories/fragments/list.html:24
|
||||
#: templates/entities/fragments/list.html:24
|
||||
#: templates/tags/fragments/list.html:24
|
||||
msgid "Archived"
|
||||
msgstr ""
|
||||
|
||||
#: apps/accounts/models.py:62
|
||||
#: apps/accounts/models.py:63
|
||||
msgid "Archived accounts don't show up nor count towards your net worth"
|
||||
msgstr ""
|
||||
|
||||
#: apps/accounts/models.py:69 apps/rules/forms.py:166 apps/rules/forms.py:179
|
||||
#: apps/accounts/models.py:70 apps/rules/forms.py:166 apps/rules/forms.py:179
|
||||
#: apps/rules/models.py:30 apps/rules/models.py:242
|
||||
#: apps/transactions/forms.py:60 apps/transactions/forms.py:493
|
||||
#: apps/transactions/forms.py:750 apps/transactions/models.py:275
|
||||
#: apps/transactions/models.py:445 apps/transactions/models.py:650
|
||||
#: apps/transactions/forms.py:60 apps/transactions/forms.py:495
|
||||
#: apps/transactions/forms.py:756 apps/transactions/models.py:278
|
||||
#: apps/transactions/models.py:448 apps/transactions/models.py:668
|
||||
msgid "Account"
|
||||
msgstr ""
|
||||
|
||||
#: apps/accounts/models.py:70 apps/export_app/forms.py:20
|
||||
#: apps/accounts/models.py:71 apps/export_app/forms.py:20
|
||||
#: 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:114
|
||||
@@ -173,7 +173,7 @@ msgstr ""
|
||||
msgid "Accounts"
|
||||
msgstr ""
|
||||
|
||||
#: apps/accounts/models.py:82
|
||||
#: apps/accounts/models.py:84
|
||||
msgid "Exchange currency cannot be the same as the account's main currency."
|
||||
msgstr ""
|
||||
|
||||
@@ -184,7 +184,7 @@ msgstr ""
|
||||
#: apps/accounts/views/account_groups.py:69
|
||||
#: apps/accounts/views/account_groups.py:152 apps/accounts/views/accounts.py:68
|
||||
#: apps/accounts/views/accounts.py:106 apps/dca/views.py:63
|
||||
#: apps/dca/views.py:146 apps/rules/views.py:99 apps/rules/views.py:195
|
||||
#: apps/dca/views.py:146 apps/rules/views.py:105 apps/rules/views.py:205
|
||||
#: apps/transactions/views/categories.py:91
|
||||
#: apps/transactions/views/categories.py:129
|
||||
#: apps/transactions/views/entities.py:91
|
||||
@@ -199,7 +199,7 @@ msgstr ""
|
||||
|
||||
#: apps/accounts/views/account_groups.py:111
|
||||
#: apps/accounts/views/accounts.py:145 apps/dca/views.py:105
|
||||
#: apps/rules/views.py:154 apps/transactions/views/categories.py:168
|
||||
#: apps/rules/views.py:162 apps/transactions/views/categories.py:168
|
||||
#: apps/transactions/views/entities.py:130 apps/transactions/views/tags.py:130
|
||||
msgid "Item no longer shared with you"
|
||||
msgstr ""
|
||||
@@ -210,14 +210,14 @@ msgstr ""
|
||||
|
||||
#: apps/accounts/views/account_groups.py:135
|
||||
#: apps/accounts/views/accounts.py:169 apps/dca/views.py:129
|
||||
#: apps/rules/views.py:178 apps/transactions/views/categories.py:192
|
||||
#: apps/rules/views.py:187 apps/transactions/views/categories.py:192
|
||||
#: apps/transactions/views/entities.py:154 apps/transactions/views/tags.py:154
|
||||
msgid "Ownership taken successfully"
|
||||
msgstr ""
|
||||
|
||||
#: apps/accounts/views/account_groups.py:165
|
||||
#: apps/accounts/views/accounts.py:119 apps/dca/views.py:159
|
||||
#: apps/rules/views.py:208 apps/transactions/views/categories.py:142
|
||||
#: apps/rules/views.py:218 apps/transactions/views/categories.py:142
|
||||
#: apps/transactions/views/entities.py:184 apps/transactions/views/tags.py:184
|
||||
msgid "Configuration saved successfully"
|
||||
msgstr ""
|
||||
@@ -442,7 +442,7 @@ msgstr ""
|
||||
#: apps/currencies/forms.py:69 apps/dca/models.py:158 apps/rules/forms.py:169
|
||||
#: apps/rules/forms.py:182 apps/rules/models.py:33 apps/rules/models.py:254
|
||||
#: apps/transactions/forms.py:64 apps/transactions/forms.py:331
|
||||
#: apps/transactions/models.py:285
|
||||
#: apps/transactions/models.py:288
|
||||
#: templates/dca/fragments/strategy/details.html:52
|
||||
#: templates/exchange_rates/fragments/table.html:10
|
||||
#: templates/exchange_rates_services/fragments/table.html:10
|
||||
@@ -472,59 +472,59 @@ msgstr ""
|
||||
msgid "Currencies"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:48
|
||||
#: apps/currencies/models.py:49
|
||||
msgid "Currency cannot have itself as exchange currency."
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:59
|
||||
#: apps/currencies/models.py:60
|
||||
msgid "From Currency"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:65
|
||||
#: apps/currencies/models.py:66
|
||||
msgid "To Currency"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:68 apps/currencies/models.py:73
|
||||
#: apps/currencies/models.py:69 apps/currencies/models.py:74
|
||||
msgid "Exchange Rate"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:70
|
||||
#: apps/currencies/models.py:71
|
||||
msgid "Date and Time"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:74 apps/export_app/forms.py:68
|
||||
#: apps/currencies/models.py:75 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:126
|
||||
msgid "Exchange Rates"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:86
|
||||
#: apps/currencies/models.py:87
|
||||
msgid "From and To currencies cannot be the same."
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:101
|
||||
#: apps/currencies/models.py:102
|
||||
msgid "On"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:102
|
||||
#: apps/currencies/models.py:103
|
||||
msgid "Every X hours"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:103
|
||||
#: apps/currencies/models.py:104
|
||||
msgid "Not on"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:105
|
||||
#: apps/currencies/models.py:106
|
||||
msgid "Service Name"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:107
|
||||
#: apps/currencies/models.py:108
|
||||
msgid "Service Type"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:109 apps/transactions/models.py:202
|
||||
#: apps/transactions/models.py:225 apps/transactions/models.py:248
|
||||
#: apps/currencies/models.py:110 apps/transactions/models.py:202
|
||||
#: apps/transactions/models.py:226 apps/transactions/models.py:250
|
||||
#: templates/categories/fragments/list.html:21
|
||||
#: templates/entities/fragments/list.html:21
|
||||
#: templates/recurring_transactions/fragments/list.html:21
|
||||
@@ -532,69 +532,69 @@ msgstr ""
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:114
|
||||
#: apps/currencies/models.py:115
|
||||
msgid "API Key"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:115
|
||||
#: apps/currencies/models.py:116
|
||||
msgid "API key for the service (if required)"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:120
|
||||
#: apps/currencies/models.py:121
|
||||
msgid "Interval Type"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:124
|
||||
#: apps/currencies/models.py:125
|
||||
msgid "Interval"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:127
|
||||
#: apps/currencies/models.py:128
|
||||
msgid "Last Successful Fetch"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:132
|
||||
#: apps/currencies/models.py:133
|
||||
msgid "Target Currencies"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:134
|
||||
#: apps/currencies/models.py:135
|
||||
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:142
|
||||
#: apps/currencies/models.py:143
|
||||
msgid "Target Accounts"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:144
|
||||
#: apps/currencies/models.py:145
|
||||
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:151
|
||||
#: apps/currencies/models.py:152
|
||||
msgid "Exchange Rate Service"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:152
|
||||
#: apps/currencies/models.py:153
|
||||
msgid "Exchange Rate Services"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:204
|
||||
#: apps/currencies/models.py:205
|
||||
msgid "'Every X hours' interval type requires a positive integer."
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:213
|
||||
#: apps/currencies/models.py:214
|
||||
msgid "'Every X hours' interval must be between 1 and 24."
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/models.py:227
|
||||
#: apps/currencies/models.py:228
|
||||
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:238
|
||||
#: apps/currencies/models.py:239
|
||||
msgid ""
|
||||
"Invalid format. Please check the requirements for your selected interval "
|
||||
"type."
|
||||
@@ -624,19 +624,19 @@ msgstr ""
|
||||
msgid "Exchange rate deleted successfully"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/views/exchange_rates_services.py:46
|
||||
#: apps/currencies/views/exchange_rates_services.py:50
|
||||
msgid "Service added successfully"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/views/exchange_rates_services.py:74
|
||||
#: apps/currencies/views/exchange_rates_services.py:79
|
||||
msgid "Service updated successfully"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/views/exchange_rates_services.py:100
|
||||
#: apps/currencies/views/exchange_rates_services.py:106
|
||||
msgid "Service deleted successfully"
|
||||
msgstr ""
|
||||
|
||||
#: apps/currencies/views/exchange_rates_services.py:115
|
||||
#: apps/currencies/views/exchange_rates_services.py:122
|
||||
msgid "Services queued successfully"
|
||||
msgstr ""
|
||||
|
||||
@@ -673,7 +673,7 @@ msgstr ""
|
||||
msgid "You must provide an account."
|
||||
msgstr ""
|
||||
|
||||
#: apps/dca/forms.py:312 apps/transactions/forms.py:443
|
||||
#: apps/dca/forms.py:312 apps/transactions/forms.py:445
|
||||
msgid "From and To accounts must be different."
|
||||
msgstr ""
|
||||
|
||||
@@ -692,8 +692,8 @@ msgstr ""
|
||||
|
||||
#: apps/dca/models.py:26 apps/dca/models.py:181 apps/rules/forms.py:173
|
||||
#: apps/rules/forms.py:188 apps/rules/models.py:37 apps/rules/models.py:270
|
||||
#: apps/transactions/forms.py:345 apps/transactions/models.py:298
|
||||
#: apps/transactions/models.py:494 apps/transactions/models.py:678
|
||||
#: apps/transactions/forms.py:347 apps/transactions/models.py:301
|
||||
#: apps/transactions/models.py:497 apps/transactions/models.py:696
|
||||
msgid "Notes"
|
||||
msgstr ""
|
||||
|
||||
@@ -754,7 +754,7 @@ msgid "Users"
|
||||
msgstr ""
|
||||
|
||||
#: apps/export_app/forms.py:32 apps/export_app/forms.py:137
|
||||
#: apps/transactions/models.py:359 templates/includes/navbar.html:57
|
||||
#: apps/transactions/models.py:362 templates/includes/navbar.html:57
|
||||
#: templates/includes/navbar.html:104
|
||||
#: templates/recurring_transactions/fragments/list_transactions.html:5
|
||||
#: templates/recurring_transactions/fragments/table.html:37
|
||||
@@ -771,23 +771,23 @@ msgstr ""
|
||||
#: apps/export_app/forms.py:50 apps/export_app/forms.py:136
|
||||
#: apps/rules/forms.py:178 apps/rules/forms.py:187 apps/rules/models.py:40
|
||||
#: apps/rules/models.py:282 apps/transactions/filters.py:81
|
||||
#: apps/transactions/forms.py:56 apps/transactions/forms.py:516
|
||||
#: apps/transactions/forms.py:773 apps/transactions/models.py:259
|
||||
#: apps/transactions/models.py:313 apps/transactions/models.py:490
|
||||
#: apps/transactions/models.py:675 templates/entities/fragments/list.html:5
|
||||
#: apps/transactions/forms.py:56 apps/transactions/forms.py:518
|
||||
#: apps/transactions/forms.py:779 apps/transactions/models.py:261
|
||||
#: apps/transactions/models.py:316 apps/transactions/models.py:493
|
||||
#: apps/transactions/models.py:693 templates/entities/fragments/list.html:5
|
||||
#: templates/entities/pages/index.html:4 templates/includes/navbar.html:110
|
||||
msgid "Entities"
|
||||
msgstr ""
|
||||
|
||||
#: apps/export_app/forms.py:56 apps/export_app/forms.py:140
|
||||
#: apps/transactions/models.py:705 templates/includes/navbar.html:74
|
||||
#: apps/transactions/models.py:730 templates/includes/navbar.html:74
|
||||
#: templates/recurring_transactions/fragments/list.html:5
|
||||
#: templates/recurring_transactions/pages/index.html:4
|
||||
msgid "Recurring Transactions"
|
||||
msgstr ""
|
||||
|
||||
#: apps/export_app/forms.py:62 apps/export_app/forms.py:138
|
||||
#: apps/transactions/models.py:501 templates/includes/navbar.html:72
|
||||
#: apps/transactions/models.py:511 templates/includes/navbar.html:72
|
||||
#: templates/installment_plans/fragments/list.html:5
|
||||
#: templates/installment_plans/pages/index.html:4
|
||||
msgid "Installment Plans"
|
||||
@@ -851,15 +851,15 @@ msgstr ""
|
||||
msgid "Please upload either a ZIP file or at least one CSV file"
|
||||
msgstr ""
|
||||
|
||||
#: apps/export_app/views.py:174
|
||||
#: apps/export_app/views.py:177
|
||||
msgid "You have to select at least one export"
|
||||
msgstr ""
|
||||
|
||||
#: apps/export_app/views.py:193
|
||||
#: apps/export_app/views.py:197
|
||||
msgid "Data restored successfully"
|
||||
msgstr ""
|
||||
|
||||
#: apps/export_app/views.py:205
|
||||
#: apps/export_app/views.py:209
|
||||
msgid ""
|
||||
"There was an error restoring your data. Check the logs for more details."
|
||||
msgstr ""
|
||||
@@ -918,23 +918,23 @@ msgstr ""
|
||||
msgid "File name"
|
||||
msgstr ""
|
||||
|
||||
#: apps/import_app/views.py:62
|
||||
#: apps/import_app/views.py:67
|
||||
msgid "Import Profile added successfully"
|
||||
msgstr ""
|
||||
|
||||
#: apps/import_app/views.py:97
|
||||
#: apps/import_app/views.py:103
|
||||
msgid "Import Profile update successfully"
|
||||
msgstr ""
|
||||
|
||||
#: apps/import_app/views.py:123
|
||||
#: apps/import_app/views.py:130
|
||||
msgid "Import Profile deleted successfully"
|
||||
msgstr ""
|
||||
|
||||
#: apps/import_app/views.py:185
|
||||
#: apps/import_app/views.py:195
|
||||
msgid "Import Run queued successfully"
|
||||
msgstr ""
|
||||
|
||||
#: apps/import_app/views.py:211
|
||||
#: apps/import_app/views.py:222
|
||||
msgid "Run deleted successfully"
|
||||
msgstr ""
|
||||
|
||||
@@ -1022,14 +1022,14 @@ msgid "Operator"
|
||||
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:282
|
||||
#: apps/transactions/models.py:450 apps/transactions/models.py:656
|
||||
#: apps/rules/models.py:246 apps/transactions/models.py:285
|
||||
#: apps/transactions/models.py:453 apps/transactions/models.py:674
|
||||
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:284 templates/cotton/transaction/item.html:21
|
||||
#: apps/transactions/models.py:287 templates/cotton/transaction/item.html:21
|
||||
#: templates/cotton/transaction/item.html:31
|
||||
#: templates/transactions/widgets/paid_toggle_button.html:12
|
||||
#: templates/transactions/widgets/unselectable_paid_toggle_button.html:16
|
||||
@@ -1038,32 +1038,32 @@ msgstr ""
|
||||
|
||||
#: apps/rules/forms.py:170 apps/rules/forms.py:183 apps/rules/models.py:34
|
||||
#: apps/rules/models.py:258 apps/transactions/forms.py:68
|
||||
#: apps/transactions/forms.py:334 apps/transactions/forms.py:522
|
||||
#: apps/transactions/models.py:286 apps/transactions/models.py:468
|
||||
#: apps/transactions/models.py:680
|
||||
#: apps/transactions/forms.py:334 apps/transactions/forms.py:524
|
||||
#: apps/transactions/models.py:289 apps/transactions/models.py:471
|
||||
#: apps/transactions/models.py:698
|
||||
msgid "Reference Date"
|
||||
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:291
|
||||
#: apps/transactions/models.py:661 templates/insights/fragments/sankey.html:95
|
||||
#: apps/rules/models.py:262 apps/transactions/models.py:294
|
||||
#: apps/transactions/models.py:679 templates/insights/fragments/sankey.html:95
|
||||
msgid "Amount"
|
||||
msgstr ""
|
||||
|
||||
#: apps/rules/forms.py:172 apps/rules/forms.py:185 apps/rules/models.py:14
|
||||
#: apps/rules/models.py:36 apps/rules/models.py:266
|
||||
#: apps/transactions/forms.py:337 apps/transactions/models.py:296
|
||||
#: apps/transactions/models.py:452 apps/transactions/models.py:664
|
||||
#: apps/transactions/forms.py:338 apps/transactions/models.py:299
|
||||
#: apps/transactions/models.py:455 apps/transactions/models.py:682
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#: apps/rules/forms.py:175 apps/rules/forms.py:190 apps/rules/models.py:274
|
||||
#: apps/transactions/models.py:335
|
||||
#: apps/transactions/models.py:338
|
||||
msgid "Internal Note"
|
||||
msgstr ""
|
||||
|
||||
#: apps/rules/forms.py:176 apps/rules/forms.py:191 apps/rules/models.py:278
|
||||
#: apps/transactions/models.py:337
|
||||
#: apps/transactions/models.py:340
|
||||
msgid "Internal ID"
|
||||
msgstr ""
|
||||
|
||||
@@ -1149,43 +1149,43 @@ msgstr ""
|
||||
msgid "Update or create transaction action"
|
||||
msgstr ""
|
||||
|
||||
#: apps/rules/views.py:54
|
||||
#: apps/rules/views.py:58
|
||||
msgid "Rule deactivated successfully"
|
||||
msgstr ""
|
||||
|
||||
#: apps/rules/views.py:56
|
||||
#: apps/rules/views.py:60
|
||||
msgid "Rule activated successfully"
|
||||
msgstr ""
|
||||
|
||||
#: apps/rules/views.py:74
|
||||
#: apps/rules/views.py:79
|
||||
msgid "Rule added successfully"
|
||||
msgstr ""
|
||||
|
||||
#: apps/rules/views.py:112
|
||||
#: apps/rules/views.py:118
|
||||
msgid "Rule updated successfully"
|
||||
msgstr ""
|
||||
|
||||
#: apps/rules/views.py:157
|
||||
#: apps/rules/views.py:165
|
||||
msgid "Rule deleted successfully"
|
||||
msgstr ""
|
||||
|
||||
#: apps/rules/views.py:270
|
||||
#: apps/rules/views.py:282
|
||||
msgid "Action updated successfully"
|
||||
msgstr ""
|
||||
|
||||
#: apps/rules/views.py:300
|
||||
#: apps/rules/views.py:313
|
||||
msgid "Action deleted successfully"
|
||||
msgstr ""
|
||||
|
||||
#: apps/rules/views.py:323
|
||||
#: apps/rules/views.py:337
|
||||
msgid "Update or Create Transaction action added successfully"
|
||||
msgstr ""
|
||||
|
||||
#: apps/rules/views.py:355
|
||||
#: apps/rules/views.py:370
|
||||
msgid "Update or Create Transaction action updated successfully"
|
||||
msgstr ""
|
||||
|
||||
#: apps/rules/views.py:384
|
||||
#: apps/rules/views.py:400
|
||||
msgid "Update or Create Transaction action deleted successfully"
|
||||
msgstr ""
|
||||
|
||||
@@ -1236,28 +1236,28 @@ msgstr ""
|
||||
msgid "To Amount"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/forms.py:410
|
||||
#: apps/transactions/forms.py:412
|
||||
#: templates/cotton/ui/quick_transactions_buttons.html:40
|
||||
msgid "Transfer"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/forms.py:652
|
||||
#: apps/transactions/forms.py:658
|
||||
msgid "Tag name"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/forms.py:684
|
||||
#: apps/transactions/forms.py:690
|
||||
msgid "Entity name"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/forms.py:716
|
||||
#: apps/transactions/forms.py:722
|
||||
msgid "Category name"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/forms.py:718
|
||||
#: apps/transactions/forms.py:724
|
||||
msgid "Muted categories won't count towards your monthly total"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/forms.py:900
|
||||
#: apps/transactions/forms.py:910
|
||||
msgid "End date should be after the start date"
|
||||
msgstr ""
|
||||
|
||||
@@ -1279,26 +1279,26 @@ msgstr ""
|
||||
msgid "Transaction Categories"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:227
|
||||
#: apps/transactions/models.py:228
|
||||
msgid ""
|
||||
"Deactivated tags won't be able to be selected when creating new transactions"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:235 apps/transactions/models.py:236
|
||||
#: apps/transactions/models.py:236 apps/transactions/models.py:237
|
||||
msgid "Transaction Tags"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:250
|
||||
#: apps/transactions/models.py:252
|
||||
msgid ""
|
||||
"Deactivated entities won't be able to be selected when creating new "
|
||||
"transactions"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:258
|
||||
#: apps/transactions/models.py:260
|
||||
msgid "Entity"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:269
|
||||
#: apps/transactions/models.py:272
|
||||
#: templates/calendar_view/fragments/list.html:42
|
||||
#: templates/calendar_view/fragments/list.html:44
|
||||
#: templates/calendar_view/fragments/list.html:52
|
||||
@@ -1309,7 +1309,7 @@ msgstr ""
|
||||
msgid "Income"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:270
|
||||
#: apps/transactions/models.py:273
|
||||
#: templates/calendar_view/fragments/list.html:46
|
||||
#: templates/calendar_view/fragments/list.html:48
|
||||
#: templates/calendar_view/fragments/list.html:56
|
||||
@@ -1319,117 +1319,125 @@ msgstr ""
|
||||
msgid "Expense"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:324 apps/transactions/models.py:500
|
||||
#: apps/transactions/models.py:327 apps/transactions/models.py:510
|
||||
msgid "Installment Plan"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:333 apps/transactions/models.py:704
|
||||
#: apps/transactions/models.py:336 apps/transactions/models.py:729
|
||||
msgid "Recurring Transaction"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:341
|
||||
#: apps/transactions/models.py:344
|
||||
msgid "Deleted"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:346
|
||||
#: apps/transactions/models.py:349
|
||||
msgid "Deleted At"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:358
|
||||
#: apps/transactions/models.py:361
|
||||
msgid "Transaction"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:430 templates/tags/fragments/table.html:71
|
||||
#: apps/transactions/models.py:433 templates/tags/fragments/table.html:71
|
||||
msgid "No tags"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:431
|
||||
#: apps/transactions/models.py:434
|
||||
msgid "No category"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:433
|
||||
#: apps/transactions/models.py:436
|
||||
msgid "No description"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:439
|
||||
#: apps/transactions/models.py:442
|
||||
msgid "Yearly"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:440 apps/users/models.py:26
|
||||
#: apps/transactions/models.py:443 apps/users/models.py:26
|
||||
#: templates/includes/navbar.html:26
|
||||
msgid "Monthly"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:441
|
||||
#: apps/transactions/models.py:444
|
||||
msgid "Weekly"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:442
|
||||
#: apps/transactions/models.py:445
|
||||
msgid "Daily"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:455
|
||||
#: apps/transactions/models.py:458
|
||||
msgid "Number of Installments"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:460
|
||||
#: apps/transactions/models.py:463
|
||||
msgid "Installment Start"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:461
|
||||
#: apps/transactions/models.py:464
|
||||
msgid "The installment number to start counting from"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:466 apps/transactions/models.py:684
|
||||
#: apps/transactions/models.py:469 apps/transactions/models.py:702
|
||||
msgid "Start Date"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:470 apps/transactions/models.py:685
|
||||
#: apps/transactions/models.py:473 apps/transactions/models.py:703
|
||||
msgid "End Date"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:475
|
||||
#: apps/transactions/models.py:478
|
||||
msgid "Recurrence"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:478
|
||||
#: apps/transactions/models.py:481
|
||||
msgid "Installment Amount"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:643
|
||||
#: apps/transactions/models.py:500 apps/transactions/models.py:719
|
||||
msgid "Add description to transactions"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:503 apps/transactions/models.py:722
|
||||
msgid "Add notes to transactions"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:661
|
||||
msgid "day(s)"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:644
|
||||
#: apps/transactions/models.py:662
|
||||
msgid "week(s)"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:645
|
||||
#: apps/transactions/models.py:663
|
||||
msgid "month(s)"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:646
|
||||
#: apps/transactions/models.py:664
|
||||
msgid "year(s)"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:648
|
||||
#: apps/transactions/models.py:666
|
||||
#: templates/recurring_transactions/fragments/list.html:24
|
||||
msgid "Paused"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:687
|
||||
#: apps/transactions/models.py:705
|
||||
msgid "Recurrence Type"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:690
|
||||
#: apps/transactions/models.py:708
|
||||
msgid "Recurrence Interval"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:694
|
||||
#: apps/transactions/models.py:712
|
||||
msgid "Last Generated Date"
|
||||
msgstr ""
|
||||
|
||||
#: apps/transactions/models.py:697
|
||||
#: apps/transactions/models.py:715
|
||||
msgid "Last Generated Reference Date"
|
||||
msgstr ""
|
||||
|
||||
@@ -1606,11 +1614,11 @@ msgstr ""
|
||||
msgid "Important dates"
|
||||
msgstr ""
|
||||
|
||||
#: apps/users/forms.py:19 apps/users/models.py:13
|
||||
#: apps/users/forms.py:19 apps/users/models.py:13 templates/users/login.html:19
|
||||
msgid "E-mail"
|
||||
msgstr ""
|
||||
|
||||
#: apps/users/forms.py:25
|
||||
#: apps/users/forms.py:25 templates/users/login.html:20
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
@@ -2476,23 +2484,32 @@ msgstr ""
|
||||
msgid "Calculator"
|
||||
msgstr ""
|
||||
|
||||
#: templates/includes/navbar/user_menu.html:12
|
||||
#: templates/includes/navbar/user_menu.html:14
|
||||
msgid "Settings"
|
||||
msgstr ""
|
||||
|
||||
#: templates/includes/navbar/user_menu.html:39
|
||||
#: templates/includes/navbar/user_menu.html:41
|
||||
msgid "Clear cache"
|
||||
msgstr ""
|
||||
|
||||
#: templates/includes/navbar/user_menu.html:43
|
||||
#: templates/includes/navbar/user_menu.html:45
|
||||
msgid "Logout"
|
||||
msgstr ""
|
||||
|
||||
#: templates/includes/scripts/hyperscript/htmx_error_handler.html:5
|
||||
#: templates/includes/scripts/hyperscript/htmx_error_handler.html:8
|
||||
msgid "Access Denied"
|
||||
msgstr ""
|
||||
|
||||
#: templates/includes/scripts/hyperscript/htmx_error_handler.html:9
|
||||
msgid ""
|
||||
"You do not have permission to perform this action or access this resource."
|
||||
msgstr ""
|
||||
|
||||
#: templates/includes/scripts/hyperscript/htmx_error_handler.html:18
|
||||
msgid "Something went wrong loading your data"
|
||||
msgstr ""
|
||||
|
||||
#: templates/includes/scripts/hyperscript/htmx_error_handler.html:6
|
||||
#: templates/includes/scripts/hyperscript/htmx_error_handler.html:19
|
||||
msgid "Try reloading the page or check the console for more information."
|
||||
msgstr ""
|
||||
|
||||
@@ -2659,6 +2676,14 @@ msgstr ""
|
||||
msgid "No installment plans"
|
||||
msgstr ""
|
||||
|
||||
#: templates/layouts/base.html:40
|
||||
msgid "This is a demo!"
|
||||
msgstr ""
|
||||
|
||||
#: templates/layouts/base.html:40
|
||||
msgid "Any data you add here will be wiped in 24hrs or less"
|
||||
msgstr ""
|
||||
|
||||
#: templates/mini_tools/currency_converter/currency_converter.html:58
|
||||
msgid "Invert"
|
||||
msgstr ""
|
||||
@@ -2969,6 +2994,14 @@ msgstr ""
|
||||
msgid "Show amounts"
|
||||
msgstr ""
|
||||
|
||||
#: templates/users/login.html:17
|
||||
msgid "Welcome to WYGIWYH's demo!"
|
||||
msgstr ""
|
||||
|
||||
#: templates/users/login.html:18
|
||||
msgid "Use the credentials below to login"
|
||||
msgstr ""
|
||||
|
||||
#: templates/yearly_overview/pages/overview_by_account.html:7
|
||||
#: templates/yearly_overview/pages/overview_by_currency.html:9
|
||||
msgid "Yearly Overview"
|
||||
|
||||
3007
app/locale/fr/LC_MESSAGES/django.po
Normal file
3007
app/locale/fr/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-03-09 04:55+0000\n"
|
||||
"PO-Revision-Date: 2025-03-09 04:56+0000\n"
|
||||
"POT-Creation-Date: 2025-03-31 05:30+0000\n"
|
||||
"PO-Revision-Date: 2025-03-31 05:38+0000\n"
|
||||
"Last-Translator: Herculino Trotta <netotrotta@gmail.com>\n"
|
||||
"Language-Team: Portuguese (Brazil) <https://translations.herculino.com/"
|
||||
"projects/wygiwyh/app/pt_BR/>\n"
|
||||
@@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||
"X-Generator: Weblate 5.10.2\n"
|
||||
"X-Generator: Weblate 5.10.4\n"
|
||||
|
||||
#: apps/accounts/forms.py:24
|
||||
msgid "Group name"
|
||||
@@ -28,9 +28,9 @@ msgstr "Nome do grupo"
|
||||
#: apps/currencies/forms.py:142 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:202
|
||||
#: apps/transactions/forms.py:269 apps/transactions/forms.py:623
|
||||
#: apps/transactions/forms.py:666 apps/transactions/forms.py:698
|
||||
#: apps/transactions/forms.py:733 apps/transactions/forms.py:881
|
||||
#: apps/transactions/forms.py:269 apps/transactions/forms.py:629
|
||||
#: apps/transactions/forms.py:672 apps/transactions/forms.py:704
|
||||
#: apps/transactions/forms.py:739 apps/transactions/forms.py:891
|
||||
msgid "Update"
|
||||
msgstr "Atualizar"
|
||||
|
||||
@@ -40,9 +40,9 @@ msgstr "Atualizar"
|
||||
#: 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:187 apps/transactions/forms.py:211
|
||||
#: apps/transactions/forms.py:631 apps/transactions/forms.py:674
|
||||
#: apps/transactions/forms.py:706 apps/transactions/forms.py:741
|
||||
#: apps/transactions/forms.py:889
|
||||
#: apps/transactions/forms.py:637 apps/transactions/forms.py:680
|
||||
#: apps/transactions/forms.py:712 apps/transactions/forms.py:747
|
||||
#: apps/transactions/forms.py:899
|
||||
#: templates/account_groups/fragments/list.html:9
|
||||
#: templates/accounts/fragments/list.html:9
|
||||
#: templates/categories/fragments/list.html:9
|
||||
@@ -73,9 +73,9 @@ msgstr "Novo saldo"
|
||||
#: apps/insights/forms.py:118 apps/rules/forms.py:174 apps/rules/forms.py:189
|
||||
#: apps/rules/models.py:38 apps/rules/models.py:286
|
||||
#: apps/transactions/forms.py:40 apps/transactions/forms.py:303
|
||||
#: apps/transactions/forms.py:310 apps/transactions/forms.py:508
|
||||
#: apps/transactions/forms.py:765 apps/transactions/models.py:302
|
||||
#: apps/transactions/models.py:485 apps/transactions/models.py:668
|
||||
#: apps/transactions/forms.py:310 apps/transactions/forms.py:510
|
||||
#: apps/transactions/forms.py:771 apps/transactions/models.py:305
|
||||
#: apps/transactions/models.py:488 apps/transactions/models.py:686
|
||||
#: templates/insights/fragments/category_overview/index.html:9
|
||||
msgid "Category"
|
||||
msgstr "Categoria"
|
||||
@@ -85,18 +85,18 @@ msgstr "Categoria"
|
||||
#: apps/rules/forms.py:177 apps/rules/forms.py:186 apps/rules/models.py:39
|
||||
#: apps/rules/models.py:290 apps/transactions/filters.py:74
|
||||
#: apps/transactions/forms.py:48 apps/transactions/forms.py:319
|
||||
#: apps/transactions/forms.py:327 apps/transactions/forms.py:501
|
||||
#: apps/transactions/forms.py:758 apps/transactions/models.py:308
|
||||
#: apps/transactions/models.py:487 apps/transactions/models.py:672
|
||||
#: apps/transactions/forms.py:327 apps/transactions/forms.py:503
|
||||
#: apps/transactions/forms.py:764 apps/transactions/models.py:311
|
||||
#: apps/transactions/models.py:490 apps/transactions/models.py:690
|
||||
#: templates/includes/navbar.html:108 templates/tags/fragments/list.html:5
|
||||
#: templates/tags/pages/index.html:4
|
||||
msgid "Tags"
|
||||
msgstr "Tags"
|
||||
|
||||
#: apps/accounts/models.py:12 apps/accounts/models.py:28 apps/dca/models.py:13
|
||||
#: 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:198 apps/transactions/models.py:222
|
||||
#: apps/transactions/models.py:245
|
||||
#: apps/transactions/models.py:198 apps/transactions/models.py:223
|
||||
#: apps/transactions/models.py:247
|
||||
#: templates/account_groups/fragments/list.html:25
|
||||
#: templates/accounts/fragments/list.html:25
|
||||
#: templates/categories/fragments/table.html:16
|
||||
@@ -111,7 +111,7 @@ msgstr "Tags"
|
||||
msgid "Name"
|
||||
msgstr "Nome"
|
||||
|
||||
#: apps/accounts/models.py:18 apps/accounts/models.py:32
|
||||
#: apps/accounts/models.py:18 apps/accounts/models.py:33
|
||||
msgid "Account Group"
|
||||
msgstr "Grupo da Conta"
|
||||
|
||||
@@ -121,52 +121,52 @@ msgstr "Grupo da Conta"
|
||||
msgid "Account Groups"
|
||||
msgstr "Grupos da Conta"
|
||||
|
||||
#: apps/accounts/models.py:38 apps/currencies/models.py:39
|
||||
#: apps/accounts/models.py:39 apps/currencies/models.py:39
|
||||
#: templates/accounts/fragments/list.html:27
|
||||
msgid "Currency"
|
||||
msgstr "Moeda"
|
||||
|
||||
#: apps/accounts/models.py:44 apps/currencies/models.py:27
|
||||
#: apps/accounts/models.py:45 apps/currencies/models.py:27
|
||||
#: templates/accounts/fragments/list.html:28
|
||||
msgid "Exchange Currency"
|
||||
msgstr "Moeda de Câmbio"
|
||||
|
||||
#: apps/accounts/models.py:49 apps/currencies/models.py:32
|
||||
#: apps/accounts/models.py:50 apps/currencies/models.py:32
|
||||
msgid "Default currency for exchange calculations"
|
||||
msgstr "Moeda padrão para os cálculos de câmbio"
|
||||
|
||||
#: apps/accounts/models.py:54
|
||||
#: apps/accounts/models.py:55
|
||||
msgid "Asset account"
|
||||
msgstr "Conta de ativos"
|
||||
|
||||
#: apps/accounts/models.py:56
|
||||
#: apps/accounts/models.py:57
|
||||
msgid ""
|
||||
"Asset accounts count towards your Net Worth, but not towards your month."
|
||||
msgstr ""
|
||||
"As contas de ativos contam para o seu patrimônio líquido, mas não para o seu "
|
||||
"mês."
|
||||
|
||||
#: apps/accounts/models.py:61 templates/accounts/fragments/list.html:30
|
||||
#: apps/accounts/models.py:62 templates/accounts/fragments/list.html:30
|
||||
#: templates/categories/fragments/list.html:24
|
||||
#: templates/entities/fragments/list.html:24
|
||||
#: templates/tags/fragments/list.html:24
|
||||
msgid "Archived"
|
||||
msgstr "Arquivada"
|
||||
|
||||
#: apps/accounts/models.py:62
|
||||
#: apps/accounts/models.py:63
|
||||
msgid "Archived accounts don't show up nor count towards your net worth"
|
||||
msgstr ""
|
||||
"Contas arquivadas não aparecem nem contam para o seu patrimônio líquido"
|
||||
|
||||
#: apps/accounts/models.py:69 apps/rules/forms.py:166 apps/rules/forms.py:179
|
||||
#: apps/accounts/models.py:70 apps/rules/forms.py:166 apps/rules/forms.py:179
|
||||
#: apps/rules/models.py:30 apps/rules/models.py:242
|
||||
#: apps/transactions/forms.py:60 apps/transactions/forms.py:493
|
||||
#: apps/transactions/forms.py:750 apps/transactions/models.py:275
|
||||
#: apps/transactions/models.py:445 apps/transactions/models.py:650
|
||||
#: apps/transactions/forms.py:60 apps/transactions/forms.py:495
|
||||
#: apps/transactions/forms.py:756 apps/transactions/models.py:278
|
||||
#: apps/transactions/models.py:448 apps/transactions/models.py:668
|
||||
msgid "Account"
|
||||
msgstr "Conta"
|
||||
|
||||
#: apps/accounts/models.py:70 apps/export_app/forms.py:20
|
||||
#: apps/accounts/models.py:71 apps/export_app/forms.py:20
|
||||
#: 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:114
|
||||
@@ -177,7 +177,7 @@ msgstr "Conta"
|
||||
msgid "Accounts"
|
||||
msgstr "Contas"
|
||||
|
||||
#: apps/accounts/models.py:82
|
||||
#: apps/accounts/models.py:84
|
||||
msgid "Exchange currency cannot be the same as the account's main currency."
|
||||
msgstr "A moeda de câmbio não pode ser a mesma que a moeda principal da conta."
|
||||
|
||||
@@ -188,7 +188,7 @@ msgstr "Grupo de Conta adicionado com sucesso"
|
||||
#: apps/accounts/views/account_groups.py:69
|
||||
#: apps/accounts/views/account_groups.py:152 apps/accounts/views/accounts.py:68
|
||||
#: apps/accounts/views/accounts.py:106 apps/dca/views.py:63
|
||||
#: apps/dca/views.py:146 apps/rules/views.py:99 apps/rules/views.py:195
|
||||
#: apps/dca/views.py:146 apps/rules/views.py:105 apps/rules/views.py:205
|
||||
#: apps/transactions/views/categories.py:91
|
||||
#: apps/transactions/views/categories.py:129
|
||||
#: apps/transactions/views/entities.py:91
|
||||
@@ -203,7 +203,7 @@ msgstr "Grupo de Conta atualizado com sucesso"
|
||||
|
||||
#: apps/accounts/views/account_groups.py:111
|
||||
#: apps/accounts/views/accounts.py:145 apps/dca/views.py:105
|
||||
#: apps/rules/views.py:154 apps/transactions/views/categories.py:168
|
||||
#: apps/rules/views.py:162 apps/transactions/views/categories.py:168
|
||||
#: apps/transactions/views/entities.py:130 apps/transactions/views/tags.py:130
|
||||
msgid "Item no longer shared with you"
|
||||
msgstr "Item não está mais compartilhado com você"
|
||||
@@ -214,14 +214,14 @@ msgstr "Grupo de Conta apagado com sucesso"
|
||||
|
||||
#: apps/accounts/views/account_groups.py:135
|
||||
#: apps/accounts/views/accounts.py:169 apps/dca/views.py:129
|
||||
#: apps/rules/views.py:178 apps/transactions/views/categories.py:192
|
||||
#: apps/rules/views.py:187 apps/transactions/views/categories.py:192
|
||||
#: apps/transactions/views/entities.py:154 apps/transactions/views/tags.py:154
|
||||
msgid "Ownership taken successfully"
|
||||
msgstr "Propriedade assumida com sucesso"
|
||||
|
||||
#: apps/accounts/views/account_groups.py:165
|
||||
#: apps/accounts/views/accounts.py:119 apps/dca/views.py:159
|
||||
#: apps/rules/views.py:208 apps/transactions/views/categories.py:142
|
||||
#: apps/rules/views.py:218 apps/transactions/views/categories.py:142
|
||||
#: apps/transactions/views/entities.py:184 apps/transactions/views/tags.py:184
|
||||
msgid "Configuration saved successfully"
|
||||
msgstr "Configuração salva com sucesso"
|
||||
@@ -451,7 +451,7 @@ msgstr "Sufixo"
|
||||
#: apps/currencies/forms.py:69 apps/dca/models.py:158 apps/rules/forms.py:169
|
||||
#: apps/rules/forms.py:182 apps/rules/models.py:33 apps/rules/models.py:254
|
||||
#: apps/transactions/forms.py:64 apps/transactions/forms.py:331
|
||||
#: apps/transactions/models.py:285
|
||||
#: apps/transactions/models.py:288
|
||||
#: templates/dca/fragments/strategy/details.html:52
|
||||
#: templates/exchange_rates/fragments/table.html:10
|
||||
#: templates/exchange_rates_services/fragments/table.html:10
|
||||
@@ -481,59 +481,59 @@ msgstr "Casas Decimais"
|
||||
msgid "Currencies"
|
||||
msgstr "Moedas"
|
||||
|
||||
#: apps/currencies/models.py:48
|
||||
#: apps/currencies/models.py:49
|
||||
msgid "Currency cannot have itself as exchange currency."
|
||||
msgstr "A moeda não pode ter a si mesma como moeda de câmbio."
|
||||
|
||||
#: apps/currencies/models.py:59
|
||||
#: apps/currencies/models.py:60
|
||||
msgid "From Currency"
|
||||
msgstr "Moeda de origem"
|
||||
|
||||
#: apps/currencies/models.py:65
|
||||
#: apps/currencies/models.py:66
|
||||
msgid "To Currency"
|
||||
msgstr "Moeda de destino"
|
||||
|
||||
#: apps/currencies/models.py:68 apps/currencies/models.py:73
|
||||
#: apps/currencies/models.py:69 apps/currencies/models.py:74
|
||||
msgid "Exchange Rate"
|
||||
msgstr "Taxa de Câmbio"
|
||||
|
||||
#: apps/currencies/models.py:70
|
||||
#: apps/currencies/models.py:71
|
||||
msgid "Date and Time"
|
||||
msgstr "Data e Tempo"
|
||||
|
||||
#: apps/currencies/models.py:74 apps/export_app/forms.py:68
|
||||
#: apps/currencies/models.py:75 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:126
|
||||
msgid "Exchange Rates"
|
||||
msgstr "Taxas de Câmbio"
|
||||
|
||||
#: apps/currencies/models.py:86
|
||||
#: apps/currencies/models.py:87
|
||||
msgid "From and To currencies cannot be the same."
|
||||
msgstr "As moedas De e Para não podem ser as mesmas."
|
||||
|
||||
#: apps/currencies/models.py:101
|
||||
#: apps/currencies/models.py:102
|
||||
msgid "On"
|
||||
msgstr "Em"
|
||||
|
||||
#: apps/currencies/models.py:102
|
||||
#: apps/currencies/models.py:103
|
||||
msgid "Every X hours"
|
||||
msgstr "A cada X horas"
|
||||
|
||||
#: apps/currencies/models.py:103
|
||||
#: apps/currencies/models.py:104
|
||||
msgid "Not on"
|
||||
msgstr "Não em"
|
||||
|
||||
#: apps/currencies/models.py:105
|
||||
#: apps/currencies/models.py:106
|
||||
msgid "Service Name"
|
||||
msgstr "Nome do Serviço"
|
||||
|
||||
#: apps/currencies/models.py:107
|
||||
#: apps/currencies/models.py:108
|
||||
msgid "Service Type"
|
||||
msgstr "Tipo de Serviço"
|
||||
|
||||
#: apps/currencies/models.py:109 apps/transactions/models.py:202
|
||||
#: apps/transactions/models.py:225 apps/transactions/models.py:248
|
||||
#: apps/currencies/models.py:110 apps/transactions/models.py:202
|
||||
#: apps/transactions/models.py:226 apps/transactions/models.py:250
|
||||
#: templates/categories/fragments/list.html:21
|
||||
#: templates/entities/fragments/list.html:21
|
||||
#: templates/recurring_transactions/fragments/list.html:21
|
||||
@@ -541,31 +541,31 @@ msgstr "Tipo de Serviço"
|
||||
msgid "Active"
|
||||
msgstr "Ativo"
|
||||
|
||||
#: apps/currencies/models.py:114
|
||||
#: apps/currencies/models.py:115
|
||||
msgid "API Key"
|
||||
msgstr "Chave de API"
|
||||
|
||||
#: apps/currencies/models.py:115
|
||||
#: apps/currencies/models.py:116
|
||||
msgid "API key for the service (if required)"
|
||||
msgstr "Chave de API para o serviço (se necessário)"
|
||||
|
||||
#: apps/currencies/models.py:120
|
||||
#: apps/currencies/models.py:121
|
||||
msgid "Interval Type"
|
||||
msgstr "Tipo de Intervalo"
|
||||
|
||||
#: apps/currencies/models.py:124
|
||||
#: apps/currencies/models.py:125
|
||||
msgid "Interval"
|
||||
msgstr "Intervalo"
|
||||
|
||||
#: apps/currencies/models.py:127
|
||||
#: apps/currencies/models.py:128
|
||||
msgid "Last Successful Fetch"
|
||||
msgstr "Última execução bem-sucedida"
|
||||
|
||||
#: apps/currencies/models.py:132
|
||||
#: apps/currencies/models.py:133
|
||||
msgid "Target Currencies"
|
||||
msgstr "Moedas-alvo"
|
||||
|
||||
#: apps/currencies/models.py:134
|
||||
#: apps/currencies/models.py:135
|
||||
msgid ""
|
||||
"Select currencies to fetch exchange rates for. Rates will be fetched for "
|
||||
"each currency against their set exchange currency."
|
||||
@@ -573,11 +573,11 @@ msgstr ""
|
||||
"Selecione as moedas para as quais deseja obter as taxas de câmbio. As taxas "
|
||||
"serão obtidas para cada moeda em relação à moeda de câmbio definida."
|
||||
|
||||
#: apps/currencies/models.py:142
|
||||
#: apps/currencies/models.py:143
|
||||
msgid "Target Accounts"
|
||||
msgstr "Contas-alvo"
|
||||
|
||||
#: apps/currencies/models.py:144
|
||||
#: apps/currencies/models.py:145
|
||||
msgid ""
|
||||
"Select accounts to fetch exchange rates for. Rates will be fetched for each "
|
||||
"account's currency against their set exchange currency."
|
||||
@@ -586,24 +586,24 @@ msgstr ""
|
||||
"serão obtidas para a moeda de cada conta em relação à moeda de câmbio "
|
||||
"definida."
|
||||
|
||||
#: apps/currencies/models.py:151
|
||||
#: apps/currencies/models.py:152
|
||||
msgid "Exchange Rate Service"
|
||||
msgstr "Serviço de Taxa de Câmbio"
|
||||
|
||||
#: apps/currencies/models.py:152
|
||||
#: apps/currencies/models.py:153
|
||||
msgid "Exchange Rate Services"
|
||||
msgstr "Serviços de Taxa de Câmbio"
|
||||
|
||||
#: apps/currencies/models.py:204
|
||||
#: apps/currencies/models.py:205
|
||||
msgid "'Every X hours' interval type requires a positive integer."
|
||||
msgstr ""
|
||||
"Intervalo do tipo 'A cada X horas' requerer um número inteiro positivo."
|
||||
|
||||
#: apps/currencies/models.py:213
|
||||
#: apps/currencies/models.py:214
|
||||
msgid "'Every X hours' interval must be between 1 and 24."
|
||||
msgstr "Intervalo do tipo 'A cada X horas' requerer um número entre 1 e 24."
|
||||
|
||||
#: apps/currencies/models.py:227
|
||||
#: apps/currencies/models.py:228
|
||||
msgid ""
|
||||
"Invalid hour format. Use comma-separated hours (0-23) and/or ranges (e.g., "
|
||||
"'1-5,8,10-12')."
|
||||
@@ -611,7 +611,7 @@ msgstr ""
|
||||
"Formato inválido de hora. Use uma lista de horas separada por vírgulas "
|
||||
"(0-23) e/ou uma faixa (ex.: '1-5,8,10-12')."
|
||||
|
||||
#: apps/currencies/models.py:238
|
||||
#: apps/currencies/models.py:239
|
||||
msgid ""
|
||||
"Invalid format. Please check the requirements for your selected interval "
|
||||
"type."
|
||||
@@ -643,19 +643,19 @@ msgstr "Taxa de câmbio atualizada com sucesso"
|
||||
msgid "Exchange rate deleted successfully"
|
||||
msgstr "Taxa de câmbio apagada com sucesso"
|
||||
|
||||
#: apps/currencies/views/exchange_rates_services.py:46
|
||||
#: apps/currencies/views/exchange_rates_services.py:50
|
||||
msgid "Service added successfully"
|
||||
msgstr "Serviço adicionado com sucesso"
|
||||
|
||||
#: apps/currencies/views/exchange_rates_services.py:74
|
||||
#: apps/currencies/views/exchange_rates_services.py:79
|
||||
msgid "Service updated successfully"
|
||||
msgstr "Serviço atualizado com sucesso"
|
||||
|
||||
#: apps/currencies/views/exchange_rates_services.py:100
|
||||
#: apps/currencies/views/exchange_rates_services.py:106
|
||||
msgid "Service deleted successfully"
|
||||
msgstr "Serviço apagado com sucesso"
|
||||
|
||||
#: apps/currencies/views/exchange_rates_services.py:115
|
||||
#: apps/currencies/views/exchange_rates_services.py:122
|
||||
msgid "Services queued successfully"
|
||||
msgstr "Serviços marcados para execução com sucesso"
|
||||
|
||||
@@ -692,7 +692,7 @@ msgstr "Conectar transação"
|
||||
msgid "You must provide an account."
|
||||
msgstr "Você deve informar uma conta."
|
||||
|
||||
#: apps/dca/forms.py:312 apps/transactions/forms.py:443
|
||||
#: apps/dca/forms.py:312 apps/transactions/forms.py:445
|
||||
msgid "From and To accounts must be different."
|
||||
msgstr "As contas De e Para devem ser diferentes."
|
||||
|
||||
@@ -711,8 +711,8 @@ msgstr "Moeda de pagamento"
|
||||
|
||||
#: apps/dca/models.py:26 apps/dca/models.py:181 apps/rules/forms.py:173
|
||||
#: apps/rules/forms.py:188 apps/rules/models.py:37 apps/rules/models.py:270
|
||||
#: apps/transactions/forms.py:345 apps/transactions/models.py:298
|
||||
#: apps/transactions/models.py:494 apps/transactions/models.py:678
|
||||
#: apps/transactions/forms.py:347 apps/transactions/models.py:301
|
||||
#: apps/transactions/models.py:497 apps/transactions/models.py:696
|
||||
msgid "Notes"
|
||||
msgstr "Notas"
|
||||
|
||||
@@ -773,7 +773,7 @@ msgid "Users"
|
||||
msgstr "Usuários"
|
||||
|
||||
#: apps/export_app/forms.py:32 apps/export_app/forms.py:137
|
||||
#: apps/transactions/models.py:359 templates/includes/navbar.html:57
|
||||
#: apps/transactions/models.py:362 templates/includes/navbar.html:57
|
||||
#: templates/includes/navbar.html:104
|
||||
#: templates/recurring_transactions/fragments/list_transactions.html:5
|
||||
#: templates/recurring_transactions/fragments/table.html:37
|
||||
@@ -790,23 +790,23 @@ msgstr "Categorias"
|
||||
#: apps/export_app/forms.py:50 apps/export_app/forms.py:136
|
||||
#: apps/rules/forms.py:178 apps/rules/forms.py:187 apps/rules/models.py:40
|
||||
#: apps/rules/models.py:282 apps/transactions/filters.py:81
|
||||
#: apps/transactions/forms.py:56 apps/transactions/forms.py:516
|
||||
#: apps/transactions/forms.py:773 apps/transactions/models.py:259
|
||||
#: apps/transactions/models.py:313 apps/transactions/models.py:490
|
||||
#: apps/transactions/models.py:675 templates/entities/fragments/list.html:5
|
||||
#: apps/transactions/forms.py:56 apps/transactions/forms.py:518
|
||||
#: apps/transactions/forms.py:779 apps/transactions/models.py:261
|
||||
#: apps/transactions/models.py:316 apps/transactions/models.py:493
|
||||
#: apps/transactions/models.py:693 templates/entities/fragments/list.html:5
|
||||
#: templates/entities/pages/index.html:4 templates/includes/navbar.html:110
|
||||
msgid "Entities"
|
||||
msgstr "Entidades"
|
||||
|
||||
#: apps/export_app/forms.py:56 apps/export_app/forms.py:140
|
||||
#: apps/transactions/models.py:705 templates/includes/navbar.html:74
|
||||
#: apps/transactions/models.py:730 templates/includes/navbar.html:74
|
||||
#: templates/recurring_transactions/fragments/list.html:5
|
||||
#: templates/recurring_transactions/pages/index.html:4
|
||||
msgid "Recurring Transactions"
|
||||
msgstr "Transações Recorrentes"
|
||||
|
||||
#: apps/export_app/forms.py:62 apps/export_app/forms.py:138
|
||||
#: apps/transactions/models.py:501 templates/includes/navbar.html:72
|
||||
#: apps/transactions/models.py:511 templates/includes/navbar.html:72
|
||||
#: templates/installment_plans/fragments/list.html:5
|
||||
#: templates/installment_plans/pages/index.html:4
|
||||
msgid "Installment Plans"
|
||||
@@ -870,15 +870,15 @@ msgstr "Restaurar"
|
||||
msgid "Please upload either a ZIP file or at least one CSV file"
|
||||
msgstr "Carregue um arquivo ZIP ou pelo menos um arquivo CSV"
|
||||
|
||||
#: apps/export_app/views.py:174
|
||||
#: apps/export_app/views.py:177
|
||||
msgid "You have to select at least one export"
|
||||
msgstr "É necessário selecionar pelo menos uma exportação"
|
||||
|
||||
#: apps/export_app/views.py:193
|
||||
#: apps/export_app/views.py:197
|
||||
msgid "Data restored successfully"
|
||||
msgstr "Dados restaurados com sucesso"
|
||||
|
||||
#: apps/export_app/views.py:205
|
||||
#: apps/export_app/views.py:209
|
||||
msgid ""
|
||||
"There was an error restoring your data. Check the logs for more details."
|
||||
msgstr ""
|
||||
@@ -939,23 +939,23 @@ msgstr "Status"
|
||||
msgid "File name"
|
||||
msgstr "Nome do Arquivo"
|
||||
|
||||
#: apps/import_app/views.py:62
|
||||
#: apps/import_app/views.py:67
|
||||
msgid "Import Profile added successfully"
|
||||
msgstr "Perfil de Importação adicionado com sucesso"
|
||||
|
||||
#: apps/import_app/views.py:97
|
||||
#: apps/import_app/views.py:103
|
||||
msgid "Import Profile update successfully"
|
||||
msgstr "Importação atualizada com sucesso"
|
||||
|
||||
#: apps/import_app/views.py:123
|
||||
#: apps/import_app/views.py:130
|
||||
msgid "Import Profile deleted successfully"
|
||||
msgstr "Importação apagada com sucesso"
|
||||
|
||||
#: apps/import_app/views.py:185
|
||||
#: apps/import_app/views.py:195
|
||||
msgid "Import Run queued successfully"
|
||||
msgstr "Importação adicionada à fila com sucesso"
|
||||
|
||||
#: apps/import_app/views.py:211
|
||||
#: apps/import_app/views.py:222
|
||||
msgid "Run deleted successfully"
|
||||
msgstr "Importação apagada com sucesso"
|
||||
|
||||
@@ -1043,14 +1043,14 @@ msgid "Operator"
|
||||
msgstr "Operador"
|
||||
|
||||
#: apps/rules/forms.py:167 apps/rules/forms.py:180 apps/rules/models.py:31
|
||||
#: apps/rules/models.py:246 apps/transactions/models.py:282
|
||||
#: apps/transactions/models.py:450 apps/transactions/models.py:656
|
||||
#: apps/rules/models.py:246 apps/transactions/models.py:285
|
||||
#: apps/transactions/models.py:453 apps/transactions/models.py:674
|
||||
msgid "Type"
|
||||
msgstr "Tipo"
|
||||
|
||||
#: 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:284 templates/cotton/transaction/item.html:21
|
||||
#: apps/transactions/models.py:287 templates/cotton/transaction/item.html:21
|
||||
#: templates/cotton/transaction/item.html:31
|
||||
#: templates/transactions/widgets/paid_toggle_button.html:12
|
||||
#: templates/transactions/widgets/unselectable_paid_toggle_button.html:16
|
||||
@@ -1059,32 +1059,32 @@ msgstr "Pago"
|
||||
|
||||
#: apps/rules/forms.py:170 apps/rules/forms.py:183 apps/rules/models.py:34
|
||||
#: apps/rules/models.py:258 apps/transactions/forms.py:68
|
||||
#: apps/transactions/forms.py:334 apps/transactions/forms.py:522
|
||||
#: apps/transactions/models.py:286 apps/transactions/models.py:468
|
||||
#: apps/transactions/models.py:680
|
||||
#: apps/transactions/forms.py:334 apps/transactions/forms.py:524
|
||||
#: apps/transactions/models.py:289 apps/transactions/models.py:471
|
||||
#: apps/transactions/models.py:698
|
||||
msgid "Reference Date"
|
||||
msgstr "Data de Referência"
|
||||
|
||||
#: apps/rules/forms.py:171 apps/rules/forms.py:184 apps/rules/models.py:35
|
||||
#: apps/rules/models.py:262 apps/transactions/models.py:291
|
||||
#: apps/transactions/models.py:661 templates/insights/fragments/sankey.html:95
|
||||
#: apps/rules/models.py:262 apps/transactions/models.py:294
|
||||
#: apps/transactions/models.py:679 templates/insights/fragments/sankey.html:95
|
||||
msgid "Amount"
|
||||
msgstr "Quantia"
|
||||
|
||||
#: apps/rules/forms.py:172 apps/rules/forms.py:185 apps/rules/models.py:14
|
||||
#: apps/rules/models.py:36 apps/rules/models.py:266
|
||||
#: apps/transactions/forms.py:337 apps/transactions/models.py:296
|
||||
#: apps/transactions/models.py:452 apps/transactions/models.py:664
|
||||
#: apps/transactions/forms.py:338 apps/transactions/models.py:299
|
||||
#: apps/transactions/models.py:455 apps/transactions/models.py:682
|
||||
msgid "Description"
|
||||
msgstr "Descrição"
|
||||
|
||||
#: apps/rules/forms.py:175 apps/rules/forms.py:190 apps/rules/models.py:274
|
||||
#: apps/transactions/models.py:335
|
||||
#: apps/transactions/models.py:338
|
||||
msgid "Internal Note"
|
||||
msgstr "Nota Interna"
|
||||
|
||||
#: apps/rules/forms.py:176 apps/rules/forms.py:191 apps/rules/models.py:278
|
||||
#: apps/transactions/models.py:337
|
||||
#: apps/transactions/models.py:340
|
||||
msgid "Internal ID"
|
||||
msgstr "ID Interna"
|
||||
|
||||
@@ -1172,43 +1172,43 @@ msgstr ""
|
||||
msgid "Update or create transaction action"
|
||||
msgstr "Ação de atualizar ou criar transação"
|
||||
|
||||
#: apps/rules/views.py:54
|
||||
#: apps/rules/views.py:58
|
||||
msgid "Rule deactivated successfully"
|
||||
msgstr "Regra desativada com sucesso"
|
||||
|
||||
#: apps/rules/views.py:56
|
||||
#: apps/rules/views.py:60
|
||||
msgid "Rule activated successfully"
|
||||
msgstr "Regra ativada com sucesso"
|
||||
|
||||
#: apps/rules/views.py:74
|
||||
#: apps/rules/views.py:79
|
||||
msgid "Rule added successfully"
|
||||
msgstr "Regra adicionada com sucesso"
|
||||
|
||||
#: apps/rules/views.py:112
|
||||
#: apps/rules/views.py:118
|
||||
msgid "Rule updated successfully"
|
||||
msgstr "Regra atualizada com sucesso"
|
||||
|
||||
#: apps/rules/views.py:157
|
||||
#: apps/rules/views.py:165
|
||||
msgid "Rule deleted successfully"
|
||||
msgstr "Regra apagada com sucesso"
|
||||
|
||||
#: apps/rules/views.py:270
|
||||
#: apps/rules/views.py:282
|
||||
msgid "Action updated successfully"
|
||||
msgstr "Ação atualizada com sucesso"
|
||||
|
||||
#: apps/rules/views.py:300
|
||||
#: apps/rules/views.py:313
|
||||
msgid "Action deleted successfully"
|
||||
msgstr "Ação apagada com sucesso"
|
||||
|
||||
#: apps/rules/views.py:323
|
||||
#: apps/rules/views.py:337
|
||||
msgid "Update or Create Transaction action added successfully"
|
||||
msgstr "Ação Atualizar ou Criar Transação adicionada com sucesso"
|
||||
|
||||
#: apps/rules/views.py:355
|
||||
#: apps/rules/views.py:370
|
||||
msgid "Update or Create Transaction action updated successfully"
|
||||
msgstr "Ação Atualizar ou Criar Transação atualizada com sucesso"
|
||||
|
||||
#: apps/rules/views.py:384
|
||||
#: apps/rules/views.py:400
|
||||
msgid "Update or Create Transaction action deleted successfully"
|
||||
msgstr "Ação Atualizar ou Criar Transação apagada com sucesso"
|
||||
|
||||
@@ -1259,28 +1259,28 @@ msgstr "Quantia de origem"
|
||||
msgid "To Amount"
|
||||
msgstr "Quantia de destino"
|
||||
|
||||
#: apps/transactions/forms.py:410
|
||||
#: apps/transactions/forms.py:412
|
||||
#: templates/cotton/ui/quick_transactions_buttons.html:40
|
||||
msgid "Transfer"
|
||||
msgstr "Transferir"
|
||||
|
||||
#: apps/transactions/forms.py:652
|
||||
#: apps/transactions/forms.py:658
|
||||
msgid "Tag name"
|
||||
msgstr "Nome da Tag"
|
||||
|
||||
#: apps/transactions/forms.py:684
|
||||
#: apps/transactions/forms.py:690
|
||||
msgid "Entity name"
|
||||
msgstr "Nome da entidade"
|
||||
|
||||
#: apps/transactions/forms.py:716
|
||||
#: apps/transactions/forms.py:722
|
||||
msgid "Category name"
|
||||
msgstr "Nome da Categoria"
|
||||
|
||||
#: apps/transactions/forms.py:718
|
||||
#: apps/transactions/forms.py:724
|
||||
msgid "Muted categories won't count towards your monthly total"
|
||||
msgstr "As categorias silenciadas não serão contabilizadas em seu total mensal"
|
||||
|
||||
#: apps/transactions/forms.py:900
|
||||
#: apps/transactions/forms.py:910
|
||||
msgid "End date should be after the start date"
|
||||
msgstr "Data final deve ser após data inicial"
|
||||
|
||||
@@ -1304,17 +1304,17 @@ msgstr "Categoria da Transação"
|
||||
msgid "Transaction Categories"
|
||||
msgstr "Categorias da Trasanção"
|
||||
|
||||
#: apps/transactions/models.py:227
|
||||
#: apps/transactions/models.py:228
|
||||
msgid ""
|
||||
"Deactivated tags won't be able to be selected when creating new transactions"
|
||||
msgstr ""
|
||||
"As tags desativadas não poderão ser selecionadas ao criar novas transações"
|
||||
|
||||
#: apps/transactions/models.py:235 apps/transactions/models.py:236
|
||||
#: apps/transactions/models.py:236 apps/transactions/models.py:237
|
||||
msgid "Transaction Tags"
|
||||
msgstr "Tags da Transação"
|
||||
|
||||
#: apps/transactions/models.py:250
|
||||
#: apps/transactions/models.py:252
|
||||
msgid ""
|
||||
"Deactivated entities won't be able to be selected when creating new "
|
||||
"transactions"
|
||||
@@ -1322,11 +1322,11 @@ msgstr ""
|
||||
"As entidades desativadas não poderão ser selecionadas ao criar novas "
|
||||
"transações"
|
||||
|
||||
#: apps/transactions/models.py:258
|
||||
#: apps/transactions/models.py:260
|
||||
msgid "Entity"
|
||||
msgstr "Entidade"
|
||||
|
||||
#: apps/transactions/models.py:269
|
||||
#: apps/transactions/models.py:272
|
||||
#: templates/calendar_view/fragments/list.html:42
|
||||
#: templates/calendar_view/fragments/list.html:44
|
||||
#: templates/calendar_view/fragments/list.html:52
|
||||
@@ -1337,7 +1337,7 @@ msgstr "Entidade"
|
||||
msgid "Income"
|
||||
msgstr "Renda"
|
||||
|
||||
#: apps/transactions/models.py:270
|
||||
#: apps/transactions/models.py:273
|
||||
#: templates/calendar_view/fragments/list.html:46
|
||||
#: templates/calendar_view/fragments/list.html:48
|
||||
#: templates/calendar_view/fragments/list.html:56
|
||||
@@ -1347,117 +1347,125 @@ msgstr "Renda"
|
||||
msgid "Expense"
|
||||
msgstr "Despesa"
|
||||
|
||||
#: apps/transactions/models.py:324 apps/transactions/models.py:500
|
||||
#: apps/transactions/models.py:327 apps/transactions/models.py:510
|
||||
msgid "Installment Plan"
|
||||
msgstr "Parcelamento"
|
||||
|
||||
#: apps/transactions/models.py:333 apps/transactions/models.py:704
|
||||
#: apps/transactions/models.py:336 apps/transactions/models.py:729
|
||||
msgid "Recurring Transaction"
|
||||
msgstr "Transação Recorrente"
|
||||
|
||||
#: apps/transactions/models.py:341
|
||||
#: apps/transactions/models.py:344
|
||||
msgid "Deleted"
|
||||
msgstr "Apagado"
|
||||
|
||||
#: apps/transactions/models.py:346
|
||||
#: apps/transactions/models.py:349
|
||||
msgid "Deleted At"
|
||||
msgstr "Apagado Em"
|
||||
|
||||
#: apps/transactions/models.py:358
|
||||
#: apps/transactions/models.py:361
|
||||
msgid "Transaction"
|
||||
msgstr "Transação"
|
||||
|
||||
#: apps/transactions/models.py:430 templates/tags/fragments/table.html:71
|
||||
#: apps/transactions/models.py:433 templates/tags/fragments/table.html:71
|
||||
msgid "No tags"
|
||||
msgstr "Nenhuma tag"
|
||||
|
||||
#: apps/transactions/models.py:431
|
||||
#: apps/transactions/models.py:434
|
||||
msgid "No category"
|
||||
msgstr "Sem categoria"
|
||||
|
||||
#: apps/transactions/models.py:433
|
||||
#: apps/transactions/models.py:436
|
||||
msgid "No description"
|
||||
msgstr "Sem descrição"
|
||||
|
||||
#: apps/transactions/models.py:439
|
||||
#: apps/transactions/models.py:442
|
||||
msgid "Yearly"
|
||||
msgstr "Anual"
|
||||
|
||||
#: apps/transactions/models.py:440 apps/users/models.py:26
|
||||
#: apps/transactions/models.py:443 apps/users/models.py:26
|
||||
#: templates/includes/navbar.html:26
|
||||
msgid "Monthly"
|
||||
msgstr "Mensal"
|
||||
|
||||
#: apps/transactions/models.py:441
|
||||
#: apps/transactions/models.py:444
|
||||
msgid "Weekly"
|
||||
msgstr "Semanal"
|
||||
|
||||
#: apps/transactions/models.py:442
|
||||
#: apps/transactions/models.py:445
|
||||
msgid "Daily"
|
||||
msgstr "Diária"
|
||||
|
||||
#: apps/transactions/models.py:455
|
||||
#: apps/transactions/models.py:458
|
||||
msgid "Number of Installments"
|
||||
msgstr "Número de Parcelas"
|
||||
|
||||
#: apps/transactions/models.py:460
|
||||
#: apps/transactions/models.py:463
|
||||
msgid "Installment Start"
|
||||
msgstr "Parcela inicial"
|
||||
|
||||
#: apps/transactions/models.py:461
|
||||
#: apps/transactions/models.py:464
|
||||
msgid "The installment number to start counting from"
|
||||
msgstr "O número da parcela a partir do qual se inicia a contagem"
|
||||
|
||||
#: apps/transactions/models.py:466 apps/transactions/models.py:684
|
||||
#: apps/transactions/models.py:469 apps/transactions/models.py:702
|
||||
msgid "Start Date"
|
||||
msgstr "Data de Início"
|
||||
|
||||
#: apps/transactions/models.py:470 apps/transactions/models.py:685
|
||||
#: apps/transactions/models.py:473 apps/transactions/models.py:703
|
||||
msgid "End Date"
|
||||
msgstr "Data Final"
|
||||
|
||||
#: apps/transactions/models.py:475
|
||||
#: apps/transactions/models.py:478
|
||||
msgid "Recurrence"
|
||||
msgstr "Recorrência"
|
||||
|
||||
#: apps/transactions/models.py:478
|
||||
#: apps/transactions/models.py:481
|
||||
msgid "Installment Amount"
|
||||
msgstr "Valor da Parcela"
|
||||
|
||||
#: apps/transactions/models.py:643
|
||||
#: apps/transactions/models.py:500 apps/transactions/models.py:719
|
||||
msgid "Add description to transactions"
|
||||
msgstr "Adicionar descrição às transações"
|
||||
|
||||
#: apps/transactions/models.py:503 apps/transactions/models.py:722
|
||||
msgid "Add notes to transactions"
|
||||
msgstr "Adicionar notas às transações"
|
||||
|
||||
#: apps/transactions/models.py:661
|
||||
msgid "day(s)"
|
||||
msgstr "dia(s)"
|
||||
|
||||
#: apps/transactions/models.py:644
|
||||
#: apps/transactions/models.py:662
|
||||
msgid "week(s)"
|
||||
msgstr "semana(s)"
|
||||
|
||||
#: apps/transactions/models.py:645
|
||||
#: apps/transactions/models.py:663
|
||||
msgid "month(s)"
|
||||
msgstr "mês(es)"
|
||||
|
||||
#: apps/transactions/models.py:646
|
||||
#: apps/transactions/models.py:664
|
||||
msgid "year(s)"
|
||||
msgstr "ano(s)"
|
||||
|
||||
#: apps/transactions/models.py:648
|
||||
#: apps/transactions/models.py:666
|
||||
#: templates/recurring_transactions/fragments/list.html:24
|
||||
msgid "Paused"
|
||||
msgstr "Pausado"
|
||||
|
||||
#: apps/transactions/models.py:687
|
||||
#: apps/transactions/models.py:705
|
||||
msgid "Recurrence Type"
|
||||
msgstr "Tipo de recorrência"
|
||||
|
||||
#: apps/transactions/models.py:690
|
||||
#: apps/transactions/models.py:708
|
||||
msgid "Recurrence Interval"
|
||||
msgstr "Intervalo de recorrência"
|
||||
|
||||
#: apps/transactions/models.py:694
|
||||
#: apps/transactions/models.py:712
|
||||
msgid "Last Generated Date"
|
||||
msgstr "Última data gerada"
|
||||
|
||||
#: apps/transactions/models.py:697
|
||||
#: apps/transactions/models.py:715
|
||||
msgid "Last Generated Reference Date"
|
||||
msgstr "Última data de referência gerada"
|
||||
|
||||
@@ -1634,11 +1642,11 @@ msgstr "Permissões"
|
||||
msgid "Important dates"
|
||||
msgstr "Datas importantes"
|
||||
|
||||
#: apps/users/forms.py:19 apps/users/models.py:13
|
||||
#: apps/users/forms.py:19 apps/users/models.py:13 templates/users/login.html:19
|
||||
msgid "E-mail"
|
||||
msgstr "E-mail"
|
||||
|
||||
#: apps/users/forms.py:25
|
||||
#: apps/users/forms.py:25 templates/users/login.html:20
|
||||
msgid "Password"
|
||||
msgstr "Senha"
|
||||
|
||||
@@ -2507,23 +2515,32 @@ msgstr "Django Admin"
|
||||
msgid "Calculator"
|
||||
msgstr "Calculadora"
|
||||
|
||||
#: templates/includes/navbar/user_menu.html:12
|
||||
#: templates/includes/navbar/user_menu.html:14
|
||||
msgid "Settings"
|
||||
msgstr "Configurações"
|
||||
|
||||
#: templates/includes/navbar/user_menu.html:39
|
||||
#: templates/includes/navbar/user_menu.html:41
|
||||
msgid "Clear cache"
|
||||
msgstr "Limpar cache"
|
||||
|
||||
#: templates/includes/navbar/user_menu.html:43
|
||||
#: templates/includes/navbar/user_menu.html:45
|
||||
msgid "Logout"
|
||||
msgstr "Sair"
|
||||
|
||||
#: templates/includes/scripts/hyperscript/htmx_error_handler.html:5
|
||||
#: templates/includes/scripts/hyperscript/htmx_error_handler.html:8
|
||||
msgid "Access Denied"
|
||||
msgstr "Acesso Negado"
|
||||
|
||||
#: templates/includes/scripts/hyperscript/htmx_error_handler.html:9
|
||||
msgid ""
|
||||
"You do not have permission to perform this action or access this resource."
|
||||
msgstr "Você não tem permissão para executar essa ação ou acessar esse recurso."
|
||||
|
||||
#: templates/includes/scripts/hyperscript/htmx_error_handler.html:18
|
||||
msgid "Something went wrong loading your data"
|
||||
msgstr "Algo deu errado ao carregar seus dados"
|
||||
|
||||
#: templates/includes/scripts/hyperscript/htmx_error_handler.html:6
|
||||
#: templates/includes/scripts/hyperscript/htmx_error_handler.html:19
|
||||
msgid "Try reloading the page or check the console for more information."
|
||||
msgstr ""
|
||||
"Tente recarregar a página ou verifique o console para obter mais informações."
|
||||
@@ -2693,6 +2710,15 @@ msgstr "Isso excluirá o parcelamento e todas as transações associadas a ele"
|
||||
msgid "No installment plans"
|
||||
msgstr "Nenhum parcelamento"
|
||||
|
||||
#: templates/layouts/base.html:40
|
||||
msgid "This is a demo!"
|
||||
msgstr "Isto é uma demonstração!"
|
||||
|
||||
#: templates/layouts/base.html:40
|
||||
msgid "Any data you add here will be wiped in 24hrs or less"
|
||||
msgstr ""
|
||||
"Todos os dados que você adicionar aqui serão apagados em 24 horas ou menos"
|
||||
|
||||
#: templates/mini_tools/currency_converter/currency_converter.html:58
|
||||
msgid "Invert"
|
||||
msgstr "Inverter"
|
||||
@@ -3006,6 +3032,14 @@ msgstr "Reproduzir sons"
|
||||
msgid "Show amounts"
|
||||
msgstr "Mostrar valores"
|
||||
|
||||
#: templates/users/login.html:17
|
||||
msgid "Welcome to WYGIWYH's demo!"
|
||||
msgstr "Boas-vindas à demonstração do WYGIWYH!"
|
||||
|
||||
#: templates/users/login.html:18
|
||||
msgid "Use the credentials below to login"
|
||||
msgstr "Use as credenciais abaixo para fazer login"
|
||||
|
||||
#: templates/yearly_overview/pages/overview_by_account.html:7
|
||||
#: templates/yearly_overview/pages/overview_by_currency.html:9
|
||||
msgid "Yearly Overview"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{% block title %}{% translate 'Transactions on' %} {{ date|date:"SHORT_DATE_FORMAT" }}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div hx-get="{% url 'calendar_transactions_list' day=date.day month=date.month year=date.year %}" hx-trigger="updated from:window" hx-vals='{"disable_selection": true}' hx-target="closest .offcanvas" class="show-loading" id="transactions-list">
|
||||
<div hx-get="{% url 'calendar_transactions_list' day=date.day month=date.month year=date.year %}" hx-trigger="updated from:window" hx-target="closest .offcanvas" class="show-loading" id="transactions-list">
|
||||
{% for transaction in transactions %}
|
||||
<c-transaction.item :transaction="transaction"></c-transaction.item>
|
||||
{% empty %}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
<i class="fa-solid fa-user"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-start dropdown-menu-lg-end">
|
||||
<li class="dropdown-item-text">{{ user.email }}</li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li><a class="dropdown-item"
|
||||
hx-get="{% url 'user_settings' %}"
|
||||
hx-target="#generic-offcanvas"
|
||||
|
||||
@@ -1,15 +1,30 @@
|
||||
{% load i18n %}
|
||||
<script type="text/hyperscript">
|
||||
behavior htmx_error_handler
|
||||
on htmx:responseError or htmx:afterRequest[detail.failed] or htmx:sendError queue none
|
||||
call Swal.fire({title: '{% trans 'Something went wrong loading your data' %}',
|
||||
text: '{% trans 'Try reloading the page or check the console for more information.' %}',
|
||||
icon: 'error',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary'
|
||||
},
|
||||
buttonsStyling: true})
|
||||
then log event
|
||||
then halt the event
|
||||
end
|
||||
behavior htmx_error_handler
|
||||
on htmx:responseError or htmx:afterRequest[detail.failed] or htmx:sendError queue none
|
||||
-- Check if the event detail contains the xhr object and the status is 403
|
||||
if event.detail.xhr.status == 403 then
|
||||
call Swal.fire({
|
||||
title: '{% trans "Access Denied" %}',
|
||||
text: '{% trans "You do not have permission to perform this action or access this resource." %}',
|
||||
icon: 'warning',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-warning' -- Optional: different button style
|
||||
},
|
||||
buttonsStyling: true
|
||||
})
|
||||
else
|
||||
call Swal.fire({
|
||||
title: '{% trans "Something went wrong loading your data" %}',
|
||||
text: '{% trans "Try reloading the page or check the console for more information." %}',
|
||||
icon: 'error',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary'
|
||||
},
|
||||
buttonsStyling: true
|
||||
})
|
||||
end
|
||||
then log event
|
||||
then halt the event
|
||||
end
|
||||
</script>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{% block title %}{% translate 'Installments' %}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div hx-get="{% url 'installment_plan_transactions' installment_plan_id=installment_plan.id %}" hx-trigger="updated from:window" hx-vals='{"disable_selection": true}' hx-target="closest .offcanvas" class="show-loading" id="transactions-list">
|
||||
<div hx-get="{% url 'installment_plan_transactions' installment_plan_id=installment_plan.id %}" hx-trigger="updated from:window" hx-target="closest .offcanvas" class="show-loading" id="transactions-list">
|
||||
{% for transaction in transactions %}
|
||||
<c-transaction.item :transaction="transaction"></c-transaction.item>
|
||||
{% endfor %}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{% load settings %}
|
||||
{% load pwa %}
|
||||
{% load formats %}
|
||||
{% load i18n %}
|
||||
@@ -5,43 +6,53 @@
|
||||
{% load webpack_loader %}
|
||||
<!doctype html>
|
||||
<html lang="en" data-bs-theme="dark">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>
|
||||
{% filter site_title %}
|
||||
{% block title %}
|
||||
{% endblock title %}
|
||||
{% endfilter %}
|
||||
</title>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>
|
||||
{% filter site_title %}
|
||||
{% block title %}
|
||||
{% endblock title %}
|
||||
{% endfilter %}
|
||||
</title>
|
||||
|
||||
{% include 'includes/head/favicons.html' %}
|
||||
{% progressive_web_app_meta %}
|
||||
{% include 'includes/head/favicons.html' %}
|
||||
{% progressive_web_app_meta %}
|
||||
|
||||
{% include 'includes/styles.html' %}
|
||||
{% block extra_styles %}{% endblock %}
|
||||
|
||||
{% include 'includes/scripts.html' %}
|
||||
{% include 'includes/styles.html' %}
|
||||
{% block extra_styles %}{% endblock %}
|
||||
|
||||
{% block extra_js_head %}{% endblock %}
|
||||
</head>
|
||||
<body class="font-monospace">
|
||||
<div _="install hide_amounts
|
||||
{% include 'includes/scripts.html' %}
|
||||
|
||||
{% block extra_js_head %}{% endblock %}
|
||||
</head>
|
||||
<body class="font-monospace">
|
||||
<div _="install hide_amounts
|
||||
install htmx_error_handler
|
||||
{% block body_hyperscript %}{% endblock %}"
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>
|
||||
{% include 'includes/navbar.html' %}
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>
|
||||
{% include 'includes/navbar.html' %}
|
||||
|
||||
<div id="content">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
|
||||
{% include 'includes/offcanvas.html' %}
|
||||
{% include 'includes/toasts.html' %}
|
||||
{% settings "DEMO" as demo_mode %}
|
||||
{% if demo_mode %}
|
||||
<div class="px-3 m-0" id="demo-mode-alert" hx-preserve>
|
||||
<div class="alert alert-warning alert-dismissible fade show my-3" role="alert">
|
||||
<strong>{% trans 'This is a demo!' %}</strong> {% trans 'Any data you add here will be wiped in 24hrs or less' %}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% include 'includes/tools/calculator.html' %}
|
||||
<div id="content">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
|
||||
{% block extra_js_body %}{% endblock %}
|
||||
</body>
|
||||
{% include 'includes/offcanvas.html' %}
|
||||
{% include 'includes/toasts.html' %}
|
||||
</div>
|
||||
|
||||
{% include 'includes/tools/calculator.html' %}
|
||||
|
||||
{% block extra_js_body %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{# Filter transactions form#}
|
||||
<div class="collapse" id="collapse-filter">
|
||||
<div class="collapse" id="collapse-filter" hx-preserve>
|
||||
<div class="card card-body">
|
||||
<form _="on change or submit or search trigger updated on window end
|
||||
install init_tom_select
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{% block title %}{% translate 'Transactions' %}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div hx-get="{% url 'recurring_transaction_transactions' recurring_transaction_id=recurring_transaction.id %}" hx-trigger="updated from:window" hx-vals='{"disable_selection": true}' hx-target="closest .offcanvas" class="show-loading" id="transactions-list">
|
||||
<div hx-get="{% url 'recurring_transaction_transactions' recurring_transaction_id=recurring_transaction.id %}" hx-trigger="updated from:window" hx-target="closest .offcanvas" class="show-loading" id="transactions-list">
|
||||
{% for transaction in transactions %}
|
||||
<c-transaction.item :transaction="transaction"></c-transaction.item>
|
||||
{% endfor %}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
{% extends "layouts/base_auth.html" %}
|
||||
{% load i18n %}
|
||||
{% load settings %}
|
||||
{% load crispy_forms_tags %}
|
||||
|
||||
{% block title %}Login{% endblock %}
|
||||
@@ -7,15 +9,26 @@
|
||||
<div>
|
||||
<div class="container">
|
||||
<div class="row vh-100 d-flex justify-content-center align-items-center">
|
||||
<div class="col-md-6 col-xl-4 col-12">
|
||||
<div class="card shadow-lg">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title text-center mb-4">Login</h2>
|
||||
{% crispy form %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 col-xl-4 col-12">
|
||||
{% settings "DEMO" as demo_mode %}
|
||||
{% if demo_mode %}
|
||||
<div class="card shadow mb-3">
|
||||
<div class="card-body">
|
||||
<h1 class="h5 card-title text-center mb-4">{% trans "Welcome to WYGIWYH's demo!" %}</h1>
|
||||
<p>{% trans 'Use the credentials below to login' %}:</p>
|
||||
<p>{% trans 'E-mail' %}: <span class="badge text-bg-secondary user-select-all">demo@demo.com</span></p>
|
||||
<p>{% trans 'Password' %}: <span class="badge text-bg-secondary user-select-all">wygiwyhdemo</span></p>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="card shadow-lg">
|
||||
<div class="card-body">
|
||||
<h1 class="h2 card-title text-center mb-4">Login</h1>
|
||||
{% crispy form %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -11,4 +11,6 @@ python manage.py migrate
|
||||
# Create flag file to signal migrations are complete
|
||||
touch /tmp/migrations_complete
|
||||
|
||||
python manage.py setup_users
|
||||
|
||||
exec python manage.py runserver 0.0.0.0:8000
|
||||
|
||||
@@ -13,4 +13,6 @@ python manage.py migrate
|
||||
# Create flag file to signal migrations are complete
|
||||
touch /tmp/migrations_complete
|
||||
|
||||
python manage.py setup_users
|
||||
|
||||
exec gunicorn WYGIWYH.wsgi:application --bind 0.0.0.0:8000 --timeout 600
|
||||
|
||||
@@ -14,7 +14,7 @@ djangorestframework~=3.15.2
|
||||
drf-spectacular~=0.27.2
|
||||
django-import-export~=4.3.5
|
||||
|
||||
gunicorn==22.0.0
|
||||
gunicorn==23.0.0
|
||||
whitenoise[brotli]==6.6.0
|
||||
|
||||
watchfiles==0.24.0 # https://github.com/samuelcolvin/watchfiles
|
||||
|
||||
Reference in New Issue
Block a user