feat: added tags for cards, aligned status headers
This commit is contained in:
@@ -5,7 +5,7 @@ from sqlalchemy import select, and_, union_all, func, Subquery, literal
|
||||
|
||||
from enums.profit_table_group_by import ProfitTableGroupBy
|
||||
from models import CardService, Card, CardStatusHistory, CardProductService, CardProduct, Service, Client, \
|
||||
ShippingWarehouse, BaseMarketplace, User, Project, Board
|
||||
ShippingWarehouse, BaseMarketplace, User, Project, Board, CardTag, cards_card_tags, user_position
|
||||
from schemas.statistics import GetProfitChartDataResponse, GetProfitChartDataRequest, ProfitChartDataItem, \
|
||||
GetProfitTableDataResponse, GetProfitTableDataRequest, ProfitTableDataItem, CommonProfitFilters
|
||||
from services.base import BaseService
|
||||
@@ -112,13 +112,11 @@ class ProfitStatisticsService(BaseService):
|
||||
.join(Service, CardService.service_id == Service.id)
|
||||
.join(sub_filtered_status_history, Card.id == sub_filtered_status_history.c.card_id)
|
||||
.where(
|
||||
and_(
|
||||
Card.is_deleted == False,
|
||||
Card.is_services_profit_accounted == True,
|
||||
Card.is_completed == True if self.is_completed_only else True
|
||||
)
|
||||
Card.is_deleted == False,
|
||||
Card.is_services_profit_accounted == True,
|
||||
Card.is_completed == True if self.is_completed_only else True,
|
||||
)
|
||||
.group_by(Card.id, "date")
|
||||
.group_by(Card.id, sub_filtered_status_history.c.date)
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
@@ -129,6 +127,14 @@ class ProfitStatisticsService(BaseService):
|
||||
)
|
||||
return stmt.where(Card.board_id.in_(board_ids_stmt))
|
||||
|
||||
@staticmethod
|
||||
def _apply_tag_filter(tag_id: int, stmt):
|
||||
sub_card_ids = (
|
||||
select(cards_card_tags.c.card_id)
|
||||
.where(cards_card_tags.c.card_tag_id == tag_id)
|
||||
)
|
||||
return stmt.where(Card.id.in_(sub_card_ids))
|
||||
|
||||
@staticmethod
|
||||
def _apply_filters(request: CommonProfitFilters, stmt_card_services, stmt_card_product_services):
|
||||
if request.client_id != -1:
|
||||
@@ -156,6 +162,13 @@ class ProfitStatisticsService(BaseService):
|
||||
stmt_card_product_services = stmt_card_product_services.where(
|
||||
Card.current_status_id == request.card_status_id)
|
||||
|
||||
if request.card_tag_id != -1:
|
||||
stmt_card_services = ProfitStatisticsService._apply_tag_filter(request.card_tag_id, stmt_card_services)
|
||||
stmt_card_product_services = ProfitStatisticsService._apply_tag_filter(
|
||||
request.card_tag_id,
|
||||
stmt_card_product_services
|
||||
)
|
||||
|
||||
if request.manager_id != -1:
|
||||
stmt_card_services = stmt_card_services.where(Card.manager_id == request.manager_id)
|
||||
stmt_card_product_services = stmt_card_product_services.where(Card.manager_id == request.manager_id)
|
||||
@@ -334,7 +347,8 @@ class ProfitStatisticsService(BaseService):
|
||||
def _join_and_group_by_managers(stmt):
|
||||
managers = (
|
||||
select(User)
|
||||
.where(User.role_key == "employee")
|
||||
.join(user_position)
|
||||
.where(and_(User.is_deleted == False, user_position.c.position_key == "sales_manager"))
|
||||
.subquery()
|
||||
)
|
||||
return (
|
||||
@@ -350,6 +364,23 @@ class ProfitStatisticsService(BaseService):
|
||||
.group_by(managers.c.id, "grouped_value")
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _join_and_group_by_tags(stmt):
|
||||
return (
|
||||
select(
|
||||
CardTag.id,
|
||||
CardTag.name.label("grouped_value"),
|
||||
CardTag.is_deleted,
|
||||
func.count(stmt.c.card_id).label("cards_count"),
|
||||
func.sum(stmt.c.revenue).label("revenue"),
|
||||
func.sum(stmt.c.profit).label("profit"),
|
||||
)
|
||||
.join(cards_card_tags, cards_card_tags.c.card_id == stmt.c.card_id)
|
||||
.join(CardTag, cards_card_tags.c.card_tag_id == CardTag.id)
|
||||
.where(CardTag.is_deleted == False)
|
||||
.group_by(CardTag.is_deleted, CardTag.id, CardTag.name)
|
||||
)
|
||||
|
||||
async def _get_data_rows_grouped_by_date(
|
||||
self,
|
||||
stmt_card_services,
|
||||
@@ -476,6 +507,7 @@ class ProfitStatisticsService(BaseService):
|
||||
|
||||
async def _get_table_grouped_by_statuses(self, request: GetProfitTableDataRequest) -> GetProfitTableDataResponse:
|
||||
date_from, date_to = request.date_range
|
||||
self.is_completed_only = request.is_completed_only
|
||||
|
||||
sub_cards_dates = self._get_filtered_sub_status_history(date_from, date_to)
|
||||
|
||||
@@ -518,6 +550,12 @@ class ProfitStatisticsService(BaseService):
|
||||
|
||||
return await self._table_data_from_stmt(stmt_grouped_by_managers)
|
||||
|
||||
async def _get_table_grouped_by_tags(self, request: GetProfitTableDataRequest) -> GetProfitTableDataResponse:
|
||||
sub_grouped_by_cards = self._get_common_table_grouped(request)
|
||||
stmt_grouped_by_tags = self._join_and_group_by_tags(sub_grouped_by_cards)
|
||||
|
||||
return await self._table_data_from_stmt(stmt_grouped_by_tags)
|
||||
|
||||
async def get_profit_table_data(self, request: GetProfitTableDataRequest) -> GetProfitTableDataResponse:
|
||||
match request.group_table_by:
|
||||
case ProfitTableGroupBy.BY_DATES:
|
||||
@@ -536,5 +574,7 @@ class ProfitStatisticsService(BaseService):
|
||||
return await self._get_table_grouped_by_marketplace(request)
|
||||
case ProfitTableGroupBy.BY_MANAGERS:
|
||||
return await self._get_table_grouped_by_managers(request)
|
||||
case ProfitTableGroupBy.BY_TAGS:
|
||||
return await self._get_table_grouped_by_tags(request)
|
||||
|
||||
raise HTTPException(status_code=400, detail='Указана некорректная группировка')
|
||||
|
||||
Reference in New Issue
Block a user