feat: deal tags

This commit is contained in:
2025-10-19 12:12:08 +04:00
parent d7c7d1775f
commit ffee658349
16 changed files with 355 additions and 8 deletions

View File

@ -1,6 +1,7 @@
from .board import BoardRepository as BoardRepository
from .built_in_module import BuiltInModuleRepository as BuiltInModuleRepository
from .deal import DealRepository as DealRepository
from .deal_group import DealGroupRepository as DealGroupRepository
from .deal_tag import DealTagRepository as DealTagRepository
from .project import ProjectRepository as ProjectRepository
from .status import StatusRepository as StatusRepository
from .built_in_module import BuiltInModuleRepository as BuiltInModuleRepository
from .deal_group import DealGroupRepository as DealGroupRepository

View File

@ -99,6 +99,7 @@ class DealRepository(
joinedload(Deal.status),
joinedload(Deal.board),
selectinload(Deal.group),
selectinload(Deal.tags),
)
.where(Deal.is_deleted.is_(False))
)

62
repositories/deal_tag.py Normal file
View File

@ -0,0 +1,62 @@
from models import DealTag, DealTagColor, Deal
from models.project import Project
from repositories.mixins import *
from schemas.deal_tag import *
class DealTagRepository(
RepCrudMixin[DealTag, CreateDealTagSchema, UpdateDealTagSchema]
):
session: AsyncSession
entity_class = DealTag
entity_not_found_msg = "Тег не найден"
def _process_get_all_stmt_with_args(self, stmt: Select, *args) -> Select:
project_id = args[0]
return stmt.where(
DealTag.project_id == project_id, DealTag.is_deleted.is_(False)
).order_by(DealTag.id)
async def _get_tag_color(self, tag_id: int) -> DealTagColor:
stmt = select(DealTagColor).where(DealTagColor.id == tag_id)
result = await self.session.execute(stmt)
tag = result.one_or_none()
if not tag:
raise ObjectNotFoundException("Цвет тега не найден")
return tag[0]
async def update(self, deal_tag: DealTag, data: UpdateDealTagSchema) -> Project:
if data.tag_color is not None:
data.tag_color = await self._get_tag_color(data.tag_color.id)
return await self._apply_update_data_to_model(deal_tag, data, True)
async def switch_tag_in_deal(self, tag: DealTag, deal: Deal):
if tag in deal.tags:
deal.tags.remove(tag)
else:
deal.tags.append(tag)
await self.session.commit()
async def switch_tag_in_deals(self, tag: DealTag, deals: list[Deal]):
for deal in deals:
if tag in deal.tags:
deal.tags.remove(tag)
else:
deal.tags.append(tag)
await self.session.commit()
async def get_tag_colors(self) -> list[DealTagColor]:
stmt = select(DealTagColor)
result = await self.session.execute(stmt)
return list(result.scalars().all())
async def sync_deals_tags(self, deals: list[Deal]):
tags_set: set[DealTag] = set()
for deal in deals:
for tag in deal.tags:
tags_set.add(tag)
tags: list[DealTag] = list(tags_set)
for deal in deals:
deal.tags = tags

View File

@ -1,5 +1,6 @@
from sqlalchemy.orm import selectinload
from models import DealTag
from models.project import Project
from repositories.built_in_module import BuiltInModuleRepository
from repositories.mixins import *
@ -12,11 +13,17 @@ class ProjectRepository(
entity_class = Project
entity_not_found_msg = "Проект не найден"
def _apply_options(self, stmt: Select) -> Select:
return stmt.options(
selectinload(Project.boards),
selectinload(Project.tags).joinedload(DealTag.tag_color),
)
def _process_get_all_stmt(self, stmt: Select) -> Select:
return stmt.order_by(Project.id)
return self._apply_options(stmt).order_by(Project.id)
def _process_get_by_id_stmt(self, stmt: Select) -> Select:
return stmt.options(selectinload(Project.boards))
return self._apply_options(stmt)
async def update(self, project: Project, data: UpdateProjectSchema) -> Project:
if data.built_in_modules is not None: