feat: temp barcode templates
This commit is contained in:
		
							
								
								
									
										1
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								main.py
									
									
									
									
									
								
							@@ -31,6 +31,7 @@ routers_list = [
 | 
				
			|||||||
    routers.client_router,
 | 
					    routers.client_router,
 | 
				
			||||||
    routers.service_router,
 | 
					    routers.service_router,
 | 
				
			||||||
    routers.product_router,
 | 
					    routers.product_router,
 | 
				
			||||||
 | 
					    routers.barcode_router
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
for router in routers_list:
 | 
					for router in routers_list:
 | 
				
			||||||
    app.include_router(router)
 | 
					    app.include_router(router)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,4 +6,5 @@ from .client import *
 | 
				
			|||||||
from .service import *
 | 
					from .service import *
 | 
				
			||||||
from .product import *
 | 
					from .product import *
 | 
				
			||||||
from .secondary import *
 | 
					from .secondary import *
 | 
				
			||||||
 | 
					from .barcode import *
 | 
				
			||||||
configure_mappers()
 | 
					configure_mappers()
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										22
									
								
								models/barcode.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								models/barcode.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					from sqlalchemy import Integer, Column, String, Boolean
 | 
				
			||||||
 | 
					from sqlalchemy.orm import relationship
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from models import BaseModel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BarcodeTemplateAttribute(BaseModel):
 | 
				
			||||||
 | 
					    __tablename__ = 'barcode_template_attributes'
 | 
				
			||||||
 | 
					    id = Column(Integer, autoincrement=True, primary_key=True, index=True)
 | 
				
			||||||
 | 
					    name = Column(String, nullable=False, index=True, comment='Название атрибута')
 | 
				
			||||||
 | 
					    label = Column(String, nullable=False, index=True, comment='Метка атрибута')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BarcodeTemplate(BaseModel):
 | 
				
			||||||
 | 
					    __tablename__ = 'barcode_templates'
 | 
				
			||||||
 | 
					    id = Column(Integer, autoincrement=True, primary_key=True, index=True)
 | 
				
			||||||
 | 
					    name = Column(String, nullable=False, index=True, comment='Название шаблона')
 | 
				
			||||||
 | 
					    attributes = relationship('BarcodeTemplateAttributeLink',
 | 
				
			||||||
 | 
					                              back_populates='barcode_template',
 | 
				
			||||||
 | 
					                              cascade="all, delete-orphan",
 | 
				
			||||||
 | 
					                              lazy='joined')
 | 
				
			||||||
 | 
					    is_default = Column(Boolean, nullable=False, default=False, comment='По умолчанию')
 | 
				
			||||||
@@ -11,9 +11,11 @@ class Client(BaseModel):
 | 
				
			|||||||
    created_at = Column(DateTime, nullable=False, comment='Дата создания')
 | 
					    created_at = Column(DateTime, nullable=False, comment='Дата создания')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    products = relationship('Product', back_populates='client')
 | 
					    products = relationship('Product', back_populates='client')
 | 
				
			||||||
 | 
					 | 
				
			||||||
    details = relationship('ClientDetails', uselist=False, back_populates='client', cascade='all, delete')
 | 
					    details = relationship('ClientDetails', uselist=False, back_populates='client', cascade='all, delete')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    barcode_template_id = Column(Integer, ForeignKey('barcode_templates.id'), nullable=True)
 | 
				
			||||||
 | 
					    barcode_template = relationship('BarcodeTemplate')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ClientDetails(BaseModel):
 | 
					class ClientDetails(BaseModel):
 | 
				
			||||||
    __tablename__ = 'client_details'
 | 
					    __tablename__ = 'client_details'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,9 @@ class Product(BaseModel):
 | 
				
			|||||||
    client = relationship('Client', back_populates='products')
 | 
					    client = relationship('Client', back_populates='products')
 | 
				
			||||||
    barcodes = relationship('ProductBarcode', back_populates='product', cascade="all, delete-orphan")
 | 
					    barcodes = relationship('ProductBarcode', back_populates='product', cascade="all, delete-orphan")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    barcode_template_id = Column(Integer, ForeignKey('barcode_templates.id'), nullable=True)
 | 
				
			||||||
 | 
					    barcode_template = relationship('BarcodeTemplate')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ProductBarcode(BaseModel):
 | 
					class ProductBarcode(BaseModel):
 | 
				
			||||||
    __tablename__ = 'product_barcodes'
 | 
					    __tablename__ = 'product_barcodes'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,3 +31,20 @@ class DealProduct(BaseModel):
 | 
				
			|||||||
    product = relationship('Product')
 | 
					    product = relationship('Product')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    quantity = Column(Integer, nullable=False, comment='Кол-во продукта')
 | 
					    quantity = Column(Integer, nullable=False, comment='Кол-во продукта')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BarcodeTemplateAttributeLink(BaseModel):
 | 
				
			||||||
 | 
					    __tablename__ = 'barcode_template_attributes_links'
 | 
				
			||||||
 | 
					    barcode_template_id = Column(Integer,
 | 
				
			||||||
 | 
					                                 ForeignKey('barcode_templates.id'),
 | 
				
			||||||
 | 
					                                 nullable=False,
 | 
				
			||||||
 | 
					                                 comment='ID Шаблона ШК',
 | 
				
			||||||
 | 
					                                 primary_key=True)
 | 
				
			||||||
 | 
					    barcode_template = relationship('BarcodeTemplate', back_populates='attributes')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    attribute_id = Column(Integer,
 | 
				
			||||||
 | 
					                          ForeignKey('barcode_template_attributes.id'),
 | 
				
			||||||
 | 
					                          nullable=False,
 | 
				
			||||||
 | 
					                          comment='ID Атрибута',
 | 
				
			||||||
 | 
					                          primary_key=True)
 | 
				
			||||||
 | 
					    attribute = relationship('BarcodeTemplateAttribute')
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,3 +3,4 @@ from .deal import deal_router
 | 
				
			|||||||
from .client import client_router
 | 
					from .client import client_router
 | 
				
			||||||
from .service import service_router
 | 
					from .service import service_router
 | 
				
			||||||
from .product import product_router
 | 
					from .product import product_router
 | 
				
			||||||
 | 
					from .barcode import barcode_router
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										82
									
								
								routers/barcode.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								routers/barcode.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,82 @@
 | 
				
			|||||||
 | 
					from typing import Annotated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from fastapi import APIRouter, Depends
 | 
				
			||||||
 | 
					from sqlalchemy.ext.asyncio import AsyncSession
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from backend.session import get_session
 | 
				
			||||||
 | 
					from schemas.barcode import (GetBarcodeTemplateByIdResponse,
 | 
				
			||||||
 | 
					                             GetBarcodeTemplateByIdRequest,
 | 
				
			||||||
 | 
					                             BarcodeTemplateCreateResponse,
 | 
				
			||||||
 | 
					                             BarcodeTemplateCreateRequest, GetAllBarcodeTemplateAttributesResponse,
 | 
				
			||||||
 | 
					                             CreateBarcodeTemplateAttributeResponse, CreateBarcodeTemplateAttributeRequest,
 | 
				
			||||||
 | 
					                             BarcodeTemplateUpdateResponse, BarcodeTemplateUpdateRequest)
 | 
				
			||||||
 | 
					from services.barcode import BarcodeService
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					barcode_router = APIRouter(
 | 
				
			||||||
 | 
					    prefix='/barcode',
 | 
				
			||||||
 | 
					    tags=['barcode'],
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# region Templates
 | 
				
			||||||
 | 
					@barcode_router.get(
 | 
				
			||||||
 | 
					    '/template/get',
 | 
				
			||||||
 | 
					    response_model=GetBarcodeTemplateByIdResponse,
 | 
				
			||||||
 | 
					    operation_id='get_barcode_template_by_id'
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					async def get_barcode_template_by_id(
 | 
				
			||||||
 | 
					        request: GetBarcodeTemplateByIdRequest,
 | 
				
			||||||
 | 
					        session: Annotated[AsyncSession, Depends(get_session)]
 | 
				
			||||||
 | 
					):
 | 
				
			||||||
 | 
					    return await BarcodeService(session).get_barcode_template_by_id(request)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@barcode_router.post(
 | 
				
			||||||
 | 
					    '/template/create',
 | 
				
			||||||
 | 
					    response_model=BarcodeTemplateCreateResponse,
 | 
				
			||||||
 | 
					    operation_id='create_barcode_template'
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					async def create_barcode_template(
 | 
				
			||||||
 | 
					        request: BarcodeTemplateCreateRequest,
 | 
				
			||||||
 | 
					        session: Annotated[AsyncSession, Depends(get_session)]
 | 
				
			||||||
 | 
					):
 | 
				
			||||||
 | 
					    return await BarcodeService(session).create_barcode_template(request)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@barcode_router.post(
 | 
				
			||||||
 | 
					    '/template/update',
 | 
				
			||||||
 | 
					    response_model=BarcodeTemplateUpdateResponse,
 | 
				
			||||||
 | 
					    operation_id='update_barcode_template'
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					async def update_barcode_template(
 | 
				
			||||||
 | 
					        request: BarcodeTemplateUpdateRequest,
 | 
				
			||||||
 | 
					        session: Annotated[AsyncSession, Depends(get_session)]
 | 
				
			||||||
 | 
					):
 | 
				
			||||||
 | 
					    return await BarcodeService(session).update_barcode_template(request)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# region Template attributes
 | 
				
			||||||
 | 
					@barcode_router.get(
 | 
				
			||||||
 | 
					    '/template/attribute/get-all',
 | 
				
			||||||
 | 
					    response_model=GetAllBarcodeTemplateAttributesResponse,
 | 
				
			||||||
 | 
					    operation_id='get_all_barcode_template_attributes'
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					async def get_all_barcode_template_attributes(
 | 
				
			||||||
 | 
					        session: Annotated[AsyncSession, Depends(get_session)]
 | 
				
			||||||
 | 
					):
 | 
				
			||||||
 | 
					    return await BarcodeService(session).get_all_barcode_template_attributes()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@barcode_router.post(
 | 
				
			||||||
 | 
					    '/template/attribute/create',
 | 
				
			||||||
 | 
					    response_model=CreateBarcodeTemplateAttributeResponse,
 | 
				
			||||||
 | 
					    operation_id='create_barcode_template_attribute'
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					async def create_barcode_template_attribute(
 | 
				
			||||||
 | 
					        request: CreateBarcodeTemplateAttributeRequest,
 | 
				
			||||||
 | 
					        session: Annotated[AsyncSession, Depends(get_session)]
 | 
				
			||||||
 | 
					):
 | 
				
			||||||
 | 
					    return await BarcodeService(session).create_barcode_template_attribute(request)
 | 
				
			||||||
 | 
					# endregion
 | 
				
			||||||
							
								
								
									
										64
									
								
								schemas/barcode.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								schemas/barcode.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
				
			|||||||
 | 
					from schemas.base import CustomModelCamel, OkMessageSchema
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# region Entities
 | 
				
			||||||
 | 
					class BarcodeTemplateAttribute(CustomModelCamel):
 | 
				
			||||||
 | 
					    id: int
 | 
				
			||||||
 | 
					    label: str
 | 
				
			||||||
 | 
					    name: str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BarcodeTemplate(CustomModelCamel):
 | 
				
			||||||
 | 
					    id: int
 | 
				
			||||||
 | 
					    name: str
 | 
				
			||||||
 | 
					    is_default: bool
 | 
				
			||||||
 | 
					    attributes: list[BarcodeTemplateAttribute]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# region Requests
 | 
				
			||||||
 | 
					class GetBarcodeTemplateByIdRequest(CustomModelCamel):
 | 
				
			||||||
 | 
					    id: int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BarcodeTemplateCreateResponse(OkMessageSchema):
 | 
				
			||||||
 | 
					    id: int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BarcodeTemplateUpdateResponse(OkMessageSchema):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GetAllBarcodeTemplateAttributesResponse(CustomModelCamel):
 | 
				
			||||||
 | 
					    attributes: list[BarcodeTemplateAttribute]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CreateBarcodeTemplateAttributeRequest(CustomModelCamel):
 | 
				
			||||||
 | 
					    name: str
 | 
				
			||||||
 | 
					    label: str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# region Responses
 | 
				
			||||||
 | 
					class GetBarcodeTemplateByIdResponse(CustomModelCamel):
 | 
				
			||||||
 | 
					    barcode_template: BarcodeTemplate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BarcodeTemplateCreateRequest(CustomModelCamel):
 | 
				
			||||||
 | 
					    name: str
 | 
				
			||||||
 | 
					    attribute_ids: list[int]
 | 
				
			||||||
 | 
					    is_default: bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BarcodeTemplateUpdateRequest(CustomModelCamel):
 | 
				
			||||||
 | 
					    id: int
 | 
				
			||||||
 | 
					    name: str
 | 
				
			||||||
 | 
					    is_default: bool
 | 
				
			||||||
 | 
					    attribute_ids: list[int]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CreateBarcodeTemplateAttributeResponse(OkMessageSchema):
 | 
				
			||||||
 | 
					    id: int
 | 
				
			||||||
 | 
					# endregion
 | 
				
			||||||
							
								
								
									
										147
									
								
								services/barcode.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								services/barcode.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,147 @@
 | 
				
			|||||||
 | 
					from sqlalchemy import select, update
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from models import BarcodeTemplate, BarcodeTemplateAttribute, BarcodeTemplateAttributeLink
 | 
				
			||||||
 | 
					from schemas.barcode import (GetBarcodeTemplateByIdRequest,
 | 
				
			||||||
 | 
					                             GetBarcodeTemplateByIdResponse,
 | 
				
			||||||
 | 
					                             BarcodeTemplateCreateResponse,
 | 
				
			||||||
 | 
					                             BarcodeTemplateCreateRequest, CreateBarcodeTemplateAttributeRequest,
 | 
				
			||||||
 | 
					                             BarcodeTemplateUpdateResponse, BarcodeTemplateUpdateRequest)
 | 
				
			||||||
 | 
					from services.base import BaseService
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BarcodeService(BaseService):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # region Template
 | 
				
			||||||
 | 
					    async def get_barcode_template_by_id(self,
 | 
				
			||||||
 | 
					                                         request: GetBarcodeTemplateByIdRequest) -> GetBarcodeTemplateByIdResponse:
 | 
				
			||||||
 | 
					        stmt = select(BarcodeTemplate).filter(BarcodeTemplate.id == request.id)
 | 
				
			||||||
 | 
					        query = await self.session.execute(
 | 
				
			||||||
 | 
					            stmt
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        return query.scalar()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def create_barcode_template(self, request: BarcodeTemplateCreateRequest) -> BarcodeTemplateCreateResponse:
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            if request.is_default:
 | 
				
			||||||
 | 
					                stmt = select(BarcodeTemplate).filter(BarcodeTemplate.is_default == True)
 | 
				
			||||||
 | 
					                query = await self.session.execute(stmt)
 | 
				
			||||||
 | 
					                if query.scalar():
 | 
				
			||||||
 | 
					                    raise ValueError('Стандартный шаблон уже существует')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # prevent duplicate template
 | 
				
			||||||
 | 
					            stmt = select(BarcodeTemplate).filter(BarcodeTemplate.name == request.name)
 | 
				
			||||||
 | 
					            query = await self.session.execute(stmt)
 | 
				
			||||||
 | 
					            if query.scalar():
 | 
				
			||||||
 | 
					                raise ValueError('Шаблон с таким именем уже существует')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # create template then add attributes
 | 
				
			||||||
 | 
					            template = BarcodeTemplate(name=request.name, is_default=request.is_default)
 | 
				
			||||||
 | 
					            self.session.add(template)
 | 
				
			||||||
 | 
					            await self.session.flush()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # get all attributes from database
 | 
				
			||||||
 | 
					            stmt = select(BarcodeTemplateAttribute).filter(
 | 
				
			||||||
 | 
					                BarcodeTemplateAttribute.id.in_(request.attribute_ids))
 | 
				
			||||||
 | 
					            query = await self.session.execute(stmt)
 | 
				
			||||||
 | 
					            attributes = query.scalars().all()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # add attributes to template
 | 
				
			||||||
 | 
					            for attribute in attributes:
 | 
				
			||||||
 | 
					                template_attribute_link = BarcodeTemplateAttributeLink(
 | 
				
			||||||
 | 
					                    barcode_template_id=template.id,
 | 
				
			||||||
 | 
					                    attribute_id=attribute.id
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                self.session.add(template_attribute_link)
 | 
				
			||||||
 | 
					                await self.session.flush()
 | 
				
			||||||
 | 
					            await self.session.commit()
 | 
				
			||||||
 | 
					            return BarcodeTemplateCreateResponse(message='Шаблон успешно создан',
 | 
				
			||||||
 | 
					                                                 ok=True,
 | 
				
			||||||
 | 
					                                                 id=template.id)
 | 
				
			||||||
 | 
					        except Exception as e:
 | 
				
			||||||
 | 
					            await self.session.rollback()
 | 
				
			||||||
 | 
					            return BarcodeTemplateCreateResponse(message=str(e),
 | 
				
			||||||
 | 
					                                                 ok=False,
 | 
				
			||||||
 | 
					                                                 id=-1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def update_barcode_template(self, request: BarcodeTemplateUpdateRequest) -> BarcodeTemplateUpdateResponse:
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            stmt = select(BarcodeTemplate).filter(BarcodeTemplate.id == request.id)
 | 
				
			||||||
 | 
					            query = await self.session.execute(stmt)
 | 
				
			||||||
 | 
					            template = query.scalar()
 | 
				
			||||||
 | 
					            if not template:
 | 
				
			||||||
 | 
					                raise ValueError('Шаблон не найден')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if request.is_default:
 | 
				
			||||||
 | 
					                stmt = select(BarcodeTemplate).filter(BarcodeTemplate.is_default == True)
 | 
				
			||||||
 | 
					                query = await self.session.execute(stmt)
 | 
				
			||||||
 | 
					                default_template = query.scalar()
 | 
				
			||||||
 | 
					                if default_template and default_template.id != request.id:
 | 
				
			||||||
 | 
					                    raise ValueError('Стандартный шаблон уже существует')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # update template then add attributes with dict and value syntax
 | 
				
			||||||
 | 
					            request_dict = request.dict()
 | 
				
			||||||
 | 
					            del request_dict['id']
 | 
				
			||||||
 | 
					            del request_dict['attribute_ids']
 | 
				
			||||||
 | 
					            await self.session.execute(
 | 
				
			||||||
 | 
					                update(BarcodeTemplate)
 | 
				
			||||||
 | 
					                .where(BarcodeTemplate.id == request.id)
 | 
				
			||||||
 | 
					                .values(**request_dict)
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # difference deleted and new
 | 
				
			||||||
 | 
					            template_attributes = set([attribute.attribute_id for attribute in template.attributes])
 | 
				
			||||||
 | 
					            request_attributes = set(request.attribute_ids)
 | 
				
			||||||
 | 
					            new_attributes = request_attributes.difference(template_attributes)
 | 
				
			||||||
 | 
					            deleted_attributes = template_attributes.difference(request_attributes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # delete attributes
 | 
				
			||||||
 | 
					            for attribute in template.attributes:
 | 
				
			||||||
 | 
					                if attribute.attribute_id not in deleted_attributes:
 | 
				
			||||||
 | 
					                    continue
 | 
				
			||||||
 | 
					                await self.session.delete(attribute)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # add new attributes
 | 
				
			||||||
 | 
					            for new_attribute in new_attributes:
 | 
				
			||||||
 | 
					                template_attribute_link = BarcodeTemplateAttributeLink(
 | 
				
			||||||
 | 
					                    barcode_template_id=template.id,
 | 
				
			||||||
 | 
					                    attribute_id=new_attribute
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                self.session.add(template_attribute_link)
 | 
				
			||||||
 | 
					                await self.session.flush()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            await self.session.commit()
 | 
				
			||||||
 | 
					            return BarcodeTemplateUpdateResponse(message='Шаблон успешно обновлен',
 | 
				
			||||||
 | 
					                                                 ok=True)
 | 
				
			||||||
 | 
					        except Exception as e:
 | 
				
			||||||
 | 
					            await self.session.rollback()
 | 
				
			||||||
 | 
					            return BarcodeTemplateUpdateResponse(message=str(e),
 | 
				
			||||||
 | 
					                                                 ok=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # region Template attributes
 | 
				
			||||||
 | 
					    async def get_all_barcode_template_attributes(self):
 | 
				
			||||||
 | 
					        stmt = select(BarcodeTemplateAttribute)
 | 
				
			||||||
 | 
					        query = await self.session.execute(stmt)
 | 
				
			||||||
 | 
					        return query.scalars().all()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def create_barcode_template_attribute(self, request: CreateBarcodeTemplateAttributeRequest):
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            # prevent duplicate attribute
 | 
				
			||||||
 | 
					            stmt = select(BarcodeTemplateAttribute).filter(BarcodeTemplateAttribute.name == request.name)
 | 
				
			||||||
 | 
					            query = await self.session.execute(stmt)
 | 
				
			||||||
 | 
					            if query.scalar():
 | 
				
			||||||
 | 
					                raise ValueError('Атрибут с таким именем уже существует')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            attribute = BarcodeTemplateAttribute(**request.dict())
 | 
				
			||||||
 | 
					            self.session.add(attribute)
 | 
				
			||||||
 | 
					            await self.session.commit()
 | 
				
			||||||
 | 
					            return BarcodeTemplateCreateResponse(message='Атрибут успешно создан',
 | 
				
			||||||
 | 
					                                                 ok=True,
 | 
				
			||||||
 | 
					                                                 id=attribute.id)
 | 
				
			||||||
 | 
					        except Exception as e:
 | 
				
			||||||
 | 
					            await self.session.rollback()
 | 
				
			||||||
 | 
					            return BarcodeTemplateCreateResponse(message=str(e),
 | 
				
			||||||
 | 
					                                                 ok=False,
 | 
				
			||||||
 | 
					                                                 id=-1)
 | 
				
			||||||
 | 
					    # endregion
 | 
				
			||||||
		Reference in New Issue
	
	Block a user