Add models for CRM entities: Activity, Contact, Deal, Organization, OrganizationMember, Task; update User model
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
"""Deal ORM model and schemas."""
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
from enum import StrEnum
|
||||
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
from sqlalchemy import DateTime, Enum as SqlEnum, ForeignKey, Integer, Numeric, String, func
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from app.models.base import Base
|
||||
|
||||
|
||||
class DealStatus(StrEnum):
|
||||
NEW = "new"
|
||||
IN_PROGRESS = "in_progress"
|
||||
WON = "won"
|
||||
LOST = "lost"
|
||||
|
||||
|
||||
class DealStage(StrEnum):
|
||||
QUALIFICATION = "qualification"
|
||||
PROPOSAL = "proposal"
|
||||
NEGOTIATION = "negotiation"
|
||||
CLOSED = "closed"
|
||||
|
||||
|
||||
class Deal(Base):
|
||||
"""Represents a sales opportunity/deal."""
|
||||
|
||||
__tablename__ = "deals"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
organization_id: Mapped[int] = mapped_column(ForeignKey("organizations.id", ondelete="CASCADE"))
|
||||
contact_id: Mapped[int] = mapped_column(ForeignKey("contacts.id", ondelete="RESTRICT"))
|
||||
owner_id: Mapped[int] = mapped_column(ForeignKey("users.id", ondelete="RESTRICT"))
|
||||
title: Mapped[str] = mapped_column(String(255), nullable=False)
|
||||
amount: Mapped[Decimal | None] = mapped_column(Numeric(12, 2), nullable=True)
|
||||
currency: Mapped[str | None] = mapped_column(String(8), nullable=True)
|
||||
status: Mapped[DealStatus] = mapped_column(
|
||||
SqlEnum(DealStatus, name="deal_status"), nullable=False, default=DealStatus.NEW
|
||||
)
|
||||
stage: Mapped[DealStage] = mapped_column(
|
||||
SqlEnum(DealStage, name="deal_stage"), nullable=False, default=DealStage.QUALIFICATION
|
||||
)
|
||||
created_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), server_default=func.now(), nullable=False
|
||||
)
|
||||
updated_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False
|
||||
)
|
||||
|
||||
organization = relationship("Organization", back_populates="deals")
|
||||
contact = relationship("Contact", back_populates="deals")
|
||||
owner = relationship("User", back_populates="owned_deals")
|
||||
tasks = relationship("Task", back_populates="deal", cascade="all, delete-orphan")
|
||||
activities = relationship("Activity", back_populates="deal", cascade="all, delete-orphan")
|
||||
|
||||
|
||||
class DealBase(BaseModel):
|
||||
organization_id: int
|
||||
contact_id: int
|
||||
owner_id: int
|
||||
title: str
|
||||
amount: Decimal | None = None
|
||||
currency: str | None = None
|
||||
status: DealStatus = DealStatus.NEW
|
||||
stage: DealStage = DealStage.QUALIFICATION
|
||||
|
||||
|
||||
class DealCreate(DealBase):
|
||||
pass
|
||||
|
||||
|
||||
class DealRead(DealBase):
|
||||
id: int
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
Reference in New Issue
Block a user