Coverage for src/couchers/models/donations.py: 100%
32 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-12-25 10:58 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2025-12-25 10:58 +0000
1import enum
2from datetime import datetime
3from typing import TYPE_CHECKING
5from sqlalchemy import BigInteger, DateTime, Enum, Float, ForeignKey, Integer, String, func
6from sqlalchemy.orm import Mapped, mapped_column, relationship
8from couchers.models.base import Base
10if TYPE_CHECKING:
11 from couchers.models.users import User
14class DonationType(enum.Enum):
15 one_time = enum.auto()
16 recurring = enum.auto()
19class InvoiceType(enum.Enum):
20 on_platform = enum.auto()
21 external_shop = enum.auto()
24class DonationInitiation(Base):
25 """
26 Whenever someone initiates a donation through the platform
27 """
29 __tablename__ = "donation_initiations"
31 id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
32 created: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
33 user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), index=True)
35 amount: Mapped[int] = mapped_column(Integer)
36 stripe_checkout_session_id: Mapped[str] = mapped_column(String)
38 donation_type: Mapped[DonationType] = mapped_column(Enum(DonationType))
39 source: Mapped[str | None] = mapped_column(String, nullable=True)
41 user: Mapped["User"] = relationship("User", backref="donation_initiations")
44class Invoice(Base):
45 """
46 Successful donations, both one-off and recurring
48 Triggered by `payment_intent.succeeded` webhook
49 """
51 __tablename__ = "invoices"
53 id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
54 created: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
55 user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
57 amount: Mapped[float] = mapped_column(Float)
59 stripe_payment_intent_id: Mapped[str] = mapped_column(String, unique=True)
60 stripe_receipt_url: Mapped[str] = mapped_column(String)
62 invoice_type: Mapped[InvoiceType] = mapped_column(Enum(InvoiceType))
64 user: Mapped["User"] = relationship("User", backref="invoices")