diff --git a/app/WYGIWYH/settings.py b/app/WYGIWYH/settings.py index 86ddecc..aab680f 100644 --- a/app/WYGIWYH/settings.py +++ b/app/WYGIWYH/settings.py @@ -55,6 +55,7 @@ INSTALLED_APPS = [ "hijack", "hijack.contrib.admin", "django_filters", + "import_export", "apps.users.apps.UsersConfig", "procrastinate.contrib.django", "apps.transactions.apps.TransactionsConfig", @@ -63,6 +64,7 @@ INSTALLED_APPS = [ "apps.common.apps.CommonConfig", "apps.net_worth.apps.NetWorthConfig", "apps.import_app.apps.ImportConfig", + "apps.export_app.apps.ExportConfig", "apps.api.apps.ApiConfig", "cachalot", "rest_framework", diff --git a/app/WYGIWYH/urls.py b/app/WYGIWYH/urls.py index bd17bac..a9612fb 100644 --- a/app/WYGIWYH/urls.py +++ b/app/WYGIWYH/urls.py @@ -49,5 +49,6 @@ urlpatterns = [ path("", include("apps.dca.urls")), path("", include("apps.mini_tools.urls")), path("", include("apps.import_app.urls")), + path("", include("apps.export_app.urls")), path("", include("apps.insights.urls")), ] diff --git a/app/apps/export_app/__init__.py b/app/apps/export_app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/apps/export_app/admin.py b/app/apps/export_app/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/app/apps/export_app/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/app/apps/export_app/apps.py b/app/apps/export_app/apps.py new file mode 100644 index 0000000..1744c75 --- /dev/null +++ b/app/apps/export_app/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class ExportConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "apps.export_app" diff --git a/app/apps/export_app/migrations/__init__.py b/app/apps/export_app/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/apps/export_app/models.py b/app/apps/export_app/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/app/apps/export_app/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/app/apps/export_app/resources/__init__.py b/app/apps/export_app/resources/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/apps/export_app/resources/transactions.py b/app/apps/export_app/resources/transactions.py new file mode 100644 index 0000000..aca17c7 --- /dev/null +++ b/app/apps/export_app/resources/transactions.py @@ -0,0 +1,39 @@ +from import_export import fields, resources + +from apps.export_app.widgets.foreign_key import AutoCreateForeignKeyWidget +from apps.export_app.widgets.many_to_many import AutoCreateManyToManyWidget +from apps.transactions.models import ( + Transaction, + TransactionCategory, + TransactionTag, + TransactionEntity, +) + + +class TransactionResource(resources.ModelResource): + account = fields.Field( + attribute="account", + column_name="account", + widget=AutoCreateForeignKeyWidget("accounts.Account", "name"), + ) + + category = fields.Field( + attribute="category", + column_name="category", + widget=AutoCreateForeignKeyWidget(TransactionCategory, "name"), + ) + + tags = fields.Field( + attribute="tags", + column_name="tags", + widget=AutoCreateManyToManyWidget(TransactionTag, field="name"), + ) + + entities = fields.Field( + attribute="entities", + column_name="entities", + widget=AutoCreateManyToManyWidget(TransactionEntity, field="name"), + ) + + class Meta: + model = Transaction diff --git a/app/apps/export_app/tests.py b/app/apps/export_app/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/app/apps/export_app/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/app/apps/export_app/urls.py b/app/apps/export_app/urls.py new file mode 100644 index 0000000..bfe4736 --- /dev/null +++ b/app/apps/export_app/urls.py @@ -0,0 +1,6 @@ +from django.urls import path +import apps.export_app.views as views + +urlpatterns = [ + path("export/", views.export, name="export"), +] diff --git a/app/apps/export_app/views.py b/app/apps/export_app/views.py new file mode 100644 index 0000000..e950d8d --- /dev/null +++ b/app/apps/export_app/views.py @@ -0,0 +1,9 @@ +from django.shortcuts import render + +from apps.export_app.resources.transactions import TransactionResource + + +# Create your views here. +def export(request): + dataset = TransactionResource().export() + print(dataset.csv) diff --git a/app/apps/export_app/widgets/__init__.py b/app/apps/export_app/widgets/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/apps/export_app/widgets/foreign_key.py b/app/apps/export_app/widgets/foreign_key.py new file mode 100644 index 0000000..232a810 --- /dev/null +++ b/app/apps/export_app/widgets/foreign_key.py @@ -0,0 +1,11 @@ +from import_export.widgets import ForeignKeyWidget + + +class AutoCreateForeignKeyWidget(ForeignKeyWidget): + def clean(self, value, row=None, *args, **kwargs): + if value: + try: + return super().clean(value, row, **kwargs) + except self.model.DoesNotExist: + return self.model.objects.create(name=value) + return None diff --git a/app/apps/export_app/widgets/many_to_many.py b/app/apps/export_app/widgets/many_to_many.py new file mode 100644 index 0000000..b559e3a --- /dev/null +++ b/app/apps/export_app/widgets/many_to_many.py @@ -0,0 +1,21 @@ +from import_export.widgets import ManyToManyWidget + + +class AutoCreateManyToManyWidget(ManyToManyWidget): + def clean(self, value, row=None, *args, **kwargs): + if not value: + return [] + + values = value.split(self.separator) + cleaned_values = [] + + for val in values: + val = val.strip() + if val: + try: + obj = self.model.objects.get(**{self.field: val}) + except self.model.DoesNotExist: + obj = self.model.objects.create(name=val) + cleaned_values.append(obj) + + return cleaned_values diff --git a/app/apps/insights/views.py b/app/apps/insights/views.py index 177f57f..a9e8513 100644 --- a/app/apps/insights/views.py +++ b/app/apps/insights/views.py @@ -152,8 +152,6 @@ def category_sum_by_currency(request): else: currency_data = None - print(currency_data) - return render( request, "insights/fragments/category_explorer/charts/currency.html", diff --git a/requirements.txt b/requirements.txt index b7e8ae1..a9ce110 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,6 +12,7 @@ django-cotton~=1.2.1 django-pwa~=2.0.1 djangorestframework~=3.15.2 drf-spectacular~=0.27.2 +django-import-export~=4.3.5 gunicorn==22.0.0 whitenoise[brotli]==6.6.0