Files
Fulfillment-Backend/services/deal.py
2024-03-19 09:01:46 +03:00

101 lines
4.0 KiB
Python

import datetime
from typing import Type, Union
from sqlalchemy import select
from sqlalchemy.orm import joinedload, selectinload
from models import User, Deal
from models.deal import *
from schemas.client import ClientDetailsSchema
from schemas.deal import *
from services.base import BaseService
from services.client import ClientService
class DealService(BaseService):
async def _get_deal_by_id(self, deal_id) -> Union[Deal, None]:
return await self.session.get(Deal, deal_id)
async def change_status(self, deal: Deal,
status: DealStatus,
user: User,
deadline: datetime.datetime = None) -> DealStatusHistory:
deadline = deadline
status_change = DealStatusHistory(
deal_id=deal.id,
user_id=user.id,
changed_at=datetime.datetime.now(),
from_status=deal.current_status,
to_status=status,
next_status_deadline=deadline
)
self.session.add(status_change)
await self.session.flush()
return status_change
async def create(self, request: DealCreateRequest, user: User) -> DealCreateResponse:
deal = Deal(
name=request.name,
created_at=datetime.datetime.now(),
current_status=DealStatus.CREATED
)
self.session.add(deal)
await self.session.flush()
# Append status history
await self.change_status(deal, DealStatus.AWAITING_ACCEPTANCE, user)
await self.session.commit()
return DealCreateResponse(ok=True)
async def quick_create(self, request: DealQuickCreateRequest, user: User) -> DealQuickCreateResponse:
client_service = ClientService(self.session)
client = await client_service.get_by_name(request.client_name)
if not client:
client = await client_service.create_client_raw(
user,
request.client_name,
ClientDetailsSchema(address=request.client_address))
await client_service.update_details(user, client, ClientDetailsSchema(address=request.client_address))
deal = Deal(
name=request.name,
created_at=datetime.datetime.now(),
client_id=client.id,
current_status=DealStatus.CREATED
)
self.session.add(deal)
await self.session.flush()
await self.change_status(deal, DealStatus.AWAITING_ACCEPTANCE, user, deadline=request.acceptance_date)
await self.session.commit()
return DealQuickCreateResponse(deal_id=deal.id)
async def change_status_manual(self, request: DealChangeStatusRequest, user: User) -> DealChangeStatusResponse:
# Changing current status
deal = await self._get_deal_by_id(request.deal_id)
if not deal:
return DealChangeStatusResponse(ok=False)
await self.change_status(deal, DealStatus(request.new_status), user)
await self.session.commit()
return DealChangeStatusResponse(ok=True)
async def get_summary(self) -> DealSummaryResponse:
deals_query = await self.session.scalars(select(Deal)
.options(selectinload(Deal.status_history),
joinedload(Deal.client))
.where(Deal.is_deleted == False,
Deal.is_completed == False))
summaries = []
for deal in deals_query.all():
deal: Deal
last_status: DealStatusHistory = max(deal.status_history, key=lambda status: status.changed_at)
summaries.append(
DealSummary(
id=deal.id,
client_name=deal.client.name,
name=deal.name,
changed_at=last_status.changed_at,
status=last_status.to_status
)
)
return DealSummaryResponse(summaries=summaries)