feat: billing guest access
This commit is contained in:
		@@ -19,8 +19,10 @@ oauth2_schema = HTTPBearer()
 | 
			
		||||
algorithm = 'HS256'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def get_current_user(session: Annotated[AsyncSession, Depends(get_session)],
 | 
			
		||||
                           token: Annotated[HTTPAuthorizationCredentials, Depends(oauth2_schema)]) -> User | None:
 | 
			
		||||
async def get_current_user(
 | 
			
		||||
        session: Annotated[AsyncSession, Depends(get_session)],
 | 
			
		||||
        token: Annotated[HTTPAuthorizationCredentials, Depends(oauth2_schema)]
 | 
			
		||||
) -> Union[User, None, dict]:
 | 
			
		||||
    if not token.credentials:
 | 
			
		||||
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='Invalid token')
 | 
			
		||||
    try:
 | 
			
		||||
@@ -28,6 +30,8 @@ async def get_current_user(session: Annotated[AsyncSession, Depends(get_session)
 | 
			
		||||
        user_id = payload.get('sub')
 | 
			
		||||
        if not user_id:
 | 
			
		||||
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='Invalid credentials')
 | 
			
		||||
        if user_id == 'guest':
 | 
			
		||||
            return payload
 | 
			
		||||
        user_id = int(user_id)
 | 
			
		||||
 | 
			
		||||
        user = await session.get(User, user_id)
 | 
			
		||||
@@ -35,16 +39,26 @@ async def get_current_user(session: Annotated[AsyncSession, Depends(get_session)
 | 
			
		||||
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='Invalid credentials')
 | 
			
		||||
        return user
 | 
			
		||||
    except JWTError as e:
 | 
			
		||||
        print(e)
 | 
			
		||||
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='Invalid token')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def authorized_user(
 | 
			
		||||
        user: Annotated[User, Depends(get_current_user)]
 | 
			
		||||
):
 | 
			
		||||
    if type(user) is User:
 | 
			
		||||
        return user
 | 
			
		||||
    raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='Invalid token')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def guest_user(user: Annotated[User, Depends(get_current_user)]):
 | 
			
		||||
    if (type(user) is User) or (type(user) is dict):
 | 
			
		||||
        return user
 | 
			
		||||
    raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='Invalid token')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AuthService(BaseService):
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def _generate_jwt_token(user: User) -> str:
 | 
			
		||||
        payload = {
 | 
			
		||||
            'sub': str(user.id)
 | 
			
		||||
        }
 | 
			
		||||
    def _generate_jwt_token(payload: dict) -> str:
 | 
			
		||||
        return jwt.encode(payload, backend.config.SECRET_KEY, algorithm=algorithm)
 | 
			
		||||
 | 
			
		||||
    async def authenticate(self, request: AuthLoginRequest):
 | 
			
		||||
