feat: temp barcode templates
This commit is contained in:
@@ -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()
|
||||
|
||||
7
barcodes/attributes/article_attribute_getter.py
Normal file
7
barcodes/attributes/article_attribute_getter.py
Normal 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
|
||||
@@ -1,7 +0,0 @@
|
||||
# from barcodes.attributes import BaseAttributeWriter
|
||||
# from barcodes.barcode import Barcode
|
||||
#
|
||||
#
|
||||
# class ArticleAttributeWriter(BaseAttributeWriter):
|
||||
# def write(self, barcode: Barcode):
|
||||
# pass
|
||||
8
barcodes/attributes/client_name_attribute_getter.py
Normal file
8
barcodes/attributes/client_name_attribute_getter.py
Normal 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
|
||||
7
barcodes/attributes/name_attribute_getter.py
Normal file
7
barcodes/attributes/name_attribute_getter.py
Normal 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
|
||||
@@ -1,7 +0,0 @@
|
||||
# from barcodes.attributes import BaseAttributeWriter
|
||||
# from barcodes.barcode import Barcode
|
||||
#
|
||||
#
|
||||
# class NameAttributeWriter(BaseAttributeWriter):
|
||||
# def write(self, barcode: Barcode):
|
||||
# pass
|
||||
@@ -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)
|
||||
#
|
||||
@@ -1,6 +0,0 @@
|
||||
# from models import ProductBarcode
|
||||
#
|
||||
#
|
||||
# class BarcodeGenerator:
|
||||
# def __init__(self, barcode: ProductBarcode):
|
||||
# self.barcode = barcode
|
||||
@@ -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='По умолчанию')
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user