Files
westfarnandCursor 787f0e48fb Populate the client website template with catalog feature flags.
Extract always-on public/portal/UTM plus optional email_sms, directmail, blog, payments, social, and social_ai so new client sites can be bootstrapped from this seed.

Refs #1
Refs #2

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-26 07:55:26 -05:00

53 lines
1.7 KiB
Python

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")))