diff --git a/aleksis/apps/tezor/models/__init__.py b/aleksis/apps/tezor/models/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/aleksis/apps/tezor/models/base.py b/aleksis/apps/tezor/models/base.py new file mode 100644 index 0000000000000000000000000000000000000000..e8feec9086097aa215fea9fdf5f865d7a3e51e9c --- /dev/null +++ b/aleksis/apps/tezor/models/base.py @@ -0,0 +1,13 @@ +from django.db import models +from django.utils.translation import gettext_lazy as _ + +from aleksis.core.mixins import ExtensibleModel + + +class Client(ExtensibleModel): + name = models.CharField(verbose_name=_("Name")) + + class Meta: + constraints = [ + models.UniqueConstraint(fields=["name", "site"], name="uniq_client_per_site") + ] diff --git a/aleksis/apps/tezor/models/invoice.py b/aleksis/apps/tezor/models/invoice.py new file mode 100644 index 0000000000000000000000000000000000000000..9c82d15930b53d0fa8fce9f17f209b30c9056868 --- /dev/null +++ b/aleksis/apps/tezor/models/invoice.py @@ -0,0 +1,55 @@ +from django.db import models +from django.utils.translation import gettext_lazy as _ + +from djmoney.models.fields import CurrencyField, MoneyField + +from aleksis.core.mixins import ExtensibleModel + +from .base import Client + + +class InvoiceGroup(ExtensibleModel): + name = models.CharField(verbose_name=_("Invoice group name"), max_length=255) + client = models.ForeignKey(Client, verbose_name=_("Linked client"), related_name="invoice_groups") + + class Meta: + constraints = [ + models.UniqueConstraint(fields=["client", "name"], name="group_uniq_per_client") + ] + + +class Invoice(ExtensibleModel): + group = models.ForeignKey(InvoiceGroup, verbose_name=_("Invoice group"), related_name="invoices") + + number = models.CharField(verbose_name=_("Invoice number")) + date = models.DateField(verbose_name=_("Invoice date")) + + @property + def currency(self): + try: + return self.positions.first().net_amount_currency + except InvoicePosition.DoesNotExist: + return None + + class Meta: + constraints = [ + models.UniqueConstraint(fields=["group", "number"], name="number_uniq_per_group") + ] + + +class InvoicePosition(ExtensibleModel): + invoice = models.ForeignKey(Invoice, verbose_name=_("Invoice"), related_name="positions") + + description = models.TextField(verbose_name=_("Description")) + + vat_rate = models.PositiveSmallIntegerField(verbose_name=_("VAT rate"), default=0) + net_amount = models.MoneyField(verbose_name=_("Net amount")) + + @property + def gross_amount(self): + # FIXME turn into manager/annotation/etc. + return self.net_amount * (1 + self.vat_rate / 100) + + class Meta: + # FIXME Add check constraint for currency + pass