JourneyJoker/payment/models/invoice.py
2021-10-28 09:26:17 +02:00

116 lines
No EOL
3.3 KiB
Python

from django.db import models
from django.contrib.auth import get_user_model
from django.core.files.base import ContentFile
from django.utils import timezone
from django.conf import settings
import uuid
from dbsettings.functions import getValue
from auction.models import Inquiry
from .billingaddress import BillingAddress
from ..functions import invoice_upload_path
from ..pdfviews import InvoicePDFView
class InvoiceTypeChoices(models.IntegerChoices):
INVOICE = (0, "Rechnung")
DEPOSIT = (1, "Sicherheitsleistung")
class Invoice(models.Model):
uuid = models.UUIDField(default=uuid.uuid4)
user = models.ForeignKey(get_user_model(), models.PROTECT)
billing_address = models.ForeignKey(BillingAddress, models.PROTECT)
currency = models.CharField(max_length=3)
tax_rate = models.DecimalField(max_digits=4, decimal_places=2)
invoice = models.FileField(null=True, blank=True, upload_to=invoice_upload_path)
inquiry = models.OneToOneField(Inquiry, null=True, blank=True, on_delete=models.SET_NULL)
created = models.DateTimeField(auto_now_add=True)
type = models.IntegerField(choices=InvoiceTypeChoices.choices, default=1)
@property
def price_net(self):
price = 0
for item in self.invoiceitem_set.all():
price += item.net_total
return price
@property
def tax(self):
return round(self.price_net * self.tax_rate / 100, 2)
@property
def price_gross(self):
return self.price_net + self.tax
@property
def payment_instructions(self):
return None
@property
def url(self):
try:
return self.invoice.url
except:
return False
@property
def balance(self):
paid_amount = 0
for payment in self.invoicepayment_set.all():
paid_amount += payment.amount
return paid_amount - self.price_gross
@property
def is_paid(self):
return self.balance >= 0
def finalize(self, *args, **kwargs):
if self.is_paid:
try:
self.inquiry.process_payment(*args, **kwargs)
except Inquiry.DoesNotExist:
pass
self.generate_invoice()
def generate_invoice(self):
view = InvoicePDFView()
bottom_tip = (f"{ self.payment_instructions }<br /><br />" if self.payment_instructions else "") + getValue("billing.bottom_tip", "")
bottom_tip += "<br />" if bottom_tip else ""
bottom_tip += "Dokument erstellt: %s" % str(timezone.now())
args = {
"type": InvoiceTypeChoices._value2label_map_[self.type],
"object": self,
"bottom_tip": bottom_tip
}
self.invoice = ContentFile(view.render(**args), "invoice.pdf")
self.save()
@classmethod
def from_inquiry(cls, inquiry):
invoice = cls.objects.create(
user = inquiry.client.user,
billing_address = BillingAddress.from_profile(inquiry.client),
currency = settings.CURRENCY_CODE,
tax_rate = 0,
inquiry = inquiry
)
invoice.invoiceitem_set.create(
name = "SL",
description = "Rückzahlbare Sicherheitsleistung zu JourneyJoker-Anfrage #%i" % inquiry.id,
count = 1,
net_each = inquiry.budget
)
return invoice