This commit is contained in:
Artem Tsyrulnikov
2026-01-15 22:02:16 +03:00
parent 6ec26c96e3
commit 049024ebe8
72 changed files with 2417 additions and 2054 deletions

View File

@@ -11,10 +11,7 @@ if TYPE_CHECKING:
from .creative import Creative
from .project import Project
class PurchaseStatus(enum.StrEnum):
ACTIVE = 'active'
ARCHIVED = 'archived'
__all__ = ['Placement', 'PlacementStatus', 'PlacementType', 'InviteLinkType', 'CostType']
class CostType(enum.StrEnum):
@@ -22,7 +19,7 @@ class CostType(enum.StrEnum):
CPM = 'cpm'
class PurchaseChannelStatus(enum.StrEnum):
class PlacementStatus(enum.StrEnum):
PLANNED = 'planned'
APPROVED = 'approved'
REJECTED = 'rejected'
@@ -30,66 +27,71 @@ class PurchaseChannelStatus(enum.StrEnum):
COMPLETED = 'completed'
class PurchaseType(enum.StrEnum):
class PlacementType(enum.StrEnum):
SELF_PROMO = 'self_promo'
STANDARD = 'standard'
class Purchase(TimestampedModel):
status = fields.CharEnumField(PurchaseStatus, default=PurchaseStatus.ACTIVE)
placement_at = fields.DatetimeField(null=True)
payment_at = fields.DatetimeField(null=True)
cost_type = fields.CharEnumField(CostType, null=True, max_length=8)
cost_value = fields.FloatField(null=True)
cost_before_bargain = fields.FloatField(null=True)
purchase_type = fields.CharEnumField(PurchaseType, null=True, max_length=16)
format = fields.TextField(null=True)
comment = fields.TextField(null=True)
project: fields.ForeignKeyRelation['Project'] = fields.ForeignKeyField(
'models.Project', related_name='purchases', on_delete=fields.CASCADE, index=True
)
creative: fields.ForeignKeyRelation['Creative'] = fields.ForeignKeyField(
'models.Creative', related_name='purchases', on_delete=fields.CASCADE, index=True
)
if TYPE_CHECKING:
project_id: uuid.UUID
creative_id: uuid.UUID
class Meta:
table = 'purchase'
indexes = (('project', 'status'),)
class InviteLinkType(enum.StrEnum):
PUBLIC = 'public' # открытая ссылка
APPROVAL = 'approval' # с одобрением ботом
class PurchaseChannel(TimestampedModel):
status = fields.CharEnumField(PurchaseChannelStatus, default=PurchaseChannelStatus.PLANNED)
class Placement(TimestampedModel):
"""Размещение, управляемое пользователем (бывший PurchaseChannel + Purchase)"""
status = fields.CharEnumField(PlacementStatus, default=PlacementStatus.PLANNED)
placement_at = fields.DatetimeField(null=True)
payment_at = fields.DatetimeField(null=True)
cost_type = fields.CharEnumField(CostType, null=True, max_length=8)
cost_value = fields.FloatField(null=True)
cost_before_bargain = fields.FloatField(null=True)
placement_type = fields.CharEnumField(PlacementType, null=True, max_length=16)
format = fields.TextField(null=True)
comment = fields.TextField(null=True)
invite_link = fields.CharField(max_length=512)
invite_link_type = fields.CharEnumField(InviteLinkType)
purchase: fields.ForeignKeyRelation['Purchase'] = fields.ForeignKeyField(
'models.Purchase', related_name='channels', on_delete=fields.CASCADE, index=True
project: fields.ForeignKeyRelation['Project'] = fields.ForeignKeyField(
'models.Project', related_name='placements', on_delete=fields.CASCADE, index=True
)
creative: fields.ForeignKeyRelation['Creative'] = fields.ForeignKeyField(
'models.Creative', related_name='placements', on_delete=fields.CASCADE, index=True
)
channel: fields.ForeignKeyRelation['Channel'] = fields.ForeignKeyField(
'models.Channel', related_name='purchase_channels', on_delete=fields.CASCADE, index=True
'models.Channel', related_name='placements', on_delete=fields.CASCADE, index=True
)
if TYPE_CHECKING:
purchase_id: uuid.UUID
project_id: uuid.UUID
creative_id: uuid.UUID
channel_id: uuid.UUID
class Meta:
table = 'purchase_channel'
unique_together = (('purchase_id', 'channel_id'),)
table = 'placement'
indexes = (('project', 'status'),)
# DEPRECATED: старые модели, будут удалены после миграции
# class PurchaseStatus(enum.StrEnum):
# ACTIVE = 'active'
# ARCHIVED = 'archived'
#
# class PurchaseChannelStatus(enum.StrEnum):
# PLANNED = 'planned'
# APPROVED = 'approved'
# REJECTED = 'rejected'
# IN_PROGRESS = 'in_progress'
# COMPLETED = 'completed'
#
# class PurchaseType(enum.StrEnum):
# SELF_PROMO = 'self_promo'
# STANDARD = 'standard'
#
# class Purchase(TimestampedModel):
# ...
#
# class PurchaseChannel(TimestampedModel):
# ...