feat: temp barcode templates

This commit is contained in:
2024-05-09 03:33:44 +03:00
parent 61d27d2389
commit 87085379ed
15 changed files with 136 additions and 81 deletions

View File

@@ -1,21 +1,24 @@
# from abc import abstractmethod, ABC from abc import abstractmethod, ABC
#
# from .article_attribute_writer import ArticleAttributeWriter from models import Product
# from .name_attribute_writer import NameAttributeWriter from .article_attribute_getter import ArticleAttributeGetter
# from ..barcode import Barcode from .client_name_attribute_getter import ClientNameAttributeGetter
# from .name_attribute_getter import NameAttributeGetter
#
# class BaseAttributeWriter(ABC):
# @abstractmethod class BaseAttributeGetter(ABC):
# def write(self, barcode: Barcode): @abstractmethod
# pass def get_value(self, product: Product):
# pass
#
# class AttributeWriterFactory:
# @staticmethod class AttributeWriterFactory:
# def get_writer(key: str): @staticmethod
# match key: def get_writer(key: str):
# case 'name': match key:
# return NameAttributeWriter() case 'name':
# case 'article': return NameAttributeGetter()
# return ArticleAttributeWriter() case 'article':
return ArticleAttributeGetter()
case 'client.name':
return ClientNameAttributeGetter()

View File

@@ -0,0 +1,7 @@
from barcodes.attributes import BaseAttributeGetter
from models import Product
class ArticleAttributeGetter(BaseAttributeGetter):
def get_value(self, product: Product):
return product.article

View File

@@ -1,7 +0,0 @@
# from barcodes.attributes import BaseAttributeWriter
# from barcodes.barcode import Barcode
#
#
# class ArticleAttributeWriter(BaseAttributeWriter):
# def write(self, barcode: Barcode):
# pass

View File

@@ -0,0 +1,8 @@
from barcodes.attributes import BaseAttributeGetter
from models import Product, Client
class ClientNameAttributeGetter(BaseAttributeGetter):
def get_value(self, product: Product):
client: Client = product.client
return client.name

View File

@@ -0,0 +1,7 @@
from barcodes.attributes import BaseAttributeGetter
from models import Product
class NameAttributeGetter(BaseAttributeGetter):
def get_value(self, product: Product):
return product.name

View File

@@ -1,7 +0,0 @@
# from barcodes.attributes import BaseAttributeWriter
# from barcodes.barcode import Barcode
#
#
# class NameAttributeWriter(BaseAttributeWriter):
# def write(self, barcode: Barcode):
# pass

View File

@@ -1,15 +0,0 @@
# 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)
#

View File

@@ -1,6 +0,0 @@
# from models import ProductBarcode
#
#
# class BarcodeGenerator:
# def __init__(self, barcode: ProductBarcode):
# self.barcode = barcode

View File

@@ -13,12 +13,11 @@ class BarcodeTemplateAttribute(BaseModel):
class BarcodeTemplateAdditionalField(BaseModel): class BarcodeTemplateAdditionalField(BaseModel):
__tablename__ = 'barcode_template_additional_fields' __tablename__ = 'barcode_template_additional_fields'
id = Column(Integer, autoincrement=True, primary_key=True, index=True) name = Column(String, nullable=False, primary_key=True, comment='Название поля')
name = Column(String, nullable=False)
value = Column(String, nullable=False) value = Column(String, nullable=False)
barcode_template_id = Column(Integer, ForeignKey('barcode_templates.id'), nullable=False) barcode_template_id = Column(Integer, ForeignKey('barcode_templates.id'), nullable=False, primary_key=True)
barcode_template = relationship('BarcodeTemplate', back_populates='additional_fields') barcode_template = relationship('BarcodeTemplate')
class BarcodeTemplate(BaseModel): class BarcodeTemplate(BaseModel):
@@ -27,14 +26,13 @@ class BarcodeTemplate(BaseModel):
name = Column(String, nullable=False, index=True, comment='Название шаблона') name = Column(String, nullable=False, index=True, comment='Название шаблона')
attributes = relationship('BarcodeTemplateAttribute', attributes = relationship('BarcodeTemplateAttribute',
secondary=barcode_template_attribute_link, secondary=barcode_template_attribute_link,
# back_populates='barcode_template', cascade="all",
# cascade="all, delete-orphan",
lazy='selectin' lazy='selectin'
) )
additional_fields = relationship('BarcodeTemplateAdditionalField', additional_fields = relationship('BarcodeTemplateAdditionalField',
lazy='selectin',
back_populates='barcode_template', back_populates='barcode_template',
lazy='selectin' cascade="all")
)
is_default = Column(Boolean, nullable=False, default=False, comment='По умолчанию') is_default = Column(Boolean, nullable=False, default=False, comment='По умолчанию')

