mirror of
https://github.com/eitchtee/WYGIWYH.git
synced 2026-04-14 04:49:51 +02:00
Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
448841dadc | ||
|
|
1b6934694e | ||
|
|
d4d00ba02f | ||
|
|
19a65ac45f | ||
|
|
b72e7bd707 | ||
|
|
190be3e813 | ||
|
|
88300b314c | ||
|
|
fab77c8d9f | ||
|
|
1ae7158d7e | ||
|
|
05f0356288 | ||
|
|
b3cea17b8d | ||
|
|
0b66b23f16 | ||
|
|
80fdf70f7d | ||
|
|
fa931b0db2 | ||
|
|
cab79b4203 | ||
|
|
ddab3db6b5 | ||
|
|
9fa704811c | ||
|
|
4c0d14def0 | ||
|
|
43382d2ffe | ||
|
|
27d448afd6 | ||
|
|
1dd90974bd | ||
|
|
31cc8db3ac | ||
|
|
3d85a15ec9 | ||
|
|
90f98c2d15 | ||
|
|
643855e60e | ||
|
|
e0f7b532f8 | ||
|
|
b4d3e4b42f | ||
|
|
9a7ccb0973 | ||
|
|
a9b67ff272 | ||
|
|
233b9629a2 | ||
|
|
4180c177f1 | ||
|
|
f1bc04756f | ||
|
|
13795c797f | ||
|
|
331a7d5b18 | ||
|
|
81b8da30d6 | ||
|
|
80bad240e7 | ||
|
|
187c56c96c | ||
|
|
3796112d77 | ||
|
|
958940089a | ||
|
|
a08548bb13 | ||
|
|
7fe446e510 | ||
|
|
eccb0d15ee | ||
|
|
7ebd329706 | ||
|
|
d3fcd5fe7e | ||
|
|
b0a3acbdde | ||
|
|
33ce38d74c | ||
|
|
fa51a7fef9 | ||
|
|
d7c072a35c | ||
|
|
c88a6dcf3a |
@@ -23,3 +23,5 @@ WEB_CONCURRENCY=4
|
|||||||
ENABLE_SOFT_DELETE=false
|
ENABLE_SOFT_DELETE=false
|
||||||
# If ENABLE_SOFT_DELETE is true, transactions deleted for more than KEEP_DELETED_TRANSACTIONS_FOR days will be truly deleted. Set to 0 to keep all.
|
# If ENABLE_SOFT_DELETE is true, transactions deleted for more than KEEP_DELETED_TRANSACTIONS_FOR days will be truly deleted. Set to 0 to keep all.
|
||||||
KEEP_DELETED_TRANSACTIONS_FOR=365
|
KEEP_DELETED_TRANSACTIONS_FOR=365
|
||||||
|
|
||||||
|
TASK_WORKERS=1 # This only work if you're using the single container option. Increase to have more open queues via procrastinate, you probably don't need to increase this.
|
||||||
|
|||||||
18
.github/workflows/release.yml
vendored
18
.github/workflows/release.yml
vendored
@@ -3,6 +3,8 @@ name: Release Pipeline
|
|||||||
on:
|
on:
|
||||||
release:
|
release:
|
||||||
types: [created]
|
types: [created]
|
||||||
|
push:
|
||||||
|
branches: [ main ]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
IMAGE_NAME: wygiwyh
|
IMAGE_NAME: wygiwyh
|
||||||
@@ -29,7 +31,21 @@ jobs:
|
|||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
- name: Build and push image
|
- name: Build and push nightly image
|
||||||
|
if: github.event_name == 'push'
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: ./docker/prod/django/Dockerfile
|
||||||
|
push: true
|
||||||
|
provenance: false
|
||||||
|
tags: ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:nightly
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
|
||||||
|
- name: Build and push release image
|
||||||
|
if: github.event_name == 'release'
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
|
|||||||
25
README.md
25
README.md
@@ -95,31 +95,16 @@ You can now access localhost:OUTBOUND_PORT
|
|||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> If you're going to use another IP that isn't localhost, add it to `DJANGO_ALLOWED_HOSTS`, without `http://`
|
> If you're going to use another IP that isn't localhost, add it to `DJANGO_ALLOWED_HOSTS`, without `http://`
|
||||||
|
|
||||||
|
|
||||||
## Building from source
|
## Building from source
|
||||||
|
Features are only added to main when ready, if you want to run the latest version, you must build from source.
|
||||||
|
|
||||||
Features are only added to `main` when ready, if you want to run the latest version, you must build from source.
|
All the required Dockerfiles are [here](https://github.com/eitchtee/WYGIWYH/tree/main/docker/prod).
|
||||||
|
|
||||||
```bash
|
## Unraid
|
||||||
# Create a folder for WYGIWYH (optional)
|
|
||||||
$ mkdir WYGIWYH
|
|
||||||
|
|
||||||
# Go into the folder
|
[nwithan8](https://github.com/nwithan8) has kindly provided a Unraid template for WYGIWYH, have a look at the [unraid_templates](https://github.com/nwithan8/unraid_templates) repo.
|
||||||
$ cd WYGIWYH
|
|
||||||
|
|
||||||
# Clone this repository
|
WYGIWYH and WYGIWYH--Procrastinate should be available on the Unraid Store. You need both for all features.
|
||||||
$ git clone https://github.com/eitchtee/WYGIWYH.git .
|
|
||||||
|
|
||||||
$ cp docker-compose.prod.yml docker-compose.yml
|
|
||||||
$ cp .env.example .env
|
|
||||||
# Now edit both files as you see fit
|
|
||||||
|
|
||||||
# Run the app
|
|
||||||
$ docker compose up -d --build
|
|
||||||
|
|
||||||
# Create the first admin account
|
|
||||||
$ docker compose exec -it web python manage.py createsuperuser
|
|
||||||
```
|
|
||||||
|
|
||||||
# How it works
|
# How it works
|
||||||
|
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ INSTALLED_APPS = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
"apps.common.middleware.thread_local.ThreadLocalMiddleware",
|
||||||
"debug_toolbar.middleware.DebugToolbarMiddleware",
|
"debug_toolbar.middleware.DebugToolbarMiddleware",
|
||||||
"django.middleware.security.SecurityMiddleware",
|
"django.middleware.security.SecurityMiddleware",
|
||||||
"whitenoise.middleware.WhiteNoiseMiddleware",
|
"whitenoise.middleware.WhiteNoiseMiddleware",
|
||||||
@@ -221,7 +222,7 @@ SESSION_COOKIE_SECURE = os.getenv("HTTPS_ENABLED", "false").lower() == "true"
|
|||||||
|
|
||||||
DEBUG_TOOLBAR_CONFIG = {
|
DEBUG_TOOLBAR_CONFIG = {
|
||||||
"ROOT_TAG_EXTRA_ATTRS": "hx-preserve",
|
"ROOT_TAG_EXTRA_ATTRS": "hx-preserve",
|
||||||
"SHOW_TOOLBAR_CALLBACK": lambda r: False, # disables it}
|
# "SHOW_TOOLBAR_CALLBACK": lambda r: False, # disables it
|
||||||
}
|
}
|
||||||
DEBUG_TOOLBAR_PANELS = [
|
DEBUG_TOOLBAR_PANELS = [
|
||||||
"debug_toolbar.panels.history.HistoryPanel",
|
"debug_toolbar.panels.history.HistoryPanel",
|
||||||
|
|||||||
31
app/apps/common/functions/format.py
Normal file
31
app/apps/common/functions/format.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
from apps.common.middleware.thread_local import get_current_user
|
||||||
|
from django.utils.formats import get_format as original_get_format
|
||||||
|
|
||||||
|
|
||||||
|
def get_format(format_type=None, lang=None, use_l10n=None):
|
||||||
|
user = get_current_user()
|
||||||
|
|
||||||
|
if user and user.is_authenticated and hasattr(user, "settings"):
|
||||||
|
user_settings = user.settings
|
||||||
|
if format_type == "THOUSAND_SEPARATOR":
|
||||||
|
number_format = getattr(user_settings, "number_format", None)
|
||||||
|
if number_format == "DC":
|
||||||
|
return "."
|
||||||
|
elif number_format == "CD":
|
||||||
|
return ","
|
||||||
|
elif format_type == "DECIMAL_SEPARATOR":
|
||||||
|
number_format = getattr(user_settings, "number_format", None)
|
||||||
|
if number_format == "DC":
|
||||||
|
return ","
|
||||||
|
elif number_format == "CD":
|
||||||
|
return "."
|
||||||
|
elif format_type == "SHORT_DATE_FORMAT":
|
||||||
|
date_format = getattr(user_settings, "date_format", None)
|
||||||
|
if date_format and date_format != "SHORT_DATE_FORMAT":
|
||||||
|
return date_format
|
||||||
|
elif format_type == "SHORT_DATETIME_FORMAT":
|
||||||
|
datetime_format = getattr(user_settings, "datetime_format", None)
|
||||||
|
if datetime_format and datetime_format != "SHORT_DATETIME_FORMAT":
|
||||||
|
return datetime_format
|
||||||
|
|
||||||
|
return original_get_format(format_type, lang, use_l10n)
|
||||||
@@ -1,14 +1,17 @@
|
|||||||
import zoneinfo
|
import zoneinfo
|
||||||
|
|
||||||
|
from django.utils import formats
|
||||||
from django.utils import timezone, translation
|
from django.utils import timezone, translation
|
||||||
from django.utils.translation import activate
|
from django.utils.functional import lazy
|
||||||
|
|
||||||
|
from apps.common.functions.format import get_format as custom_get_format
|
||||||
from apps.users.models import UserSettings
|
from apps.users.models import UserSettings
|
||||||
|
|
||||||
|
|
||||||
class LocalizationMiddleware:
|
class LocalizationMiddleware:
|
||||||
def __init__(self, get_response):
|
def __init__(self, get_response):
|
||||||
self.get_response = get_response
|
self.get_response = get_response
|
||||||
|
self.patch_get_format()
|
||||||
|
|
||||||
def __call__(self, request):
|
def __call__(self, request):
|
||||||
tz = request.COOKIES.get("mytz")
|
tz = request.COOKIES.get("mytz")
|
||||||
@@ -33,9 +36,14 @@ class LocalizationMiddleware:
|
|||||||
timezone.activate(zoneinfo.ZoneInfo("UTC"))
|
timezone.activate(zoneinfo.ZoneInfo("UTC"))
|
||||||
|
|
||||||
if user_language and user_language != "auto":
|
if user_language and user_language != "auto":
|
||||||
activate(user_language)
|
translation.activate(user_language)
|
||||||
else:
|
else:
|
||||||
detected_language = translation.get_language_from_request(request)
|
detected_language = translation.get_language_from_request(request)
|
||||||
activate(detected_language)
|
translation.activate(detected_language)
|
||||||
|
|
||||||
return self.get_response(request)
|
return self.get_response(request)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def patch_get_format():
|
||||||
|
formats.get_format = custom_get_format
|
||||||
|
formats.get_format_lazy = lazy(custom_get_format, str, list, tuple)
|
||||||
|
|||||||
73
app/apps/common/middleware/thread_local.py
Normal file
73
app/apps/common/middleware/thread_local.py
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
"""
|
||||||
|
threadlocals middleware
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
make the request object everywhere available (e.g. in model instance).
|
||||||
|
|
||||||
|
based on: http://code.djangoproject.com/wiki/CookBookThreadlocalsAndUser
|
||||||
|
|
||||||
|
Put this into your settings:
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
MIDDLEWARE_CLASSES = (
|
||||||
|
...
|
||||||
|
'django_tools.middlewares.ThreadLocal.ThreadLocalMiddleware',
|
||||||
|
...
|
||||||
|
)
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
from django_tools.middlewares import ThreadLocal
|
||||||
|
|
||||||
|
# Get the current request object:
|
||||||
|
request = ThreadLocal.get_current_request()
|
||||||
|
|
||||||
|
# You can get the current user directly with:
|
||||||
|
user = ThreadLocal.get_current_user()
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
:copyleft: 2009-2017 by the django-tools team, see AUTHORS for more details.
|
||||||
|
:license: GNU GPL v3 or above, see LICENSE for more details.
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
from threading import local
|
||||||
|
except ImportError:
|
||||||
|
from django.utils._threading_local import local
|
||||||
|
|
||||||
|
try:
|
||||||
|
from django.utils.deprecation import MiddlewareMixin
|
||||||
|
except ImportError:
|
||||||
|
MiddlewareMixin = object # fallback for Django < 1.10
|
||||||
|
|
||||||
|
|
||||||
|
_thread_locals = local()
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_request():
|
||||||
|
"""returns the request object for this thread"""
|
||||||
|
return getattr(_thread_locals, "request", None)
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_user():
|
||||||
|
"""returns the current user, if exist, otherwise returns None"""
|
||||||
|
request = get_current_request()
|
||||||
|
if request:
|
||||||
|
return getattr(request, "user", None)
|
||||||
|
|
||||||
|
|
||||||
|
class ThreadLocalMiddleware(MiddlewareMixin):
|
||||||
|
"""Simple middleware that adds the request object in thread local storage."""
|
||||||
|
|
||||||
|
def process_request(self, request):
|
||||||
|
_thread_locals.request = request
|
||||||
|
|
||||||
|
def process_response(self, request, response):
|
||||||
|
if hasattr(_thread_locals, "request"):
|
||||||
|
del _thread_locals.request
|
||||||
|
return response
|
||||||
|
|
||||||
|
def process_exception(self, request, exception):
|
||||||
|
if hasattr(_thread_locals, "request"):
|
||||||
|
del _thread_locals.request
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from asgiref.sync import sync_to_async
|
||||||
|
from django.core import management
|
||||||
|
|
||||||
from procrastinate import builtin_tasks
|
from procrastinate import builtin_tasks
|
||||||
from procrastinate.contrib.django import app
|
from procrastinate.contrib.django import app
|
||||||
|
|
||||||
@@ -24,3 +27,16 @@ async def remove_old_jobs(context, timestamp):
|
|||||||
exc_info=True,
|
exc_info=True,
|
||||||
)
|
)
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
|
||||||
|
@app.periodic(cron="0 6 1 * *")
|
||||||
|
@app.task(queueing_lock="remove_expired_sessions")
|
||||||
|
async def remove_expired_sessions(timestamp=None):
|
||||||
|
"""Cleanup expired sessions by using Django management command."""
|
||||||
|
try:
|
||||||
|
await sync_to_async(management.call_command)("clearsessions", verbosity=0)
|
||||||
|
except Exception:
|
||||||
|
logger.error(
|
||||||
|
"Error while executing 'remove_expired_sessions' task",
|
||||||
|
exc_info=True,
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
from django import template
|
|
||||||
from django.template.defaultfilters import date as date_filter
|
|
||||||
from django.utils import formats, timezone
|
|
||||||
|
|
||||||
register = template.Library()
|
|
||||||
|
|
||||||
|
|
||||||
@register.filter
|
|
||||||
def custom_date(value, user=None):
|
|
||||||
if not value:
|
|
||||||
return ""
|
|
||||||
|
|
||||||
# Determine if the value is a datetime or just a date
|
|
||||||
is_datetime = hasattr(value, "hour")
|
|
||||||
|
|
||||||
# Convert to current timezone if it's a datetime
|
|
||||||
if is_datetime and timezone.is_aware(value):
|
|
||||||
value = timezone.localtime(value)
|
|
||||||
|
|
||||||
if user and user.is_authenticated:
|
|
||||||
user_settings = user.settings
|
|
||||||
|
|
||||||
if is_datetime:
|
|
||||||
format_setting = user_settings.datetime_format
|
|
||||||
else:
|
|
||||||
format_setting = user_settings.date_format
|
|
||||||
|
|
||||||
return formats.date_format(value, format_setting, use_l10n=True)
|
|
||||||
|
|
||||||
return date_filter(
|
|
||||||
value, "SHORT_DATE_FORMAT" if not is_datetime else "SHORT_DATETIME_FORMAT"
|
|
||||||
)
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
from django import template
|
from django import template
|
||||||
from django.utils.formats import get_format
|
|
||||||
|
|
||||||
|
from apps.common.functions.format import get_format
|
||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
|
||||||
|
|||||||
@@ -13,4 +13,9 @@ urlpatterns = [
|
|||||||
views.month_year_picker,
|
views.month_year_picker,
|
||||||
name="month_year_picker",
|
name="month_year_picker",
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
"cache/invalidate/",
|
||||||
|
views.invalidate_cache,
|
||||||
|
name="invalidate_cache",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ def django_to_python_datetime(django_format):
|
|||||||
def django_to_airdatepicker_datetime(django_format):
|
def django_to_airdatepicker_datetime(django_format):
|
||||||
format_map = {
|
format_map = {
|
||||||
# Time
|
# Time
|
||||||
"h": "h", # Hour (12-hour)
|
"h": "hh", # Hour (12-hour)
|
||||||
"H": "H", # Hour (24-hour)
|
"H": "H", # Hour (24-hour)
|
||||||
"i": "m", # Minutes
|
"i": "m", # Minutes
|
||||||
"A": "AA", # AM/PM uppercase
|
"A": "AA", # AM/PM uppercase
|
||||||
@@ -76,7 +76,7 @@ def django_to_airdatepicker_datetime(django_format):
|
|||||||
def django_to_airdatepicker_datetime_separated(django_format):
|
def django_to_airdatepicker_datetime_separated(django_format):
|
||||||
format_map = {
|
format_map = {
|
||||||
# Time formats
|
# Time formats
|
||||||
"h": "hH", # Hour (12-hour)
|
"h": "hh", # Hour (12-hour)
|
||||||
"H": "HH", # Hour (24-hour)
|
"H": "HH", # Hour (24-hour)
|
||||||
"i": "mm", # Minutes
|
"i": "mm", # Minutes
|
||||||
"A": "AA", # AM/PM uppercase
|
"A": "AA", # AM/PM uppercase
|
||||||
|
|||||||
@@ -1,17 +1,32 @@
|
|||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
|
|
||||||
|
from django.contrib import messages
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
from django.db.models.functions import ExtractYear, ExtractMonth
|
from django.db.models.functions import ExtractYear, ExtractMonth
|
||||||
|
from django.http import HttpResponse
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django.views.decorators.http import require_http_methods
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
from cachalot.api import invalidate
|
||||||
|
|
||||||
|
from apps.common.decorators.htmx import only_htmx
|
||||||
from apps.transactions.models import Transaction
|
from apps.transactions.models import Transaction
|
||||||
|
|
||||||
|
|
||||||
|
@only_htmx
|
||||||
|
@login_required
|
||||||
|
@require_http_methods(["GET"])
|
||||||
def toasts(request):
|
def toasts(request):
|
||||||
return render(request, "common/fragments/toasts.html")
|
return render(request, "common/fragments/toasts.html")
|
||||||
|
|
||||||
|
|
||||||
|
@only_htmx
|
||||||
|
@login_required
|
||||||
|
@require_http_methods(["GET"])
|
||||||
def month_year_picker(request):
|
def month_year_picker(request):
|
||||||
field = request.GET.get("field", "reference_date")
|
field = request.GET.get("field", "reference_date")
|
||||||
for_ = request.GET.get("for", None)
|
for_ = request.GET.get("for", None)
|
||||||
@@ -84,3 +99,19 @@ def month_year_picker(request):
|
|||||||
"current_year": current_year,
|
"current_year": current_year,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@only_htmx
|
||||||
|
@login_required
|
||||||
|
@require_http_methods(["GET"])
|
||||||
|
def invalidate_cache(request):
|
||||||
|
invalidate()
|
||||||
|
|
||||||
|
messages.success(request, _("Cache cleared successfully"))
|
||||||
|
|
||||||
|
return HttpResponse(
|
||||||
|
status=204,
|
||||||
|
headers={
|
||||||
|
"HX-Trigger": "updated",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import datetime
|
|||||||
|
|
||||||
from django.forms import widgets
|
from django.forms import widgets
|
||||||
from django.utils import formats, translation, dates
|
from django.utils import formats, translation, dates
|
||||||
from django.utils.formats import get_format
|
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from apps.common.utils.django import (
|
from apps.common.utils.django import (
|
||||||
@@ -10,6 +9,7 @@ from apps.common.utils.django import (
|
|||||||
django_to_airdatepicker_datetime,
|
django_to_airdatepicker_datetime,
|
||||||
django_to_airdatepicker_datetime_separated,
|
django_to_airdatepicker_datetime_separated,
|
||||||
)
|
)
|
||||||
|
from apps.common.functions.format import get_format
|
||||||
|
|
||||||
|
|
||||||
class AirDatePickerInput(widgets.DateInput):
|
class AirDatePickerInput(widgets.DateInput):
|
||||||
@@ -19,12 +19,10 @@ class AirDatePickerInput(widgets.DateInput):
|
|||||||
format=None,
|
format=None,
|
||||||
clear_button=True,
|
clear_button=True,
|
||||||
auto_close=True,
|
auto_close=True,
|
||||||
user=None,
|
|
||||||
*args,
|
*args,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
attrs = attrs or {}
|
attrs = attrs or {}
|
||||||
self.user = user
|
|
||||||
super().__init__(attrs=attrs, format=format, *args, **kwargs)
|
super().__init__(attrs=attrs, format=format, *args, **kwargs)
|
||||||
self.clear_button = clear_button
|
self.clear_button = clear_button
|
||||||
self.auto_close = auto_close
|
self.auto_close = auto_close
|
||||||
@@ -41,12 +39,6 @@ class AirDatePickerInput(widgets.DateInput):
|
|||||||
if self.format:
|
if self.format:
|
||||||
return self.format
|
return self.format
|
||||||
|
|
||||||
if self.user and hasattr(self.user, "settings"):
|
|
||||||
user_format = self.user.settings.date_format
|
|
||||||
if user_format == "SHORT_DATE_FORMAT":
|
|
||||||
return get_format("SHORT_DATE_FORMAT", use_l10n=True)
|
|
||||||
return user_format
|
|
||||||
|
|
||||||
return get_format("SHORT_DATE_FORMAT", use_l10n=True)
|
return get_format("SHORT_DATE_FORMAT", use_l10n=True)
|
||||||
|
|
||||||
def build_attrs(self, base_attrs, extra_attrs=None):
|
def build_attrs(self, base_attrs, extra_attrs=None):
|
||||||
@@ -97,12 +89,10 @@ class AirDateTimePickerInput(widgets.DateTimeInput):
|
|||||||
timepicker=True,
|
timepicker=True,
|
||||||
clear_button=True,
|
clear_button=True,
|
||||||
auto_close=True,
|
auto_close=True,
|
||||||
user=None,
|
|
||||||
*args,
|
*args,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
attrs = attrs or {}
|
attrs = attrs or {}
|
||||||
self.user = user
|
|
||||||
super().__init__(attrs=attrs, format=format, *args, **kwargs)
|
super().__init__(attrs=attrs, format=format, *args, **kwargs)
|
||||||
self.timepicker = timepicker
|
self.timepicker = timepicker
|
||||||
self.clear_button = clear_button
|
self.clear_button = clear_button
|
||||||
@@ -120,12 +110,6 @@ class AirDateTimePickerInput(widgets.DateTimeInput):
|
|||||||
if self.format:
|
if self.format:
|
||||||
return self.format
|
return self.format
|
||||||
|
|
||||||
if self.user and hasattr(self.user, "settings"):
|
|
||||||
user_format = self.user.settings.datetime_format
|
|
||||||
if user_format == "SHORT_DATETIME_FORMAT":
|
|
||||||
return get_format("SHORT_DATETIME_FORMAT", use_l10n=True)
|
|
||||||
return user_format
|
|
||||||
|
|
||||||
return get_format("SHORT_DATETIME_FORMAT", use_l10n=True)
|
return get_format("SHORT_DATETIME_FORMAT", use_l10n=True)
|
||||||
|
|
||||||
def build_attrs(self, base_attrs, extra_attrs=None):
|
def build_attrs(self, base_attrs, extra_attrs=None):
|
||||||
@@ -148,9 +132,14 @@ class AirDateTimePickerInput(widgets.DateTimeInput):
|
|||||||
|
|
||||||
def format_value(self, value):
|
def format_value(self, value):
|
||||||
"""Format the value for display in the widget."""
|
"""Format the value for display in the widget."""
|
||||||
if value:
|
if value and isinstance(value, (datetime.date, datetime.datetime)):
|
||||||
self.attrs["data-value"] = datetime.datetime.strftime(
|
self.attrs["data-value"] = datetime.datetime.strftime(
|
||||||
value, "%Y-%m-%d %H:%M:00"
|
value, "%Y-%m-%dT%H:%M:00"
|
||||||
|
)
|
||||||
|
elif value and isinstance(value, str):
|
||||||
|
value = datetime.datetime.strptime(value, "%Y-%m-%d %H:%M:00")
|
||||||
|
self.attrs["data-value"] = datetime.datetime.strftime(
|
||||||
|
value, "%Y-%m-%dT%H:%M:00"
|
||||||
)
|
)
|
||||||
|
|
||||||
if value is None:
|
if value is None:
|
||||||
@@ -195,6 +184,7 @@ class AirMonthYearPickerInput(AirDatePickerInput):
|
|||||||
|
|
||||||
# Add data attributes for AirDatepicker configuration
|
# Add data attributes for AirDatepicker configuration
|
||||||
attrs["data-now-button-txt"] = _("Today")
|
attrs["data-now-button-txt"] = _("Today")
|
||||||
|
attrs["data-date-format"] = "MMMM yyyy"
|
||||||
|
|
||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
from decimal import Decimal, InvalidOperation
|
from decimal import Decimal, InvalidOperation
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.utils.formats import get_format, number_format
|
from django.utils.formats import number_format
|
||||||
|
|
||||||
|
from apps.common.functions.format import get_format
|
||||||
|
|
||||||
|
|
||||||
def convert_to_decimal(value: str):
|
def convert_to_decimal(value: str):
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ class ExchangeRateForm(forms.ModelForm):
|
|||||||
model = ExchangeRate
|
model = ExchangeRate
|
||||||
fields = ["from_currency", "to_currency", "rate", "date"]
|
fields = ["from_currency", "to_currency", "rate", "date"]
|
||||||
|
|
||||||
def __init__(self, *args, user=None, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
self.helper = FormHelper()
|
self.helper = FormHelper()
|
||||||
@@ -81,9 +81,7 @@ class ExchangeRateForm(forms.ModelForm):
|
|||||||
self.helper.layout = Layout("date", "from_currency", "to_currency", "rate")
|
self.helper.layout = Layout("date", "from_currency", "to_currency", "rate")
|
||||||
|
|
||||||
self.fields["rate"].widget = ArbitraryDecimalDisplayNumberInput()
|
self.fields["rate"].widget = ArbitraryDecimalDisplayNumberInput()
|
||||||
self.fields["date"].widget = AirDateTimePickerInput(
|
self.fields["date"].widget = AirDateTimePickerInput(clear_button=False)
|
||||||
clear_button=False, user=user
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.instance and self.instance.pk:
|
if self.instance and self.instance.pk:
|
||||||
self.helper.layout.append(
|
self.helper.layout.append(
|
||||||
|
|||||||
@@ -72,7 +72,9 @@ class ExchangeRate(models.Model):
|
|||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
super().clean()
|
super().clean()
|
||||||
if self.from_currency == self.to_currency:
|
# Check if the attributes exist before comparing them
|
||||||
raise ValidationError(
|
if hasattr(self, "from_currency") and hasattr(self, "to_currency"):
|
||||||
{"to_currency": _("From and To currencies cannot be the same.")}
|
if self.from_currency == self.to_currency:
|
||||||
)
|
raise ValidationError(
|
||||||
|
{"to_currency": _("From and To currencies cannot be the same.")}
|
||||||
|
)
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ def exchange_rates_list_pair(request):
|
|||||||
@require_http_methods(["GET", "POST"])
|
@require_http_methods(["GET", "POST"])
|
||||||
def exchange_rate_add(request):
|
def exchange_rate_add(request):
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
form = ExchangeRateForm(request.POST, user=request.user)
|
form = ExchangeRateForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, _("Exchange rate added successfully"))
|
messages.success(request, _("Exchange rate added successfully"))
|
||||||
@@ -95,7 +95,7 @@ def exchange_rate_add(request):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
form = ExchangeRateForm(user=request.user)
|
form = ExchangeRateForm()
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
@@ -111,7 +111,7 @@ def exchange_rate_edit(request, pk):
|
|||||||
exchange_rate = get_object_or_404(ExchangeRate, id=pk)
|
exchange_rate = get_object_or_404(ExchangeRate, id=pk)
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
form = ExchangeRateForm(request.POST, instance=exchange_rate, user=request.user)
|
form = ExchangeRateForm(request.POST, instance=exchange_rate)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, _("Exchange rate updated successfully"))
|
messages.success(request, _("Exchange rate updated successfully"))
|
||||||
@@ -123,7 +123,7 @@ def exchange_rate_edit(request, pk):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
form = ExchangeRateForm(instance=exchange_rate, user=request.user)
|
form = ExchangeRateForm(instance=exchange_rate)
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class DCAEntryForm(forms.ModelForm):
|
|||||||
"notes": forms.Textarea(attrs={"rows": 3}),
|
"notes": forms.Textarea(attrs={"rows": 3}),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, user=None, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.helper = FormHelper()
|
self.helper = FormHelper()
|
||||||
self.helper.form_tag = False
|
self.helper.form_tag = False
|
||||||
@@ -106,4 +106,4 @@ class DCAEntryForm(forms.ModelForm):
|
|||||||
|
|
||||||
self.fields["amount_paid"].widget = ArbitraryDecimalDisplayNumberInput()
|
self.fields["amount_paid"].widget = ArbitraryDecimalDisplayNumberInput()
|
||||||
self.fields["amount_received"].widget = ArbitraryDecimalDisplayNumberInput()
|
self.fields["amount_received"].widget = ArbitraryDecimalDisplayNumberInput()
|
||||||
self.fields["date"].widget = AirDatePickerInput(clear_button=False, user=user)
|
self.fields["date"].widget = AirDatePickerInput(clear_button=False)
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ def strategy_detail(request, strategy_id):
|
|||||||
def strategy_entry_add(request, strategy_id):
|
def strategy_entry_add(request, strategy_id):
|
||||||
strategy = get_object_or_404(DCAStrategy, id=strategy_id)
|
strategy = get_object_or_404(DCAStrategy, id=strategy_id)
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
form = DCAEntryForm(request.POST, user=request.user)
|
form = DCAEntryForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
entry = form.save(commit=False)
|
entry = form.save(commit=False)
|
||||||
entry.strategy = strategy
|
entry.strategy = strategy
|
||||||
@@ -169,7 +169,7 @@ def strategy_entry_add(request, strategy_id):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
form = DCAEntryForm(user=request.user)
|
form = DCAEntryForm()
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
@@ -184,7 +184,7 @@ def strategy_entry_edit(request, strategy_id, entry_id):
|
|||||||
dca_entry = get_object_or_404(DCAEntry, id=entry_id, strategy__id=strategy_id)
|
dca_entry = get_object_or_404(DCAEntry, id=entry_id, strategy__id=strategy_id)
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
form = DCAEntryForm(request.POST, instance=dca_entry, user=request.user)
|
form = DCAEntryForm(request.POST, instance=dca_entry)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, _("Entry updated successfully"))
|
messages.success(request, _("Entry updated successfully"))
|
||||||
@@ -196,7 +196,7 @@ def strategy_entry_edit(request, strategy_id, entry_id):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
form = DCAEntryForm(instance=dca_entry, user=request.user)
|
form = DCAEntryForm(instance=dca_entry)
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class CSVImportSettings(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class ColumnMapping(BaseModel):
|
class ColumnMapping(BaseModel):
|
||||||
source: Optional[str] = Field(
|
source: Optional[str] | Optional[list[str]] = Field(
|
||||||
default=None,
|
default=None,
|
||||||
description="CSV column header. If None, the field will be generated from transformations",
|
description="CSV column header. If None, the field will be generated from transformations",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -486,8 +486,18 @@ class ImportService:
|
|||||||
mapped_data = {}
|
mapped_data = {}
|
||||||
|
|
||||||
for field, mapping in self.mapping.items():
|
for field, mapping in self.mapping.items():
|
||||||
# If source is None, use None as the initial value
|
value = None
|
||||||
value = row.get(mapping.source) if mapping.source else None
|
|
||||||
|
if isinstance(mapping.source, str):
|
||||||
|
value = row.get(mapping.source)
|
||||||
|
elif isinstance(mapping.source, list):
|
||||||
|
for source in mapping.source:
|
||||||
|
value = row.get(source)
|
||||||
|
if value is not None:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# If source is None, use None as the initial value
|
||||||
|
value = None
|
||||||
|
|
||||||
# Use default_value if value is None
|
# Use default_value if value is None
|
||||||
if value is None:
|
if value is None:
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ def index(request):
|
|||||||
@login_required
|
@login_required
|
||||||
@require_http_methods(["GET"])
|
@require_http_methods(["GET"])
|
||||||
def monthly_overview(request, month: int, year: int):
|
def monthly_overview(request, month: int, year: int):
|
||||||
|
order = request.session.get("monthly_transactions_order", "default")
|
||||||
|
|
||||||
if month < 1 or month > 12:
|
if month < 1 or month > 12:
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
|
|
||||||
@@ -41,7 +43,7 @@ def monthly_overview(request, month: int, year: int):
|
|||||||
previous_month = 12 if month == 1 else month - 1
|
previous_month = 12 if month == 1 else month - 1
|
||||||
previous_year = year - 1 if previous_month == 12 and month == 1 else year
|
previous_year = year - 1 if previous_month == 12 and month == 1 else year
|
||||||
|
|
||||||
f = TransactionsFilter(request.GET, user=request.user)
|
f = TransactionsFilter(request.GET)
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
@@ -54,6 +56,7 @@ def monthly_overview(request, month: int, year: int):
|
|||||||
"previous_month": previous_month,
|
"previous_month": previous_month,
|
||||||
"previous_year": previous_year,
|
"previous_year": previous_year,
|
||||||
"filter": f,
|
"filter": f,
|
||||||
|
"order": order,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -62,9 +65,14 @@ def monthly_overview(request, month: int, year: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@require_http_methods(["GET"])
|
@require_http_methods(["GET"])
|
||||||
def transactions_list(request, month: int, year: int):
|
def transactions_list(request, month: int, year: int):
|
||||||
order = request.GET.get("order")
|
order = request.session.get("monthly_transactions_order", "default")
|
||||||
|
|
||||||
f = TransactionsFilter(request.GET, user=request.user)
|
if "order" in request.GET:
|
||||||
|
order = request.GET["order"]
|
||||||
|
if order != request.session["monthly_transactions_order"]:
|
||||||
|
request.session["monthly_transactions_order"] = order
|
||||||
|
|
||||||
|
f = TransactionsFilter(request.GET)
|
||||||
transactions_filtered = (
|
transactions_filtered = (
|
||||||
f.qs.filter()
|
f.qs.filter()
|
||||||
.filter(
|
.filter(
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ class TransactionsFilter(django_filters.FilterSet):
|
|||||||
"to_amount",
|
"to_amount",
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, data=None, user=None, *args, **kwargs):
|
def __init__(self, data=None, *args, **kwargs):
|
||||||
# if filterset is bound, use initial values as defaults
|
# if filterset is bound, use initial values as defaults
|
||||||
if data is not None:
|
if data is not None:
|
||||||
# get a mutable copy of the QueryDict
|
# get a mutable copy of the QueryDict
|
||||||
@@ -182,5 +182,5 @@ class TransactionsFilter(django_filters.FilterSet):
|
|||||||
|
|
||||||
self.form.fields["to_amount"].widget = ArbitraryDecimalDisplayNumberInput()
|
self.form.fields["to_amount"].widget = ArbitraryDecimalDisplayNumberInput()
|
||||||
self.form.fields["from_amount"].widget = ArbitraryDecimalDisplayNumberInput()
|
self.form.fields["from_amount"].widget = ArbitraryDecimalDisplayNumberInput()
|
||||||
self.form.fields["date_start"].widget = AirDatePickerInput(user=user)
|
self.form.fields["date_start"].widget = AirDatePickerInput()
|
||||||
self.form.fields["date_end"].widget = AirDatePickerInput(user=user)
|
self.form.fields["date_end"].widget = AirDatePickerInput()
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ class TransactionForm(forms.ModelForm):
|
|||||||
"account": TomSelect(clear_button=False, group_by="group"),
|
"account": TomSelect(clear_button=False, group_by="group"),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, user=None, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
# if editing a transaction display non-archived items and it's own item even if it's archived
|
# if editing a transaction display non-archived items and it's own item even if it's archived
|
||||||
@@ -177,7 +177,7 @@ class TransactionForm(forms.ModelForm):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.fields["reference_date"].required = False
|
self.fields["reference_date"].required = False
|
||||||
self.fields["date"].widget = AirDatePickerInput(clear_button=False, user=user)
|
self.fields["date"].widget = AirDatePickerInput(clear_button=False)
|
||||||
|
|
||||||
if self.instance and self.instance.pk:
|
if self.instance and self.instance.pk:
|
||||||
decimal_places = self.instance.account.currency.decimal_places
|
decimal_places = self.instance.account.currency.decimal_places
|
||||||
@@ -333,7 +333,7 @@ class TransferForm(forms.Form):
|
|||||||
label=_("Notes"),
|
label=_("Notes"),
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, user=None, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
self.helper = FormHelper()
|
self.helper = FormHelper()
|
||||||
@@ -402,7 +402,7 @@ class TransferForm(forms.Form):
|
|||||||
|
|
||||||
self.fields["from_amount"].widget = ArbitraryDecimalDisplayNumberInput()
|
self.fields["from_amount"].widget = ArbitraryDecimalDisplayNumberInput()
|
||||||
self.fields["to_amount"].widget = ArbitraryDecimalDisplayNumberInput()
|
self.fields["to_amount"].widget = ArbitraryDecimalDisplayNumberInput()
|
||||||
self.fields["date"].widget = AirDatePickerInput(clear_button=False, user=user)
|
self.fields["date"].widget = AirDatePickerInput(clear_button=False)
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
cleaned_data = super().clean()
|
cleaned_data = super().clean()
|
||||||
@@ -515,7 +515,7 @@ class InstallmentPlanForm(forms.ModelForm):
|
|||||||
"notes": forms.Textarea(attrs={"rows": 3}),
|
"notes": forms.Textarea(attrs={"rows": 3}),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, user=None, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
# if editing display non-archived items and it's own item even if it's archived
|
# if editing display non-archived items and it's own item even if it's archived
|
||||||
@@ -572,9 +572,7 @@ class InstallmentPlanForm(forms.ModelForm):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.fields["installment_amount"].widget = ArbitraryDecimalDisplayNumberInput()
|
self.fields["installment_amount"].widget = ArbitraryDecimalDisplayNumberInput()
|
||||||
self.fields["start_date"].widget = AirDatePickerInput(
|
self.fields["start_date"].widget = AirDatePickerInput(clear_button=False)
|
||||||
clear_button=False, user=user
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.instance and self.instance.pk:
|
if self.instance and self.instance.pk:
|
||||||
self.helper.layout.append(
|
self.helper.layout.append(
|
||||||
@@ -762,7 +760,7 @@ class RecurringTransactionForm(forms.ModelForm):
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, user=None, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
# if editing display non-archived items and it's own item even if it's archived
|
# if editing display non-archived items and it's own item even if it's archived
|
||||||
@@ -819,10 +817,8 @@ class RecurringTransactionForm(forms.ModelForm):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.fields["amount"].widget = ArbitraryDecimalDisplayNumberInput()
|
self.fields["amount"].widget = ArbitraryDecimalDisplayNumberInput()
|
||||||
self.fields["start_date"].widget = AirDatePickerInput(
|
self.fields["start_date"].widget = AirDatePickerInput(clear_button=False)
|
||||||
clear_button=False, user=user
|
self.fields["end_date"].widget = AirDatePickerInput()
|
||||||
)
|
|
||||||
self.fields["end_date"].widget = AirDatePickerInput(user=user)
|
|
||||||
|
|
||||||
if self.instance and self.instance.pk:
|
if self.instance and self.instance.pk:
|
||||||
self.helper.layout.append(
|
self.helper.layout.append(
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class SoftDeleteQuerySet(models.QuerySet):
|
|||||||
class SoftDeleteManager(models.Manager):
|
class SoftDeleteManager(models.Manager):
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
qs = SoftDeleteQuerySet(self.model, using=self._db)
|
qs = SoftDeleteQuerySet(self.model, using=self._db)
|
||||||
return qs if not settings.ENABLE_SOFT_DELETE else qs.filter(deleted=False)
|
return qs.filter(deleted=False)
|
||||||
|
|
||||||
|
|
||||||
class AllObjectsManager(models.Manager):
|
class AllObjectsManager(models.Manager):
|
||||||
@@ -60,7 +60,7 @@ class AllObjectsManager(models.Manager):
|
|||||||
class DeletedObjectsManager(models.Manager):
|
class DeletedObjectsManager(models.Manager):
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
qs = SoftDeleteQuerySet(self.model, using=self._db)
|
qs = SoftDeleteQuerySet(self.model, using=self._db)
|
||||||
return qs if not settings.ENABLE_SOFT_DELETE else qs.filter(deleted=True)
|
return qs.filter(deleted=True)
|
||||||
|
|
||||||
|
|
||||||
class TransactionCategory(models.Model):
|
class TransactionCategory(models.Model):
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ def generate_recurring_transactions(timestamp=None):
|
|||||||
|
|
||||||
@app.periodic(cron="10 1 * * *")
|
@app.periodic(cron="10 1 * * *")
|
||||||
@app.task
|
@app.task
|
||||||
def cleanup_deleted_transactions():
|
def cleanup_deleted_transactions(timestamp=None):
|
||||||
with cachalot_disabled():
|
with cachalot_disabled():
|
||||||
if settings.ENABLE_SOFT_DELETE and settings.KEEP_DELETED_TRANSACTIONS_FOR == 0:
|
if settings.ENABLE_SOFT_DELETE and settings.KEEP_DELETED_TRANSACTIONS_FOR == 0:
|
||||||
return "KEEP_DELETED_TRANSACTIONS_FOR is 0, no cleanup performed."
|
return "KEEP_DELETED_TRANSACTIONS_FOR is 0, no cleanup performed."
|
||||||
@@ -44,7 +44,7 @@ def cleanup_deleted_transactions():
|
|||||||
days=settings.KEEP_DELETED_TRANSACTIONS_FOR
|
days=settings.KEEP_DELETED_TRANSACTIONS_FOR
|
||||||
)
|
)
|
||||||
|
|
||||||
invalidate("transactions.Transaction")
|
invalidate()
|
||||||
|
|
||||||
# Hard delete soft-deleted transactions older than the cutoff date
|
# Hard delete soft-deleted transactions older than the cutoff date
|
||||||
old_transactions = Transaction.deleted_objects.filter(deleted_at__lt=cutoff_date)
|
old_transactions = Transaction.deleted_objects.filter(deleted_at__lt=cutoff_date)
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ def installment_plan_transactions(request, installment_plan_id):
|
|||||||
@require_http_methods(["GET", "POST"])
|
@require_http_methods(["GET", "POST"])
|
||||||
def installment_plan_add(request):
|
def installment_plan_add(request):
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
form = InstallmentPlanForm(request.POST, user=request.user)
|
form = InstallmentPlanForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, _("Installment Plan added successfully"))
|
messages.success(request, _("Installment Plan added successfully"))
|
||||||
@@ -93,7 +93,7 @@ def installment_plan_add(request):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
form = InstallmentPlanForm(user=request.user)
|
form = InstallmentPlanForm()
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
@@ -109,9 +109,7 @@ def installment_plan_edit(request, installment_plan_id):
|
|||||||
installment_plan = get_object_or_404(InstallmentPlan, id=installment_plan_id)
|
installment_plan = get_object_or_404(InstallmentPlan, id=installment_plan_id)
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
form = InstallmentPlanForm(
|
form = InstallmentPlanForm(request.POST, instance=installment_plan)
|
||||||
request.POST, instance=installment_plan, user=request.user
|
|
||||||
)
|
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, _("Installment Plan updated successfully"))
|
messages.success(request, _("Installment Plan updated successfully"))
|
||||||
@@ -123,7 +121,7 @@ def installment_plan_edit(request, installment_plan_id):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
form = InstallmentPlanForm(instance=installment_plan, user=request.user)
|
form = InstallmentPlanForm(instance=installment_plan)
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ def recurring_transaction_transactions(request, recurring_transaction_id):
|
|||||||
@require_http_methods(["GET", "POST"])
|
@require_http_methods(["GET", "POST"])
|
||||||
def recurring_transaction_add(request):
|
def recurring_transaction_add(request):
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
form = RecurringTransactionForm(request.POST, user=request.user)
|
form = RecurringTransactionForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, _("Recurring Transaction added successfully"))
|
messages.success(request, _("Recurring Transaction added successfully"))
|
||||||
@@ -118,7 +118,7 @@ def recurring_transaction_add(request):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
form = RecurringTransactionForm(user=request.user)
|
form = RecurringTransactionForm()
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
@@ -136,9 +136,7 @@ def recurring_transaction_edit(request, recurring_transaction_id):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
form = RecurringTransactionForm(
|
form = RecurringTransactionForm(request.POST, instance=recurring_transaction)
|
||||||
request.POST, instance=recurring_transaction, user=request.user
|
|
||||||
)
|
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, _("Recurring Transaction updated successfully"))
|
messages.success(request, _("Recurring Transaction updated successfully"))
|
||||||
@@ -150,9 +148,7 @@ def recurring_transaction_edit(request, recurring_transaction_id):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
form = RecurringTransactionForm(
|
form = RecurringTransactionForm(instance=recurring_transaction)
|
||||||
instance=recurring_transaction, user=request.user
|
|
||||||
)
|
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ def transaction_add(request):
|
|||||||
).date()
|
).date()
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
form = TransactionForm(request.POST, user=request.user)
|
form = TransactionForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, _("Transaction added successfully"))
|
messages.success(request, _("Transaction added successfully"))
|
||||||
@@ -55,7 +55,6 @@ def transaction_add(request):
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
form = TransactionForm(
|
form = TransactionForm(
|
||||||
user=request.user,
|
|
||||||
initial={
|
initial={
|
||||||
"date": expected_date,
|
"date": expected_date,
|
||||||
"type": transaction_type,
|
"type": transaction_type,
|
||||||
@@ -84,13 +83,12 @@ def transaction_simple_add(request):
|
|||||||
).date()
|
).date()
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
form = TransactionForm(request.POST, user=request.user)
|
form = TransactionForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, _("Transaction added successfully"))
|
messages.success(request, _("Transaction added successfully"))
|
||||||
|
|
||||||
form = TransactionForm(
|
form = TransactionForm(
|
||||||
user=request.user,
|
|
||||||
initial={
|
initial={
|
||||||
"date": expected_date,
|
"date": expected_date,
|
||||||
"type": transaction_type,
|
"type": transaction_type,
|
||||||
@@ -99,7 +97,6 @@ def transaction_simple_add(request):
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
form = TransactionForm(
|
form = TransactionForm(
|
||||||
user=request.user,
|
|
||||||
initial={
|
initial={
|
||||||
"date": expected_date,
|
"date": expected_date,
|
||||||
"type": transaction_type,
|
"type": transaction_type,
|
||||||
@@ -120,7 +117,7 @@ def transaction_edit(request, transaction_id, **kwargs):
|
|||||||
transaction = get_object_or_404(Transaction, id=transaction_id)
|
transaction = get_object_or_404(Transaction, id=transaction_id)
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
form = TransactionForm(request.POST, user=request.user, instance=transaction)
|
form = TransactionForm(request.POST, instance=transaction)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, _("Transaction updated successfully"))
|
messages.success(request, _("Transaction updated successfully"))
|
||||||
@@ -130,7 +127,7 @@ def transaction_edit(request, transaction_id, **kwargs):
|
|||||||
headers={"HX-Trigger": "updated, hide_offcanvas"},
|
headers={"HX-Trigger": "updated, hide_offcanvas"},
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
form = TransactionForm(instance=transaction, user=request.user)
|
form = TransactionForm(instance=transaction)
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
@@ -152,7 +149,7 @@ def transactions_bulk_edit(request):
|
|||||||
count = transactions.count()
|
count = transactions.count()
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
form = BulkEditTransactionForm(request.POST, user=request.user)
|
form = BulkEditTransactionForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
# Apply changes from the form to all selected transactions
|
# Apply changes from the form to all selected transactions
|
||||||
for transaction in transactions:
|
for transaction in transactions:
|
||||||
@@ -184,9 +181,7 @@ def transactions_bulk_edit(request):
|
|||||||
headers={"HX-Trigger": "updated, hide_offcanvas"},
|
headers={"HX-Trigger": "updated, hide_offcanvas"},
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
form = BulkEditTransactionForm(
|
form = BulkEditTransactionForm(initial={"is_paid": None, "type": None})
|
||||||
initial={"is_paid": None, "type": None}, user=request.user
|
|
||||||
)
|
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
"form": form,
|
"form": form,
|
||||||
@@ -276,7 +271,7 @@ def transactions_transfer(request):
|
|||||||
).date()
|
).date()
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
form = TransferForm(request.POST, user=request.user)
|
form = TransferForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, _("Transfer added successfully"))
|
messages.success(request, _("Transfer added successfully"))
|
||||||
@@ -290,7 +285,6 @@ def transactions_transfer(request):
|
|||||||
"reference_date": expected_date,
|
"reference_date": expected_date,
|
||||||
"date": expected_date,
|
"date": expected_date,
|
||||||
},
|
},
|
||||||
user=request.user,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return render(request, "transactions/fragments/transfer.html", {"form": form})
|
return render(request, "transactions/fragments/transfer.html", {"form": form})
|
||||||
@@ -319,15 +313,23 @@ def transaction_pay(request, transaction_id):
|
|||||||
@login_required
|
@login_required
|
||||||
@require_http_methods(["GET"])
|
@require_http_methods(["GET"])
|
||||||
def transaction_all_index(request):
|
def transaction_all_index(request):
|
||||||
f = TransactionsFilter(request.GET, user=request.user)
|
order = request.session.get("all_transactions_order", "default")
|
||||||
return render(request, "transactions/pages/transactions.html", {"filter": f})
|
f = TransactionsFilter(request.GET)
|
||||||
|
return render(
|
||||||
|
request, "transactions/pages/transactions.html", {"filter": f, "order": order}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@only_htmx
|
@only_htmx
|
||||||
@login_required
|
@login_required
|
||||||
@require_http_methods(["GET"])
|
@require_http_methods(["GET"])
|
||||||
def transaction_all_list(request):
|
def transaction_all_list(request):
|
||||||
order = request.GET.get("order")
|
order = request.session.get("all_transactions_order", "default")
|
||||||
|
|
||||||
|
if "order" in request.GET:
|
||||||
|
order = request.GET["order"]
|
||||||
|
if order != request.session["all_transactions_order"]:
|
||||||
|
request.session["all_transactions_order"] = order
|
||||||
|
|
||||||
transactions = Transaction.objects.prefetch_related(
|
transactions = Transaction.objects.prefetch_related(
|
||||||
"account",
|
"account",
|
||||||
@@ -341,7 +343,7 @@ def transaction_all_list(request):
|
|||||||
|
|
||||||
transactions = default_order(transactions, order=order)
|
transactions = default_order(transactions, order=order)
|
||||||
|
|
||||||
f = TransactionsFilter(request.GET, user=request.user, queryset=transactions)
|
f = TransactionsFilter(request.GET, queryset=transactions)
|
||||||
|
|
||||||
page_number = request.GET.get("page", 1)
|
page_number = request.GET.get("page", 1)
|
||||||
paginator = Paginator(f.qs, 100)
|
paginator = Paginator(f.qs, 100)
|
||||||
@@ -371,7 +373,7 @@ def transaction_all_summary(request):
|
|||||||
"installment_plan",
|
"installment_plan",
|
||||||
).all()
|
).all()
|
||||||
|
|
||||||
f = TransactionsFilter(request.GET, user=request.user, queryset=transactions)
|
f = TransactionsFilter(request.GET, queryset=transactions)
|
||||||
|
|
||||||
currency_data = calculate_currency_totals(f.qs.all(), ignore_empty=True)
|
currency_data = calculate_currency_totals(f.qs.all(), ignore_empty=True)
|
||||||
currency_percentages = calculate_percentage_distribution(currency_data)
|
currency_percentages = calculate_percentage_distribution(currency_data)
|
||||||
|
|||||||
@@ -81,6 +81,12 @@ class UserSettingsForm(forms.ModelForm):
|
|||||||
("Y.m.d h:i A", "2025.01.20 03:30 PM"),
|
("Y.m.d h:i A", "2025.01.20 03:30 PM"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
NUMBER_FORMAT_CHOICES = [
|
||||||
|
("AA", _("Default")),
|
||||||
|
("DC", "1.234,50"),
|
||||||
|
("CD", "1,234.50"),
|
||||||
|
]
|
||||||
|
|
||||||
date_format = forms.ChoiceField(
|
date_format = forms.ChoiceField(
|
||||||
choices=DATE_FORMAT_CHOICES, initial="SHORT_DATE_FORMAT", label=_("Date Format")
|
choices=DATE_FORMAT_CHOICES, initial="SHORT_DATE_FORMAT", label=_("Date Format")
|
||||||
)
|
)
|
||||||
@@ -90,6 +96,12 @@ class UserSettingsForm(forms.ModelForm):
|
|||||||
label=_("Datetime Format"),
|
label=_("Datetime Format"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
number_format = forms.ChoiceField(
|
||||||
|
choices=NUMBER_FORMAT_CHOICES,
|
||||||
|
initial="AA",
|
||||||
|
label=_("Number Format"),
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = UserSettings
|
model = UserSettings
|
||||||
fields = [
|
fields = [
|
||||||
@@ -98,6 +110,7 @@ class UserSettingsForm(forms.ModelForm):
|
|||||||
"start_page",
|
"start_page",
|
||||||
"date_format",
|
"date_format",
|
||||||
"datetime_format",
|
"datetime_format",
|
||||||
|
"number_format",
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
@@ -111,6 +124,7 @@ class UserSettingsForm(forms.ModelForm):
|
|||||||
"timezone",
|
"timezone",
|
||||||
"date_format",
|
"date_format",
|
||||||
"datetime_format",
|
"datetime_format",
|
||||||
|
"number_format",
|
||||||
"start_page",
|
"start_page",
|
||||||
FormActions(
|
FormActions(
|
||||||
NoClassSubmit(
|
NoClassSubmit(
|
||||||
|
|||||||
18
app/apps/users/migrations/0017_usersettings_number_format.py
Normal file
18
app/apps/users/migrations/0017_usersettings_number_format.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.1.5 on 2025-01-27 12:32
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('users', '0016_alter_usersettings_language'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='usersettings',
|
||||||
|
name='number_format',
|
||||||
|
field=models.CharField(default='AA', max_length=2, verbose_name='Number Format'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import pytz
|
import pytz
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.db import models
|
|
||||||
from django.contrib.auth.models import AbstractUser, Group
|
from django.contrib.auth.models import AbstractUser, Group
|
||||||
|
from django.db import models
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from apps.users.managers import UserManager
|
from apps.users.managers import UserManager
|
||||||
@@ -44,6 +44,9 @@ class UserSettings(models.Model):
|
|||||||
default="SHORT_DATETIME_FORMAT",
|
default="SHORT_DATETIME_FORMAT",
|
||||||
verbose_name=_("Datetime Format"),
|
verbose_name=_("Datetime Format"),
|
||||||
)
|
)
|
||||||
|
number_format = models.CharField(
|
||||||
|
max_length=2, default="AA", verbose_name=_("Number Format")
|
||||||
|
)
|
||||||
|
|
||||||
language = models.CharField(
|
language = models.CharField(
|
||||||
max_length=10,
|
max_length=10,
|
||||||
@@ -66,3 +69,6 @@ class UserSettings(models.Model):
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.user.email}'s settings"
|
return f"{self.user.email}'s settings"
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
super().clean()
|
||||||
|
|||||||
2319
app/locale/de/LC_MESSAGES/django.po
Normal file
2319
app/locale/de/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
@@ -8,9 +8,9 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-01-25 18:49+0000\n"
|
"POT-Creation-Date: 2025-01-28 00:49+0000\n"
|
||||||
"PO-Revision-Date: 2025-01-26 12:50+0100\n"
|
"PO-Revision-Date: 2025-01-27 13:27-0300\n"
|
||||||
"Last-Translator: Dimitri Decrock <dimitri@fam-decrock.eu>\n"
|
"Last-Translator: Herculino Trotta\n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
"Language: nl\n"
|
"Language: nl\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@@ -24,28 +24,28 @@ msgid "Group name"
|
|||||||
msgstr "Groepsnaam"
|
msgstr "Groepsnaam"
|
||||||
|
|
||||||
#: apps/accounts/forms.py:40 apps/accounts/forms.py:96
|
#: apps/accounts/forms.py:40 apps/accounts/forms.py:96
|
||||||
#: apps/currencies/forms.py:52 apps/currencies/forms.py:92 apps/dca/forms.py:41
|
#: apps/currencies/forms.py:52 apps/currencies/forms.py:90 apps/dca/forms.py:41
|
||||||
#: apps/dca/forms.py:93 apps/import_app/forms.py:34 apps/rules/forms.py:45
|
#: apps/dca/forms.py:93 apps/import_app/forms.py:34 apps/rules/forms.py:45
|
||||||
#: apps/rules/forms.py:87 apps/transactions/forms.py:190
|
#: apps/rules/forms.py:87 apps/transactions/forms.py:190
|
||||||
#: apps/transactions/forms.py:257 apps/transactions/forms.py:583
|
#: apps/transactions/forms.py:257 apps/transactions/forms.py:581
|
||||||
#: apps/transactions/forms.py:626 apps/transactions/forms.py:658
|
#: apps/transactions/forms.py:624 apps/transactions/forms.py:656
|
||||||
#: apps/transactions/forms.py:693 apps/transactions/forms.py:831
|
#: apps/transactions/forms.py:691 apps/transactions/forms.py:827
|
||||||
msgid "Update"
|
msgid "Update"
|
||||||
msgstr "Bijwerken"
|
msgstr "Bijwerken"
|
||||||
|
|
||||||
#: apps/accounts/forms.py:48 apps/accounts/forms.py:104
|
#: apps/accounts/forms.py:48 apps/accounts/forms.py:104
|
||||||
#: apps/common/widgets/tom_select.py:12 apps/currencies/forms.py:60
|
#: apps/common/widgets/tom_select.py:12 apps/currencies/forms.py:60
|
||||||
#: apps/currencies/forms.py:100 apps/dca/forms.py:49 apps/dca/forms.py:102
|
#: apps/currencies/forms.py:98 apps/dca/forms.py:49 apps/dca/forms.py:102
|
||||||
#: apps/import_app/forms.py:42 apps/rules/forms.py:53 apps/rules/forms.py:95
|
#: apps/import_app/forms.py:42 apps/rules/forms.py:53 apps/rules/forms.py:95
|
||||||
#: apps/transactions/forms.py:174 apps/transactions/forms.py:199
|
#: apps/transactions/forms.py:174 apps/transactions/forms.py:199
|
||||||
#: apps/transactions/forms.py:591 apps/transactions/forms.py:634
|
#: apps/transactions/forms.py:589 apps/transactions/forms.py:632
|
||||||
#: apps/transactions/forms.py:666 apps/transactions/forms.py:701
|
#: apps/transactions/forms.py:664 apps/transactions/forms.py:699
|
||||||
#: apps/transactions/forms.py:839
|
#: apps/transactions/forms.py:835
|
||||||
#: templates/account_groups/fragments/list.html:9
|
#: templates/account_groups/fragments/list.html:9
|
||||||
#: templates/accounts/fragments/list.html:9
|
#: templates/accounts/fragments/list.html:9
|
||||||
#: templates/categories/fragments/list.html:9
|
#: templates/categories/fragments/list.html:9
|
||||||
#: templates/currencies/fragments/list.html:9
|
#: templates/currencies/fragments/list.html:9
|
||||||
#: templates/dca/fragments/strategy/details.html:38
|
#: templates/dca/fragments/strategy/details.html:37
|
||||||
#: templates/dca/fragments/strategy/list.html:9
|
#: templates/dca/fragments/strategy/list.html:9
|
||||||
#: templates/entities/fragments/list.html:9
|
#: templates/entities/fragments/list.html:9
|
||||||
#: templates/exchange_rates/fragments/list.html:10
|
#: templates/exchange_rates/fragments/list.html:10
|
||||||
@@ -69,7 +69,7 @@ msgstr "Nieuw saldo"
|
|||||||
#: apps/accounts/forms.py:119 apps/rules/models.py:27
|
#: apps/accounts/forms.py:119 apps/rules/models.py:27
|
||||||
#: apps/transactions/forms.py:39 apps/transactions/forms.py:291
|
#: apps/transactions/forms.py:39 apps/transactions/forms.py:291
|
||||||
#: apps/transactions/forms.py:298 apps/transactions/forms.py:478
|
#: apps/transactions/forms.py:298 apps/transactions/forms.py:478
|
||||||
#: apps/transactions/forms.py:725 apps/transactions/models.py:159
|
#: apps/transactions/forms.py:723 apps/transactions/models.py:159
|
||||||
#: apps/transactions/models.py:311 apps/transactions/models.py:491
|
#: apps/transactions/models.py:311 apps/transactions/models.py:491
|
||||||
msgid "Category"
|
msgid "Category"
|
||||||
msgstr "Categorie"
|
msgstr "Categorie"
|
||||||
@@ -77,7 +77,7 @@ msgstr "Categorie"
|
|||||||
#: apps/accounts/forms.py:126 apps/rules/models.py:28
|
#: apps/accounts/forms.py:126 apps/rules/models.py:28
|
||||||
#: apps/transactions/filters.py:74 apps/transactions/forms.py:47
|
#: apps/transactions/filters.py:74 apps/transactions/forms.py:47
|
||||||
#: apps/transactions/forms.py:307 apps/transactions/forms.py:315
|
#: apps/transactions/forms.py:307 apps/transactions/forms.py:315
|
||||||
#: apps/transactions/forms.py:471 apps/transactions/forms.py:718
|
#: apps/transactions/forms.py:471 apps/transactions/forms.py:716
|
||||||
#: apps/transactions/models.py:165 apps/transactions/models.py:313
|
#: apps/transactions/models.py:165 apps/transactions/models.py:313
|
||||||
#: apps/transactions/models.py:495 templates/includes/navbar.html:98
|
#: apps/transactions/models.py:495 templates/includes/navbar.html:98
|
||||||
#: templates/tags/fragments/list.html:5 templates/tags/pages/index.html:4
|
#: templates/tags/fragments/list.html:5 templates/tags/pages/index.html:4
|
||||||
@@ -151,7 +151,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: apps/accounts/models.py:59 apps/rules/models.py:19
|
#: apps/accounts/models.py:59 apps/rules/models.py:19
|
||||||
#: apps/transactions/forms.py:59 apps/transactions/forms.py:463
|
#: apps/transactions/forms.py:59 apps/transactions/forms.py:463
|
||||||
#: apps/transactions/forms.py:710 apps/transactions/models.py:132
|
#: apps/transactions/forms.py:708 apps/transactions/models.py:132
|
||||||
#: apps/transactions/models.py:271 apps/transactions/models.py:473
|
#: apps/transactions/models.py:271 apps/transactions/models.py:473
|
||||||
msgid "Account"
|
msgid "Account"
|
||||||
msgstr "Rekening"
|
msgstr "Rekening"
|
||||||
@@ -322,11 +322,17 @@ msgstr "Fout"
|
|||||||
msgid "Info"
|
msgid "Info"
|
||||||
msgstr "Info"
|
msgstr "Info"
|
||||||
|
|
||||||
#: apps/common/widgets/datepicker.py:55 apps/common/widgets/datepicker.py:197
|
#: apps/common/views.py:110
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "Category updated successfully"
|
||||||
|
msgid "Cache cleared successfully"
|
||||||
|
msgstr "Categorie succesvol bijgewerkt"
|
||||||
|
|
||||||
|
#: apps/common/widgets/datepicker.py:47 apps/common/widgets/datepicker.py:186
|
||||||
msgid "Today"
|
msgid "Today"
|
||||||
msgstr "Vandaag"
|
msgstr "Vandaag"
|
||||||
|
|
||||||
#: apps/common/widgets/datepicker.py:139
|
#: apps/common/widgets/datepicker.py:123
|
||||||
msgid "Now"
|
msgid "Now"
|
||||||
msgstr "Nu"
|
msgstr "Nu"
|
||||||
|
|
||||||
@@ -356,8 +362,8 @@ msgstr "Achtervoegsel"
|
|||||||
#: apps/currencies/forms.py:68 apps/dca/models.py:156 apps/rules/models.py:22
|
#: apps/currencies/forms.py:68 apps/dca/models.py:156 apps/rules/models.py:22
|
||||||
#: apps/transactions/forms.py:63 apps/transactions/forms.py:319
|
#: apps/transactions/forms.py:63 apps/transactions/forms.py:319
|
||||||
#: apps/transactions/models.py:142
|
#: apps/transactions/models.py:142
|
||||||
#: templates/dca/fragments/strategy/details.html:53
|
#: templates/dca/fragments/strategy/details.html:52
|
||||||
#: templates/exchange_rates/fragments/table.html:11
|
#: templates/exchange_rates/fragments/table.html:10
|
||||||
msgid "Date"
|
msgid "Date"
|
||||||
msgstr "Datum"
|
msgstr "Datum"
|
||||||
|
|
||||||
@@ -407,7 +413,7 @@ msgstr "Datum en Tijd"
|
|||||||
msgid "Exchange Rates"
|
msgid "Exchange Rates"
|
||||||
msgstr "Wisselkoersen"
|
msgstr "Wisselkoersen"
|
||||||
|
|
||||||
#: apps/currencies/models.py:77
|
#: apps/currencies/models.py:79
|
||||||
msgid "From and To currencies cannot be the same."
|
msgid "From and To currencies cannot be the same."
|
||||||
msgstr "Van en Naar munteenheid kunnen niet dezelfde zijn."
|
msgstr "Van en Naar munteenheid kunnen niet dezelfde zijn."
|
||||||
|
|
||||||
@@ -461,11 +467,11 @@ msgstr "DCA Strategieën"
|
|||||||
msgid "Strategy"
|
msgid "Strategy"
|
||||||
msgstr "Strategie"
|
msgstr "Strategie"
|
||||||
|
|
||||||
#: apps/dca/models.py:158 templates/dca/fragments/strategy/details.html:55
|
#: apps/dca/models.py:158 templates/dca/fragments/strategy/details.html:54
|
||||||
msgid "Amount Paid"
|
msgid "Amount Paid"
|
||||||
msgstr "Betaald bedrag"
|
msgstr "Betaald bedrag"
|
||||||
|
|
||||||
#: apps/dca/models.py:161 templates/dca/fragments/strategy/details.html:54
|
#: apps/dca/models.py:161 templates/dca/fragments/strategy/details.html:53
|
||||||
msgid "Amount Received"
|
msgid "Amount Received"
|
||||||
msgstr "Ontvangen bedrag"
|
msgstr "Ontvangen bedrag"
|
||||||
|
|
||||||
@@ -643,7 +649,7 @@ msgstr "Bedrag"
|
|||||||
|
|
||||||
#: apps/rules/models.py:29 apps/transactions/filters.py:81
|
#: apps/rules/models.py:29 apps/transactions/filters.py:81
|
||||||
#: apps/transactions/forms.py:55 apps/transactions/forms.py:486
|
#: apps/transactions/forms.py:55 apps/transactions/forms.py:486
|
||||||
#: apps/transactions/forms.py:733 apps/transactions/models.py:117
|
#: apps/transactions/forms.py:731 apps/transactions/models.py:117
|
||||||
#: apps/transactions/models.py:170 apps/transactions/models.py:316
|
#: apps/transactions/models.py:170 apps/transactions/models.py:316
|
||||||
#: apps/transactions/models.py:498 templates/entities/fragments/list.html:5
|
#: apps/transactions/models.py:498 templates/entities/fragments/list.html:5
|
||||||
#: templates/entities/pages/index.html:4 templates/includes/navbar.html:100
|
#: templates/entities/pages/index.html:4 templates/includes/navbar.html:100
|
||||||
@@ -761,23 +767,23 @@ msgstr "Overschrijving"
|
|||||||
msgid "From and To accounts must be different."
|
msgid "From and To accounts must be different."
|
||||||
msgstr "Van en Naar rekening moeten verschillend zijn."
|
msgstr "Van en Naar rekening moeten verschillend zijn."
|
||||||
|
|
||||||
#: apps/transactions/forms.py:612
|
#: apps/transactions/forms.py:610
|
||||||
msgid "Tag name"
|
msgid "Tag name"
|
||||||
msgstr "Labelnaam"
|
msgstr "Labelnaam"
|
||||||
|
|
||||||
#: apps/transactions/forms.py:644
|
#: apps/transactions/forms.py:642
|
||||||
msgid "Entity name"
|
msgid "Entity name"
|
||||||
msgstr "Naam van bedrijf"
|
msgstr "Naam van bedrijf"
|
||||||
|
|
||||||
#: apps/transactions/forms.py:676
|
#: apps/transactions/forms.py:674
|
||||||
msgid "Category name"
|
msgid "Category name"
|
||||||
msgstr "Naam van categorie"
|
msgstr "Naam van categorie"
|
||||||
|
|
||||||
#: apps/transactions/forms.py:678
|
#: apps/transactions/forms.py:676
|
||||||
msgid "Muted categories won't count towards your monthly total"
|
msgid "Muted categories won't count towards your monthly total"
|
||||||
msgstr "Gedempte categorieën tellen niet mee voor je maandtotaal"
|
msgstr "Gedempte categorieën tellen niet mee voor je maandtotaal"
|
||||||
|
|
||||||
#: apps/transactions/forms.py:850
|
#: apps/transactions/forms.py:846
|
||||||
msgid "End date should be after the start date"
|
msgid "End date should be after the start date"
|
||||||
msgstr "De einddatum moet na de begindatum vallen"
|
msgstr "De einddatum moet na de begindatum vallen"
|
||||||
|
|
||||||
@@ -1046,15 +1052,15 @@ msgstr "Bedrijf succesvol verwijderd"
|
|||||||
msgid "Installment Plan added successfully"
|
msgid "Installment Plan added successfully"
|
||||||
msgstr "Afbetalingsplan succesvol toegevoegd"
|
msgstr "Afbetalingsplan succesvol toegevoegd"
|
||||||
|
|
||||||
#: apps/transactions/views/installment_plans.py:117
|
#: apps/transactions/views/installment_plans.py:115
|
||||||
msgid "Installment Plan updated successfully"
|
msgid "Installment Plan updated successfully"
|
||||||
msgstr "Afbetalingsplan succesvol bijgewerkt"
|
msgstr "Afbetalingsplan succesvol bijgewerkt"
|
||||||
|
|
||||||
#: apps/transactions/views/installment_plans.py:142
|
#: apps/transactions/views/installment_plans.py:140
|
||||||
msgid "Installment Plan refreshed successfully"
|
msgid "Installment Plan refreshed successfully"
|
||||||
msgstr "Afbetalingsplan succesvol vernieuwd"
|
msgstr "Afbetalingsplan succesvol vernieuwd"
|
||||||
|
|
||||||
#: apps/transactions/views/installment_plans.py:160
|
#: apps/transactions/views/installment_plans.py:158
|
||||||
msgid "Installment Plan deleted successfully"
|
msgid "Installment Plan deleted successfully"
|
||||||
msgstr "Afbetalingsplan succesvol verwijderd"
|
msgstr "Afbetalingsplan succesvol verwijderd"
|
||||||
|
|
||||||
@@ -1062,23 +1068,23 @@ msgstr "Afbetalingsplan succesvol verwijderd"
|
|||||||
msgid "Recurring Transaction added successfully"
|
msgid "Recurring Transaction added successfully"
|
||||||
msgstr "Terugkerende Verrichting succesvol toegevoegd"
|
msgstr "Terugkerende Verrichting succesvol toegevoegd"
|
||||||
|
|
||||||
#: apps/transactions/views/recurring_transactions.py:144
|
#: apps/transactions/views/recurring_transactions.py:142
|
||||||
msgid "Recurring Transaction updated successfully"
|
msgid "Recurring Transaction updated successfully"
|
||||||
msgstr "Terugkerende Verrichting succesvol bijgewerkt"
|
msgstr "Terugkerende Verrichting succesvol bijgewerkt"
|
||||||
|
|
||||||
#: apps/transactions/views/recurring_transactions.py:190
|
#: apps/transactions/views/recurring_transactions.py:186
|
||||||
msgid "Recurring transaction unpaused successfully"
|
msgid "Recurring transaction unpaused successfully"
|
||||||
msgstr "Terugkerende Verrichting succesvol hervat"
|
msgstr "Terugkerende Verrichting succesvol hervat"
|
||||||
|
|
||||||
#: apps/transactions/views/recurring_transactions.py:193
|
#: apps/transactions/views/recurring_transactions.py:189
|
||||||
msgid "Recurring transaction paused successfully"
|
msgid "Recurring transaction paused successfully"
|
||||||
msgstr "Terugkerende Verrichting succesvol onderbroken"
|
msgstr "Terugkerende Verrichting succesvol onderbroken"
|
||||||
|
|
||||||
#: apps/transactions/views/recurring_transactions.py:219
|
#: apps/transactions/views/recurring_transactions.py:215
|
||||||
msgid "Recurring transaction finished successfully"
|
msgid "Recurring transaction finished successfully"
|
||||||
msgstr "Terugkerende Verrichting succesvol voltooid"
|
msgstr "Terugkerende Verrichting succesvol voltooid"
|
||||||
|
|
||||||
#: apps/transactions/views/recurring_transactions.py:239
|
#: apps/transactions/views/recurring_transactions.py:235
|
||||||
msgid "Recurring Transaction deleted successfully"
|
msgid "Recurring Transaction deleted successfully"
|
||||||
msgstr "Terugkerende Verrichting succesvol verwijderd"
|
msgstr "Terugkerende Verrichting succesvol verwijderd"
|
||||||
|
|
||||||
@@ -1095,30 +1101,30 @@ msgid "Tag deleted successfully"
|
|||||||
msgstr "Label succesvol verwijderd"
|
msgstr "Label succesvol verwijderd"
|
||||||
|
|
||||||
#: apps/transactions/views/transactions.py:50
|
#: apps/transactions/views/transactions.py:50
|
||||||
#: apps/transactions/views/transactions.py:90
|
#: apps/transactions/views/transactions.py:89
|
||||||
msgid "Transaction added successfully"
|
msgid "Transaction added successfully"
|
||||||
msgstr "Verrichting succesvol toegevoegd"
|
msgstr "Verrichting succesvol toegevoegd"
|
||||||
|
|
||||||
#: apps/transactions/views/transactions.py:126
|
#: apps/transactions/views/transactions.py:123
|
||||||
msgid "Transaction updated successfully"
|
msgid "Transaction updated successfully"
|
||||||
msgstr "Verrichting succesvol bijgewerkt"
|
msgstr "Verrichting succesvol bijgewerkt"
|
||||||
|
|
||||||
#: apps/transactions/views/transactions.py:176
|
#: apps/transactions/views/transactions.py:173
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(count)s transaction updated successfully"
|
msgid "%(count)s transaction updated successfully"
|
||||||
msgid_plural "%(count)s transactions updated successfully"
|
msgid_plural "%(count)s transactions updated successfully"
|
||||||
msgstr[0] "%(count)s verrichting succesvol bijgewerkt"
|
msgstr[0] "%(count)s verrichting succesvol bijgewerkt"
|
||||||
msgstr[1] "%(count)s verrichtingen succesvol bijgewerkt"
|
msgstr[1] "%(count)s verrichtingen succesvol bijgewerkt"
|
||||||
|
|
||||||
#: apps/transactions/views/transactions.py:214
|
#: apps/transactions/views/transactions.py:209
|
||||||
msgid "Transaction duplicated successfully"
|
msgid "Transaction duplicated successfully"
|
||||||
msgstr "Verrichting succesvol gedupliceerd"
|
msgstr "Verrichting succesvol gedupliceerd"
|
||||||
|
|
||||||
#: apps/transactions/views/transactions.py:256
|
#: apps/transactions/views/transactions.py:251
|
||||||
msgid "Transaction deleted successfully"
|
msgid "Transaction deleted successfully"
|
||||||
msgstr "Verrichting succesvol verwijderd"
|
msgstr "Verrichting succesvol verwijderd"
|
||||||
|
|
||||||
#: apps/transactions/views/transactions.py:282
|
#: apps/transactions/views/transactions.py:277
|
||||||
msgid "Transfer added successfully"
|
msgid "Transfer added successfully"
|
||||||
msgstr "Transactie succesvol toegevoegd"
|
msgstr "Transactie succesvol toegevoegd"
|
||||||
|
|
||||||
@@ -1158,21 +1164,25 @@ msgstr "Ongeldig e-mailadres of wachtwoord"
|
|||||||
msgid "This account is deactivated"
|
msgid "This account is deactivated"
|
||||||
msgstr "Deze gebruiker is gedeactiveerd"
|
msgstr "Deze gebruiker is gedeactiveerd"
|
||||||
|
|
||||||
#: apps/users/forms.py:50 apps/users/forms.py:63
|
#: apps/users/forms.py:50 apps/users/forms.py:63 apps/users/forms.py:85
|
||||||
#: templates/monthly_overview/pages/overview.html:116
|
#: templates/monthly_overview/pages/overview.html:116
|
||||||
#: templates/transactions/pages/transactions.html:35
|
#: templates/transactions/pages/transactions.html:35
|
||||||
msgid "Default"
|
msgid "Default"
|
||||||
msgstr "Standaard"
|
msgstr "Standaard"
|
||||||
|
|
||||||
#: apps/users/forms.py:85 apps/users/models.py:40
|
#: apps/users/forms.py:91 apps/users/models.py:40
|
||||||
msgid "Date Format"
|
msgid "Date Format"
|
||||||
msgstr "Datumnotatie"
|
msgstr "Datumnotatie"
|
||||||
|
|
||||||
#: apps/users/forms.py:90 apps/users/models.py:45
|
#: apps/users/forms.py:96 apps/users/models.py:45
|
||||||
msgid "Datetime Format"
|
msgid "Datetime Format"
|
||||||
msgstr "Tijdsnotatie"
|
msgstr "Tijdsnotatie"
|
||||||
|
|
||||||
#: apps/users/forms.py:117
|
#: apps/users/forms.py:102 apps/users/models.py:48
|
||||||
|
msgid "Number Format"
|
||||||
|
msgstr "Nummerformat"
|
||||||
|
|
||||||
|
#: apps/users/forms.py:131
|
||||||
msgid "Save"
|
msgid "Save"
|
||||||
msgstr "Opslaan"
|
msgstr "Opslaan"
|
||||||
|
|
||||||
@@ -1196,19 +1206,19 @@ msgstr "Alle Verrichtingen"
|
|||||||
msgid "Calendar"
|
msgid "Calendar"
|
||||||
msgstr "Kalender"
|
msgstr "Kalender"
|
||||||
|
|
||||||
#: apps/users/models.py:50 apps/users/models.py:56
|
#: apps/users/models.py:53 apps/users/models.py:59
|
||||||
msgid "Auto"
|
msgid "Auto"
|
||||||
msgstr "Automatisch"
|
msgstr "Automatisch"
|
||||||
|
|
||||||
#: apps/users/models.py:52
|
#: apps/users/models.py:55
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Taal"
|
msgstr "Taal"
|
||||||
|
|
||||||
#: apps/users/models.py:58
|
#: apps/users/models.py:61
|
||||||
msgid "Time Zone"
|
msgid "Time Zone"
|
||||||
msgstr "Tijdszone"
|
msgstr "Tijdszone"
|
||||||
|
|
||||||
#: apps/users/models.py:64
|
#: apps/users/models.py:67
|
||||||
msgid "Start page"
|
msgid "Start page"
|
||||||
msgstr "Startpagina"
|
msgstr "Startpagina"
|
||||||
|
|
||||||
@@ -1244,9 +1254,9 @@ msgstr "Rekeningsgroep bewerken"
|
|||||||
#: templates/accounts/fragments/list.html:37
|
#: templates/accounts/fragments/list.html:37
|
||||||
#: templates/categories/fragments/table.html:24
|
#: templates/categories/fragments/table.html:24
|
||||||
#: templates/currencies/fragments/list.html:33
|
#: templates/currencies/fragments/list.html:33
|
||||||
#: templates/dca/fragments/strategy/details.html:64
|
#: templates/dca/fragments/strategy/details.html:63
|
||||||
#: templates/entities/fragments/table.html:23
|
#: templates/entities/fragments/table.html:23
|
||||||
#: templates/exchange_rates/fragments/table.html:20
|
#: templates/exchange_rates/fragments/table.html:19
|
||||||
#: templates/import_app/fragments/profiles/list.html:44
|
#: templates/import_app/fragments/profiles/list.html:44
|
||||||
#: templates/installment_plans/fragments/table.html:23
|
#: templates/installment_plans/fragments/table.html:23
|
||||||
#: templates/recurring_transactions/fragments/table.html:25
|
#: templates/recurring_transactions/fragments/table.html:25
|
||||||
@@ -1258,13 +1268,13 @@ msgstr "Acties"
|
|||||||
#: templates/account_groups/fragments/list.html:36
|
#: templates/account_groups/fragments/list.html:36
|
||||||
#: templates/accounts/fragments/list.html:41
|
#: templates/accounts/fragments/list.html:41
|
||||||
#: templates/categories/fragments/table.html:29
|
#: templates/categories/fragments/table.html:29
|
||||||
#: templates/cotton/transaction/item.html:110
|
#: templates/cotton/transaction/item.html:109
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:43
|
#: templates/cotton/ui/transactions_action_bar.html:47
|
||||||
#: templates/currencies/fragments/list.html:37
|
#: templates/currencies/fragments/list.html:37
|
||||||
#: templates/dca/fragments/strategy/details.html:68
|
#: templates/dca/fragments/strategy/details.html:67
|
||||||
#: templates/dca/fragments/strategy/list.html:34
|
#: templates/dca/fragments/strategy/list.html:34
|
||||||
#: templates/entities/fragments/table.html:28
|
#: templates/entities/fragments/table.html:28
|
||||||
#: templates/exchange_rates/fragments/table.html:24
|
#: templates/exchange_rates/fragments/table.html:23
|
||||||
#: templates/import_app/fragments/profiles/list.html:48
|
#: templates/import_app/fragments/profiles/list.html:48
|
||||||
#: templates/installment_plans/fragments/table.html:27
|
#: templates/installment_plans/fragments/table.html:27
|
||||||
#: templates/recurring_transactions/fragments/table.html:29
|
#: templates/recurring_transactions/fragments/table.html:29
|
||||||
@@ -1277,13 +1287,13 @@ msgstr "Bijwerken"
|
|||||||
#: templates/account_groups/fragments/list.html:43
|
#: templates/account_groups/fragments/list.html:43
|
||||||
#: templates/accounts/fragments/list.html:48
|
#: templates/accounts/fragments/list.html:48
|
||||||
#: templates/categories/fragments/table.html:36
|
#: templates/categories/fragments/table.html:36
|
||||||
#: templates/cotton/transaction/item.html:125
|
#: templates/cotton/transaction/item.html:124
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:80
|
#: templates/cotton/ui/transactions_action_bar.html:84
|
||||||
#: templates/currencies/fragments/list.html:44
|
#: templates/currencies/fragments/list.html:44
|
||||||
#: templates/dca/fragments/strategy/details.html:76
|
#: templates/dca/fragments/strategy/details.html:75
|
||||||
#: templates/dca/fragments/strategy/list.html:42
|
#: templates/dca/fragments/strategy/list.html:42
|
||||||
#: templates/entities/fragments/table.html:36
|
#: templates/entities/fragments/table.html:36
|
||||||
#: templates/exchange_rates/fragments/table.html:32
|
#: templates/exchange_rates/fragments/table.html:31
|
||||||
#: templates/import_app/fragments/profiles/list.html:69
|
#: templates/import_app/fragments/profiles/list.html:69
|
||||||
#: templates/import_app/fragments/runs/list.html:102
|
#: templates/import_app/fragments/runs/list.html:102
|
||||||
#: templates/installment_plans/fragments/table.html:56
|
#: templates/installment_plans/fragments/table.html:56
|
||||||
@@ -1298,13 +1308,13 @@ msgstr "Verwijderen"
|
|||||||
#: templates/account_groups/fragments/list.html:47
|
#: templates/account_groups/fragments/list.html:47
|
||||||
#: templates/accounts/fragments/list.html:52
|
#: templates/accounts/fragments/list.html:52
|
||||||
#: templates/categories/fragments/table.html:41
|
#: templates/categories/fragments/table.html:41
|
||||||
#: templates/cotton/transaction/item.html:129
|
#: templates/cotton/transaction/item.html:128
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:82
|
#: templates/cotton/ui/transactions_action_bar.html:86
|
||||||
#: templates/currencies/fragments/list.html:48
|
#: templates/currencies/fragments/list.html:48
|
||||||
#: templates/dca/fragments/strategy/details.html:81
|
#: templates/dca/fragments/strategy/details.html:80
|
||||||
#: templates/dca/fragments/strategy/list.html:46
|
#: templates/dca/fragments/strategy/list.html:46
|
||||||
#: templates/entities/fragments/table.html:40
|
#: templates/entities/fragments/table.html:40
|
||||||
#: templates/exchange_rates/fragments/table.html:37
|
#: templates/exchange_rates/fragments/table.html:36
|
||||||
#: templates/import_app/fragments/profiles/list.html:73
|
#: templates/import_app/fragments/profiles/list.html:73
|
||||||
#: templates/import_app/fragments/runs/list.html:106
|
#: templates/import_app/fragments/runs/list.html:106
|
||||||
#: templates/installment_plans/fragments/table.html:48
|
#: templates/installment_plans/fragments/table.html:48
|
||||||
@@ -1322,13 +1332,13 @@ msgstr "Weet je het zeker?"
|
|||||||
#: templates/account_groups/fragments/list.html:48
|
#: templates/account_groups/fragments/list.html:48
|
||||||
#: templates/accounts/fragments/list.html:53
|
#: templates/accounts/fragments/list.html:53
|
||||||
#: templates/categories/fragments/table.html:42
|
#: templates/categories/fragments/table.html:42
|
||||||
#: templates/cotton/transaction/item.html:130
|
#: templates/cotton/transaction/item.html:129
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:83
|
#: templates/cotton/ui/transactions_action_bar.html:87
|
||||||
#: templates/currencies/fragments/list.html:49
|
#: templates/currencies/fragments/list.html:49
|
||||||
#: templates/dca/fragments/strategy/details.html:82
|
#: templates/dca/fragments/strategy/details.html:81
|
||||||
#: templates/dca/fragments/strategy/list.html:47
|
#: templates/dca/fragments/strategy/list.html:47
|
||||||
#: templates/entities/fragments/table.html:41
|
#: templates/entities/fragments/table.html:41
|
||||||
#: templates/exchange_rates/fragments/table.html:38
|
#: templates/exchange_rates/fragments/table.html:37
|
||||||
#: templates/import_app/fragments/profiles/list.html:74
|
#: templates/import_app/fragments/profiles/list.html:74
|
||||||
#: templates/rules/fragments/list.html:49
|
#: templates/rules/fragments/list.html:49
|
||||||
#: templates/rules/fragments/transaction_rule/view.html:61
|
#: templates/rules/fragments/transaction_rule/view.html:61
|
||||||
@@ -1339,12 +1349,12 @@ msgstr "Je kunt dit niet meer terugdraaien!"
|
|||||||
#: templates/account_groups/fragments/list.html:49
|
#: templates/account_groups/fragments/list.html:49
|
||||||
#: templates/accounts/fragments/list.html:54
|
#: templates/accounts/fragments/list.html:54
|
||||||
#: templates/categories/fragments/table.html:43
|
#: templates/categories/fragments/table.html:43
|
||||||
#: templates/cotton/transaction/item.html:131
|
#: templates/cotton/transaction/item.html:130
|
||||||
#: templates/currencies/fragments/list.html:50
|
#: templates/currencies/fragments/list.html:50
|
||||||
#: templates/dca/fragments/strategy/details.html:83
|
#: templates/dca/fragments/strategy/details.html:82
|
||||||
#: templates/dca/fragments/strategy/list.html:48
|
#: templates/dca/fragments/strategy/list.html:48
|
||||||
#: templates/entities/fragments/table.html:42
|
#: templates/entities/fragments/table.html:42
|
||||||
#: templates/exchange_rates/fragments/table.html:39
|
#: templates/exchange_rates/fragments/table.html:38
|
||||||
#: templates/import_app/fragments/profiles/list.html:75
|
#: templates/import_app/fragments/profiles/list.html:75
|
||||||
#: templates/import_app/fragments/runs/list.html:108
|
#: templates/import_app/fragments/runs/list.html:108
|
||||||
#: templates/installment_plans/fragments/table.html:62
|
#: templates/installment_plans/fragments/table.html:62
|
||||||
@@ -1419,11 +1429,11 @@ msgstr "ZAT"
|
|||||||
msgid "SUN"
|
msgid "SUN"
|
||||||
msgstr "ZON"
|
msgstr "ZON"
|
||||||
|
|
||||||
#: templates/calendar_view/fragments/list_transactions.html:6
|
#: templates/calendar_view/fragments/list_transactions.html:5
|
||||||
msgid "Transactions on"
|
msgid "Transactions on"
|
||||||
msgstr "Verrichtingen op"
|
msgstr "Verrichtingen op"
|
||||||
|
|
||||||
#: templates/calendar_view/fragments/list_transactions.html:16
|
#: templates/calendar_view/fragments/list_transactions.html:15
|
||||||
msgid "No transactions on this date"
|
msgid "No transactions on this date"
|
||||||
msgstr "Geen verrichtingen op deze datum"
|
msgstr "Geen verrichtingen op deze datum"
|
||||||
|
|
||||||
@@ -1482,12 +1492,12 @@ msgstr "Sluiten"
|
|||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Zoeken"
|
msgstr "Zoeken"
|
||||||
|
|
||||||
#: templates/cotton/transaction/item.html:6
|
#: templates/cotton/transaction/item.html:5
|
||||||
msgid "Select"
|
msgid "Select"
|
||||||
msgstr "Selecteer"
|
msgstr "Selecteer"
|
||||||
|
|
||||||
#: templates/cotton/transaction/item.html:117
|
#: templates/cotton/transaction/item.html:116
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:72
|
#: templates/cotton/ui/transactions_action_bar.html:76
|
||||||
msgid "Duplicate"
|
msgid "Duplicate"
|
||||||
msgstr "Dupliceren"
|
msgstr "Dupliceren"
|
||||||
|
|
||||||
@@ -1511,62 +1521,62 @@ msgstr "Verwachte uitgaven"
|
|||||||
msgid "Current Expenses"
|
msgid "Current Expenses"
|
||||||
msgstr "Huidige uitgaven"
|
msgstr "Huidige uitgaven"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:25
|
#: templates/cotton/ui/transactions_action_bar.html:29
|
||||||
msgid "Select All"
|
msgid "Select All"
|
||||||
msgstr "Alles selecteren"
|
msgstr "Alles selecteren"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:31
|
#: templates/cotton/ui/transactions_action_bar.html:35
|
||||||
msgid "Unselect All"
|
msgid "Unselect All"
|
||||||
msgstr "Alles deselecteren"
|
msgstr "Alles deselecteren"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:48
|
#: templates/cotton/ui/transactions_action_bar.html:52
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:139
|
#: templates/cotton/ui/transactions_action_bar.html:143
|
||||||
msgid "Toggle Dropdown"
|
msgid "Toggle Dropdown"
|
||||||
msgstr "In- Uitklapbaar"
|
msgstr "In- Uitklapbaar"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:56
|
#: templates/cotton/ui/transactions_action_bar.html:60
|
||||||
msgid "Mark as unpaid"
|
msgid "Mark as unpaid"
|
||||||
msgstr "Markeren als niet betaald"
|
msgstr "Markeren als niet betaald"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:63
|
#: templates/cotton/ui/transactions_action_bar.html:67
|
||||||
msgid "Mark as paid"
|
msgid "Mark as paid"
|
||||||
msgstr "Markeren als betaald"
|
msgstr "Markeren als betaald"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:84
|
#: templates/cotton/ui/transactions_action_bar.html:88
|
||||||
msgid "Yes, delete them!"
|
msgid "Yes, delete them!"
|
||||||
msgstr "Ja, verwijder ze!"
|
msgstr "Ja, verwijder ze!"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:130
|
#: templates/cotton/ui/transactions_action_bar.html:134
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:154
|
#: templates/cotton/ui/transactions_action_bar.html:158
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:174
|
#: templates/cotton/ui/transactions_action_bar.html:178
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:194
|
#: templates/cotton/ui/transactions_action_bar.html:198
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:214
|
#: templates/cotton/ui/transactions_action_bar.html:218
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:234
|
#: templates/cotton/ui/transactions_action_bar.html:238
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:254
|
#: templates/cotton/ui/transactions_action_bar.html:258
|
||||||
msgid "copied!"
|
msgid "copied!"
|
||||||
msgstr "gekopieerd!"
|
msgstr "gekopieerd!"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:147
|
#: templates/cotton/ui/transactions_action_bar.html:151
|
||||||
msgid "Flat Total"
|
msgid "Flat Total"
|
||||||
msgstr "Vast Totaal"
|
msgstr "Vast Totaal"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:167
|
#: templates/cotton/ui/transactions_action_bar.html:171
|
||||||
msgid "Real Total"
|
msgid "Real Total"
|
||||||
msgstr "Werkelijk Totaal"
|
msgstr "Werkelijk Totaal"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:187
|
#: templates/cotton/ui/transactions_action_bar.html:191
|
||||||
msgid "Mean"
|
msgid "Mean"
|
||||||
msgstr "Gemiddelde"
|
msgstr "Gemiddelde"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:207
|
#: templates/cotton/ui/transactions_action_bar.html:211
|
||||||
msgid "Max"
|
msgid "Max"
|
||||||
msgstr "Maximaal"
|
msgstr "Maximaal"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:227
|
#: templates/cotton/ui/transactions_action_bar.html:231
|
||||||
msgid "Min"
|
msgid "Min"
|
||||||
msgstr "Minimaal"
|
msgstr "Minimaal"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:247
|
#: templates/cotton/ui/transactions_action_bar.html:251
|
||||||
msgid "Count"
|
msgid "Count"
|
||||||
msgstr "Rekenen"
|
msgstr "Rekenen"
|
||||||
|
|
||||||
@@ -1598,91 +1608,91 @@ msgstr "DCA-item bewerken"
|
|||||||
msgid "Add DCA strategy"
|
msgid "Add DCA strategy"
|
||||||
msgstr "DCA-strategie toevoegen"
|
msgstr "DCA-strategie toevoegen"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:23
|
#: templates/dca/fragments/strategy/details.html:22
|
||||||
msgid "No exchange rate available"
|
msgid "No exchange rate available"
|
||||||
msgstr "Geen wisselkoers beschikbaar"
|
msgstr "Geen wisselkoers beschikbaar"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:34
|
#: templates/dca/fragments/strategy/details.html:33
|
||||||
msgid "Entries"
|
msgid "Entries"
|
||||||
msgstr "Idems"
|
msgstr "Idems"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:56
|
#: templates/dca/fragments/strategy/details.html:55
|
||||||
msgid "Current Value"
|
msgid "Current Value"
|
||||||
msgstr "Actuele waarde"
|
msgstr "Actuele waarde"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:57
|
#: templates/dca/fragments/strategy/details.html:56
|
||||||
msgid "P/L"
|
msgid "P/L"
|
||||||
msgstr "W&V"
|
msgstr "W&V"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:125
|
#: templates/dca/fragments/strategy/details.html:124
|
||||||
msgid "No entries for this DCA"
|
msgid "No entries for this DCA"
|
||||||
msgstr "Geen idems in deze DCA"
|
msgstr "Geen idems in deze DCA"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:126
|
#: templates/dca/fragments/strategy/details.html:125
|
||||||
#: templates/monthly_overview/fragments/list.html:41
|
#: templates/monthly_overview/fragments/list.html:41
|
||||||
#: templates/transactions/fragments/list_all.html:40
|
#: templates/transactions/fragments/list_all.html:40
|
||||||
msgid "Try adding one"
|
msgid "Try adding one"
|
||||||
msgstr "Probeer er een toe te voegen"
|
msgstr "Probeer er een toe te voegen"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:136
|
#: templates/dca/fragments/strategy/details.html:135
|
||||||
msgid "Total Invested"
|
msgid "Total Invested"
|
||||||
msgstr "Totaal Geïnvesteerd"
|
msgstr "Totaal Geïnvesteerd"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:150
|
#: templates/dca/fragments/strategy/details.html:149
|
||||||
msgid "Total Received"
|
msgid "Total Received"
|
||||||
msgstr "Totaal Ontvangen"
|
msgstr "Totaal Ontvangen"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:164
|
#: templates/dca/fragments/strategy/details.html:163
|
||||||
msgid "Current Total Value"
|
msgid "Current Total Value"
|
||||||
msgstr "Huidige Totaalwaarde"
|
msgstr "Huidige Totaalwaarde"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:178
|
#: templates/dca/fragments/strategy/details.html:177
|
||||||
msgid "Average Entry Price"
|
msgid "Average Entry Price"
|
||||||
msgstr "Gemiddelde Instapprijs"
|
msgstr "Gemiddelde Instapprijs"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:192
|
#: templates/dca/fragments/strategy/details.html:191
|
||||||
msgid "Total P/L"
|
msgid "Total P/L"
|
||||||
msgstr "Totaal W&V"
|
msgstr "Totaal W&V"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:208
|
#: templates/dca/fragments/strategy/details.html:207
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Total %% P/L"
|
msgid "Total %% P/L"
|
||||||
msgstr "Totaal %% W&V"
|
msgstr "Totaal %% W&V"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:227
|
#: templates/dca/fragments/strategy/details.html:226
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "P/L %%"
|
msgid "P/L %%"
|
||||||
msgstr "W&V %%"
|
msgstr "W&V %%"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:289
|
#: templates/dca/fragments/strategy/details.html:288
|
||||||
msgid "Performance Over Time"
|
msgid "Performance Over Time"
|
||||||
msgstr "Prestaties Na Verloop Van Tijd"
|
msgstr "Prestaties Na Verloop Van Tijd"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:307
|
#: templates/dca/fragments/strategy/details.html:306
|
||||||
msgid "Entry Price"
|
msgid "Entry Price"
|
||||||
msgstr "Ingangsprijs"
|
msgstr "Ingangsprijs"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:315
|
#: templates/dca/fragments/strategy/details.html:314
|
||||||
msgid "Current Price"
|
msgid "Current Price"
|
||||||
msgstr "Actuele Prijs"
|
msgstr "Actuele Prijs"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:323
|
#: templates/dca/fragments/strategy/details.html:322
|
||||||
msgid "Amount Bought"
|
msgid "Amount Bought"
|
||||||
msgstr "Gekocht Bedrag"
|
msgstr "Gekocht Bedrag"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:391
|
#: templates/dca/fragments/strategy/details.html:390
|
||||||
msgid "Entry Price vs Current Price"
|
msgid "Entry Price vs Current Price"
|
||||||
msgstr "Instapprijs vs Huidige Prijs"
|
msgstr "Instapprijs vs Huidige Prijs"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:407
|
#: templates/dca/fragments/strategy/details.html:406
|
||||||
msgid "Days Between Investments"
|
msgid "Days Between Investments"
|
||||||
msgstr "Dagen Tussen Investeringen"
|
msgstr "Dagen Tussen Investeringen"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:454
|
#: templates/dca/fragments/strategy/details.html:453
|
||||||
msgid "Investment Frequency"
|
msgid "Investment Frequency"
|
||||||
msgstr "Investeringsfrequentie"
|
msgstr "Investeringsfrequentie"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:456
|
#: templates/dca/fragments/strategy/details.html:455
|
||||||
msgid "The straighter the blue line, the more consistent your DCA strategy is."
|
msgid "The straighter the blue line, the more consistent your DCA strategy is."
|
||||||
msgstr "Hoe rechter de blauwe lijn, hoe consistenter je DCA-strategie is."
|
msgstr "Hoe rechter de blauwe lijn, hoe consistenter je DCA-strategie is."
|
||||||
|
|
||||||
@@ -1727,19 +1737,19 @@ msgstr "Wisselkoers bewerken"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Allemaal"
|
msgstr "Allemaal"
|
||||||
|
|
||||||
#: templates/exchange_rates/fragments/table.html:12
|
#: templates/exchange_rates/fragments/table.html:11
|
||||||
msgid "Pairing"
|
msgid "Pairing"
|
||||||
msgstr "Koppelen"
|
msgstr "Koppelen"
|
||||||
|
|
||||||
#: templates/exchange_rates/fragments/table.html:13
|
#: templates/exchange_rates/fragments/table.html:12
|
||||||
msgid "Rate"
|
msgid "Rate"
|
||||||
msgstr "Tarief"
|
msgstr "Tarief"
|
||||||
|
|
||||||
#: templates/exchange_rates/fragments/table.html:52
|
#: templates/exchange_rates/fragments/table.html:51
|
||||||
msgid "No exchange rates"
|
msgid "No exchange rates"
|
||||||
msgstr "Geen wisselkoersen"
|
msgstr "Geen wisselkoersen"
|
||||||
|
|
||||||
#: templates/exchange_rates/fragments/table.html:59
|
#: templates/exchange_rates/fragments/table.html:58
|
||||||
#: templates/transactions/fragments/list_all.html:47
|
#: templates/transactions/fragments/list_all.html:47
|
||||||
msgid "Page navigation"
|
msgid "Page navigation"
|
||||||
msgstr "Paginanavigatie"
|
msgstr "Paginanavigatie"
|
||||||
@@ -1895,7 +1905,13 @@ msgstr "Rekenmachine"
|
|||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Instellingen"
|
msgstr "Instellingen"
|
||||||
|
|
||||||
#: templates/includes/navbar/user_menu.html:37
|
#: templates/includes/navbar/user_menu.html:38
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "Clear"
|
||||||
|
msgid "Clear cache"
|
||||||
|
msgstr "Leegmaken"
|
||||||
|
|
||||||
|
#: templates/includes/navbar/user_menu.html:42
|
||||||
msgid "Logout"
|
msgid "Logout"
|
||||||
msgstr "Uitloggen"
|
msgstr "Uitloggen"
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-01-25 16:51+0000\n"
|
"POT-Creation-Date: 2025-01-28 00:49+0000\n"
|
||||||
"PO-Revision-Date: 2025-01-25 13:53-0300\n"
|
"PO-Revision-Date: 2025-01-27 21:49-0300\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: Herculino Trotta\n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
"Language: pt_BR\n"
|
"Language: pt_BR\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@@ -24,28 +24,28 @@ msgid "Group name"
|
|||||||
msgstr "Nome do grupo"
|
msgstr "Nome do grupo"
|
||||||
|
|
||||||
#: apps/accounts/forms.py:40 apps/accounts/forms.py:96
|
#: apps/accounts/forms.py:40 apps/accounts/forms.py:96
|
||||||
#: apps/currencies/forms.py:52 apps/currencies/forms.py:92 apps/dca/forms.py:41
|
#: apps/currencies/forms.py:52 apps/currencies/forms.py:90 apps/dca/forms.py:41
|
||||||
#: apps/dca/forms.py:93 apps/import_app/forms.py:34 apps/rules/forms.py:45
|
#: apps/dca/forms.py:93 apps/import_app/forms.py:34 apps/rules/forms.py:45
|
||||||
#: apps/rules/forms.py:87 apps/transactions/forms.py:190
|
#: apps/rules/forms.py:87 apps/transactions/forms.py:190
|
||||||
#: apps/transactions/forms.py:257 apps/transactions/forms.py:583
|
#: apps/transactions/forms.py:257 apps/transactions/forms.py:581
|
||||||
#: apps/transactions/forms.py:626 apps/transactions/forms.py:658
|
#: apps/transactions/forms.py:624 apps/transactions/forms.py:656
|
||||||
#: apps/transactions/forms.py:693 apps/transactions/forms.py:831
|
#: apps/transactions/forms.py:691 apps/transactions/forms.py:827
|
||||||
msgid "Update"
|
msgid "Update"
|
||||||
msgstr "Atualizar"
|
msgstr "Atualizar"
|
||||||
|
|
||||||
#: apps/accounts/forms.py:48 apps/accounts/forms.py:104
|
#: apps/accounts/forms.py:48 apps/accounts/forms.py:104
|
||||||
#: apps/common/widgets/tom_select.py:12 apps/currencies/forms.py:60
|
#: apps/common/widgets/tom_select.py:12 apps/currencies/forms.py:60
|
||||||
#: apps/currencies/forms.py:100 apps/dca/forms.py:49 apps/dca/forms.py:102
|
#: apps/currencies/forms.py:98 apps/dca/forms.py:49 apps/dca/forms.py:102
|
||||||
#: apps/import_app/forms.py:42 apps/rules/forms.py:53 apps/rules/forms.py:95
|
#: apps/import_app/forms.py:42 apps/rules/forms.py:53 apps/rules/forms.py:95
|
||||||
#: apps/transactions/forms.py:174 apps/transactions/forms.py:199
|
#: apps/transactions/forms.py:174 apps/transactions/forms.py:199
|
||||||
#: apps/transactions/forms.py:591 apps/transactions/forms.py:634
|
#: apps/transactions/forms.py:589 apps/transactions/forms.py:632
|
||||||
#: apps/transactions/forms.py:666 apps/transactions/forms.py:701
|
#: apps/transactions/forms.py:664 apps/transactions/forms.py:699
|
||||||
#: apps/transactions/forms.py:839
|
#: apps/transactions/forms.py:835
|
||||||
#: templates/account_groups/fragments/list.html:9
|
#: templates/account_groups/fragments/list.html:9
|
||||||
#: templates/accounts/fragments/list.html:9
|
#: templates/accounts/fragments/list.html:9
|
||||||
#: templates/categories/fragments/list.html:9
|
#: templates/categories/fragments/list.html:9
|
||||||
#: templates/currencies/fragments/list.html:9
|
#: templates/currencies/fragments/list.html:9
|
||||||
#: templates/dca/fragments/strategy/details.html:38
|
#: templates/dca/fragments/strategy/details.html:37
|
||||||
#: templates/dca/fragments/strategy/list.html:9
|
#: templates/dca/fragments/strategy/list.html:9
|
||||||
#: templates/entities/fragments/list.html:9
|
#: templates/entities/fragments/list.html:9
|
||||||
#: templates/exchange_rates/fragments/list.html:10
|
#: templates/exchange_rates/fragments/list.html:10
|
||||||
@@ -69,7 +69,7 @@ msgstr "Novo saldo"
|
|||||||
#: apps/accounts/forms.py:119 apps/rules/models.py:27
|
#: apps/accounts/forms.py:119 apps/rules/models.py:27
|
||||||
#: apps/transactions/forms.py:39 apps/transactions/forms.py:291
|
#: apps/transactions/forms.py:39 apps/transactions/forms.py:291
|
||||||
#: apps/transactions/forms.py:298 apps/transactions/forms.py:478
|
#: apps/transactions/forms.py:298 apps/transactions/forms.py:478
|
||||||
#: apps/transactions/forms.py:725 apps/transactions/models.py:159
|
#: apps/transactions/forms.py:723 apps/transactions/models.py:159
|
||||||
#: apps/transactions/models.py:311 apps/transactions/models.py:491
|
#: apps/transactions/models.py:311 apps/transactions/models.py:491
|
||||||
msgid "Category"
|
msgid "Category"
|
||||||
msgstr "Categoria"
|
msgstr "Categoria"
|
||||||
@@ -77,7 +77,7 @@ msgstr "Categoria"
|
|||||||
#: apps/accounts/forms.py:126 apps/rules/models.py:28
|
#: apps/accounts/forms.py:126 apps/rules/models.py:28
|
||||||
#: apps/transactions/filters.py:74 apps/transactions/forms.py:47
|
#: apps/transactions/filters.py:74 apps/transactions/forms.py:47
|
||||||
#: apps/transactions/forms.py:307 apps/transactions/forms.py:315
|
#: apps/transactions/forms.py:307 apps/transactions/forms.py:315
|
||||||
#: apps/transactions/forms.py:471 apps/transactions/forms.py:718
|
#: apps/transactions/forms.py:471 apps/transactions/forms.py:716
|
||||||
#: apps/transactions/models.py:165 apps/transactions/models.py:313
|
#: apps/transactions/models.py:165 apps/transactions/models.py:313
|
||||||
#: apps/transactions/models.py:495 templates/includes/navbar.html:98
|
#: apps/transactions/models.py:495 templates/includes/navbar.html:98
|
||||||
#: templates/tags/fragments/list.html:5 templates/tags/pages/index.html:4
|
#: templates/tags/fragments/list.html:5 templates/tags/pages/index.html:4
|
||||||
@@ -150,7 +150,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: apps/accounts/models.py:59 apps/rules/models.py:19
|
#: apps/accounts/models.py:59 apps/rules/models.py:19
|
||||||
#: apps/transactions/forms.py:59 apps/transactions/forms.py:463
|
#: apps/transactions/forms.py:59 apps/transactions/forms.py:463
|
||||||
#: apps/transactions/forms.py:710 apps/transactions/models.py:132
|
#: apps/transactions/forms.py:708 apps/transactions/models.py:132
|
||||||
#: apps/transactions/models.py:271 apps/transactions/models.py:473
|
#: apps/transactions/models.py:271 apps/transactions/models.py:473
|
||||||
msgid "Account"
|
msgid "Account"
|
||||||
msgstr "Conta"
|
msgstr "Conta"
|
||||||
@@ -320,11 +320,15 @@ msgstr "Erro"
|
|||||||
msgid "Info"
|
msgid "Info"
|
||||||
msgstr "Informação"
|
msgstr "Informação"
|
||||||
|
|
||||||
#: apps/common/widgets/datepicker.py:55 apps/common/widgets/datepicker.py:197
|
#: apps/common/views.py:110
|
||||||
|
msgid "Cache cleared successfully"
|
||||||
|
msgstr "Cache limpo com sucesso"
|
||||||
|
|
||||||
|
#: apps/common/widgets/datepicker.py:47 apps/common/widgets/datepicker.py:186
|
||||||
msgid "Today"
|
msgid "Today"
|
||||||
msgstr "Hoje"
|
msgstr "Hoje"
|
||||||
|
|
||||||
#: apps/common/widgets/datepicker.py:139
|
#: apps/common/widgets/datepicker.py:123
|
||||||
msgid "Now"
|
msgid "Now"
|
||||||
msgstr "Agora"
|
msgstr "Agora"
|
||||||
|
|
||||||
@@ -354,8 +358,8 @@ msgstr "Sufixo"
|
|||||||
#: apps/currencies/forms.py:68 apps/dca/models.py:156 apps/rules/models.py:22
|
#: apps/currencies/forms.py:68 apps/dca/models.py:156 apps/rules/models.py:22
|
||||||
#: apps/transactions/forms.py:63 apps/transactions/forms.py:319
|
#: apps/transactions/forms.py:63 apps/transactions/forms.py:319
|
||||||
#: apps/transactions/models.py:142
|
#: apps/transactions/models.py:142
|
||||||
#: templates/dca/fragments/strategy/details.html:53
|
#: templates/dca/fragments/strategy/details.html:52
|
||||||
#: templates/exchange_rates/fragments/table.html:11
|
#: templates/exchange_rates/fragments/table.html:10
|
||||||
msgid "Date"
|
msgid "Date"
|
||||||
msgstr "Data"
|
msgstr "Data"
|
||||||
|
|
||||||
@@ -405,7 +409,7 @@ msgstr "Data e Tempo"
|
|||||||
msgid "Exchange Rates"
|
msgid "Exchange Rates"
|
||||||
msgstr "Taxas de Câmbio"
|
msgstr "Taxas de Câmbio"
|
||||||
|
|
||||||
#: apps/currencies/models.py:77
|
#: apps/currencies/models.py:79
|
||||||
msgid "From and To currencies cannot be the same."
|
msgid "From and To currencies cannot be the same."
|
||||||
msgstr "As moedas De e Para não podem ser as mesmas."
|
msgstr "As moedas De e Para não podem ser as mesmas."
|
||||||
|
|
||||||
@@ -459,11 +463,11 @@ msgstr "Estratégias CMP"
|
|||||||
msgid "Strategy"
|
msgid "Strategy"
|
||||||
msgstr "Estratégia"
|
msgstr "Estratégia"
|
||||||
|
|
||||||
#: apps/dca/models.py:158 templates/dca/fragments/strategy/details.html:55
|
#: apps/dca/models.py:158 templates/dca/fragments/strategy/details.html:54
|
||||||
msgid "Amount Paid"
|
msgid "Amount Paid"
|
||||||
msgstr "Quantia paga"
|
msgstr "Quantia paga"
|
||||||
|
|
||||||
#: apps/dca/models.py:161 templates/dca/fragments/strategy/details.html:54
|
#: apps/dca/models.py:161 templates/dca/fragments/strategy/details.html:53
|
||||||
msgid "Amount Received"
|
msgid "Amount Received"
|
||||||
msgstr "Quantia recebida"
|
msgstr "Quantia recebida"
|
||||||
|
|
||||||
@@ -641,7 +645,7 @@ msgstr "Quantia"
|
|||||||
|
|
||||||
#: apps/rules/models.py:29 apps/transactions/filters.py:81
|
#: apps/rules/models.py:29 apps/transactions/filters.py:81
|
||||||
#: apps/transactions/forms.py:55 apps/transactions/forms.py:486
|
#: apps/transactions/forms.py:55 apps/transactions/forms.py:486
|
||||||
#: apps/transactions/forms.py:733 apps/transactions/models.py:117
|
#: apps/transactions/forms.py:731 apps/transactions/models.py:117
|
||||||
#: apps/transactions/models.py:170 apps/transactions/models.py:316
|
#: apps/transactions/models.py:170 apps/transactions/models.py:316
|
||||||
#: apps/transactions/models.py:498 templates/entities/fragments/list.html:5
|
#: apps/transactions/models.py:498 templates/entities/fragments/list.html:5
|
||||||
#: templates/entities/pages/index.html:4 templates/includes/navbar.html:100
|
#: templates/entities/pages/index.html:4 templates/includes/navbar.html:100
|
||||||
@@ -759,23 +763,23 @@ msgstr "Transferir"
|
|||||||
msgid "From and To accounts must be different."
|
msgid "From and To accounts must be different."
|
||||||
msgstr "As contas De e Para devem ser diferentes."
|
msgstr "As contas De e Para devem ser diferentes."
|
||||||
|
|
||||||
#: apps/transactions/forms.py:612
|
#: apps/transactions/forms.py:610
|
||||||
msgid "Tag name"
|
msgid "Tag name"
|
||||||
msgstr "Nome da Tag"
|
msgstr "Nome da Tag"
|
||||||
|
|
||||||
#: apps/transactions/forms.py:644
|
#: apps/transactions/forms.py:642
|
||||||
msgid "Entity name"
|
msgid "Entity name"
|
||||||
msgstr "Nome da entidade"
|
msgstr "Nome da entidade"
|
||||||
|
|
||||||
#: apps/transactions/forms.py:676
|
#: apps/transactions/forms.py:674
|
||||||
msgid "Category name"
|
msgid "Category name"
|
||||||
msgstr "Nome da Categoria"
|
msgstr "Nome da Categoria"
|
||||||
|
|
||||||
#: apps/transactions/forms.py:678
|
#: apps/transactions/forms.py:676
|
||||||
msgid "Muted categories won't count towards your monthly total"
|
msgid "Muted categories won't count towards your monthly total"
|
||||||
msgstr "As categorias silenciadas não serão contabilizadas em seu total mensal"
|
msgstr "As categorias silenciadas não serão contabilizadas em seu total mensal"
|
||||||
|
|
||||||
#: apps/transactions/forms.py:850
|
#: apps/transactions/forms.py:846
|
||||||
msgid "End date should be after the start date"
|
msgid "End date should be after the start date"
|
||||||
msgstr "Data final deve ser após data inicial"
|
msgstr "Data final deve ser após data inicial"
|
||||||
|
|
||||||
@@ -1043,15 +1047,15 @@ msgstr "Entidade apagada com sucesso"
|
|||||||
msgid "Installment Plan added successfully"
|
msgid "Installment Plan added successfully"
|
||||||
msgstr "Parcelamento adicionado com sucesso"
|
msgstr "Parcelamento adicionado com sucesso"
|
||||||
|
|
||||||
#: apps/transactions/views/installment_plans.py:117
|
#: apps/transactions/views/installment_plans.py:115
|
||||||
msgid "Installment Plan updated successfully"
|
msgid "Installment Plan updated successfully"
|
||||||
msgstr "Parcelamento atualizado com sucesso"
|
msgstr "Parcelamento atualizado com sucesso"
|
||||||
|
|
||||||
#: apps/transactions/views/installment_plans.py:142
|
#: apps/transactions/views/installment_plans.py:140
|
||||||
msgid "Installment Plan refreshed successfully"
|
msgid "Installment Plan refreshed successfully"
|
||||||
msgstr "Parcelamento atualizado com sucesso"
|
msgstr "Parcelamento atualizado com sucesso"
|
||||||
|
|
||||||
#: apps/transactions/views/installment_plans.py:160
|
#: apps/transactions/views/installment_plans.py:158
|
||||||
msgid "Installment Plan deleted successfully"
|
msgid "Installment Plan deleted successfully"
|
||||||
msgstr "Parcelamento apagado com sucesso"
|
msgstr "Parcelamento apagado com sucesso"
|
||||||
|
|
||||||
@@ -1059,23 +1063,23 @@ msgstr "Parcelamento apagado com sucesso"
|
|||||||
msgid "Recurring Transaction added successfully"
|
msgid "Recurring Transaction added successfully"
|
||||||
msgstr "Transação Recorrente adicionada com sucesso"
|
msgstr "Transação Recorrente adicionada com sucesso"
|
||||||
|
|
||||||
#: apps/transactions/views/recurring_transactions.py:144
|
#: apps/transactions/views/recurring_transactions.py:142
|
||||||
msgid "Recurring Transaction updated successfully"
|
msgid "Recurring Transaction updated successfully"
|
||||||
msgstr "Transação Recorrente atualizada com sucesso"
|
msgstr "Transação Recorrente atualizada com sucesso"
|
||||||
|
|
||||||
#: apps/transactions/views/recurring_transactions.py:190
|
#: apps/transactions/views/recurring_transactions.py:186
|
||||||
msgid "Recurring transaction unpaused successfully"
|
msgid "Recurring transaction unpaused successfully"
|
||||||
msgstr "Transação Recorrente despausada com sucesso"
|
msgstr "Transação Recorrente despausada com sucesso"
|
||||||
|
|
||||||
#: apps/transactions/views/recurring_transactions.py:193
|
#: apps/transactions/views/recurring_transactions.py:189
|
||||||
msgid "Recurring transaction paused successfully"
|
msgid "Recurring transaction paused successfully"
|
||||||
msgstr "Transação Recorrente pausada com sucesso"
|
msgstr "Transação Recorrente pausada com sucesso"
|
||||||
|
|
||||||
#: apps/transactions/views/recurring_transactions.py:219
|
#: apps/transactions/views/recurring_transactions.py:215
|
||||||
msgid "Recurring transaction finished successfully"
|
msgid "Recurring transaction finished successfully"
|
||||||
msgstr "Transação Recorrente finalizada com sucesso"
|
msgstr "Transação Recorrente finalizada com sucesso"
|
||||||
|
|
||||||
#: apps/transactions/views/recurring_transactions.py:239
|
#: apps/transactions/views/recurring_transactions.py:235
|
||||||
msgid "Recurring Transaction deleted successfully"
|
msgid "Recurring Transaction deleted successfully"
|
||||||
msgstr "Transação Recorrente apagada com sucesso"
|
msgstr "Transação Recorrente apagada com sucesso"
|
||||||
|
|
||||||
@@ -1092,30 +1096,30 @@ msgid "Tag deleted successfully"
|
|||||||
msgstr "Tag apagada com sucesso"
|
msgstr "Tag apagada com sucesso"
|
||||||
|
|
||||||
#: apps/transactions/views/transactions.py:50
|
#: apps/transactions/views/transactions.py:50
|
||||||
#: apps/transactions/views/transactions.py:90
|
#: apps/transactions/views/transactions.py:89
|
||||||
msgid "Transaction added successfully"
|
msgid "Transaction added successfully"
|
||||||
msgstr "Transação adicionada com sucesso"
|
msgstr "Transação adicionada com sucesso"
|
||||||
|
|
||||||
#: apps/transactions/views/transactions.py:126
|
#: apps/transactions/views/transactions.py:123
|
||||||
msgid "Transaction updated successfully"
|
msgid "Transaction updated successfully"
|
||||||
msgstr "Transação atualizada com sucesso"
|
msgstr "Transação atualizada com sucesso"
|
||||||
|
|
||||||
#: apps/transactions/views/transactions.py:176
|
#: apps/transactions/views/transactions.py:173
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(count)s transaction updated successfully"
|
msgid "%(count)s transaction updated successfully"
|
||||||
msgid_plural "%(count)s transactions updated successfully"
|
msgid_plural "%(count)s transactions updated successfully"
|
||||||
msgstr[0] "%(count)s transação atualizada com sucesso"
|
msgstr[0] "%(count)s transação atualizada com sucesso"
|
||||||
msgstr[1] "%(count)s transações atualizadas com sucesso"
|
msgstr[1] "%(count)s transações atualizadas com sucesso"
|
||||||
|
|
||||||
#: apps/transactions/views/transactions.py:214
|
#: apps/transactions/views/transactions.py:209
|
||||||
msgid "Transaction duplicated successfully"
|
msgid "Transaction duplicated successfully"
|
||||||
msgstr "Transação duplicada com sucesso"
|
msgstr "Transação duplicada com sucesso"
|
||||||
|
|
||||||
#: apps/transactions/views/transactions.py:256
|
#: apps/transactions/views/transactions.py:251
|
||||||
msgid "Transaction deleted successfully"
|
msgid "Transaction deleted successfully"
|
||||||
msgstr "Transação apagada com sucesso"
|
msgstr "Transação apagada com sucesso"
|
||||||
|
|
||||||
#: apps/transactions/views/transactions.py:282
|
#: apps/transactions/views/transactions.py:277
|
||||||
msgid "Transfer added successfully"
|
msgid "Transfer added successfully"
|
||||||
msgstr "Transferência adicionada com sucesso"
|
msgstr "Transferência adicionada com sucesso"
|
||||||
|
|
||||||
@@ -1155,21 +1159,25 @@ msgstr "E-mail ou senha inválidos"
|
|||||||
msgid "This account is deactivated"
|
msgid "This account is deactivated"
|
||||||
msgstr "Essa conta está desativada"
|
msgstr "Essa conta está desativada"
|
||||||
|
|
||||||
#: apps/users/forms.py:50 apps/users/forms.py:63
|
#: apps/users/forms.py:50 apps/users/forms.py:63 apps/users/forms.py:85
|
||||||
#: templates/monthly_overview/pages/overview.html:116
|
#: templates/monthly_overview/pages/overview.html:116
|
||||||
#: templates/transactions/pages/transactions.html:35
|
#: templates/transactions/pages/transactions.html:35
|
||||||
msgid "Default"
|
msgid "Default"
|
||||||
msgstr "Padrão"
|
msgstr "Padrão"
|
||||||
|
|
||||||
#: apps/users/forms.py:85 apps/users/models.py:40
|
#: apps/users/forms.py:91 apps/users/models.py:40
|
||||||
msgid "Date Format"
|
msgid "Date Format"
|
||||||
msgstr "Formato de Data"
|
msgstr "Formato de Data"
|
||||||
|
|
||||||
#: apps/users/forms.py:90 apps/users/models.py:45
|
#: apps/users/forms.py:96 apps/users/models.py:45
|
||||||
msgid "Datetime Format"
|
msgid "Datetime Format"
|
||||||
msgstr "Formato de Data e Hora"
|
msgstr "Formato de Data e Hora"
|
||||||
|
|
||||||
#: apps/users/forms.py:117
|
#: apps/users/forms.py:102 apps/users/models.py:48
|
||||||
|
msgid "Number Format"
|
||||||
|
msgstr "Formato de Número"
|
||||||
|
|
||||||
|
#: apps/users/forms.py:131
|
||||||
msgid "Save"
|
msgid "Save"
|
||||||
msgstr "Salvar"
|
msgstr "Salvar"
|
||||||
|
|
||||||
@@ -1193,19 +1201,19 @@ msgstr "Todas as transações"
|
|||||||
msgid "Calendar"
|
msgid "Calendar"
|
||||||
msgstr "Calendário"
|
msgstr "Calendário"
|
||||||
|
|
||||||
#: apps/users/models.py:50 apps/users/models.py:56
|
#: apps/users/models.py:53 apps/users/models.py:59
|
||||||
msgid "Auto"
|
msgid "Auto"
|
||||||
msgstr "Automático"
|
msgstr "Automático"
|
||||||
|
|
||||||
#: apps/users/models.py:52
|
#: apps/users/models.py:55
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Linguagem"
|
msgstr "Linguagem"
|
||||||
|
|
||||||
#: apps/users/models.py:58
|
#: apps/users/models.py:61
|
||||||
msgid "Time Zone"
|
msgid "Time Zone"
|
||||||
msgstr "Fuso horário"
|
msgstr "Fuso horário"
|
||||||
|
|
||||||
#: apps/users/models.py:64
|
#: apps/users/models.py:67
|
||||||
msgid "Start page"
|
msgid "Start page"
|
||||||
msgstr "Página inicial"
|
msgstr "Página inicial"
|
||||||
|
|
||||||
@@ -1241,9 +1249,9 @@ msgstr "Editar grupo de conta"
|
|||||||
#: templates/accounts/fragments/list.html:37
|
#: templates/accounts/fragments/list.html:37
|
||||||
#: templates/categories/fragments/table.html:24
|
#: templates/categories/fragments/table.html:24
|
||||||
#: templates/currencies/fragments/list.html:33
|
#: templates/currencies/fragments/list.html:33
|
||||||
#: templates/dca/fragments/strategy/details.html:64
|
#: templates/dca/fragments/strategy/details.html:63
|
||||||
#: templates/entities/fragments/table.html:23
|
#: templates/entities/fragments/table.html:23
|
||||||
#: templates/exchange_rates/fragments/table.html:20
|
#: templates/exchange_rates/fragments/table.html:19
|
||||||
#: templates/import_app/fragments/profiles/list.html:44
|
#: templates/import_app/fragments/profiles/list.html:44
|
||||||
#: templates/installment_plans/fragments/table.html:23
|
#: templates/installment_plans/fragments/table.html:23
|
||||||
#: templates/recurring_transactions/fragments/table.html:25
|
#: templates/recurring_transactions/fragments/table.html:25
|
||||||
@@ -1255,13 +1263,13 @@ msgstr "Ações"
|
|||||||
#: templates/account_groups/fragments/list.html:36
|
#: templates/account_groups/fragments/list.html:36
|
||||||
#: templates/accounts/fragments/list.html:41
|
#: templates/accounts/fragments/list.html:41
|
||||||
#: templates/categories/fragments/table.html:29
|
#: templates/categories/fragments/table.html:29
|
||||||
#: templates/cotton/transaction/item.html:110
|
#: templates/cotton/transaction/item.html:109
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:43
|
#: templates/cotton/ui/transactions_action_bar.html:47
|
||||||
#: templates/currencies/fragments/list.html:37
|
#: templates/currencies/fragments/list.html:37
|
||||||
#: templates/dca/fragments/strategy/details.html:68
|
#: templates/dca/fragments/strategy/details.html:67
|
||||||
#: templates/dca/fragments/strategy/list.html:34
|
#: templates/dca/fragments/strategy/list.html:34
|
||||||
#: templates/entities/fragments/table.html:28
|
#: templates/entities/fragments/table.html:28
|
||||||
#: templates/exchange_rates/fragments/table.html:24
|
#: templates/exchange_rates/fragments/table.html:23
|
||||||
#: templates/import_app/fragments/profiles/list.html:48
|
#: templates/import_app/fragments/profiles/list.html:48
|
||||||
#: templates/installment_plans/fragments/table.html:27
|
#: templates/installment_plans/fragments/table.html:27
|
||||||
#: templates/recurring_transactions/fragments/table.html:29
|
#: templates/recurring_transactions/fragments/table.html:29
|
||||||
@@ -1274,13 +1282,13 @@ msgstr "Editar"
|
|||||||
#: templates/account_groups/fragments/list.html:43
|
#: templates/account_groups/fragments/list.html:43
|
||||||
#: templates/accounts/fragments/list.html:48
|
#: templates/accounts/fragments/list.html:48
|
||||||
#: templates/categories/fragments/table.html:36
|
#: templates/categories/fragments/table.html:36
|
||||||
#: templates/cotton/transaction/item.html:125
|
#: templates/cotton/transaction/item.html:124
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:80
|
#: templates/cotton/ui/transactions_action_bar.html:84
|
||||||
#: templates/currencies/fragments/list.html:44
|
#: templates/currencies/fragments/list.html:44
|
||||||
#: templates/dca/fragments/strategy/details.html:76
|
#: templates/dca/fragments/strategy/details.html:75
|
||||||
#: templates/dca/fragments/strategy/list.html:42
|
#: templates/dca/fragments/strategy/list.html:42
|
||||||
#: templates/entities/fragments/table.html:36
|
#: templates/entities/fragments/table.html:36
|
||||||
#: templates/exchange_rates/fragments/table.html:32
|
#: templates/exchange_rates/fragments/table.html:31
|
||||||
#: templates/import_app/fragments/profiles/list.html:69
|
#: templates/import_app/fragments/profiles/list.html:69
|
||||||
#: templates/import_app/fragments/runs/list.html:102
|
#: templates/import_app/fragments/runs/list.html:102
|
||||||
#: templates/installment_plans/fragments/table.html:56
|
#: templates/installment_plans/fragments/table.html:56
|
||||||
@@ -1295,13 +1303,13 @@ msgstr "Apagar"
|
|||||||
#: templates/account_groups/fragments/list.html:47
|
#: templates/account_groups/fragments/list.html:47
|
||||||
#: templates/accounts/fragments/list.html:52
|
#: templates/accounts/fragments/list.html:52
|
||||||
#: templates/categories/fragments/table.html:41
|
#: templates/categories/fragments/table.html:41
|
||||||
#: templates/cotton/transaction/item.html:129
|
#: templates/cotton/transaction/item.html:128
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:82
|
#: templates/cotton/ui/transactions_action_bar.html:86
|
||||||
#: templates/currencies/fragments/list.html:48
|
#: templates/currencies/fragments/list.html:48
|
||||||
#: templates/dca/fragments/strategy/details.html:81
|
#: templates/dca/fragments/strategy/details.html:80
|
||||||
#: templates/dca/fragments/strategy/list.html:46
|
#: templates/dca/fragments/strategy/list.html:46
|
||||||
#: templates/entities/fragments/table.html:40
|
#: templates/entities/fragments/table.html:40
|
||||||
#: templates/exchange_rates/fragments/table.html:37
|
#: templates/exchange_rates/fragments/table.html:36
|
||||||
#: templates/import_app/fragments/profiles/list.html:73
|
#: templates/import_app/fragments/profiles/list.html:73
|
||||||
#: templates/import_app/fragments/runs/list.html:106
|
#: templates/import_app/fragments/runs/list.html:106
|
||||||
#: templates/installment_plans/fragments/table.html:48
|
#: templates/installment_plans/fragments/table.html:48
|
||||||
@@ -1319,13 +1327,13 @@ msgstr "Tem certeza?"
|
|||||||
#: templates/account_groups/fragments/list.html:48
|
#: templates/account_groups/fragments/list.html:48
|
||||||
#: templates/accounts/fragments/list.html:53
|
#: templates/accounts/fragments/list.html:53
|
||||||
#: templates/categories/fragments/table.html:42
|
#: templates/categories/fragments/table.html:42
|
||||||
#: templates/cotton/transaction/item.html:130
|
#: templates/cotton/transaction/item.html:129
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:83
|
#: templates/cotton/ui/transactions_action_bar.html:87
|
||||||
#: templates/currencies/fragments/list.html:49
|
#: templates/currencies/fragments/list.html:49
|
||||||
#: templates/dca/fragments/strategy/details.html:82
|
#: templates/dca/fragments/strategy/details.html:81
|
||||||
#: templates/dca/fragments/strategy/list.html:47
|
#: templates/dca/fragments/strategy/list.html:47
|
||||||
#: templates/entities/fragments/table.html:41
|
#: templates/entities/fragments/table.html:41
|
||||||
#: templates/exchange_rates/fragments/table.html:38
|
#: templates/exchange_rates/fragments/table.html:37
|
||||||
#: templates/import_app/fragments/profiles/list.html:74
|
#: templates/import_app/fragments/profiles/list.html:74
|
||||||
#: templates/rules/fragments/list.html:49
|
#: templates/rules/fragments/list.html:49
|
||||||
#: templates/rules/fragments/transaction_rule/view.html:61
|
#: templates/rules/fragments/transaction_rule/view.html:61
|
||||||
@@ -1336,12 +1344,12 @@ msgstr "Você não será capaz de reverter isso!"
|
|||||||
#: templates/account_groups/fragments/list.html:49
|
#: templates/account_groups/fragments/list.html:49
|
||||||
#: templates/accounts/fragments/list.html:54
|
#: templates/accounts/fragments/list.html:54
|
||||||
#: templates/categories/fragments/table.html:43
|
#: templates/categories/fragments/table.html:43
|
||||||
#: templates/cotton/transaction/item.html:131
|
#: templates/cotton/transaction/item.html:130
|
||||||
#: templates/currencies/fragments/list.html:50
|
#: templates/currencies/fragments/list.html:50
|
||||||
#: templates/dca/fragments/strategy/details.html:83
|
#: templates/dca/fragments/strategy/details.html:82
|
||||||
#: templates/dca/fragments/strategy/list.html:48
|
#: templates/dca/fragments/strategy/list.html:48
|
||||||
#: templates/entities/fragments/table.html:42
|
#: templates/entities/fragments/table.html:42
|
||||||
#: templates/exchange_rates/fragments/table.html:39
|
#: templates/exchange_rates/fragments/table.html:38
|
||||||
#: templates/import_app/fragments/profiles/list.html:75
|
#: templates/import_app/fragments/profiles/list.html:75
|
||||||
#: templates/import_app/fragments/runs/list.html:108
|
#: templates/import_app/fragments/runs/list.html:108
|
||||||
#: templates/installment_plans/fragments/table.html:62
|
#: templates/installment_plans/fragments/table.html:62
|
||||||
@@ -1416,11 +1424,11 @@ msgstr "SÁB"
|
|||||||
msgid "SUN"
|
msgid "SUN"
|
||||||
msgstr "DOM"
|
msgstr "DOM"
|
||||||
|
|
||||||
#: templates/calendar_view/fragments/list_transactions.html:6
|
#: templates/calendar_view/fragments/list_transactions.html:5
|
||||||
msgid "Transactions on"
|
msgid "Transactions on"
|
||||||
msgstr "Transações em"
|
msgstr "Transações em"
|
||||||
|
|
||||||
#: templates/calendar_view/fragments/list_transactions.html:16
|
#: templates/calendar_view/fragments/list_transactions.html:15
|
||||||
msgid "No transactions on this date"
|
msgid "No transactions on this date"
|
||||||
msgstr "Nenhuma transação nesta data"
|
msgstr "Nenhuma transação nesta data"
|
||||||
|
|
||||||
@@ -1479,12 +1487,12 @@ msgstr "Fechar"
|
|||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Buscar"
|
msgstr "Buscar"
|
||||||
|
|
||||||
#: templates/cotton/transaction/item.html:6
|
#: templates/cotton/transaction/item.html:5
|
||||||
msgid "Select"
|
msgid "Select"
|
||||||
msgstr "Selecionar"
|
msgstr "Selecionar"
|
||||||
|
|
||||||
#: templates/cotton/transaction/item.html:117
|
#: templates/cotton/transaction/item.html:116
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:72
|
#: templates/cotton/ui/transactions_action_bar.html:76
|
||||||
msgid "Duplicate"
|
msgid "Duplicate"
|
||||||
msgstr "Duplicar"
|
msgstr "Duplicar"
|
||||||
|
|
||||||
@@ -1508,62 +1516,62 @@ msgstr "Despesas Previstas"
|
|||||||
msgid "Current Expenses"
|
msgid "Current Expenses"
|
||||||
msgstr "Despesas Atuais"
|
msgstr "Despesas Atuais"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:25
|
#: templates/cotton/ui/transactions_action_bar.html:29
|
||||||
msgid "Select All"
|
msgid "Select All"
|
||||||
msgstr "Selecionar todos"
|
msgstr "Selecionar todos"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:31
|
#: templates/cotton/ui/transactions_action_bar.html:35
|
||||||
msgid "Unselect All"
|
msgid "Unselect All"
|
||||||
msgstr "Desmarcar todos"
|
msgstr "Desmarcar todos"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:48
|
#: templates/cotton/ui/transactions_action_bar.html:52
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:139
|
#: templates/cotton/ui/transactions_action_bar.html:143
|
||||||
msgid "Toggle Dropdown"
|
msgid "Toggle Dropdown"
|
||||||
msgstr "Alternar menu suspenso"
|
msgstr "Alternar menu suspenso"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:56
|
#: templates/cotton/ui/transactions_action_bar.html:60
|
||||||
msgid "Mark as unpaid"
|
msgid "Mark as unpaid"
|
||||||
msgstr "Marcar como não pago"
|
msgstr "Marcar como não pago"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:63
|
#: templates/cotton/ui/transactions_action_bar.html:67
|
||||||
msgid "Mark as paid"
|
msgid "Mark as paid"
|
||||||
msgstr "Marcar como pago"
|
msgstr "Marcar como pago"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:84
|
#: templates/cotton/ui/transactions_action_bar.html:88
|
||||||
msgid "Yes, delete them!"
|
msgid "Yes, delete them!"
|
||||||
msgstr "Sim, apague!"
|
msgstr "Sim, apague!"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:130
|
#: templates/cotton/ui/transactions_action_bar.html:134
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:154
|
#: templates/cotton/ui/transactions_action_bar.html:158
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:174
|
#: templates/cotton/ui/transactions_action_bar.html:178
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:194
|
#: templates/cotton/ui/transactions_action_bar.html:198
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:214
|
#: templates/cotton/ui/transactions_action_bar.html:218
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:234
|
#: templates/cotton/ui/transactions_action_bar.html:238
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:254
|
#: templates/cotton/ui/transactions_action_bar.html:258
|
||||||
msgid "copied!"
|
msgid "copied!"
|
||||||
msgstr "copiado!"
|
msgstr "copiado!"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:147
|
#: templates/cotton/ui/transactions_action_bar.html:151
|
||||||
msgid "Flat Total"
|
msgid "Flat Total"
|
||||||
msgstr "Total Fixo"
|
msgstr "Total Fixo"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:167
|
#: templates/cotton/ui/transactions_action_bar.html:171
|
||||||
msgid "Real Total"
|
msgid "Real Total"
|
||||||
msgstr "Total Real"
|
msgstr "Total Real"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:187
|
#: templates/cotton/ui/transactions_action_bar.html:191
|
||||||
msgid "Mean"
|
msgid "Mean"
|
||||||
msgstr "Média"
|
msgstr "Média"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:207
|
#: templates/cotton/ui/transactions_action_bar.html:211
|
||||||
msgid "Max"
|
msgid "Max"
|
||||||
msgstr "Máximo"
|
msgstr "Máximo"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:227
|
#: templates/cotton/ui/transactions_action_bar.html:231
|
||||||
msgid "Min"
|
msgid "Min"
|
||||||
msgstr "Minímo"
|
msgstr "Minímo"
|
||||||
|
|
||||||
#: templates/cotton/ui/transactions_action_bar.html:247
|
#: templates/cotton/ui/transactions_action_bar.html:251
|
||||||
msgid "Count"
|
msgid "Count"
|
||||||
msgstr "Contagem"
|
msgstr "Contagem"
|
||||||
|
|
||||||
@@ -1595,91 +1603,91 @@ msgstr "Editar entrada CMP"
|
|||||||
msgid "Add DCA strategy"
|
msgid "Add DCA strategy"
|
||||||
msgstr "Adicionar estratégia CMP"
|
msgstr "Adicionar estratégia CMP"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:23
|
#: templates/dca/fragments/strategy/details.html:22
|
||||||
msgid "No exchange rate available"
|
msgid "No exchange rate available"
|
||||||
msgstr "Nenhuma taxa de câmbio disponível"
|
msgstr "Nenhuma taxa de câmbio disponível"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:34
|
#: templates/dca/fragments/strategy/details.html:33
|
||||||
msgid "Entries"
|
msgid "Entries"
|
||||||
msgstr "Entradas"
|
msgstr "Entradas"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:56
|
#: templates/dca/fragments/strategy/details.html:55
|
||||||
msgid "Current Value"
|
msgid "Current Value"
|
||||||
msgstr "Valor atual"
|
msgstr "Valor atual"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:57
|
#: templates/dca/fragments/strategy/details.html:56
|
||||||
msgid "P/L"
|
msgid "P/L"
|
||||||
msgstr "P/L"
|
msgstr "P/L"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:125
|
#: templates/dca/fragments/strategy/details.html:124
|
||||||
msgid "No entries for this DCA"
|
msgid "No entries for this DCA"
|
||||||
msgstr "Nenhuma entrada neste CMP"
|
msgstr "Nenhuma entrada neste CMP"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:126
|
#: templates/dca/fragments/strategy/details.html:125
|
||||||
#: templates/monthly_overview/fragments/list.html:41
|
#: templates/monthly_overview/fragments/list.html:41
|
||||||
#: templates/transactions/fragments/list_all.html:40
|
#: templates/transactions/fragments/list_all.html:40
|
||||||
msgid "Try adding one"
|
msgid "Try adding one"
|
||||||
msgstr "Tente adicionar uma"
|
msgstr "Tente adicionar uma"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:136
|
#: templates/dca/fragments/strategy/details.html:135
|
||||||
msgid "Total Invested"
|
msgid "Total Invested"
|
||||||
msgstr "Total investido"
|
msgstr "Total investido"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:150
|
#: templates/dca/fragments/strategy/details.html:149
|
||||||
msgid "Total Received"
|
msgid "Total Received"
|
||||||
msgstr "Total recebido"
|
msgstr "Total recebido"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:164
|
#: templates/dca/fragments/strategy/details.html:163
|
||||||
msgid "Current Total Value"
|
msgid "Current Total Value"
|
||||||
msgstr "Valor total atual"
|
msgstr "Valor total atual"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:178
|
#: templates/dca/fragments/strategy/details.html:177
|
||||||
msgid "Average Entry Price"
|
msgid "Average Entry Price"
|
||||||
msgstr "Preço médio de entrada"
|
msgstr "Preço médio de entrada"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:192
|
#: templates/dca/fragments/strategy/details.html:191
|
||||||
msgid "Total P/L"
|
msgid "Total P/L"
|
||||||
msgstr "P/L total"
|
msgstr "P/L total"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:208
|
#: templates/dca/fragments/strategy/details.html:207
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Total %% P/L"
|
msgid "Total %% P/L"
|
||||||
msgstr "P/L%% Total"
|
msgstr "P/L%% Total"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:227
|
#: templates/dca/fragments/strategy/details.html:226
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "P/L %%"
|
msgid "P/L %%"
|
||||||
msgstr "P/L %%"
|
msgstr "P/L %%"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:289
|
#: templates/dca/fragments/strategy/details.html:288
|
||||||
msgid "Performance Over Time"
|
msgid "Performance Over Time"
|
||||||
msgstr "Desempenho ao longo do tempo"
|
msgstr "Desempenho ao longo do tempo"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:307
|
#: templates/dca/fragments/strategy/details.html:306
|
||||||
msgid "Entry Price"
|
msgid "Entry Price"
|
||||||
msgstr "Preço de Entrada"
|
msgstr "Preço de Entrada"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:315
|
#: templates/dca/fragments/strategy/details.html:314
|
||||||
msgid "Current Price"
|
msgid "Current Price"
|
||||||
msgstr "Preço atual"
|
msgstr "Preço atual"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:323
|
#: templates/dca/fragments/strategy/details.html:322
|
||||||
msgid "Amount Bought"
|
msgid "Amount Bought"
|
||||||
msgstr "Quantia comprada"
|
msgstr "Quantia comprada"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:391
|
#: templates/dca/fragments/strategy/details.html:390
|
||||||
msgid "Entry Price vs Current Price"
|
msgid "Entry Price vs Current Price"
|
||||||
msgstr "Preço de Entrada vs Preço Atual"
|
msgstr "Preço de Entrada vs Preço Atual"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:407
|
#: templates/dca/fragments/strategy/details.html:406
|
||||||
msgid "Days Between Investments"
|
msgid "Days Between Investments"
|
||||||
msgstr "Dias entre investimentos"
|
msgstr "Dias entre investimentos"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:454
|
#: templates/dca/fragments/strategy/details.html:453
|
||||||
msgid "Investment Frequency"
|
msgid "Investment Frequency"
|
||||||
msgstr "Frequência de Investimento"
|
msgstr "Frequência de Investimento"
|
||||||
|
|
||||||
#: templates/dca/fragments/strategy/details.html:456
|
#: templates/dca/fragments/strategy/details.html:455
|
||||||
msgid "The straighter the blue line, the more consistent your DCA strategy is."
|
msgid "The straighter the blue line, the more consistent your DCA strategy is."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Quanto mais reta for a linha azul, mais consistente é sua estratégia de CMP."
|
"Quanto mais reta for a linha azul, mais consistente é sua estratégia de CMP."
|
||||||
@@ -1725,19 +1733,19 @@ msgstr "Editar taxa de câmbio"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Todas"
|
msgstr "Todas"
|
||||||
|
|
||||||
#: templates/exchange_rates/fragments/table.html:12
|
#: templates/exchange_rates/fragments/table.html:11
|
||||||
msgid "Pairing"
|
msgid "Pairing"
|
||||||
msgstr "Pares"
|
msgstr "Pares"
|
||||||
|
|
||||||
#: templates/exchange_rates/fragments/table.html:13
|
#: templates/exchange_rates/fragments/table.html:12
|
||||||
msgid "Rate"
|
msgid "Rate"
|
||||||
msgstr "Taxa de Câmbio"
|
msgstr "Taxa de Câmbio"
|
||||||
|
|
||||||
#: templates/exchange_rates/fragments/table.html:52
|
#: templates/exchange_rates/fragments/table.html:51
|
||||||
msgid "No exchange rates"
|
msgid "No exchange rates"
|
||||||
msgstr "Nenhuma taxa de câmbio"
|
msgstr "Nenhuma taxa de câmbio"
|
||||||
|
|
||||||
#: templates/exchange_rates/fragments/table.html:59
|
#: templates/exchange_rates/fragments/table.html:58
|
||||||
#: templates/transactions/fragments/list_all.html:47
|
#: templates/transactions/fragments/list_all.html:47
|
||||||
msgid "Page navigation"
|
msgid "Page navigation"
|
||||||
msgstr "Navegação por página"
|
msgstr "Navegação por página"
|
||||||
@@ -1894,7 +1902,11 @@ msgstr "Calculadora"
|
|||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Configurações"
|
msgstr "Configurações"
|
||||||
|
|
||||||
#: templates/includes/navbar/user_menu.html:37
|
#: templates/includes/navbar/user_menu.html:38
|
||||||
|
msgid "Clear cache"
|
||||||
|
msgstr "Limpar cache"
|
||||||
|
|
||||||
|
#: templates/includes/navbar/user_menu.html:42
|
||||||
msgid "Logout"
|
msgid "Logout"
|
||||||
msgstr "Sair"
|
msgstr "Sair"
|
||||||
|
|
||||||
|
|||||||
@@ -39,23 +39,23 @@
|
|||||||
{% for transaction in date.transactions %}
|
{% for transaction in date.transactions %}
|
||||||
{% if transaction.is_paid %}
|
{% if transaction.is_paid %}
|
||||||
{% if transaction.type == "IN" and not transaction.account.is_asset %}
|
{% if transaction.type == "IN" and not transaction.account.is_asset %}
|
||||||
<i class="fa-solid fa-circle-check tw-text-green-400" data-bs-toggle="tooltip" data-bs-title="{{ transaction.description }}"></i>
|
<i class="fa-solid fa-circle-check tw-text-green-400" data-bs-toggle="tooltip" data-bs-title="{% if transaction.description %}{{ transaction.description }}{% else %}{% trans 'Income' %}{% endif %}"></i>
|
||||||
{% elif transaction.type == "IN" and transaction.account.is_asset %}
|
{% elif transaction.type == "IN" and transaction.account.is_asset %}
|
||||||
<i class="fa-solid fa-circle-check tw-text-green-300" data-bs-toggle="tooltip" data-bs-title="{{ transaction.description }}"></i>
|
<i class="fa-solid fa-circle-check tw-text-green-300" data-bs-toggle="tooltip" data-bs-title="{% if transaction.description %}{{ transaction.description }}{% else %}{% trans 'Income' %}{% endif %}"></i>
|
||||||
{% elif transaction.type == "EX" and not transaction.account.is_asset %}
|
{% elif transaction.type == "EX" and not transaction.account.is_asset %}
|
||||||
<i class="fa-solid fa-circle-check tw-text-red-400" data-bs-toggle="tooltip" data-bs-title="{{ transaction.description }}"></i>
|
<i class="fa-solid fa-circle-check tw-text-red-400" data-bs-toggle="tooltip" data-bs-title="{% if transaction.description %}{{ transaction.description }}{% else %}{% trans 'Expense' %}{% endif %}"></i>
|
||||||
{% elif transaction.type == "EX" and transaction.account.is_asset %}
|
{% elif transaction.type == "EX" and transaction.account.is_asset %}
|
||||||
<i class="fa-solid fa-circle-check tw-text-red-300" data-bs-toggle="tooltip" data-bs-title="{{ transaction.description }}"></i>
|
<i class="fa-solid fa-circle-check tw-text-red-300" data-bs-toggle="tooltip" data-bs-title="{% if transaction.description %}{{ transaction.description }}{% else %}{% trans 'Expense' %}{% endif %}"></i>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if transaction.type == "IN" and not transaction.account.is_asset %}
|
{% if transaction.type == "IN" and not transaction.account.is_asset %}
|
||||||
<i class="fa-regular fa-circle tw-text-green-400" data-bs-toggle="tooltip" data-bs-title="{{ transaction.description }}"></i>
|
<i class="fa-regular fa-circle tw-text-green-400" data-bs-toggle="tooltip" data-bs-title="{% if transaction.description %}{{ transaction.description }}{% else %}{% trans 'Income' %}{% endif %}"></i>
|
||||||
{% elif transaction.type == "IN" and transaction.account.is_asset %}
|
{% elif transaction.type == "IN" and transaction.account.is_asset %}
|
||||||
<i class="fa-regular fa-circle tw-text-green-300" data-bs-toggle="tooltip" data-bs-title="{{ transaction.description }}"></i>
|
<i class="fa-regular fa-circle tw-text-green-300" data-bs-toggle="tooltip" data-bs-title="{% if transaction.description %}{{ transaction.description }}{% else %}{% trans 'Income' %}{% endif %}"></i>
|
||||||
{% elif transaction.type == "EX" and not transaction.account.is_asset %}
|
{% elif transaction.type == "EX" and not transaction.account.is_asset %}
|
||||||
<i class="fa-regular fa-circle tw-text-red-400" data-bs-toggle="tooltip" data-bs-title="{{ transaction.description }}"></i>
|
<i class="fa-regular fa-circle tw-text-red-400" data-bs-toggle="tooltip" data-bs-title="{% if transaction.description %}{{ transaction.description }}{% else %}{% trans 'Expense' %}{% endif %}"></i>
|
||||||
{% elif transaction.type == "EX" and transaction.account.is_asset %}
|
{% elif transaction.type == "EX" and transaction.account.is_asset %}
|
||||||
<i class="fa-regular fa-circle tw-text-green-300" data-bs-toggle="tooltip" data-bs-title="{{ transaction.description }}"></i>
|
<i class="fa-regular fa-circle tw-text-red-300" data-bs-toggle="tooltip" data-bs-title="{% if transaction.description %}{{ transaction.description }}{% else %}{% trans 'Expense' %}{% endif %}"></i>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
{% extends 'extends/offcanvas.html' %}
|
{% extends 'extends/offcanvas.html' %}
|
||||||
{% load date %}
|
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load crispy_forms_tags %}
|
{% load crispy_forms_tags %}
|
||||||
|
|
||||||
{% block title %}{% translate 'Transactions on' %} {{ date|custom_date:request.user }}{% endblock %}
|
{% block title %}{% translate 'Transactions on' %} {{ date|date:"SHORT_DATE_FORMAT" }}{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% 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">
|
<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">
|
||||||
{% for transaction in transactions %}
|
{% for transaction in transactions %}
|
||||||
<c-transaction.item
|
<c-transaction.item :transaction="transaction"></c-transaction.item>
|
||||||
:transaction="transaction"
|
{% empty %}
|
||||||
:disable-selection="True"></c-transaction.item>
|
<c-msg.empty
|
||||||
{% empty %}
|
title="{% translate 'No transactions on this date' %}"></c-msg.empty>
|
||||||
<c-msg.empty
|
{% endfor %}
|
||||||
title="{% translate 'No transactions on this date' %}"></c-msg.empty>
|
{# Floating bar #}
|
||||||
{% endfor %}
|
<c-ui.transactions-action-bar></c-ui.transactions-action-bar>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
{% load date %}
|
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="transaction d-flex my-1 {% if transaction.type == "EX" %}expense{% else %}income{% endif %}">
|
<div class="transaction d-flex my-1 {% if transaction.type == "EX" %}expense{% else %}income{% endif %}">
|
||||||
{% if not disable_selection %}
|
{% if not disable_selection %}
|
||||||
@@ -27,7 +26,7 @@
|
|||||||
{# Date#}
|
{# Date#}
|
||||||
<div class="row mb-2 mb-lg-1 tw-text-gray-400">
|
<div class="row mb-2 mb-lg-1 tw-text-gray-400">
|
||||||
<div class="col-auto pe-1"><i class="fa-solid fa-calendar fa-fw me-1 fa-xs"></i></div>
|
<div class="col-auto pe-1"><i class="fa-solid fa-calendar fa-fw me-1 fa-xs"></i></div>
|
||||||
<div class="col ps-0">{{ transaction.date|custom_date:request.user }} • {{ transaction.reference_date|date:"b/Y" }}</div>
|
<div class="col ps-0">{{ transaction.date|date:"SHORT_DATE_FORMAT" }} • {{ transaction.reference_date|date:"b/Y" }}</div>
|
||||||
</div>
|
</div>
|
||||||
{# Description#}
|
{# Description#}
|
||||||
<div class="mb-2 mb-lg-1 text-white tw-text-base">
|
<div class="mb-2 mb-lg-1 text-white tw-text-base">
|
||||||
|
|||||||
@@ -2,12 +2,16 @@
|
|||||||
<div class="tw-sticky tw-bottom-4 tw-left-0 tw-right-0 tw-z-50 tw-hidden mx-auto tw-w-fit" id="actions-bar"
|
<div class="tw-sticky tw-bottom-4 tw-left-0 tw-right-0 tw-z-50 tw-hidden mx-auto tw-w-fit" id="actions-bar"
|
||||||
_="on change from #transactions-list or htmx:afterSettle from window
|
_="on change from #transactions-list or htmx:afterSettle from window
|
||||||
if no <input[type='checkbox']:checked/> in #transactions-list
|
if no <input[type='checkbox']:checked/> in #transactions-list
|
||||||
add .slide-in-bottom-reverse then settle
|
if #actions-bar
|
||||||
then add .tw-hidden to #actions-bar
|
add .slide-in-bottom-reverse then settle
|
||||||
then remove .slide-in-bottom-reverse
|
then add .tw-hidden to #actions-bar
|
||||||
|
then remove .slide-in-bottom-reverse
|
||||||
|
end
|
||||||
else
|
else
|
||||||
remove .tw-hidden from #actions-bar
|
if #actions-bar
|
||||||
then trigger selected_transactions_updated
|
remove .tw-hidden from #actions-bar
|
||||||
|
then trigger selected_transactions_updated
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end">
|
end">
|
||||||
<div class="card slide-in-bottom">
|
<div class="card slide-in-bottom">
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
{% load date %}
|
|
||||||
{% load currency_display %}
|
{% load currency_display %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="container-fluid px-md-3 py-3 column-gap-5">
|
<div class="container-fluid px-md-3 py-3 column-gap-5">
|
||||||
@@ -17,7 +16,7 @@
|
|||||||
:prefix="strategy.payment_currency.prefix"
|
:prefix="strategy.payment_currency.prefix"
|
||||||
:suffix="strategy.payment_currency.suffix"
|
:suffix="strategy.payment_currency.suffix"
|
||||||
:decimal_places="strategy.payment_currency.decimal_places">
|
:decimal_places="strategy.payment_currency.decimal_places">
|
||||||
• {{ strategy.current_price.1|custom_date:request.user }}
|
• {{ strategy.current_price.1|date:"SHORT_DATETIME_FORMAT" }}
|
||||||
</c-amount.display>
|
</c-amount.display>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="tw-text-red-400">{% trans "No exchange rate available" %}</div>
|
<div class="tw-text-red-400">{% trans "No exchange rate available" %}</div>
|
||||||
@@ -84,7 +83,7 @@
|
|||||||
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
|
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>{{ entry.date|custom_date:request.user }}</td>
|
<td>{{ entry.date|date:"SHORT_DATE_FORMAT" }}</td>
|
||||||
<td>
|
<td>
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="entry.amount_received"
|
:amount="entry.amount_received"
|
||||||
@@ -222,7 +221,7 @@
|
|||||||
new Chart(perfomancectx, {
|
new Chart(perfomancectx, {
|
||||||
type: 'line',
|
type: 'line',
|
||||||
data: {
|
data: {
|
||||||
labels: [{% for entry in entries_data %}'{{ entry.entry.date|custom_date:request.user }}'{% if not forloop.last %}, {% endif %}{% endfor %}],
|
labels: [{% for entry in entries_data %}'{{ entry.entry.date|date:"SHORT_DATE_FORMAT" }}'{% if not forloop.last %}, {% endif %}{% endfor %}],
|
||||||
datasets: [{
|
datasets: [{
|
||||||
label: '{% trans "P/L %" %}',
|
label: '{% trans "P/L %" %}',
|
||||||
data: [{% for entry in entries_data %}{{ entry.profit_loss_percentage|floatformat:"-40u" }}{% if not forloop.last %}, {% endif %}{% endfor %}],
|
data: [{% for entry in entries_data %}{{ entry.profit_loss_percentage|floatformat:"-40u" }}{% if not forloop.last %}, {% endif %}{% endfor %}],
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
{% load date %}
|
|
||||||
{% load currency_display %}
|
{% load currency_display %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="card-body show-loading" hx-get="{% url 'exchange_rates_list_pair' %}" hx-trigger="updated from:window" hx-swap="outerHTML" hx-vals='{"page": "{{ page_obj.number }}", "from": "{{ from_currency|default_if_none:"" }}", "to": "{{ to_currency|default_if_none:"" }}"}'>
|
<div class="card-body show-loading" hx-get="{% url 'exchange_rates_list_pair' %}" hx-trigger="updated from:window" hx-swap="outerHTML" hx-vals='{"page": "{{ page_obj.number }}", "from": "{{ from_currency|default_if_none:"" }}", "to": "{{ to_currency|default_if_none:"" }}"}'>
|
||||||
@@ -40,7 +39,7 @@
|
|||||||
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
|
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="col-3">{{ exchange_rate.date|custom_date:request.user }}</td>
|
<td class="col-3">{{ exchange_rate.date|date:"SHORT_DATETIME_FORMAT" }}</td>
|
||||||
<td class="col-3"><span class="badge rounded-pill text-bg-secondary">{{ exchange_rate.from_currency.code }}</span> x <span class="badge rounded-pill text-bg-secondary">{{ exchange_rate.to_currency.code }}</span></td>
|
<td class="col-3"><span class="badge rounded-pill text-bg-secondary">{{ exchange_rate.from_currency.code }}</span> x <span class="badge rounded-pill text-bg-secondary">{{ exchange_rate.to_currency.code }}</span></td>
|
||||||
<td class="col-3">1 {{ exchange_rate.from_currency.code }} ≅ {% currency_display amount=exchange_rate.rate prefix=exchange_rate.to_currency.prefix suffix=exchange_rate.to_currency.suffix decimal_places=exchange_rate.to_currency.decimal_places%}</td>
|
<td class="col-3">1 {{ exchange_rate.from_currency.code }} ≅ {% currency_display amount=exchange_rate.rate prefix=exchange_rate.to_currency.prefix suffix=exchange_rate.to_currency.suffix decimal_places=exchange_rate.to_currency.decimal_places%}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -33,6 +33,11 @@
|
|||||||
</li>
|
</li>
|
||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
<li><hr class="dropdown-divider"></li>
|
<li><hr class="dropdown-divider"></li>
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item" hx-get="{% url 'invalidate_cache' %}" role="button">
|
||||||
|
<i class="fa-solid fa-broom me-2 fa-fw"></i>{% translate 'Clear cache' %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li><a class="dropdown-item" href="{% url 'logout' %}"><i class="fa-solid fa-door-open me-2 fa-fw"></i
|
<li><a class="dropdown-item" href="{% url 'logout' %}"><i class="fa-solid fa-door-open me-2 fa-fw"></i
|
||||||
>{% translate 'Logout' %}</a></li>
|
>{% translate 'Logout' %}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -5,11 +5,11 @@
|
|||||||
{% block title %}{% translate 'Installments' %}{% endblock %}
|
{% block title %}{% translate 'Installments' %}{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% 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">
|
<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">
|
||||||
{% for transaction in transactions %}
|
{% for transaction in transactions %}
|
||||||
<c-transaction.item
|
<c-transaction.item :transaction="transaction"></c-transaction.item>
|
||||||
:transaction="transaction"
|
{% endfor %}
|
||||||
:disable-selection="True"></c-transaction.item>
|
{# Floating bar #}
|
||||||
{% endfor %}
|
<c-ui.transactions-action-bar></c-ui.transactions-action-bar>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -23,8 +23,6 @@
|
|||||||
<div id="content">
|
<div id="content">
|
||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% include 'includes/toasts.html' %}
|
|
||||||
|
|
||||||
{% include 'includes/scripts.html' %}
|
{% include 'includes/scripts.html' %}
|
||||||
{% block extra_js %}{% endblock %}
|
{% block extra_js %}{% endblock %}
|
||||||
|
|||||||
@@ -113,9 +113,9 @@
|
|||||||
<div class="text-sm-end" _="on change trigger updated on window">
|
<div class="text-sm-end" _="on change trigger updated on window">
|
||||||
<label for="order">{% translate "Order by" %}</label>
|
<label for="order">{% translate "Order by" %}</label>
|
||||||
<select class="tw-border-0 focus-visible:tw-outline-0 w-full pe-2 tw-leading-normal text-bg-tertiary tw-font-medium rounded" name="order" id="order">
|
<select class="tw-border-0 focus-visible:tw-outline-0 w-full pe-2 tw-leading-normal text-bg-tertiary tw-font-medium rounded" name="order" id="order">
|
||||||
<option value="default">{% translate 'Default' %}</option>
|
<option value="default" {% if order == 'default' %}selected{% endif %}>{% translate 'Default' %}</option>
|
||||||
<option value="older">{% translate 'Oldest first' %}</option>
|
<option value="older" {% if order == 'older' %}selected{% endif %}>{% translate 'Oldest first' %}</option>
|
||||||
<option value="newer">{% translate 'Newest first' %}</option>
|
<option value="newer" {% if order == 'newer' %}selected{% endif %}>{% translate 'Newest first' %}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,11 +5,11 @@
|
|||||||
{% block title %}{% translate 'Transactions' %}{% endblock %}
|
{% block title %}{% translate 'Transactions' %}{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% 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">
|
<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">
|
||||||
{% for transaction in transactions %}
|
{% for transaction in transactions %}
|
||||||
<c-transaction.item
|
<c-transaction.item :transaction="transaction"></c-transaction.item>
|
||||||
:transaction="transaction"
|
{% endfor %}
|
||||||
:disable-selection="True"></c-transaction.item>
|
{# Floating bar #}
|
||||||
{% endfor %}
|
<c-ui.transactions-action-bar></c-ui.transactions-action-bar>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -32,9 +32,9 @@
|
|||||||
<div class="tw-content-center" _="on change trigger updated on window">
|
<div class="tw-content-center" _="on change trigger updated on window">
|
||||||
<label for="order">{% translate "Order by" %}</label>
|
<label for="order">{% translate "Order by" %}</label>
|
||||||
<select class="tw-border-0 focus-visible:tw-outline-0 w-full pe-2 tw-leading-normal text-bg-tertiary tw-font-medium rounded" name="order" id="order">
|
<select class="tw-border-0 focus-visible:tw-outline-0 w-full pe-2 tw-leading-normal text-bg-tertiary tw-font-medium rounded" name="order" id="order">
|
||||||
<option value="default">{% translate 'Default' %}</option>
|
<option value="default" {% if order == 'default' %}selected{% endif %}>{% translate 'Default' %}</option>
|
||||||
<option value="older">{% translate 'Oldest first' %}</option>
|
<option value="older" {% if order == 'older' %}selected{% endif %}>{% translate 'Oldest first' %}</option>
|
||||||
<option value="newer">{% translate 'Newest first' %}</option>
|
<option value="newer" {% if order == 'newer' %}selected{% endif %}>{% translate 'Newest first' %}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ volumes:
|
|||||||
wygiwyh_temp:
|
wygiwyh_temp:
|
||||||
|
|
||||||
services:
|
services:
|
||||||
web: &django
|
web:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: ./docker/dev/django/Dockerfile
|
dockerfile: ./docker/dev/django/Dockerfile
|
||||||
image: wygiwyh_dev_server
|
image: wygiwyh_dev_server
|
||||||
container_name: wygiwyh_dev_server
|
container_name: wygiwyh_dev_server
|
||||||
command: /start
|
command: /start-supervisor
|
||||||
volumes:
|
volumes:
|
||||||
- ./app/:/usr/src/app/:z
|
- ./app/:/usr/src/app/:z
|
||||||
- ./frontend/:/usr/src/frontend:z
|
- ./frontend/:/usr/src/frontend:z
|
||||||
@@ -54,12 +54,12 @@ services:
|
|||||||
- '${SQL_PORT}:5432'
|
- '${SQL_PORT}:5432'
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
procrastinate:
|
# procrastinate:
|
||||||
<<: *django
|
# <<: *django
|
||||||
image: wygiwyh_dev_procrastinate
|
# image: wygiwyh_dev_procrastinate
|
||||||
container_name: wygiwyh_dev_procrastinate
|
# container_name: wygiwyh_dev_procrastinate
|
||||||
depends_on:
|
# depends_on:
|
||||||
- db
|
# - db
|
||||||
ports: [ ]
|
# ports: [ ]
|
||||||
command: /start-procrastinate
|
# command: /start-procrastinate
|
||||||
restart: unless-stopped
|
# restart: unless-stopped
|
||||||
|
|||||||
@@ -2,15 +2,13 @@ services:
|
|||||||
web:
|
web:
|
||||||
image: eitchtee/wygiwyh:latest
|
image: eitchtee/wygiwyh:latest
|
||||||
container_name: ${SERVER_NAME}
|
container_name: ${SERVER_NAME}
|
||||||
command: /start
|
command: /start-single
|
||||||
ports:
|
ports:
|
||||||
- "${OUTBOUND_PORT}:8000"
|
- "${OUTBOUND_PORT}:8000"
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
depends_on:
|
depends_on:
|
||||||
- db
|
- db
|
||||||
volumes:
|
|
||||||
- wygiwyh_temp:/usr/src/app/temp/
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
db:
|
db:
|
||||||
@@ -23,18 +21,3 @@ services:
|
|||||||
- POSTGRES_USER=${SQL_USER}
|
- POSTGRES_USER=${SQL_USER}
|
||||||
- POSTGRES_PASSWORD=${SQL_PASSWORD}
|
- POSTGRES_PASSWORD=${SQL_PASSWORD}
|
||||||
- POSTGRES_DB=${SQL_DATABASE}
|
- POSTGRES_DB=${SQL_DATABASE}
|
||||||
|
|
||||||
procrastinate:
|
|
||||||
image: eitchtee/wygiwyh:latest
|
|
||||||
container_name: ${PROCRASTINATE_NAME}
|
|
||||||
depends_on:
|
|
||||||
- db
|
|
||||||
env_file:
|
|
||||||
- .env
|
|
||||||
volumes:
|
|
||||||
- wygiwyh_temp:/usr/src/app/temp/
|
|
||||||
command: /start-procrastinate
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
wygiwyh_temp:
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ ENV PYTHONDONTWRITEBYTECODE=1 \
|
|||||||
COPY --from=python-build-stage /usr/src/app/wheels /wheels/
|
COPY --from=python-build-stage /usr/src/app/wheels /wheels/
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install --no-install-recommends -y gettext && \
|
apt-get install --no-install-recommends -y gettext supervisor && \
|
||||||
rm -rf /var/lib/apt/lists/* && \
|
rm -rf /var/lib/apt/lists/* && \
|
||||||
pip install --upgrade pip && \
|
pip install --upgrade pip && \
|
||||||
pip install --no-cache-dir --no-index --find-links=/wheels/ /wheels/* && \
|
pip install --no-cache-dir --no-index --find-links=/wheels/ /wheels/* && \
|
||||||
@@ -26,9 +26,15 @@ RUN apt-get update && \
|
|||||||
|
|
||||||
COPY ./docker/dev/django/start /start
|
COPY ./docker/dev/django/start /start
|
||||||
COPY ./docker/dev/procrastinate/start /start-procrastinate
|
COPY ./docker/dev/procrastinate/start /start-procrastinate
|
||||||
|
COPY ./docker/dev/supervisord/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
||||||
|
COPY ./docker/dev/supervisord/supervisord.conf /etc/supervisord.conf
|
||||||
|
COPY ./docker/dev/supervisord/start /start-supervisor
|
||||||
|
|
||||||
RUN sed -i 's/\r$//g' /start && \
|
RUN sed -i 's/\r$//g' /start && \
|
||||||
chmod +x /start && \
|
chmod +x /start && \
|
||||||
sed -i 's/\r$//g' /start-procrastinate && \
|
sed -i 's/\r$//g' /start-procrastinate && \
|
||||||
chmod +x /start-procrastinate
|
chmod +x /start-procrastinate && \
|
||||||
|
sed -i 's/\r$//g' /start-supervisor && \
|
||||||
|
chmod +x /start-supervisor
|
||||||
|
|
||||||
COPY ./app .
|
COPY ./app .
|
||||||
|
|||||||
9
docker/dev/supervisord/start
Normal file
9
docker/dev/supervisord/start
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
set -o pipefail
|
||||||
|
set -o nounset
|
||||||
|
|
||||||
|
export TASK_WORKERS=${TASK_WORKERS:=1}
|
||||||
|
|
||||||
|
exec supervisord -c /etc/supervisor/conf.d/supervisord.conf
|
||||||
39
docker/dev/supervisord/supervisord.conf
Normal file
39
docker/dev/supervisord/supervisord.conf
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
[supervisord]
|
||||||
|
nodaemon=true
|
||||||
|
logfile=/dev/null
|
||||||
|
logfile_maxbytes=0
|
||||||
|
pidfile=/tmp/supervisord.pid
|
||||||
|
user=root
|
||||||
|
|
||||||
|
[supervisorctl]
|
||||||
|
serverurl=unix:///run/supervisord.sock
|
||||||
|
|
||||||
|
[rpcinterface:supervisor]
|
||||||
|
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
|
||||||
|
|
||||||
|
[unix_http_server]
|
||||||
|
file=/run/supervisord.sock
|
||||||
|
chmod=0700
|
||||||
|
|
||||||
|
[program:web]
|
||||||
|
directory=/usr/src/app
|
||||||
|
command=/bin/bash /start
|
||||||
|
stdout_logfile=/dev/fd/1
|
||||||
|
stdout_logfile_maxbytes=0
|
||||||
|
stderr_logfile=/dev/fd/2
|
||||||
|
stderr_logfile_maxbytes=0
|
||||||
|
autorestart=true
|
||||||
|
startretries=5
|
||||||
|
|
||||||
|
[program:procrastinate]
|
||||||
|
directory=/usr/src/app
|
||||||
|
command=/bin/bash /start-procrastinate
|
||||||
|
process_name=%(program_name)s_%(process_num)02d
|
||||||
|
numprocs=%(ENV_TASK_WORKERS)s
|
||||||
|
numprocs_start=1
|
||||||
|
stdout_logfile=/dev/fd/1
|
||||||
|
stdout_logfile_maxbytes=0
|
||||||
|
stderr_logfile=/dev/fd/2
|
||||||
|
stderr_logfile_maxbytes=0
|
||||||
|
autorestart=true
|
||||||
|
startretries=5
|
||||||
@@ -31,7 +31,7 @@ ENV PYTHONDONTWRITEBYTECODE=1 \
|
|||||||
COPY --from=python-build-stage /usr/src/app/wheels /wheels/
|
COPY --from=python-build-stage /usr/src/app/wheels /wheels/
|
||||||
RUN --mount=type=cache,target=/root/.cache/apt \
|
RUN --mount=type=cache,target=/root/.cache/apt \
|
||||||
apt-get update && \
|
apt-get update && \
|
||||||
apt-get install --no-install-recommends -y gettext && \
|
apt-get install --no-install-recommends -y gettext supervisor && \
|
||||||
rm -rf /var/lib/apt/lists/* && \
|
rm -rf /var/lib/apt/lists/* && \
|
||||||
pip install --upgrade pip && \
|
pip install --upgrade pip && \
|
||||||
pip install --no-cache-dir --no-index --find-links=/wheels/ /wheels/* && \
|
pip install --no-cache-dir --no-index --find-links=/wheels/ /wheels/* && \
|
||||||
@@ -39,10 +39,15 @@ RUN --mount=type=cache,target=/root/.cache/apt \
|
|||||||
|
|
||||||
COPY --chown=app:app ./docker/prod/django/start /start
|
COPY --chown=app:app ./docker/prod/django/start /start
|
||||||
COPY --chown=app:app ./docker/prod/procrastinate/start /start-procrastinate
|
COPY --chown=app:app ./docker/prod/procrastinate/start /start-procrastinate
|
||||||
|
COPY --chown=app:app ./docker/prod/supervisord/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
||||||
|
COPY --chown=app:app ./docker/prod/supervisord/supervisord.conf /etc/supervisord.conf
|
||||||
|
COPY --chown=app:app ./docker/prod/supervisord/start /start-single
|
||||||
RUN sed -i 's/\r$//g' /start && \
|
RUN sed -i 's/\r$//g' /start && \
|
||||||
chmod +x /start && \
|
chmod +x /start && \
|
||||||
sed -i 's/\r$//g' /start-procrastinate && \
|
sed -i 's/\r$//g' /start-procrastinate && \
|
||||||
chmod +x /start-procrastinate
|
chmod +x /start-procrastinate && \
|
||||||
|
sed -i 's/\r$//g' /start-single && \
|
||||||
|
chmod +x /start-single
|
||||||
|
|
||||||
COPY --chown=app:app ./app .
|
COPY --chown=app:app ./app .
|
||||||
|
|
||||||
|
|||||||
9
docker/prod/supervisord/start
Normal file
9
docker/prod/supervisord/start
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
set -o pipefail
|
||||||
|
set -o nounset
|
||||||
|
|
||||||
|
export TASK_WORKERS=${TASK_WORKERS:=1}
|
||||||
|
|
||||||
|
exec supervisord -c /etc/supervisor/conf.d/supervisord.conf
|
||||||
37
docker/prod/supervisord/supervisord.conf
Normal file
37
docker/prod/supervisord/supervisord.conf
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
[supervisord]
|
||||||
|
nodaemon=true
|
||||||
|
logfile=/dev/null
|
||||||
|
logfile_maxbytes=0
|
||||||
|
pidfile=/tmp/supervisord.pid
|
||||||
|
|
||||||
|
[supervisorctl]
|
||||||
|
serverurl=unix:///tmp/supervisord.sock
|
||||||
|
|
||||||
|
[unix_http_server]
|
||||||
|
file=/tmp/supervisord.sock
|
||||||
|
chmod=0700
|
||||||
|
|
||||||
|
[program:web]
|
||||||
|
user=app
|
||||||
|
directory=/usr/src/app
|
||||||
|
command=/bin/bash /start
|
||||||
|
stdout_logfile=/dev/fd/1
|
||||||
|
stdout_logfile_maxbytes=0
|
||||||
|
stderr_logfile=/dev/fd/2
|
||||||
|
stderr_logfile_maxbytes=0
|
||||||
|
autorestart=true
|
||||||
|
startretries=5
|
||||||
|
|
||||||
|
[program:procrastinate]
|
||||||
|
user=app
|
||||||
|
directory=/usr/src/app
|
||||||
|
command=/bin/bash /start-procrastinate
|
||||||
|
process_name=%(program_name)s_%(process_num)02d
|
||||||
|
numprocs=%(ENV_TASK_WORKERS)s
|
||||||
|
numprocs_start=1
|
||||||
|
stdout_logfile=/dev/fd/1
|
||||||
|
stdout_logfile_maxbytes=0
|
||||||
|
stderr_logfile=/dev/fd/2
|
||||||
|
stderr_logfile_maxbytes=0
|
||||||
|
autorestart=true
|
||||||
|
startretries=5
|
||||||
@@ -163,8 +163,8 @@ window.MonthYearPicker = function createDynamicDatePicker(element) {
|
|||||||
let opts = {...baseOpts, ...positionConfig};
|
let opts = {...baseOpts, ...positionConfig};
|
||||||
|
|
||||||
if (element.dataset.value) {
|
if (element.dataset.value) {
|
||||||
opts["selectedDates"] = [element.dataset.value];
|
opts["selectedDates"] = [new Date(element.dataset.value + "T00:00:00")];
|
||||||
opts["startDate"] = [element.dataset.value];
|
opts["startDate"] = [new Date(element.dataset.value + "T00:00:00")];
|
||||||
}
|
}
|
||||||
return new AirDatepicker(element, opts);
|
return new AirDatepicker(element, opts);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user