from decimal import Decimal from django.conf import settings from django.db import models from contacts.models import Contact from core.models import TimeStampedModel, UUIDPrimaryKeyModel class Invoice(UUIDPrimaryKeyModel, TimeStampedModel): class Status(models.TextChoices): DRAFT = "draft", "Draft" OPEN = "open", "Open" PAID = "paid", "Paid" VOID = "void", "Void" UNCOLLECTIBLE = "uncollectible", "Uncollectible" number = models.CharField(max_length=32, unique=True) contact = models.ForeignKey( Contact, on_delete=models.PROTECT, related_name="invoices", ) description = models.CharField(max_length=255) amount = models.DecimalField(max_digits=10, decimal_places=2) currency = models.CharField(max_length=8, default="usd") status = models.CharField( max_length=16, choices=Status.choices, default=Status.DRAFT ) due_date = models.DateField(null=True, blank=True) stripe_invoice_id = models.CharField(max_length=255, blank=True) stripe_checkout_session_id = models.CharField(max_length=255, blank=True) hosted_invoice_url = models.URLField(blank=True) paid_at = models.DateTimeField(null=True, blank=True) created_by = models.ForeignKey( settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.SET_NULL, related_name="created_invoices", ) notes = models.TextField(blank=True) class Meta: ordering = ["-created_at"] def __str__(self) -> str: return f"{self.number} · {self.contact} · {self.amount} {self.currency}" @property def amount_cents(self) -> int: return int((self.amount * Decimal("100")).quantize(Decimal("1")))