feat: temp barcode templates
This commit is contained in:
@@ -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()
|
||||||
|
|||||||
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):
|
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='По умолчанию')
|
||||||
|
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user