@@ -60,5 +74,16 @@ class AuthService(BaseService):
 | 
			
		||||
            )
 | 
			
		||||
            self.session.add(user)
 | 
			
		||||
            await self.session.commit()
 | 
			
		||||
        access_token = self._generate_jwt_token(user)
 | 
			
		||||
        payload = {
 | 
			
		||||
            'sub': str(user.id)
 | 
			
		||||
        }
 | 
			
		||||
        access_token = self._generate_jwt_token(payload)
 | 
			
		||||
        return AuthLoginResponse(access_token=access_token)
 | 
			
		||||
 | 
			
		||||
    def create_deal_guest_token(self, deal_id: int):
 | 
			
		||||
        payload = {
 | 
			
		||||
            'sub': 'guest',
 | 
			
		||||
            'deal_id': deal_id
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return self._generate_jwt_token(payload)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										118
									
								
								services/billing.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								services/billing.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,118 @@
 | 
			
		||||
import datetime
 | 
			
		||||
from typing import List
 | 
			
		||||
 | 
			
		||||
from fastapi import HTTPException
 | 
			
		||||
from sqlalchemy import select
 | 
			
		||||
from starlette import status
 | 
			
		||||
 | 
			
		||||
import backend.config
 | 
			
		||||
from external.billing import BillingClient, CreateBillingRequestValue, CreateBillRequestSchema, CreateBillRequestItems, \
 | 
			
		||||
    BillStatusUpdateRequest, NotificationChannel, NotifyReceivedBillRequestSchema, BillPaymentInfo
 | 
			
		||||
from models import DealBillRequest, Deal
 | 
			
		||||
from schemas.billing import *
 | 
			
		||||
from services.base import BaseService
 | 
			
		||||
from services.deal import DealService
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BillingService(BaseService):
 | 
			
		||||
    async def _process_update_details(
 | 
			
		||||
            self,
 | 
			
		||||
            request: BillStatusUpdateRequest
 | 
			
		||||
    ):
 | 
			
		||||
        billing_client = BillingClient(backend.config.BILLING_API_KEY)
 | 
			
		||||
        notify_received_request = NotifyReceivedBillRequestSchema(
 | 
			
		||||
            listener_transaction_id=request.listener_transaction_id,
 | 
			
		||||
            channel=NotificationChannel.PAYMENT_DETAILS,
 | 
			
		||||
            received=True
 | 
			
		||||
        )
 | 
			
		||||
        response = await billing_client.notify_received(notify_received_request)
 | 
			
		||||
        deal_bill_request = await self._get_deal_bill_by_id(request.listener_transaction_id)
 | 
			
		||||
        if not response.ok:
 | 
			
		||||
            return
 | 
			
		||||
        deal_bill_request.pdf_url = request.info.pdf_url
 | 
			
		||||
        deal_bill_request.invoice_number = request.info.invoice_number
 | 
			
		||||
        await self.session.commit()
 | 
			
		||||
 | 
			
		||||
    async def _process_update_verification(
 | 
			
		||||
            self,
 | 
			
		||||
            request: BillStatusUpdateRequest
 | 
			
		||||
    ):
 | 
			
		||||
        billing_client = BillingClient(backend.config.BILLING_API_KEY)
 | 
			
		||||
        notify_received_request = NotifyReceivedBillRequestSchema(
 | 
			
		||||
            listener_transaction_id=request.listener_transaction_id,
 | 
			
		||||
            channel=NotificationChannel.PAYMENT_VERIFICATION,
 | 
			
		||||
            received=True
 | 
			
		||||
        )
 | 
			
		||||
        response = await billing_client.notify_received(notify_received_request)
 | 
			
		||||
        if not response.ok:
 | 
			
		||||
            return
 | 
			
		||||
        deal_bill_request = await self._get_deal_bill_by_id(request.listener_transaction_id)
 | 
			
		||||
        if not deal_bill_request:
 | 
			
		||||
            return
 | 
			
		||||
        deal_bill_request.paid = request.info.payed
 | 
			
		||||
        await self.session.commit()
 | 
			
		||||
 | 
			
		||||
    async def process_update(
 | 
			
		||||
            self,
 | 
			
		||||
            request: BillStatusUpdateRequest
 | 
			
		||||
    ):
 | 
			
		||||
        if request.channel == NotificationChannel.PAYMENT_DETAILS:
 | 
			
		||||
            await self._process_update_details(request)
 | 
			
		||||
        elif request.channel == NotificationChannel.PAYMENT_VERIFICATION:
 | 
			
		||||
            await self._process_update_verification(request)
 | 
			
		||||
 | 
			
		||||
    async def create_deal_billing(self, user, request: CreateDealBillRequest) -> CreateDealBillResponse:
 | 
			
		||||
        try:
 | 
			
		||||
            deal_service = DealService(self.session)
 | 
			
		||||
            billing_client = BillingClient(backend.config.BILLING_API_KEY)
 | 
			
		||||
 | 
			
		||||
            deal: Deal = await deal_service.get_by_id(user, request.deal_id)
 | 
			
		||||
            billing_request_values: List[CreateBillingRequestValue] = []
 | 
			
		||||
            for product in deal.products:
 | 
			
		||||
                for service in product.services:
 | 
			
		||||
                    billing_request_values.append(
 | 
			
		||||
                        CreateBillingRequestValue(
 | 
			
		||||
                            name=f'[{product.product.name}] - {service.service.name}',
 | 
			
		||||
                            price=service.price,
 | 
			
		||||
                            amount=product.quantity
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
            for service in deal.services:
 | 
			
		||||
                billing_request_values.append(
 | 
			
		||||
                    CreateBillingRequestValue(
 | 
			
		||||
                        name=f'{service.service.name}',
 | 
			
		||||
                        price=service.price,
 | 
			
		||||
                        amount=service.quantity
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            create_bill_request = CreateBillRequestSchema(
 | 
			
		||||
                listener_transaction_id=deal.id,
 | 
			
		||||
                payer_name=deal.client.name,
 | 
			
		||||
                payer_inn=deal.client.details.inn,
 | 
			
		||||
                payer_phone=deal.client.details.phone_number,
 | 
			
		||||
                items=CreateBillRequestItems(
 | 
			
		||||
                    values=billing_request_values
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            create_bill_response = await billing_client.create(create_bill_request)
 | 
			
		||||
            if not create_bill_response.ok:
 | 
			
		||||
                return CreateDealBillResponse(ok=create_bill_response.ok, message='Ошибка!')
 | 
			
		||||
            deal_bill_request = DealBillRequest(
 | 
			
		||||
                deal_id=request.deal_id,
 | 
			
		||||
                created_at=datetime.datetime.now()
 | 
			
		||||
            )
 | 
			
		||||
            self.session.add(deal_bill_request)
 | 
			
		||||
            deal.is_locked = True
 | 
			
		||||
            await self.session.commit()
 | 
			
		||||
            return CreateDealBillResponse(ok=create_bill_response.ok, message='Заявка успешно создана!')
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            return CreateDealBillResponse(ok=False, message=str(e))
 | 
			
		||||
 | 
			
		||||
    async def _get_deal_bill_by_id(self, deal_id: int) -> Optional[DealBillRequest]:
 | 
			
		||||
        return await self.session.scalar(select(DealBillRequest).where(DealBillRequest.deal_id == deal_id))
 | 
			
		||||
 | 
			
		||||
    async def get_deal_bill_by_id(self, deal_id: int) -> GetDealBillById:
 | 
			
		||||
        deal_bill = await self._get_deal_bill_by_id(deal_id)
 | 
			
		||||
        if not deal_bill:
 | 
			
		||||
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='Deal bill was not found')
 | 
			
		||||
        return GetDealBillById(deal_bill=DealBillRequestSchema.model_validate(deal_bill))
 | 
			
		||||
							
								
								
									
										120
									
								
								services/deal.py
									
									
									
									
									
								
							
							
						
						
									
										120
									
								
								services/deal.py
									
									
									
									
									
								
							@@ -1,16 +1,16 @@
 | 
			
		||||
import lexorank
 | 
			
		||||
 | 
			
		||||
import models.secondary
 | 
			
		||||
from typing import Union
 | 
			
		||||
import models.deal
 | 
			
		||||
from fastapi import HTTPException
 | 
			
		||||
from sqlalchemy import select, func, update, delete, insert
 | 
			
		||||
from sqlalchemy.orm import joinedload, selectinload
 | 
			
		||||
from starlette import status
 | 
			
		||||
 | 
			
		||||
import models.deal
 | 
			
		||||
import models.secondary
 | 
			
		||||
from models import User, Service, Client
 | 
			
		||||
from models.deal import *
 | 
			
		||||
from schemas.client import ClientDetailsSchema
 | 
			
		||||
from schemas.deal import *
 | 
			
		||||
from services.auth import AuthService
 | 
			
		||||
from services.base import BaseService
 | 
			
		||||
from services.client import ClientService
 | 
			
		||||
from services.service import ServiceService
 | 
			
		||||
@@ -20,6 +20,15 @@ from services.shipping_warehouse import ShippingWarehouseService
 | 
			
		||||
class DealService(BaseService):
 | 
			
		||||
 | 
			
		||||
    # region Deal
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def grant_access(user: Union[models.User, dict], deal_id):
 | 
			
		||||
        if type(user) is models.User:
 | 
			
		||||
            return
 | 
			
		||||
        user_deal_id = user['deal_id']
 | 
			
		||||
        if int(user_deal_id) != int(deal_id):
 | 
			
		||||
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='Invalid token')
 | 
			
		||||
 | 
			
		||||
    async def _get_deal_by_id(self, deal_id) -> Union[Deal, None]:
 | 
			
		||||
        return await self.session.get(Deal, deal_id)
 | 
			
		||||
 | 
			
		||||
@@ -211,7 +220,9 @@ class DealService(BaseService):
 | 
			
		||||
            result.append(DealSchema.model_validate(deal))
 | 
			
		||||
        return DealGetAllResponse(deals=result)
 | 
			
		||||
 | 
			
		||||
    async def get_by_id(self, deal_id: int) -> DealSchema:
 | 
			
		||||
    async def get_by_id(self, user: Union[models.User, dict], deal_id: int, return_raw=False) -> Union[
 | 
			
		||||
        DealSchema, models.Deal]:
 | 
			
		||||
        self.grant_access(user, deal_id)
 | 
			
		||||
 | 
			
		||||
        deal = await self.session.scalar(
 | 
			
		||||
            select(Deal)
 | 
			
		||||
@@ -244,7 +255,8 @@ class DealService(BaseService):
 | 
			
		||||
            )
 | 
			
		||||
            .where(Deal.id == deal_id)
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        if return_raw:
 | 
			
		||||
            return deal
 | 
			
		||||
        if not deal:
 | 
			
		||||
            raise HTTPException(status_code=404, detail="Сделка не найдена")
 | 
			
		||||
        return DealSchema.model_validate(deal)
 | 
			
		||||
@@ -360,11 +372,17 @@ class DealService(BaseService):
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            return DealAddKitResponse(ok=False, message=str(e))
 | 
			
		||||
 | 
			
		||||
    def create_guest_url(self, user: models.User, request: DealCreateGuestUrlRequest) -> DealCreateGuestUrlResponse:
 | 
			
		||||
        if not user.is_admin:
 | 
			
		||||
            return DealCreateGuestUrlResponse(ok=False, message='Создать ссылку может только администратор', url="")
 | 
			
		||||
        access_token = AuthService(self.session).create_deal_guest_token(request.deal_id)
 | 
			
		||||
        url = f"deals/{request.deal_id}?accessToken={access_token}"
 | 
			
		||||
        return DealCreateGuestUrlResponse(ok=True, message='Ссылка успешно создана!', url=url)
 | 
			
		||||
 | 
			
		||||
    # endregion
 | 
			
		||||
 | 
			
		||||
    # region Deal services
 | 
			
		||||
    async def add_services(self, request: DealAddServicesRequest):
 | 
			
		||||
        # TODO refactor
 | 
			
		||||
        deal: Deal = await self.session.scalar(
 | 
			
		||||
            select(Deal)
 | 
			
		||||
            .options(selectinload(Deal.services))
 | 
			
		||||
@@ -404,9 +422,13 @@ class DealService(BaseService):
 | 
			
		||||
        await self.session.commit()
 | 
			
		||||
        return DealAddServicesResponse(ok=True, message='Услуги успешно добавлены')
 | 
			
		||||
 | 
			
		||||
    async def update_service_quantity(self,
 | 
			
		||||
                                      request: DealUpdateServiceQuantityRequest) -> DealUpdateServiceQuantityResponse:
 | 
			
		||||
    async def update_service_quantity(
 | 
			
		||||
            self,
 | 
			
		||||
            user: Union[models.User, dict],
 | 
			
		||||
            request: DealUpdateServiceQuantityRequest
 | 
			
		||||
    ) -> DealUpdateServiceQuantityResponse:
 | 
			
		||||
        try:
 | 
			
		||||
            self.grant_access(user, request.deal_id)
 | 
			
		||||
            deal_service = await self.session.scalar(
 | 
			
		||||
                select(models.secondary.DealService)
 | 
			
		||||
                .where(models.secondary.DealService.deal_id == request.deal_id,
 | 
			
		||||
@@ -421,8 +443,12 @@ class DealService(BaseService):
 | 
			
		||||
            await self.session.rollback()
 | 
			
		||||
            return DealUpdateServiceQuantityResponse(ok=False, message=str(e))
 | 
			
		||||
 | 
			
		||||
    async def add_service(self, request: DealAddServiceRequest) -> DealAddServiceResponse:
 | 
			
		||||
    async def add_service(self,
 | 
			
		||||
                          user: Union[models.User, dict],
 | 
			
		||||
                          request: DealAddServiceRequest
 | 
			
		||||
                          ) -> DealAddServiceResponse:
 | 
			
		||||
        try:
 | 
			
		||||
            self.grant_access(user, request.deal_id)
 | 
			
		||||
            deal = await self.session.scalar(select(Deal).where(Deal.id == request.deal_id))
 | 
			
		||||
            if not deal:
 | 
			
		||||
                raise HTTPException(status_code=404, detail="Сделка не найдена")
 | 
			
		||||
@@ -450,8 +476,13 @@ class DealService(BaseService):
 | 
			
		||||
            await self.session.rollback()
 | 
			
		||||
            return DealAddServiceResponse(ok=False, message=str(e))
 | 
			
		||||
 | 
			
		||||
    async def delete_service(self, request: DealDeleteServiceRequest) -> DealDeleteServiceResponse:
 | 
			
		||||
    async def delete_service(
 | 
			
		||||
            self,
 | 
			
		||||
            user: Union[models.User, dict],
 | 
			
		||||
            request: DealDeleteServiceRequest
 | 
			
		||||
    ) -> DealDeleteServiceResponse:
 | 
			
		||||
        try:
 | 
			
		||||
            self.grant_access(user, request.deal_id)
 | 
			
		||||
            deal_service = await self.session.scalar(
 | 
			
		||||
                select(models.secondary.DealService)
 | 
			
		||||
                .where(models.secondary.DealService.deal_id == request.deal_id,
 | 
			
		||||
@@ -466,8 +497,13 @@ class DealService(BaseService):
 | 
			
		||||
            await self.session.rollback()
 | 
			
		||||
            return DealDeleteServiceResponse(ok=False, message=str(e))
 | 
			
		||||
 | 
			
		||||
    async def delete_services(self, request: DealDeleteServicesRequest) -> DealDeleteServicesResponse:
 | 
			
		||||
    async def delete_services(
 | 
			
		||||
            self,
 | 
			
		||||
            user: Union[models.User, dict],
 | 
			
		||||
            request: DealDeleteServicesRequest
 | 
			
		||||
    ) -> DealDeleteServicesResponse:
 | 
			
		||||
        try:
 | 
			
		||||
            self.grant_access(user, request)
 | 
			
		||||
            deal_services = await self.session.scalars(
 | 
			
		||||
                select(models.secondary.DealService)
 | 
			
		||||
                .where(models.secondary.DealService.deal_id == request.deal_id,
 | 
			
		||||
@@ -481,8 +517,13 @@ class DealService(BaseService):
 | 
			
		||||
            await self.session.rollback()
 | 
			
		||||
            return DealDeleteServicesResponse(ok=False, message=str(e))
 | 
			
		||||
 | 
			
		||||
    async def update_service(self, request: DealUpdateServiceRequest) -> DealUpdateServiceResponse:
 | 
			
		||||
    async def update_service(
 | 
			
		||||
            self,
 | 
			
		||||
            user: Union[models.User, dict],
 | 
			
		||||
            request: DealUpdateServiceRequest
 | 
			
		||||
    ) -> DealUpdateServiceResponse:
 | 
			
		||||
        try:
 | 
			
		||||
            self.grant_access(user, request.deal_id)
 | 
			
		||||
            deal_service = await self.session.scalar(
 | 
			
		||||
                select(models.secondary.DealService)
 | 
			
		||||
                .where(models.secondary.DealService.deal_id == request.deal_id,
 | 
			
		||||
@@ -535,9 +576,13 @@ class DealService(BaseService):
 | 
			
		||||
            await self.session.rollback()
 | 
			
		||||
            return DealUpdateServiceQuantityResponse(ok=False, message=str(e))
 | 
			
		||||
 | 
			
		||||
    async def copy_services(self, request: DealServicesCopyRequest) -> DealServicesCopyResponse:
 | 
			
		||||
    async def copy_services(
 | 
			
		||||
            self,
 | 
			
		||||
            user: Union[models.User, dict],
 | 
			
		||||
            request: DealServicesCopyRequest
 | 
			
		||||
    ) -> DealServicesCopyResponse:
 | 
			
		||||
        try:
 | 
			
		||||
 | 
			
		||||
            self.grant_access(user, request.deal_id)
 | 
			
		||||
            source_services_stmt = (
 | 
			
		||||
                select(
 | 
			
		||||
                    models.DealProductService
 | 
			
		||||
@@ -614,9 +659,13 @@ class DealService(BaseService):
 | 
			
		||||
    # endregion
 | 
			
		||||
 | 
			
		||||
    # region Deal products
 | 
			
		||||
    async def update_product_quantity(self,
 | 
			
		||||
                                      request: DealUpdateProductQuantityRequest) -> DealUpdateProductQuantityResponse:
 | 
			
		||||
    async def update_product_quantity(
 | 
			
		||||
            self,
 | 
			
		||||
            user: Union[models.User, dict],
 | 
			
		||||
            request: DealUpdateProductQuantityRequest
 | 
			
		||||
    ) -> DealUpdateProductQuantityResponse:
 | 
			
		||||
        try:
 | 
			
		||||
            self.grant_access(user, request.deal_id)
 | 
			
		||||
            # check if there is no deal or no product with different exceptions
 | 
			
		||||
            deal_product = await self.session.scalar(
 | 
			
		||||
                select(models.secondary.DealProduct)
 | 
			
		||||
@@ -632,8 +681,15 @@ class DealService(BaseService):
 | 
			
		||||
            await self.session.rollback()
 | 
			
		||||
            return DealUpdateProductQuantityResponse(ok=False, message=str(e))
 | 
			
		||||
 | 
			
		||||
    async def add_product(self, request: DealAddProductRequest) -> DealAddProductResponse:
 | 
			
		||||
    async def add_product(
 | 
			
		||||
            self,
 | 
			
		||||
            user: Union[models.User, dict],
 | 
			
		||||
 | 
			
		||||
            request: DealAddProductRequest
 | 
			
		||||
    ) -> DealAddProductResponse:
 | 
			
		||||
        try:
 | 
			
		||||
            self.grant_access(user, request.deal_id)
 | 
			
		||||
 | 
			
		||||
            deal = await self.session.scalar(select(Deal).where(Deal.id == request.deal_id))
 | 
			
		||||
            if not deal:
 | 
			
		||||
                raise HTTPException(status_code=404, detail="Сделка не найдена")
 | 
			
		||||
@@ -670,8 +726,13 @@ class DealService(BaseService):
 | 
			
		||||
            await self.session.rollback()
 | 
			
		||||
            return DealAddProductResponse(ok=False, message=str(e))
 | 
			
		||||
 | 
			
		||||
    async def delete_product(self, request: DealDeleteProductRequest) -> DealDeleteProductResponse:
 | 
			
		||||
    async def delete_product(
 | 
			
		||||
            self,
 | 
			
		||||
            user: Union[models.User, dict],
 | 
			
		||||
            request: DealDeleteProductRequest
 | 
			
		||||
    ) -> DealDeleteProductResponse:
 | 
			
		||||
        try:
 | 
			
		||||
            self.grant_access(user, request.deal_id)
 | 
			
		||||
            deal_product = await self.session.scalar(
 | 
			
		||||
                select(models.secondary.DealProduct)
 | 
			
		||||
                .where(models.secondary.DealProduct.deal_id == request.deal_id,
 | 
			
		||||
@@ -686,8 +747,13 @@ class DealService(BaseService):
 | 
			
		||||
            await self.session.rollback()
 | 
			
		||||
            return DealDeleteProductResponse(ok=False, message=str(e))
 | 
			
		||||
 | 
			
		||||
    async def delete_products(self, request: DealDeleteProductsRequest) -> DealDeleteProductsResponse:
 | 
			
		||||
    async def delete_products(
 | 
			
		||||
            self,
 | 
			
		||||
            user: Union[models.User, dict],
 | 
			
		||||
            request: DealDeleteProductsRequest
 | 
			
		||||
    ) -> DealDeleteProductsResponse:
 | 
			
		||||
        try:
 | 
			
		||||
            self.grant_access(user, request.deal_id)
 | 
			
		||||
            deal_products = await self.session.scalars(
 | 
			
		||||
                select(models.secondary.DealProduct)
 | 
			
		||||
                .where(models.secondary.DealProduct.deal_id == request.deal_id,
 | 
			
		||||
@@ -701,8 +767,13 @@ class DealService(BaseService):
 | 
			
		||||
            await self.session.rollback()
 | 
			
		||||
            return DealDeleteProductsResponse(ok=False, message=str(e))
 | 
			
		||||
 | 
			
		||||
    async def update_product(self, request: DealUpdateProductRequest):
 | 
			
		||||
    async def update_product(
 | 
			
		||||
            self,
 | 
			
		||||
            user: Union[models.User, dict],
 | 
			
		||||
            request: DealUpdateProductRequest
 | 
			
		||||
    ):
 | 
			
		||||
        try:
 | 
			
		||||
            self.grant_access(user, request.deal_id)
 | 
			
		||||
            deal_product: models.DealProduct = await self.session.scalar(
 | 
			
		||||
                select(models.secondary.DealProduct)
 | 
			
		||||
                .where(models.secondary.DealProduct.deal_id == request.deal_id,
 | 
			
		||||
@@ -781,8 +852,13 @@ class DealService(BaseService):
 | 
			
		||||
            await self.session.rollback()
 | 
			
		||||
            return DealUpdateProductResponse(ok=False, message=str(e))
 | 
			
		||||
 | 
			
		||||
    async def add_kit_to_deal_product(self, request: DealProductAddKitRequest) -> DealProductAddKitResponse:
 | 
			
		||||
    async def add_kit_to_deal_product(
 | 
			
		||||
            self,
 | 
			
		||||
            user: Union[models.User, dict],
 | 
			
		||||
            request: DealProductAddKitRequest
 | 
			
		||||
    ) -> DealProductAddKitResponse:
 | 
			
		||||
        try:
 | 
			
		||||
            self.grant_access(user, request.deal_id)
 | 
			
		||||
            service_service = ServiceService(self.session)
 | 
			
		||||
            kit = await service_service.get_kit_by_id(request.kit_id)
 | 
			
		||||
            if not kit:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,5 @@
 | 
			
		||||
from typing import Union
 | 
			
		||||
 | 
			
		||||
from fastapi import HTTPException
 | 
			
		||||
from sqlalchemy import select, func, Integer, update
 | 
			
		||||
from sqlalchemy.orm import selectinload
 | 
			
		||||
@@ -5,25 +7,17 @@ from sqlalchemy.orm import selectinload
 | 
			
		||||
import utils.barcodes
 | 
			
		||||
from backend import config
 | 
			
		||||
from external.s3_uploader.uploader import S3Uploader
 | 
			
		||||
from models.product import Product, ProductBarcode, ProductImage
 | 
			
		||||
from models import User
 | 
			
		||||
from models.product import Product, ProductImage
 | 
			
		||||
from schemas.base import PaginationSchema
 | 
			
		||||
from services.base import BaseService
 | 
			
		||||
from schemas.product import *
 | 
			
		||||
from services.base import BaseService
 | 
			
		||||
from utils.dependecies import is_valid_pagination
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ProductService(BaseService):
 | 
			
		||||
 | 
			
		||||
    async def create(self, request: ProductCreateRequest) -> ProductCreateResponse:
 | 
			
		||||
        # Unique article validation
 | 
			
		||||
        # existing_product_query = await self.session.execute(
 | 
			
		||||
        #     select(Product)
 | 
			
		||||
        #     .where(Product.client_id == request.client_id,
 | 
			
		||||
        #            Product.article == request.article)
 | 
			
		||||
        # )
 | 
			
		||||
        # existing_product = existing_product_query.first()
 | 
			
		||||
        # if existing_product:
 | 
			
		||||
        #     return ProductCreateResponse(ok=False, message='Товар с таким артикулом уже существует у клиента')
 | 
			
		||||
 | 
			
		||||
        # Creating product
 | 
			
		||||
        product_dict = request.dict()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user