import decimal from django.contrib.auth import get_user_model from django.db import models from django.utils import timezone from django.utils.translation import gettext_lazy as _ from subjects import models as subject_models UserModel = get_user_model() class Invoice(models.Model): class Meta: verbose_name = _('Invoice') verbose_name_plural = _('Invoices') user = models.ForeignKey(UserModel, models.CASCADE) supplier = models.ForeignKey( subject_models.Subject, on_delete=models.CASCADE, related_name='+', verbose_name=_('Supplier'), ) supplier_data = models.ForeignKey( subject_models.SubjectData, on_delete=models.CASCADE, related_name='+', verbose_name=_('Supplier data'), ) customer = models.ForeignKey( subject_models.Subject, on_delete=models.CASCADE, related_name='+', verbose_name=_('Customer'), ) customer_data = models.ForeignKey( subject_models.SubjectData, on_delete=models.CASCADE, related_name='+', verbose_name=_('Customer data'), ) invoice_date = models.DateField(_('Invoice date'), default=timezone.now) due_date = models.DateField(_('Due date')) def __str__(self): return f'{self.id} - {self.supplier_data.name} -> {self.customer_data.name}' def total_price(self) -> decimal.Decimal: total = decimal.Decimal(0) for item in self.items.all(): total += item.total_price() return total def custom_id(self) -> str: return f'{self.invoice_date.year}-{self.id:04}' class InvoiceItem(models.Model): class Meta: verbose_name = _('Invoice Item') verbose_name_plural = _('Invoice Items') invoice = models.ForeignKey( Invoice, on_delete=models.CASCADE, related_name='items', ) amount = models.DecimalField(_('Amount'), decimal_places=3, max_digits=8) amount_unit = models.CharField(_('Amount unit'), max_length=32) description = models.CharField(_('Description'), max_length=64) price_for_amount = models.DecimalField( _('Price for amount'), decimal_places=3, max_digits=8, ) def total_price(self) -> decimal.Decimal: return self.amount * self.price_for_amount def __str__(self): return f'{self.id} -> {self.invoice.id}' class InvoiceFile(models.Model): class Meta: verbose_name = _('Invoice File') verbose_name_plural = _('Invoice Files') invoice = models.ForeignKey(Invoice, on_delete=models.CASCADE, related_name='files') file = models.FileField( _('File'), upload_to='invoice-files/%Y/%m/%d/', null=True, blank=True, ) created_date = models.DateTimeField(_('Created Date'), auto_now=True) def __str__(self): return self.file.name def get_file_name(self, ext: str) -> str: return f'{self.invoice.id}-{self.created_date.strftime("%H%M%S")}.{ext}'