169 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
from lexorank import lexorank
 | 
						|
from sqlalchemy import select, insert, update, delete
 | 
						|
from sqlalchemy.orm import selectinload
 | 
						|
 | 
						|
from models import DealService as DealServiceModel, User, Deal, DealProduct, Product, GroupBillRequest
 | 
						|
from models.deal_group import DealGroup, deal_relations
 | 
						|
from schemas.group import *
 | 
						|
from services.base import BaseService
 | 
						|
from services.deal import DealService
 | 
						|
 | 
						|
 | 
						|
class DealGroupService(BaseService):
 | 
						|
    async def get_deals_by_group_id(self, group_id) -> list[Deal]:
 | 
						|
        group: DealGroup | None = await self.session.scalar(
 | 
						|
            select(DealGroup)
 | 
						|
            .where(DealGroup.id == group_id)
 | 
						|
            .options(
 | 
						|
                selectinload(DealGroup.deals).selectinload(Deal.products).selectinload(DealProduct.services),
 | 
						|
                selectinload(DealGroup.deals).selectinload(Deal.products)
 | 
						|
                .selectinload(DealProduct.product).selectinload(Product.barcodes),
 | 
						|
                selectinload(DealGroup.deals).selectinload(Deal.services).selectinload(DealServiceModel.service),
 | 
						|
                selectinload(DealGroup.deals).selectinload(Deal.status_history),
 | 
						|
                selectinload(DealGroup.deals).selectinload(Deal.group).selectinload(DealGroup.deals),
 | 
						|
                selectinload(DealGroup.deals).joinedload(Deal.client),
 | 
						|
                selectinload(DealGroup.deals).joinedload(Deal.shipping_warehouse),
 | 
						|
            )
 | 
						|
        )
 | 
						|
        return group.deals if group else []
 | 
						|
 | 
						|
    async def create_group_model(self) -> DealGroup:
 | 
						|
        group = DealGroup(
 | 
						|
            name='',
 | 
						|
            lexorank=lexorank.middle(lexorank.Bucket.BUCEKT_0).__str__(),
 | 
						|
        )
 | 
						|
        self.session.add(group)
 | 
						|
        await self.session.flush()
 | 
						|
        return group
 | 
						|
 | 
						|
    async def create_group(self, user: User, request: DealCreateGroupRequest) -> DealCreateGroupResponse:
 | 
						|
        try:
 | 
						|
            group = await self.create_group_model()
 | 
						|
 | 
						|
            for deal_id in [request.dragging_deal_id, request.hovered_deal_id]:
 | 
						|
                insert_stmt = insert(deal_relations).values({
 | 
						|
                    'deal_id': deal_id,
 | 
						|
                    'group_id': group.id
 | 
						|
                })
 | 
						|
                await self.session.execute(insert_stmt)
 | 
						|
            # changing status if needed on draggable deal
 | 
						|
            dragging_deal = await self.session.scalar(
 | 
						|
                select(Deal).where(Deal.id == request.dragging_deal_id)
 | 
						|
            )
 | 
						|
            dropped_deal = await self.session.scalar(
 | 
						|
                select(Deal).where(Deal.id == request.hovered_deal_id)
 | 
						|
            )
 | 
						|
            if dragging_deal.current_status_id != dropped_deal.current_status_id:
 | 
						|
                deal_service = DealService(self.session)
 | 
						|
                await deal_service.change_status(dragging_deal, dropped_deal.current_status_id, user)
 | 
						|
            await self.session.commit()
 | 
						|
            return DealCreateGroupResponse(ok=True, message="Группа успешно создана")
 | 
						|
        except Exception as e:
 | 
						|
            return DealCreateGroupResponse(ok=False, message=str(e))
 | 
						|
 | 
						|
    async def update_group(self, request: DealGroupUpdateRequest) -> DealGroupUpdateResponse:
 | 
						|
        try:
 | 
						|
            group = await self.session.scalar(
 | 
						|
                select(DealGroup).where(DealGroup.id == request.data.id)
 | 
						|
            )
 | 
						|
            if not group:
 | 
						|
                return DealGroupUpdateResponse(ok=False, message="Группа не найдена")
 | 
						|
            # update by dictionary
 | 
						|
            request_dict = request.data.model_dump()
 | 
						|
            request_dict.pop("bill_request", None)
 | 
						|
 | 
						|
            update_stmt = (
 | 
						|
                update(DealGroup)
 | 
						|
                .where(DealGroup.id == request.data.id)
 | 
						|
                .values(**request_dict)
 | 
						|
            )
 | 
						|
            await self.session.execute(update_stmt)
 | 
						|
            await self.session.commit()
 | 
						|
            return DealGroupUpdateResponse(ok=True, message="Группа успешно обновлена")
 | 
						|
        except Exception as e:
 | 
						|
            await self.session.rollback()
 | 
						|
            return DealGroupUpdateResponse(ok=False, message=str(e))
 | 
						|
 | 
						|
    async def complete_group(self, group_id: int) -> list[Deal]:
 | 
						|
        deals = await self.get_deals_by_group_id(group_id)
 | 
						|
        for deal in deals:
 | 
						|
            deal.is_completed = True
 | 
						|
        return deals
 | 
						|
 | 
						|
    async def delete_group(self, group_id: int) -> None:
 | 
						|
        deals = await self.get_deals_by_group_id(group_id)
 | 
						|
        for deal in deals:
 | 
						|
            deal.is_deleted = True
 | 
						|
        await self.session.commit()
 | 
						|
 | 
						|
    async def change_group_status(
 | 
						|
            self,
 | 
						|
            user: User,
 | 
						|
            request: DealGroupChangeStatusRequest,
 | 
						|
    ) -> DealGroupChangeStatusResponse:
 | 
						|
        try:
 | 
						|
            # getting all deals in group
 | 
						|
            deals = await self.session.scalars(
 | 
						|
                select(deal_relations.c.deal_id)
 | 
						|
                .where(deal_relations.c.group_id == request.group_id)
 | 
						|
            )
 | 
						|
 | 
						|
            deal_service = DealService(self.session)
 | 
						|
            for deal_id in deals:
 | 
						|
                deal = await self.session.scalar(
 | 
						|
                    select(Deal).where(Deal.id == deal_id)
 | 
						|
                )
 | 
						|
                await deal_service.change_status(deal, request.new_status, user)
 | 
						|
            await self.session.commit()
 | 
						|
            return DealGroupChangeStatusResponse(ok=True, message="Статус группы успешно изменен")
 | 
						|
        except Exception as e:
 | 
						|
            await self.session.rollback()
 | 
						|
            return DealGroupChangeStatusResponse(ok=False, message=str(e))
 | 
						|
 | 
						|
    async def add_deal(self, user: User, request: DealAddToGroupRequest) -> DealAddToGroupResponse:
 | 
						|
        try:
 | 
						|
            group_bill_request = await self.session.get(GroupBillRequest, request.group_id)
 | 
						|
            if group_bill_request:
 | 
						|
                raise Exception("Нельзя добавить сделку, так как на группу выставлен счёт.")
 | 
						|
 | 
						|
            # changing status if needed
 | 
						|
            deal_id = await self.session.scalar(
 | 
						|
                select(deal_relations.c.deal_id)
 | 
						|
                .where(deal_relations.c.group_id == request.group_id)
 | 
						|
            )
 | 
						|
            group_deal_status = await self.session.scalar(
 | 
						|
                select(Deal.current_status_id)
 | 
						|
                .where(Deal.id == deal_id)
 | 
						|
            )
 | 
						|
            request_deal = await self.session.scalar(
 | 
						|
                select(Deal).where(Deal.id == request.deal_id)
 | 
						|
            )
 | 
						|
            if group_deal_status != request_deal.current_status_id:
 | 
						|
                await DealService(self.session).change_status(request_deal, group_deal_status, user)
 | 
						|
            insert_stmt = insert(deal_relations).values({
 | 
						|
                'deal_id': request.deal_id,
 | 
						|
                'group_id': request.group_id
 | 
						|
            })
 | 
						|
            await self.session.execute(insert_stmt)
 | 
						|
            await self.session.commit()
 | 
						|
 | 
						|
            return DealAddToGroupResponse(ok=True, message="Сделка успешно добавлена в группу")
 | 
						|
        except Exception as e:
 | 
						|
            await self.session.rollback()
 | 
						|
            return DealAddToGroupResponse(ok=False, message=str(e))
 | 
						|
 | 
						|
    async def remove_deal(self, request: DealRemoveFromGroupRequest) -> DealRemoveFromGroupResponse:
 | 
						|
        try:
 | 
						|
            delete_stmt = (
 | 
						|
                delete(deal_relations)
 | 
						|
                .where(
 | 
						|
                    deal_relations.c.deal_id == request.deal_id,
 | 
						|
                )
 | 
						|
            )
 | 
						|
            await self.session.execute(delete_stmt)
 | 
						|
            await self.session.commit()
 | 
						|
            return DealRemoveFromGroupResponse(ok=True, message="Сделка успешно удалена из группы")
 | 
						|
        except Exception as e:
 | 
						|
            await self.session.rollback()
 | 
						|
            return DealRemoveFromGroupResponse(ok=False, message=str(e))
 |