157 lines
7.5 KiB
Python
157 lines
7.5 KiB
Python
from sqlalchemy import select, update
|
||
|
||
from models import BarcodeTemplate, BarcodeTemplateAttribute, BarcodeTemplateAttributeLink
|
||
from schemas.barcode import (GetBarcodeTemplateByIdRequest,
|
||
GetBarcodeTemplateByIdResponse,
|
||
BarcodeTemplateCreateResponse,
|
||
BarcodeTemplateCreateRequest, CreateBarcodeTemplateAttributeRequest,
|
||
BarcodeTemplateUpdateResponse, BarcodeTemplateUpdateRequest,
|
||
BarcodeTemplateAttributeSchema, GetAllBarcodeTemplateAttributesResponse,
|
||
GetAllBarcodeTemplatesResponse)
|
||
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 get_all_barcode_templates(self) -> GetAllBarcodeTemplatesResponse:
|
||
stmt = select(BarcodeTemplate).order_by(BarcodeTemplate.id)
|
||
query = await self.session.execute(stmt)
|
||
templates = query.scalars().all()
|
||
return GetAllBarcodeTemplatesResponse(templates=templates)
|
||
|
||
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) -> GetAllBarcodeTemplateAttributesResponse:
|
||
stmt = select(BarcodeTemplateAttribute).order_by(BarcodeTemplateAttribute.id)
|
||
query = await self.session.execute(stmt)
|
||
attributes = query.scalars().all()
|
||
return GetAllBarcodeTemplateAttributesResponse(attributes=attributes)
|
||
|
||
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
|