feat: deals viewer mode and links for viewers
This commit is contained in:
107
services/card.py
107
services/card.py
@@ -2,14 +2,15 @@ from collections import defaultdict
|
||||
|
||||
import lexorank
|
||||
import math
|
||||
import starlette.status
|
||||
from fastapi import HTTPException
|
||||
from sqlalchemy import select, func, update, delete, insert, and_, Select
|
||||
from sqlalchemy.orm import joinedload, selectinload, noload
|
||||
from starlette import status
|
||||
|
||||
from card_attributes import CardAttributesCommandHandler
|
||||
from card_attributes.exceptions import CardAttributeException
|
||||
from models import *
|
||||
from schemas.auth import UserUnion
|
||||
from schemas.base import PaginationSchema
|
||||
from schemas.card import *
|
||||
from schemas.client import ClientDetailsSchema
|
||||
@@ -20,20 +21,13 @@ from services.card_tag import CardTagService
|
||||
from services.client import ClientService
|
||||
from services.service import ServiceService
|
||||
from services.shipping_warehouse import ShippingWarehouseService
|
||||
from utils.auth import verify_user_deal_editor, verify_user_viewer
|
||||
|
||||
|
||||
class CardsService(BaseService):
|
||||
|
||||
# region Card
|
||||
|
||||
@staticmethod
|
||||
def grant_access(user: Union[User, dict], card_id: int):
|
||||
if type(user) is User:
|
||||
return
|
||||
user_card_id = user['deal_id']
|
||||
if int(user_card_id) != int(card_id):
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='Invalid token')
|
||||
|
||||
async def _get_card_by_id(self, card_id) -> Union[Card, None]:
|
||||
return await self.session.get(Card, card_id)
|
||||
|
||||
@@ -235,7 +229,12 @@ class CardsService(BaseService):
|
||||
total_items=total_items,
|
||||
)
|
||||
|
||||
async def get_summary(self, request: GetCardSummariesRequest, pagination: PaginationSchema) -> CardSummaryResponse:
|
||||
async def get_summary(
|
||||
self,
|
||||
request: GetCardSummariesRequest,
|
||||
pagination: PaginationSchema,
|
||||
user: UserUnion,
|
||||
) -> CardSummaryResponse:
|
||||
price_subquery = self._get_price_subquery()
|
||||
products_quantity_subquery = self._get_products_quantity_subquery()
|
||||
q = (
|
||||
@@ -268,6 +267,9 @@ class CardsService(BaseService):
|
||||
)
|
||||
)
|
||||
|
||||
if isinstance(user, dict) and "client_id" in user:
|
||||
q = q.where(Card.client_id == user["client_id"])
|
||||
|
||||
q = self._apply_summary_filters(q, request)
|
||||
|
||||
pagination_info = await self._summaries_pagination_info(q, pagination)
|
||||
@@ -346,10 +348,9 @@ class CardsService(BaseService):
|
||||
result.append(CardSchema.model_validate(card))
|
||||
return CardGetAllResponse(cards=result)
|
||||
|
||||
async def get_by_id(self, user: Union[User, dict], card_id: int, return_raw=False) -> Union[
|
||||
CardSchema, Card]:
|
||||
self.grant_access(user, card_id)
|
||||
|
||||
async def get_by_id(self, user: UserUnion, card_id: int, return_raw=False) -> Union[
|
||||
CardSchema, Card
|
||||
]:
|
||||
card: Optional[Card] = await self.session.scalar(
|
||||
select(Card)
|
||||
.options(
|
||||
@@ -393,11 +394,17 @@ class CardsService(BaseService):
|
||||
)
|
||||
.where(Card.id == card_id)
|
||||
)
|
||||
if return_raw:
|
||||
return card
|
||||
|
||||
if not card:
|
||||
raise HTTPException(status_code=404, detail="Карточка не найдена")
|
||||
|
||||
if not verify_user_deal_editor(user, card_id, False) and \
|
||||
not verify_user_viewer(user, card.client_id, False):
|
||||
raise HTTPException(status_code=starlette.status.HTTP_403_FORBIDDEN, detail='Forbidden')
|
||||
|
||||
if return_raw:
|
||||
return card
|
||||
|
||||
return CardSchema.model_validate(card)
|
||||
|
||||
async def update_general_info(
|
||||
@@ -450,12 +457,15 @@ class CardsService(BaseService):
|
||||
await self.session.rollback()
|
||||
return CardUpdateGeneralInfoResponse(ok=False, message=str(e))
|
||||
|
||||
async def update_products_and_services_general_info(self, request: ProductsAndServicesGeneralInfoRequest) -> (
|
||||
async def update_products_and_services_general_info(self, request: ProductsAndServicesGeneralInfoRequest,
|
||||
user: UserUnion) -> (
|
||||
ProductsAndServicesGeneralInfoResponse
|
||||
):
|
||||
verify_user_deal_editor(user, request.card_id)
|
||||
|
||||
card: Optional[Card] = await self.session.get(Card, request.card_id)
|
||||
if not card:
|
||||
return ProductsAndServicesGeneralInfoRequest(ok=False, message='Карточка не найдена')
|
||||
return ProductsAndServicesGeneralInfoResponse(ok=False, message='Карточка не найдена')
|
||||
|
||||
# Updating shipping warehouse
|
||||
shipping_warehouse_service = ShippingWarehouseService(self.session)
|
||||
@@ -464,8 +474,10 @@ class CardsService(BaseService):
|
||||
shipping_warehouse = await shipping_warehouse_service.create_by_name(request.data.shipping_warehouse)
|
||||
|
||||
if card.group:
|
||||
for card in card.group.cards:
|
||||
card.is_services_profit_accounted = request.data.is_services_profit_accounted
|
||||
stmt_group = select(CardGroup).where(CardGroup.id == card.group.id).options(selectinload(CardGroup.cards))
|
||||
group = (await self.session.scalars(stmt_group)).one_or_none()
|
||||
for c in group.cards:
|
||||
c.is_services_profit_accounted = request.data.is_services_profit_accounted
|
||||
else:
|
||||
card.is_services_profit_accounted = request.data.is_services_profit_accounted
|
||||
|
||||
@@ -579,7 +591,7 @@ class CardsService(BaseService):
|
||||
except Exception as e:
|
||||
return CardAddKitResponse(ok=False, message=str(e))
|
||||
|
||||
def create_guest_url(self, user: User, request: CardCreateGuestUrlRequest) -> CardCreateGuestUrlResponse:
|
||||
async def create_guest_url(self, request: CardCreateGuestUrlRequest) -> CardCreateGuestUrlResponse:
|
||||
access_token = AuthService(self.session).create_deal_guest_token(request.card_id)
|
||||
url = f"deals/{request.card_id}?accessToken={access_token}"
|
||||
return CardCreateGuestUrlResponse(ok=True, message='Ссылка успешно создана!', url=url)
|
||||
@@ -668,11 +680,11 @@ class CardsService(BaseService):
|
||||
|
||||
async def update_service_quantity(
|
||||
self,
|
||||
user: Union[User, dict],
|
||||
user: UserUnion,
|
||||
request: CardUpdateServiceQuantityRequest
|
||||
) -> CardUpdateServiceQuantityResponse:
|
||||
try:
|
||||
self.grant_access(user, request.card_id)
|
||||
verify_user_deal_editor(user, request.card_id)
|
||||
card_service = await self.session.scalar(
|
||||
select(CardService)
|
||||
.where(CardService.card_id == request.card_id,
|
||||
@@ -689,11 +701,11 @@ class CardsService(BaseService):
|
||||
|
||||
async def add_service(
|
||||
self,
|
||||
user: Union[User, dict],
|
||||
user: UserUnion,
|
||||
request: CardAddServiceRequest
|
||||
) -> CardAddServiceResponse:
|
||||
try:
|
||||
self.grant_access(user, request.card_id)
|
||||
verify_user_deal_editor(user, request.card_id)
|
||||
card = await self.session.scalar(select(Card).where(Card.id == request.card_id))
|
||||
if not card:
|
||||
raise HTTPException(status_code=404, detail="Карточка не найдена")
|
||||
@@ -723,11 +735,12 @@ class CardsService(BaseService):
|
||||
|
||||
async def delete_service(
|
||||
self,
|
||||
user: Union[User, dict],
|
||||
user: UserUnion,
|
||||
request: CardDeleteServiceRequest
|
||||
) -> CardDeleteServiceResponse:
|
||||
try:
|
||||
self.grant_access(user, request.card_id)
|
||||
verify_user_deal_editor(user, request.card_id)
|
||||
|
||||
card_service = await self.session.scalar(
|
||||
select(CardService)
|
||||
.where(CardService.card_id == request.card_id,
|
||||
@@ -744,11 +757,12 @@ class CardsService(BaseService):
|
||||
|
||||
async def delete_services(
|
||||
self,
|
||||
user: Union[User, dict],
|
||||
user: UserUnion,
|
||||
request: CardDeleteServicesRequest
|
||||
) -> CardDeleteServicesResponse:
|
||||
try:
|
||||
self.grant_access(user, request)
|
||||
verify_user_deal_editor(user, request.card_id)
|
||||
|
||||
card_services = await self.session.scalars(
|
||||
select(CardService)
|
||||
.where(CardService.card_id == request.card_id,
|
||||
@@ -764,11 +778,11 @@ class CardsService(BaseService):
|
||||
|
||||
async def update_service(
|
||||
self,
|
||||
user: Union[User, dict],
|
||||
user: UserUnion,
|
||||
request: CardUpdateServiceRequest
|
||||
) -> CardUpdateServiceResponse:
|
||||
try:
|
||||
self.grant_access(user, request.card_id)
|
||||
verify_user_deal_editor(user, request.card_id)
|
||||
card_service = await self.session.scalar(
|
||||
select(CardService)
|
||||
.where(CardService.card_id == request.card_id,
|
||||
@@ -823,11 +837,11 @@ class CardsService(BaseService):
|
||||
|
||||
async def copy_services(
|
||||
self,
|
||||
user: Union[User, dict],
|
||||
user: UserUnion,
|
||||
request: CardServicesCopyRequest
|
||||
) -> CardServicesCopyResponse:
|
||||
try:
|
||||
self.grant_access(user, request.card_id)
|
||||
verify_user_deal_editor(user, request.card_id)
|
||||
source_services_stmt = (
|
||||
select(
|
||||
CardProductService
|
||||
@@ -911,11 +925,11 @@ class CardsService(BaseService):
|
||||
# region Card products
|
||||
async def update_product_quantity(
|
||||
self,
|
||||
user: Union[User, dict],
|
||||
user: UserUnion,
|
||||
request: CardUpdateProductQuantityRequest
|
||||
) -> CardUpdateProductQuantityResponse:
|
||||
try:
|
||||
self.grant_access(user, request.card_id)
|
||||
verify_user_deal_editor(user, request.card_id)
|
||||
# check if there is no card or no product with different exceptions
|
||||
card_product = await self.session.scalar(
|
||||
select(CardProduct)
|
||||
@@ -933,12 +947,11 @@ class CardsService(BaseService):
|
||||
|
||||
async def add_product(
|
||||
self,
|
||||
user: Union[User, dict],
|
||||
|
||||
user: UserUnion,
|
||||
request: CardAddProductRequest
|
||||
) -> CardAddProductResponse:
|
||||
try:
|
||||
self.grant_access(user, request.card_id)
|
||||
verify_user_deal_editor(user, request.card_id)
|
||||
|
||||
card = await self.session.scalar(select(Card).where(Card.id == request.card_id))
|
||||
if not card:
|
||||
@@ -978,11 +991,12 @@ class CardsService(BaseService):
|
||||
|
||||
async def delete_product(
|
||||
self,
|
||||
user: Union[User, dict],
|
||||
user: UserUnion,
|
||||
request: CardDeleteProductRequest
|
||||
) -> CardDeleteProductResponse:
|
||||
try:
|
||||
self.grant_access(user, request.card_id)
|
||||
verify_user_deal_editor(user, request.card_id)
|
||||
|
||||
card_product = await self.session.scalar(
|
||||
select(CardProduct)
|
||||
.where(CardProduct.card_id == request.card_id,
|
||||
@@ -999,11 +1013,11 @@ class CardsService(BaseService):
|
||||
|
||||
async def delete_products(
|
||||
self,
|
||||
user: Union[User, dict],
|
||||
user: UserUnion,
|
||||
request: CardDeleteProductsRequest
|
||||
) -> CardDeleteProductsResponse:
|
||||
try:
|
||||
self.grant_access(user, request.card_id)
|
||||
verify_user_deal_editor(user, request.card_id)
|
||||
card_products = await self.session.scalars(
|
||||
select(CardProduct)
|
||||
.where(CardProduct.card_id == request.card_id,
|
||||
@@ -1019,11 +1033,11 @@ class CardsService(BaseService):
|
||||
|
||||
async def update_product(
|
||||
self,
|
||||
user: Union[User, dict],
|
||||
user: UserUnion,
|
||||
request: CardUpdateProductRequest
|
||||
):
|
||||
try:
|
||||
self.grant_access(user, request.card_id)
|
||||
verify_user_deal_editor(user, request.card_id)
|
||||
card_product: CardProduct = await self.session.scalar(
|
||||
select(CardProduct)
|
||||
.where(CardProduct.card_id == request.card_id,
|
||||
@@ -1106,11 +1120,12 @@ class CardsService(BaseService):
|
||||
|
||||
async def add_kit_to_card_product(
|
||||
self,
|
||||
user: Union[User, dict],
|
||||
user: UserUnion,
|
||||
request: CardProductAddKitRequest
|
||||
) -> CardProductAddKitResponse:
|
||||
try:
|
||||
self.grant_access(user, request.card_id)
|
||||
verify_user_deal_editor(user, request.card_id)
|
||||
|
||||
service_service = ServiceService(self.session)
|
||||
kit = await service_service.get_kit_by_id(request.kit_id)
|
||||
if not kit:
|
||||
|
||||
Reference in New Issue
Block a user