View File

@@ -15,7 +15,7 @@ class Product(BaseModel):
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_id = Column(Integer, ForeignKey('barcode_templates.id'), nullable=True)
barcode_template = relationship('BarcodeTemplate') barcode_template = relationship('BarcodeTemplate', lazy='joined')
class ProductBarcode(BaseModel): class ProductBarcode(BaseModel):

View File

@@ -1,3 +1,5 @@
from typing import List
from schemas.base import CustomModelCamel, OkMessageSchema from schemas.base import CustomModelCamel, OkMessageSchema
@@ -8,11 +10,17 @@ class BarcodeTemplateAttributeSchema(CustomModelCamel):
name: str name: str
class BarcodeTemplateAdditionalAttributeSchema(CustomModelCamel):
name: str
value: str
class BaseBarcodeTemplateSchema(CustomModelCamel): class BaseBarcodeTemplateSchema(CustomModelCamel):
name: str name: str
is_default: bool is_default: bool
width: int width: int
height: int height: int
additional_attributes: list[BarcodeTemplateAdditionalAttributeSchema]
class BarcodeTemplateSchema(BaseBarcodeTemplateSchema): class BarcodeTemplateSchema(BaseBarcodeTemplateSchema):
@@ -20,6 +28,16 @@ class BarcodeTemplateSchema(BaseBarcodeTemplateSchema):
attributes: list[BarcodeTemplateAttributeSchema] attributes: list[BarcodeTemplateAttributeSchema]
class BarcodeAttributeSchema(CustomModelCamel):
name: str
value: str
class BarcodeSchema(CustomModelCamel):
barcode: str
attributes: List[BarcodeAttributeSchema]
# endregion # endregion
# region Requests # region Requests
@@ -44,6 +62,12 @@ class BarcodeTemplateDeleteRequest(CustomModelCamel):
id: int id: int
class GetProductBarcodeRequest(CustomModelCamel):
product_id: int
barcode: str
barcode_template_id: int | None = None
# endregion # endregion
# region Responses # region Responses
@@ -74,4 +98,8 @@ class GetAllBarcodeTemplateAttributesResponse(CustomModelCamel):
class BarcodeTemplateDeleteResponse(OkMessageSchema): class BarcodeTemplateDeleteResponse(OkMessageSchema):
pass pass
class GetProductBarcodeResponse(CustomModelCamel):
barcode: BarcodeSchema
# endregion # endregion

View File

@@ -1,6 +1,6 @@
from typing import List from typing import List
from pydantic import validator, field_validator from pydantic import field_validator
from schemas.barcode import BarcodeTemplateSchema from schemas.barcode import BarcodeTemplateSchema
from schemas.base import CustomModelCamel, OkMessageSchema from schemas.base import CustomModelCamel, OkMessageSchema

View File

