закупы в бэк

This commit is contained in:
Artem Tsyrulnikov
2026-01-06 19:25:01 +03:00
parent cb6bdd5580
commit 87643735a1
10 changed files with 334 additions and 30 deletions

View File

@@ -174,8 +174,12 @@ class Database(typing.Protocol):
invite_link_type: domain.purchase.InviteLinkType,
*,
status: domain.PurchaseChannelStatus | None = None,
planned_cost: float | None = None,
comment: str | None = None,
placement_at: datetime.datetime | None = None,
cost_type: domain.purchase.CostType | None = None,
cost_value: float | None = None,
cost_before_bargain: float | None = None,
format: str | None = None,
) -> domain.PurchaseChannel: ...
async def update_purchase_channel(self, purchase_channel: domain.PurchaseChannel) -> None: ...

View File

@@ -11,6 +11,39 @@ if TYPE_CHECKING:
log = logging.getLogger(__name__)
def _build_cost_info(cost_type: domain.purchase.CostType | None, cost_value: float | None) -> dto.CostInfo | None:
if cost_type is None or cost_value is None:
return None
return dto.CostInfo(type=cost_type, value=cost_value)
def _build_purchase_details(purchase: domain.Purchase) -> dto.PurchaseDetails | None:
details = dto.PurchaseDetails(
placement_at=purchase.placement_at,
payment_at=purchase.payment_at,
cost=_build_cost_info(purchase.cost_type, purchase.cost_value),
cost_before_bargain=purchase.cost_before_bargain,
purchase_type=purchase.purchase_type,
format=purchase.format,
comment=purchase.comment,
)
if details.model_dump(exclude_none=True):
return details
return None
def _build_purchase_channel_details(purchase_channel: domain.PurchaseChannel) -> dto.PurchaseChannelDetails | None:
details = dto.PurchaseChannelDetails(
placement_at=purchase_channel.placement_at,
cost=_build_cost_info(purchase_channel.cost_type, purchase_channel.cost_value),
cost_before_bargain=purchase_channel.cost_before_bargain,
format=purchase_channel.format,
)
if details.model_dump(exclude_none=True):
return details
return None
def _build_purchase_output(
purchase: domain.Purchase, purchase_channels: list[domain.PurchaseChannel]
) -> dto.PurchaseOutput:
@@ -24,7 +57,6 @@ def _build_purchase_output(
dto.PurchaseChannelOutput(
id=purchase_channel.id,
status=purchase_channel.status,
planned_cost=purchase_channel.planned_cost,
comment=purchase_channel.comment,
invite_link=purchase_channel.invite_link,
invite_link_type=purchase_channel.invite_link_type,
@@ -34,6 +66,7 @@ def _build_purchase_output(
title=channel.title,
username=channel.username,
),
details=_build_purchase_channel_details(purchase_channel),
)
)
@@ -42,6 +75,7 @@ def _build_purchase_output(
status=purchase.status,
creative_id=purchase.creative_id,
channels=channels_output,
details=_build_purchase_details(purchase),
)
@@ -69,7 +103,20 @@ async def create_purchase(
channels = await self.database.get_purchase_channels(existing_purchase.id)
return _build_purchase_output(existing_purchase, channels)
purchase = domain.Purchase(workspace_id=workspace_id, project_id=project.id, creative_id=creative.id)
details = input.details
purchase = domain.Purchase(
workspace_id=workspace_id,
project_id=project.id,
creative_id=creative.id,
placement_at=details.placement_at if details else None,
payment_at=details.payment_at if details else None,
cost_type=details.cost.type if details and details.cost else None,
cost_value=details.cost.value if details and details.cost else None,
cost_before_bargain=details.cost_before_bargain if details else None,
purchase_type=details.purchase_type if details else None,
format=details.format if details else None,
comment=details.comment if details else None,
)
await self.database.create_purchase(purchase)
if project.channel.telegram_id is None:
@@ -94,14 +141,19 @@ async def create_purchase(
invite_link = await self.telegram_bot.create_chat_invite_link(project.channel.telegram_id, requires_approval)
channel_details = channel_input.details
purchase_channel = await self.database.add_channel_to_purchase(
purchase.id,
channel.id,
invite_link=invite_link,
invite_link_type=invite_link_type,
status=channel_input.status,
planned_cost=channel_input.planned_cost,
comment=channel_input.comment,
placement_at=channel_details.placement_at if channel_details else None,
cost_type=channel_details.cost.type if channel_details and channel_details.cost else None,
cost_value=channel_details.cost.value if channel_details and channel_details.cost else None,
cost_before_bargain=channel_details.cost_before_bargain if channel_details else None,
format=channel_details.format if channel_details else None,
)
purchase_channel.channel = channel
purchase_channels.append(purchase_channel)