import magic from django.conf import settings from django.core.exceptions import ValidationError from django.core.validators import FileExtensionValidator from django.db import models from django.utils.translation import gettext_lazy as _ CURRENCIES = [(1, "EUR")] def customer_invoice_path(instance, filename): return "invoices/{0}/{1}.pdf".format( instance.customer.username, instance.invoice_number ) def validate_pdf(value): valid_mime_types = ["application/pdf"] file_mime_type = magic.from_buffer(value.read(1024), mime=True) if file_mime_type not in valid_mime_types: raise ValidationError("Unsupported file type.") class Invoice(models.Model): customer = models.ForeignKey( settings.AUTH_USER_MODEL, verbose_name=_("customer"), on_delete=models.CASCADE ) invoice = models.FileField( upload_to=customer_invoice_path, validators=[validate_pdf, FileExtensionValidator(allowed_extensions=["pdf"])], ) invoice_number = models.SlugField( verbose_name=_("invoice number"), max_length=10, unique=True ) invoice_date = models.DateField(verbose_name=_("invoice date")) invoice_value = models.DecimalField( verbose_name=_("amount"), decimal_places=2, max_digits=10 ) invoice_currency = models.PositiveSmallIntegerField( verbose_name=_("currency"), choices=CURRENCIES ) due_date = models.DateField(verbose_name=_("due date")) payment_date = models.DateField( verbose_name=_("payment date"), blank=True, null=True ) payment_variant = models.TextField( verbose_name=_("payment variant"), blank=True, null=True ) class Meta: verbose_name = _("invoice") verbose_name_plural = _("invoices") ordering = ["-invoice_date", "customer"] def __str__(self): return _("Invoice {0}").format(self.invoice_number)