@@ -1,9 +1,8 @@
from typing import List from typing import List
from schemas.barcode import BarcodeTemplateSchema
from pydantic import validator, field_validator
from models import ProductBarcode
from schemas.base import CustomModelCamel, PaginationInfoSchema, OkMessageSchema from schemas.base import CustomModelCamel, PaginationInfoSchema, OkMessageSchema
from pydantic import field_validator
from models import ProductBarcode
# region Entities # region Entities
@@ -14,6 +13,7 @@ class ProductSchema(CustomModelCamel):
article: str article: str
client_id: int client_id: int
barcodes: list[str] barcodes: list[str]
barcode_template: BarcodeTemplateSchema | None = None
@field_validator('barcodes', mode="before") @field_validator('barcodes', mode="before")
def barcodes_to_list(cls, v): def barcodes_to_list(cls, v):
@@ -30,7 +30,7 @@ class ProductCreateRequest(CustomModelCamel):
article: str article: str
client_id: int client_id: int
barcodes: List[str] barcodes: List[str]
barcode_template: BarcodeTemplateSchema | None = None
class ProductDeleteRequest(CustomModelCamel): class ProductDeleteRequest(CustomModelCamel):
product_id: int product_id: int

View File

@@ -1,20 +1,52 @@
from sqlalchemy import select, update, insert from sqlalchemy import select, update, insert
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload, joinedload
from models import BarcodeTemplate, BarcodeTemplateAttribute, barcode_template_attribute_link from models import BarcodeTemplate, BarcodeTemplateAttribute, barcode_template_attribute_link, Product
from schemas.barcode import (GetBarcodeTemplateByIdRequest, from schemas.barcode import *
GetBarcodeTemplateByIdResponse,
BarcodeTemplateCreateResponse,
BarcodeTemplateCreateRequest, CreateBarcodeTemplateAttributeRequest,
BarcodeTemplateUpdateResponse, BarcodeTemplateUpdateRequest,
BarcodeTemplateAttributeSchema, GetAllBarcodeTemplateAttributesResponse,
GetAllBarcodeTemplatesResponse, BarcodeTemplateDeleteRequest,
BarcodeTemplateDeleteResponse)
from services.base import BaseService from services.base import BaseService
class BarcodeService(BaseService): class BarcodeService(BaseService):
# region Barcode
async def get_barcode(self, request: GetProductBarcodeRequest) -> GetProductBarcodeResponse:
# get product by id
stmt = (
select(Product)
.options(
joinedload(Product.client)
)
.filter(Product.id == request.product_id)
)
query = await self.session.execute(stmt)
product: Product = query.scalar()
if not product:
raise ValueError('Товар не найден')
# get barcode template by id
if request.barcode_template_id:
stmt = select(BarcodeTemplate).filter(BarcodeTemplate.id == request.barcode_template_id)
query = await self.session.execute(stmt)
barcode_template = query.scalar()
if not barcode_template:
raise ValueError('Шаблон не найден')
elif product.barcode_template:
barcode_template = product.barcode_template
elif product.client.barcode_template:
barcode_template = product.client.barcode_template
else:
stmt = select(BarcodeTemplate).filter(BarcodeTemplate.is_default == True)
query = await self.session.execute(stmt)
barcode_template = query.scalar()
if not barcode_template:
raise ValueError('Стандартный шаблон не найден')
barcode_template: BarcodeTemplate
# endregion
# endregion
# region Template # region Template
async def get_barcode_template_by_id(self, async def get_barcode_template_by_id(self,
request: GetBarcodeTemplateByIdRequest) -> GetBarcodeTemplateByIdResponse: request: GetBarcodeTemplateByIdRequest) -> GetBarcodeTemplateByIdResponse:

View File

@@ -26,6 +26,9 @@ class ProductService(BaseService):
# Creating product # Creating product
product_dict = request.dict() product_dict = request.dict()
del product_dict['barcodes'] del product_dict['barcodes']
del product_dict['barcode_template']
if request.barcode_template:
product_dict['barcode_template_id'] = request.barcode_template.id
product = Product(**product_dict) product = Product(**product_dict)
self.session.add(product) self.session.add(product)
@@ -60,6 +63,10 @@ class ProductService(BaseService):
product_dict = request.product.dict() product_dict = request.product.dict()
del product_dict['id'] del product_dict['id']
del product_dict['barcodes'] del product_dict['barcodes']
del product_dict['barcode_template']
if request.product.barcode_template:
product_dict['barcode_template_id'] = request.product.barcode_template.id
await self.session.execute( await self.session.execute(
update(Product) update(Product)
.where(Product.id == request.product.id) .where(Product.id == request.product.id)