othr
This commit is contained in:
@@ -1,21 +1,21 @@
|
||||
from abc import abstractmethod, ABC
|
||||
|
||||
from .article_attribute_writer import ArticleAttributeWriter
|
||||
from .name_attribute_writer import NameAttributeWriter
|
||||
from ..barcode import Barcode
|
||||
|
||||
|
||||
class BaseAttributeWriter(ABC):
|
||||
@abstractmethod
|
||||
def write(self, barcode: Barcode):
|
||||
pass
|
||||
|
||||
|
||||
class AttributeWriterFactory:
|
||||
@staticmethod
|
||||
def get_writer(key: str):
|
||||
match key:
|
||||
case 'name':
|
||||
return NameAttributeWriter()
|
||||
case 'article':
|
||||
return ArticleAttributeWriter()
|
||||
# from abc import abstractmethod, ABC
|
||||
#
|
||||
# from .article_attribute_writer import ArticleAttributeWriter
|
||||
# from .name_attribute_writer import NameAttributeWriter
|
||||
# from ..barcode import Barcode
|
||||
#
|
||||
#
|
||||
# class BaseAttributeWriter(ABC):
|
||||
# @abstractmethod
|
||||
# def write(self, barcode: Barcode):
|
||||
# pass
|
||||
#
|
||||
#
|
||||
# class AttributeWriterFactory:
|
||||
# @staticmethod
|
||||
# def get_writer(key: str):
|
||||
# match key:
|
||||
# case 'name':
|
||||
# return NameAttributeWriter()
|
||||
# case 'article':
|
||||
# return ArticleAttributeWriter()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from barcodes.attributes import BaseAttributeWriter
|
||||
from barcodes.barcode import Barcode
|
||||
|
||||
|
||||
class ArticleAttributeWriter(BaseAttributeWriter):
|
||||
def write(self, barcode: Barcode):
|
||||
pass
|
||||
# from barcodes.attributes import BaseAttributeWriter
|
||||
# from barcodes.barcode import Barcode
|
||||
#
|
||||
#
|
||||
# class ArticleAttributeWriter(BaseAttributeWriter):
|
||||
# def write(self, barcode: Barcode):
|
||||
# pass
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from barcodes.attributes import BaseAttributeWriter
|
||||
from barcodes.barcode import Barcode
|
||||
|
||||
|
||||
class NameAttributeWriter(BaseAttributeWriter):
|
||||
def write(self, barcode: Barcode):
|
||||
pass
|
||||
# from barcodes.attributes import BaseAttributeWriter
|
||||
# from barcodes.barcode import Barcode
|
||||
#
|
||||
#
|
||||
# class NameAttributeWriter(BaseAttributeWriter):
|
||||
# def write(self, barcode: Barcode):
|
||||
# pass
|
||||
@@ -1,15 +1,15 @@
|
||||
from .attributes import AttributeWriterFactory
|
||||
from models import ProductBarcode, BarcodeTemplate, BarcodeTemplateAttribute
|
||||
|
||||
|
||||
class Barcode:
|
||||
def __init__(self, session, barcode: ProductBarcode):
|
||||
self.session = session
|
||||
self.barcode = barcode
|
||||
|
||||
def render(self, template: BarcodeTemplate):
|
||||
for attribute in template.attributes:
|
||||
attribute: BarcodeTemplateAttribute
|
||||
writer = AttributeWriterFactory.get_writer(attribute.key)
|
||||
writer.write(self)
|
||||
|
||||
# from .attributes import AttributeWriterFactory
|
||||
# from models import ProductBarcode, BarcodeTemplate, BarcodeTemplateAttribute
|
||||
#
|
||||
#
|
||||
# class Barcode:
|
||||
# def __init__(self, session, barcode: ProductBarcode):
|
||||
# self.session = session
|
||||
# self.barcode = barcode
|
||||
#
|
||||
# def render(self, template: BarcodeTemplate):
|
||||
# for attribute in template.attributes:
|
||||
# attribute: BarcodeTemplateAttribute
|
||||
# writer = AttributeWriterFactory.get_writer(attribute.key)
|
||||
# writer.write(self)
|
||||
#
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from models import ProductBarcode
|
||||
|
||||
|
||||
class BarcodeGenerator:
|
||||
def __init__(self, barcode: ProductBarcode):
|
||||
self.barcode = barcode
|
||||
# from models import ProductBarcode
|
||||
#
|
||||
#
|
||||
# class BarcodeGenerator:
|
||||
# def __init__(self, barcode: ProductBarcode):
|
||||
# self.barcode = barcode
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from sqlalchemy import Integer, Column, String, Boolean
|
||||
from sqlalchemy import Integer, Column, String, Boolean, ForeignKey
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from models import BaseModel
|
||||
from models import BaseModel, barcode_template_attribute_link
|
||||
|
||||
|
||||
class BarcodeTemplateAttribute(BaseModel):
|
||||
@@ -11,14 +11,31 @@ class BarcodeTemplateAttribute(BaseModel):
|
||||
name = Column(String, nullable=False, index=True, comment='Метка атрибута')
|
||||
|
||||
|
||||
class BarcodeTemplateAdditionalField(BaseModel):
|
||||
__tablename__ = 'barcode_template_additional_fields'
|
||||
id = Column(Integer, autoincrement=True, primary_key=True, index=True)
|
||||
name = Column(String, nullable=False)
|
||||
value = Column(String, nullable=False)
|
||||
|
||||
barcode_template_id = Column(Integer, ForeignKey('barcode_templates.id'), nullable=False)
|
||||
barcode_template = relationship('BarcodeTemplate', back_populates='additional_fields')
|
||||
|
||||
|
||||
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')
|
||||
attributes = relationship('BarcodeTemplateAttribute',
|
||||
secondary=barcode_template_attribute_link,
|
||||
# back_populates='barcode_template',
|
||||
# cascade="all, delete-orphan",
|
||||
lazy='selectin'
|
||||
)
|
||||
additional_fields = relationship('BarcodeTemplateAdditionalField',
|
||||
back_populates='barcode_template',
|
||||
lazy='selectin'
|
||||
)
|
||||
|
||||
is_default = Column(Boolean, nullable=False, default=False, comment='По умолчанию')
|
||||
|
||||
# size
|
||||
|
||||
@@ -14,7 +14,7 @@ class Client(BaseModel):
|
||||
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')
|
||||
barcode_template = relationship('BarcodeTemplate', lazy='selectin')
|
||||
|
||||
|
||||
class ClientDetails(BaseModel):
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
from enum import IntEnum, unique
|
||||
|
||||
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Boolean, Sequence
|
||||
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Boolean
|
||||
from sqlalchemy.orm import relationship, backref
|
||||
|
||||
from models.base import BaseModel, metadata
|
||||
from models.utils import add_sequence_to_model
|
||||
from models.base import BaseModel
|
||||
|
||||
|
||||
@unique
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
from sqlalchemy import Column, Integer, String, ForeignKey, Sequence
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from models import BaseModel, metadata
|
||||
|
||||
deal_rank_seq = Sequence('test_ochko', start=1, increment=1, metadata=metadata)
|
||||
|
||||
sequence = Sequence('my_sequence_name')
|
||||
from models import BaseModel
|
||||
|
||||
|
||||
class Product(BaseModel):
|
||||
|
||||
@@ -33,18 +33,26 @@ class DealProduct(BaseModel):
|
||||
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')
|
||||
# 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')
|
||||
barcode_template_attribute_link = Table(
|
||||
'barcode_template_attribute_links',
|
||||
BaseModel.metadata,
|
||||
Column('barcode_template_id', ForeignKey('barcode_templates.id')),
|
||||
Column('attribute_id', ForeignKey('barcode_template_attributes.id'))
|
||||
)
|
||||
|
||||
@@ -10,7 +10,8 @@ from schemas.barcode import (GetBarcodeTemplateByIdResponse,
|
||||
BarcodeTemplateCreateRequest, GetAllBarcodeTemplateAttributesResponse,
|
||||
CreateBarcodeTemplateAttributeResponse, CreateBarcodeTemplateAttributeRequest,
|
||||
BarcodeTemplateUpdateResponse, BarcodeTemplateUpdateRequest,
|
||||
GetAllBarcodeTemplatesResponse)
|
||||
GetAllBarcodeTemplatesResponse, BarcodeTemplateDeleteRequest,
|
||||
BarcodeTemplateDeleteResponse)
|
||||
from services.barcode import BarcodeService
|
||||
|
||||
barcode_router = APIRouter(
|
||||
@@ -67,6 +68,18 @@ async def update_barcode_template(
|
||||
return await BarcodeService(session).update_barcode_template(request)
|
||||
|
||||
|
||||
@barcode_router.post(
|
||||
'/template/delete',
|
||||
response_model=BarcodeTemplateDeleteResponse,
|
||||
operation_id='delete_barcode_template'
|
||||
)
|
||||
async def delete_barcode_template(
|
||||
request: BarcodeTemplateDeleteRequest,
|
||||
session: Annotated[AsyncSession, Depends(get_session)]
|
||||
):
|
||||
return await BarcodeService(session).delete_template(request)
|
||||
|
||||
|
||||
# endregion
|
||||
|
||||
# region Template attributes
|
||||
|
||||
@@ -40,6 +40,10 @@ class CreateBarcodeTemplateAttributeRequest(CustomModelCamel):
|
||||
label: str
|
||||
|
||||
|
||||
class BarcodeTemplateDeleteRequest(CustomModelCamel):
|
||||
id: int
|
||||
|
||||
|
||||
# endregion
|
||||
|
||||
# region Responses
|
||||
@@ -66,4 +70,8 @@ class GetAllBarcodeTemplatesResponse(CustomModelCamel):
|
||||
|
||||
class GetAllBarcodeTemplateAttributesResponse(CustomModelCamel):
|
||||
attributes: list[BarcodeTemplateAttributeSchema]
|
||||
|
||||
|
||||
class BarcodeTemplateDeleteResponse(OkMessageSchema):
|
||||
pass
|
||||
# endregion
|
||||
|
||||
@@ -2,6 +2,7 @@ from typing import List
|
||||
|
||||
from pydantic import validator, field_validator
|
||||
|
||||
from schemas.barcode import BarcodeTemplateSchema
|
||||
from schemas.base import CustomModelCamel, OkMessageSchema
|
||||
|
||||
|
||||
@@ -20,6 +21,7 @@ class ClientDetailsSchema(CustomModelCamel):
|
||||
class ClientSchema(CustomModelCamel):
|
||||
id: int
|
||||
name: str
|
||||
barcode_template: BarcodeTemplateSchema | None = None
|
||||
details: ClientDetailsSchema | None = None
|
||||
|
||||
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
from sqlalchemy import select, update
|
||||
from sqlalchemy import select, update, insert
|
||||
from sqlalchemy.orm import selectinload
|
||||
|
||||
from models import BarcodeTemplate, BarcodeTemplateAttribute, BarcodeTemplateAttributeLink
|
||||
from models import BarcodeTemplate, BarcodeTemplateAttribute, barcode_template_attribute_link
|
||||
from schemas.barcode import (GetBarcodeTemplateByIdRequest,
|
||||
GetBarcodeTemplateByIdResponse,
|
||||
BarcodeTemplateCreateResponse,
|
||||
BarcodeTemplateCreateRequest, CreateBarcodeTemplateAttributeRequest,
|
||||
BarcodeTemplateUpdateResponse, BarcodeTemplateUpdateRequest,
|
||||
BarcodeTemplateAttributeSchema, GetAllBarcodeTemplateAttributesResponse,
|
||||
GetAllBarcodeTemplatesResponse)
|
||||
GetAllBarcodeTemplatesResponse, BarcodeTemplateDeleteRequest,
|
||||
BarcodeTemplateDeleteResponse)
|
||||
from services.base import BaseService
|
||||
|
||||
|
||||
@@ -23,7 +25,12 @@ class BarcodeService(BaseService):
|
||||
return query.scalar()
|
||||
|
||||
async def get_all_barcode_templates(self) -> GetAllBarcodeTemplatesResponse:
|
||||
stmt = select(BarcodeTemplate).order_by(BarcodeTemplate.id)
|
||||
stmt = (
|
||||
select(BarcodeTemplate)
|
||||
.options(
|
||||
selectinload(BarcodeTemplate.attributes)
|
||||
)
|
||||
.order_by(BarcodeTemplate.id))
|
||||
query = await self.session.execute(stmt)
|
||||
templates = query.scalars().all()
|
||||
return GetAllBarcodeTemplatesResponse(templates=templates)
|
||||
@@ -43,10 +50,12 @@ class BarcodeService(BaseService):
|
||||
raise ValueError('Шаблон с таким именем уже существует')
|
||||
|
||||
# create template then add attributes
|
||||
template = BarcodeTemplate(name=request.name, is_default=request.is_default)
|
||||
request_dict = request.dict()
|
||||
del request_dict['attribute_ids']
|
||||
template = BarcodeTemplate(**request_dict)
|
||||
self.session.add(template)
|
||||
await self.session.flush()
|
||||
|
||||
await self.session.refresh(template)
|
||||
# get all attributes from database
|
||||
stmt = select(BarcodeTemplateAttribute).filter(
|
||||
BarcodeTemplateAttribute.id.in_(request.attribute_ids))
|
||||
@@ -55,12 +64,7 @@ class BarcodeService(BaseService):
|
||||
|
||||
# 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()
|
||||
template.attributes.append(attribute)
|
||||
await self.session.commit()
|
||||
return BarcodeTemplateCreateResponse(message='Шаблон успешно создан',
|
||||
ok=True,
|
||||
@@ -97,24 +101,22 @@ class BarcodeService(BaseService):
|
||||
)
|
||||
|
||||
# difference deleted and new
|
||||
template_attributes = set([attribute.attribute_id for attribute in template.attributes])
|
||||
template_attributes = set([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)
|
||||
new_attribute_ids = request_attributes.difference(template_attributes)
|
||||
deleted_attribute_ids = template_attributes.difference(request_attributes)
|
||||
|
||||
# delete attributes
|
||||
for attribute in template.attributes:
|
||||
if attribute.attribute_id not in deleted_attributes:
|
||||
if attribute.id not in deleted_attribute_ids:
|
||||
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)
|
||||
template.attributes.remove(attribute)
|
||||
for new_attribute_id in new_attribute_ids:
|
||||
stmt = insert(barcode_template_attribute_link).values({
|
||||
'barcode_template_id': template.id,
|
||||
'attribute_id': new_attribute_id
|
||||
})
|
||||
await self.session.execute(stmt)
|
||||
await self.session.flush()
|
||||
|
||||
await self.session.commit()
|
||||
@@ -125,6 +127,15 @@ class BarcodeService(BaseService):
|
||||
return BarcodeTemplateUpdateResponse(message=str(e),
|
||||
ok=False)
|
||||
|
||||
async def delete_template(self, request: BarcodeTemplateDeleteRequest) -> BarcodeTemplateDeleteResponse:
|
||||
try:
|
||||
template = await self.session.get(BarcodeTemplate, request.id)
|
||||
await self.session.delete(template)
|
||||
await self.session.commit()
|
||||
return BarcodeTemplateDeleteResponse(ok=True, message='Шаблон успешно удален')
|
||||
except Exception as e:
|
||||
return BarcodeTemplateDeleteResponse(ok=False, message=str(e))
|
||||
|
||||
# endregion
|
||||
|
||||
# region Template attributes
|
||||
|
||||
@@ -91,7 +91,17 @@ class ClientService(BaseService):
|
||||
client = await self.get_by_id(request.data.id)
|
||||
if not client:
|
||||
return ClientUpdateResponse(ok=False, message='Клиент не найден')
|
||||
await self.session.execute(update(Client).where(Client.id == client.id).values(name=request.data.name))
|
||||
request_dict = request.data.dict()
|
||||
del request_dict['id']
|
||||
del request_dict['details']
|
||||
del request_dict['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='Клиент обновлен')
|
||||
|
||||
@@ -21,7 +21,7 @@ class DealService(BaseService):
|
||||
async def _get_deal_by_id(self, deal_id) -> Union[Deal, None]:
|
||||
return await self.session.get(Deal, deal_id)
|
||||
|
||||
async def _get_rank_for_deal(self, deal_status: DealStatus) -> int:
|
||||
async def _get_rank_for_deal(self, deal_status: DealStatus) -> str:
|
||||
deal_query = await self.session.execute(
|
||||
select(Deal).where(Deal.current_status == deal_status).order_by(Deal.lexorank.desc()).limit(1))
|
||||
deal = deal_query.scalar_one_or_none()
|
||||
@@ -35,7 +35,7 @@ class DealService(BaseService):
|
||||
user: User,
|
||||
deadline: datetime.datetime = None,
|
||||
rank=None,
|
||||
comment: str = '') -> DealStatusHistory:
|
||||
comment: str = ''):
|
||||
if not deal.current_status == status:
|
||||
deadline = deadline
|
||||
status_change = DealStatusHistory(
|
||||
|
||||
Reference in New Issue
Block a user