diff --git a/nummi/main/migrations/0007_snapshot_file_alter_invoice_file_alter_snapshot_date.py b/nummi/main/migrations/0007_snapshot_file_alter_invoice_file_alter_snapshot_date.py new file mode 100644 index 0000000..c00239e --- /dev/null +++ b/nummi/main/migrations/0007_snapshot_file_alter_invoice_file_alter_snapshot_date.py @@ -0,0 +1,44 @@ +# Generated by Django 4.1.4 on 2022-12-21 08:53 + +import datetime +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("main", "0006_alter_category_options_alter_invoice_options_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="snapshot", + name="file", + field=models.FileField( + blank=True, + max_length=128, + null=True, + upload_to="snapshots/", + validators=[django.core.validators.FileExtensionValidator(["pdf"])], + verbose_name="Fichier", + ), + ), + migrations.AlterField( + model_name="invoice", + name="file", + field=models.FileField( + max_length=128, + upload_to="invoices/", + validators=[django.core.validators.FileExtensionValidator(["pdf"])], + verbose_name="Fichier", + ), + ), + migrations.AlterField( + model_name="snapshot", + name="date", + field=models.DateField( + default=datetime.date.today, unique=True, verbose_name="Date" + ), + ), + ] diff --git a/nummi/main/models.py b/nummi/main/models.py index 7238625..12647d3 100644 --- a/nummi/main/models.py +++ b/nummi/main/models.py @@ -1,9 +1,11 @@ +import pathlib from datetime import date import uuid from django.db import models from django.forms import ModelForm from django.core.validators import FileExtensionValidator from django.utils.translation import gettext as _ +from django.core.files.storage import Storage class Category(models.Model): @@ -90,15 +92,20 @@ class TransactionForm(ModelForm): ] +def invoice_path(instance, filename): + return pathlib.Path("invoices", str(instance.id), filename) + + class Invoice(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) name = models.CharField( max_length=256, default=_("Invoice"), verbose_name=_("Name") ) file = models.FileField( - upload_to="invoices/", + upload_to=invoice_path, validators=[FileExtensionValidator(["pdf"])], verbose_name=_("File"), + max_length=128, ) transaction = models.ForeignKey(Transaction, on_delete=models.CASCADE) @@ -123,6 +130,10 @@ class InvoiceForm(ModelForm): fields = ["name", "file"] +def snapshot_path(instance, filename): + return pathlib.Path("snapshots", str(instance.id)).with_suffix(".pdf") + + class Snapshot(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) date = models.DateField(default=date.today, unique=True, verbose_name=_("Date")) @@ -135,12 +146,22 @@ class Snapshot(models.Model): diff = models.DecimalField( max_digits=12, decimal_places=2, editable=False, blank=True, null=True ) + file = models.FileField( + upload_to=snapshot_path, + validators=[FileExtensionValidator(["pdf"])], + verbose_name=_("File"), + max_length=256, + blank=True, + ) def __str__(self): return f"{_('Snapshot')} {self.date}" def save(self, *args, only_super=False, **kwargs): if not only_super: + _prever = Snapshot.objects.get(id=self.id) + if _prever.file and _prever.file != self.file: + pathlib.Path(_prever.file.path).unlink(missing_ok=True) _prev = ( self.__class__.objects.order_by("-date") .exclude(id=self.id) @@ -188,6 +209,7 @@ class Snapshot(models.Model): _next.save(only_super=True) def delete(self, *args, only_super=False, **kwargs): + self.file.delete() if not only_super: try: _next = self.__class__.objects.get(previous=self) @@ -244,4 +266,4 @@ class SnapshotForm(ModelForm): class Meta: model = Snapshot - fields = ["date", "value"] + fields = ["date", "value", "file"] diff --git a/nummi/main/templates/main/snapshot.html b/nummi/main/templates/main/snapshot.html index 4458f25..7396a02 100644 --- a/nummi/main/templates/main/snapshot.html +++ b/nummi/main/templates/main/snapshot.html @@ -23,7 +23,7 @@ {{ snapshot }} -
+ {% csrf_token %} {{ form }} {% form_buttons snapshot %} diff --git a/nummi/main/views.py b/nummi/main/views.py index 6b7e622..a6cb1ca 100644 --- a/nummi/main/views.py +++ b/nummi/main/views.py @@ -154,9 +154,11 @@ def snapshot(request, uuid=None): _snapshot = Snapshot.objects.get(id=uuid) except Snapshot.DoesNotExist: _snapshot = Snapshot(id=uuid) - _form = SnapshotForm(request.POST, instance=_snapshot) + _form = SnapshotForm(request.POST, request.FILES, instance=_snapshot) if _form.is_valid(): _form.save() + return redirect(snapshot, uuid=uuid) + context = { "snapshot": _snapshot, "form": _form, diff --git a/nummi/nummi/settings.py b/nummi/nummi/settings.py index e5ecaab..fb7478a 100644 --- a/nummi/nummi/settings.py +++ b/nummi/nummi/settings.py @@ -16,6 +16,7 @@ import os # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent MEDIA_ROOT = Path(os.environ.get("NUMMI_MEDIA_ROOT", "/var/lib/nummi")) +MEDIA_URL = "files/" # Quick-start development settings - unsuitable for production diff --git a/nummi/nummi/urls.py b/nummi/nummi/urls.py index 37a7a5e..e201c47 100644 --- a/nummi/nummi/urls.py +++ b/nummi/nummi/urls.py @@ -17,10 +17,12 @@ from django.conf.urls.i18n import i18n_patterns from django.contrib import admin from django.urls import include, path from django.views.generic.base import RedirectView +from django.conf import settings +from django.conf.urls.static import static urlpatterns = i18n_patterns( path("", include("main.urls")), path("plot/", include("plot.urls")), path("admin/", admin.site.urls), prefix_default_language=False, -) +) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)