135 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import datetime
 | 
						||
from typing import Union
 | 
						||
 | 
						||
from sqlalchemy import select, update
 | 
						||
from sqlalchemy.orm import joinedload
 | 
						||
 | 
						||
from models import Client, ClientDetails, User
 | 
						||
from schemas.client import *
 | 
						||
from services.base import BaseService
 | 
						||
 | 
						||
 | 
						||
class ClientService(BaseService):
 | 
						||
 | 
						||
    async def get_by_name(self, name: str) -> Union[Client, None]:
 | 
						||
        client = await self.session.scalar(select(Client).where(Client.name == name))
 | 
						||
        return client
 | 
						||
 | 
						||
    async def get_by_id(self, client_id: int) -> Union[Client, None]:
 | 
						||
        return await self.session.get(Client, client_id)
 | 
						||
 | 
						||
    async def get_details_by_client_id(self, client_id: int) -> Union[ClientDetails, None]:
 | 
						||
        details = await self.session.scalar(select(ClientDetails).where(ClientDetails.client_id == client_id))
 | 
						||
        return details
 | 
						||
 | 
						||
    async def get_all(self) -> ClientGetAllResponse:
 | 
						||
        clients_query = await self.session.scalars(
 | 
						||
            select(Client)
 | 
						||
            .options(joinedload(Client.details))
 | 
						||
            .order_by(Client.id.desc())
 | 
						||
        )
 | 
						||
        clients = clients_query.all()
 | 
						||
        result = []
 | 
						||
        for client in clients:
 | 
						||
            result.append(ClientSchema.model_validate(client))
 | 
						||
        return ClientGetAllResponse(clients=result)
 | 
						||
 | 
						||
    async def create_details(self, user, client: Client, request: ClientDetailsSchema):
 | 
						||
        dict_data = request.dict()
 | 
						||
        dict_data['client_id'] = client.id
 | 
						||
        dict_data['last_modified_at'] = datetime.datetime.now()
 | 
						||
        dict_data['modified_by_user_id'] = user.id
 | 
						||
        details = ClientDetails(**dict_data)
 | 
						||
        self.session.add(details)
 | 
						||
        await self.session.flush()
 | 
						||
        return details
 | 
						||
 | 
						||
    async def update_details(self, user: User, client: Client, request: ClientDetailsSchema) -> ClientDetails:
 | 
						||
        details = await self.get_details_by_client_id(client_id=client.id)
 | 
						||
        if not details:
 | 
						||
            details = await self.create_details(user, client, request)
 | 
						||
        dict_data = request.dict()
 | 
						||
        dict_data['last_modified_at'] = datetime.datetime.now()
 | 
						||
        dict_data['modified_by_user_id'] = user.id
 | 
						||
        await self.session.execute(update(ClientDetails).where(ClientDetails.id == details.id).values(**dict_data))
 | 
						||
        await self.session.flush()
 | 
						||
 | 
						||
    async def create_client_raw(self,
 | 
						||
                                user: User,
 | 
						||
                                client_name: str,
 | 
						||
                                details_schema: ClientDetailsSchema) -> Client:
 | 
						||
        client = Client(name=client_name, created_at=datetime.datetime.now())
 | 
						||
        self.session.add(client)
 | 
						||
        await self.session.flush()
 | 
						||
 | 
						||
        await self.update_details(user, client, details_schema)
 | 
						||
 | 
						||
        return client
 | 
						||
 | 
						||
    async def search_clients(self, request: ClientSearchRequest) -> ClientSearchResponse:
 | 
						||
        query = await self.session.scalars(select(Client)
 | 
						||
                                           .where(Client.name.ilike(f'%{request.name}%'))
 | 
						||
                                           .options(joinedload(Client.details)))
 | 
						||
        clients = []
 | 
						||
        for client in query.all():
 | 
						||
            clients.append(ClientSchema.model_validate(client))
 | 
						||
        return ClientSearchResponse(clients=clients)
 | 
						||
 | 
						||
    async def create(self, request: ClientCreateRequest, user: User) -> ClientCreateResponse:
 | 
						||
        try:
 | 
						||
            client = await self.get_by_name(request.data.name)
 | 
						||
            if client:
 | 
						||
                return ClientCreateResponse(ok=False, message='Клиент с таким именем уже существует')
 | 
						||
            client_dict = request.data.dict()
 | 
						||
            del client_dict['id']
 | 
						||
            del client_dict['details']
 | 
						||
            del client_dict['barcode_template']
 | 
						||
            if request.data.barcode_template:
 | 
						||
                client_dict['barcode_template_id'] = request.data.barcode_template.id
 | 
						||
            client_dict['created_at'] = datetime.datetime.now()
 | 
						||
 | 
						||
            client = Client(**client_dict)
 | 
						||
            self.session.add(client)
 | 
						||
            await self.session.flush()
 | 
						||
            await self.create_details(user, client, request.data.details)
 | 
						||
 | 
						||
            # await self.create_client_raw(user, request.data.name, request.data.details)
 | 
						||
            await self.session.commit()
 | 
						||
            return ClientCreateResponse(ok=True, message='Client created')
 | 
						||
        except Exception as e:
 | 
						||
            return ClientCreateResponse(ok=False, message=str(e))
 | 
						||
 | 
						||
    async def update(self, request: ClientUpdateRequest, user: User) -> ClientUpdateResponse:
 | 
						||
        try:
 | 
						||
            client = await self.get_by_id(request.data.id)
 | 
						||
            if not client:
 | 
						||
                return ClientUpdateResponse(ok=False, message='Клиент не найден')
 | 
						||
            request_dict = request.data.dict()
 | 
						||
            del request_dict['id']
 | 
						||
            del request_dict['details']
 | 
						||
            del request_dict['barcode_template']
 | 
						||
            if request.data.barcode_template:
 | 
						||
                request_dict['barcode_template_id'] = request.data.barcode_template.id
 | 
						||
            stmt = (
 | 
						||
                update(Client)
 | 
						||
                .where(Client.id == client.id)
 | 
						||
                .values(**request_dict)
 | 
						||
            )
 | 
						||
            await self.session.execute(stmt)
 | 
						||
            await self.update_details(user, client, request.data.details)
 | 
						||
            await self.session.commit()
 | 
						||
            return ClientUpdateResponse(ok=True, message='Клиент обновлен')
 | 
						||
        except Exception as e:
 | 
						||
            return ClientUpdateResponse(ok=False, message=str(e))
 | 
						||
 | 
						||
    async def delete(self, request: ClientDeleteRequest) -> ClientDeleteResponse:
 | 
						||
        try:
 | 
						||
            client = await self.get_by_id(request.client_id)
 | 
						||
            if not client:
 | 
						||
                return ClientDeleteResponse(ok=False, message='Клиент не найден')
 | 
						||
            await self.session.delete(client)
 | 
						||
            await self.session.commit()
 | 
						||
            return ClientDeleteResponse(ok=True, message='Клиент удален')
 | 
						||
        except Exception as e:
 | 
						||
            return ClientDeleteResponse(ok=False, message=str(e))
 |