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 .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 models import Product
from .article_attribute_getter import ArticleAttributeGetter
from .client_name_attribute_getter import ClientNameAttributeGetter
from .name_attribute_getter import NameAttributeGetter
class BaseAttributeGetter(ABC):
@abstractmethod
def get_value(self, product: Product):
pass
class AttributeWriterFactory:
@staticmethod
def get_writer(key: str):
match key:
case 'name':
return NameAttributeGetter()
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):
__tablename__ = 'barcode_template_additional_fields'
id = Column(Integer, autoincrement=True, primary_key=True, index=True)
name = Column(String, nullable=False)
name = Column(String, nullable=False, primary_key=True, comment='Название поля')
value = Column(String, nullable=False)
barcode_template_id = Column(Integer, ForeignKey('barcode_templates.id'), nullable=False)
barcode_template = relationship('BarcodeTemplate', back_populates='additional_fields')
barcode_template_id = Column(Integer, ForeignKey('barcode_templates.id'), nullable=False, primary_key=True)
barcode_template = relationship('BarcodeTemplate')
class BarcodeTemplate(BaseModel):
@@ -27,14 +26,13 @@ class BarcodeTemplate(BaseModel):
name = Column(String, nullable=False, index=True, comment='Название шаблона')
attributes = relationship('BarcodeTemplateAttribute',
secondary=barcode_template_attribute_link,
# back_populates='barcode_template',
# cascade="all, delete-orphan",
cascade="all",
lazy='selectin'
)
additional_fields = relationship('BarcodeTemplateAdditionalField',
lazy='selectin',
back_populates='barcode_template',
lazy='selectin'
)
cascade="all")
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")
barcode_template_id = Column(Integer, ForeignKey('barcode_templates.id'), nullable=True)
barcode_template = relationship('BarcodeTemplate')
barcode_template = relationship('BarcodeTemplate', lazy='joined')
class ProductBarcode(BaseModel):

View File

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

View File

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

View File

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

View File

@@ -1,20 +1,52 @@
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 schemas.barcode import (GetBarcodeTemplateByIdRequest,
GetBarcodeTemplateByIdResponse,
BarcodeTemplateCreateResponse,
BarcodeTemplateCreateRequest, CreateBarcodeTemplateAttributeRequest,
BarcodeTemplateUpdateResponse, BarcodeTemplateUpdateRequest,
BarcodeTemplateAttributeSchema, GetAllBarcodeTemplateAttributesResponse,
GetAllBarcodeTemplatesResponse, BarcodeTemplateDeleteRequest,
BarcodeTemplateDeleteResponse)
from models import BarcodeTemplate, BarcodeTemplateAttribute, barcode_template_attribute_link, Product
from schemas.barcode import *
from services.base import 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
async def get_barcode_template_by_id(self,
request: GetBarcodeTemplateByIdRequest) -> GetBarcodeTemplateByIdResponse:

View File

@@ -26,6 +26,9 @@ class ProductService(BaseService):
# Creating product
product_dict = request.dict()
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)
self.session.add(product)
@@ -60,6 +63,10 @@ class ProductService(BaseService):
product_dict = request.product.dict()
del product_dict['id']
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(
update(Product)
.where(Product.id == request.product.id)