feat: barcode templates
This commit is contained in:
@ -1,6 +1,16 @@
|
|||||||
from .deal_product import DealProduct as DealProduct, DealProductService as DealProductService
|
from .barcode import (
|
||||||
from .deal_service import (
|
ProductBarcode as ProductBarcode,
|
||||||
DealService as DealService,
|
ProductBarcodeImage as ProductBarcodeImage,
|
||||||
)
|
)
|
||||||
|
from .barcode_template import (
|
||||||
|
BarcodeTemplateAttribute as BarcodeTemplateAttribute,
|
||||||
|
BarcodeTemplateSize as BarcodeTemplateSize,
|
||||||
|
BarcodeTemplate as BarcodeTemplate,
|
||||||
|
)
|
||||||
|
from .deal_product import (
|
||||||
|
DealProduct as DealProduct,
|
||||||
|
DealProductService as DealProductService,
|
||||||
|
)
|
||||||
|
from .deal_service import DealService as DealService
|
||||||
from .product import Product as Product
|
from .product import Product as Product
|
||||||
from .service import Service as Service, ServiceCategory as ServiceCategory
|
from .service import Service as Service, ServiceCategory as ServiceCategory
|
||||||
|
|||||||
36
modules/fulfillment_base/models/barcode.py
Normal file
36
modules/fulfillment_base/models/barcode.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from sqlalchemy import ForeignKey
|
||||||
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||||
|
|
||||||
|
from models.base import BaseModel
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from modules.fulfillment_base.models import Product
|
||||||
|
|
||||||
|
|
||||||
|
class ProductBarcode(BaseModel):
|
||||||
|
__tablename__ = "fulfillment_base_product_barcodes"
|
||||||
|
|
||||||
|
product_id: Mapped[int] = mapped_column(
|
||||||
|
ForeignKey("fulfillment_base_products.id"),
|
||||||
|
primary_key=True,
|
||||||
|
)
|
||||||
|
product: Mapped["Product"] = relationship(back_populates="barcodes")
|
||||||
|
|
||||||
|
barcode: Mapped[str] = mapped_column(
|
||||||
|
primary_key=True, index=True, comment="ШК товара"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ProductBarcodeImage(BaseModel):
|
||||||
|
__tablename__ = "fulfillment_base_product_barcode_images"
|
||||||
|
|
||||||
|
product_id: Mapped[int] = mapped_column(
|
||||||
|
ForeignKey("fulfillment_base_products.id"),
|
||||||
|
primary_key=True,
|
||||||
|
comment="ID товара",
|
||||||
|
)
|
||||||
|
product: Mapped["Product"] = relationship(back_populates="barcode_image")
|
||||||
|
|
||||||
|
filename: Mapped[str] = mapped_column()
|
||||||
42
modules/fulfillment_base/models/barcode_template.py
Normal file
42
modules/fulfillment_base/models/barcode_template.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
from sqlalchemy import ForeignKey, Table, Column
|
||||||
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||||
|
|
||||||
|
from models.base import BaseModel
|
||||||
|
from models.mixins import IdMixin, SoftDeleteMixin
|
||||||
|
|
||||||
|
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")),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class BarcodeTemplateAttribute(BaseModel, IdMixin):
|
||||||
|
__tablename__ = "barcode_template_attributes"
|
||||||
|
|
||||||
|
key: Mapped[str] = mapped_column(index=True, comment="Ключ атрибута")
|
||||||
|
name: Mapped[str] = mapped_column(index=True, comment="Метка атрибута")
|
||||||
|
|
||||||
|
|
||||||
|
class BarcodeTemplateSize(BaseModel, IdMixin):
|
||||||
|
__tablename__ = "barcode_template_sizes"
|
||||||
|
|
||||||
|
name: Mapped[str] = mapped_column(index=True, comment="Название размера")
|
||||||
|
width: Mapped[int] = mapped_column(comment="Ширина в мм")
|
||||||
|
height: Mapped[int] = mapped_column(comment="Высота в мм")
|
||||||
|
|
||||||
|
|
||||||
|
class BarcodeTemplate(BaseModel, IdMixin, SoftDeleteMixin):
|
||||||
|
__tablename__ = "barcode_templates"
|
||||||
|
|
||||||
|
name: Mapped[str] = mapped_column(index=True, comment="Название шаблона")
|
||||||
|
attributes: Mapped[list["BarcodeTemplateAttribute"]] = relationship(
|
||||||
|
secondary=barcode_template_attribute_link,
|
||||||
|
lazy="selectin",
|
||||||
|
)
|
||||||
|
|
||||||
|
is_default: Mapped[bool] = mapped_column(default=False, comment="По умолчанию")
|
||||||
|
|
||||||
|
size_id: Mapped[int] = mapped_column(ForeignKey("barcode_template_sizes.id"))
|
||||||
|
size: Mapped["BarcodeTemplateSize"] = relationship(lazy="joined")
|
||||||
@ -1,8 +1,15 @@
|
|||||||
|
from typing import Optional
|
||||||
|
|
||||||
from sqlalchemy import ForeignKey
|
from sqlalchemy import ForeignKey
|
||||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||||
|
|
||||||
from models.base import BaseModel
|
from models.base import BaseModel
|
||||||
from models.mixins import IdMixin, SoftDeleteMixin
|
from models.mixins import IdMixin, SoftDeleteMixin
|
||||||
|
from modules.fulfillment_base.models import (
|
||||||
|
ProductBarcode,
|
||||||
|
BarcodeTemplate,
|
||||||
|
ProductBarcodeImage,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Product(BaseModel, IdMixin, SoftDeleteMixin):
|
class Product(BaseModel, IdMixin, SoftDeleteMixin):
|
||||||
@ -28,6 +35,22 @@ class Product(BaseModel, IdMixin, SoftDeleteMixin):
|
|||||||
cascade="all, delete-orphan",
|
cascade="all, delete-orphan",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
barcodes: Mapped[list["ProductBarcode"]] = relationship(
|
||||||
|
back_populates="product",
|
||||||
|
cascade="all, delete-orphan",
|
||||||
|
)
|
||||||
|
|
||||||
|
barcode_template_id: Mapped[Optional[int]] = mapped_column(
|
||||||
|
ForeignKey("barcode_templates.id")
|
||||||
|
)
|
||||||
|
barcode_template: Mapped["BarcodeTemplate"] = relationship(lazy="joined")
|
||||||
|
|
||||||
|
barcode_image: Mapped["ProductBarcodeImage"] = relationship(
|
||||||
|
back_populates="product",
|
||||||
|
lazy="joined",
|
||||||
|
uselist=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ProductImage(BaseModel, IdMixin):
|
class ProductImage(BaseModel, IdMixin):
|
||||||
__tablename__ = "fulfillment_base_product_images"
|
__tablename__ = "fulfillment_base_product_images"
|
||||||
|
|||||||
@ -5,3 +5,4 @@ from .product import ProductRepository as ProductRepository
|
|||||||
from .service import ServiceRepository as ServiceRepository
|
from .service import ServiceRepository as ServiceRepository
|
||||||
from .services_kit import ServicesKitRepository as ServicesKitRepository
|
from .services_kit import ServicesKitRepository as ServicesKitRepository
|
||||||
from .service_category import ServiceCategoryRepository as ServiceCategoryRepository
|
from .service_category import ServiceCategoryRepository as ServiceCategoryRepository
|
||||||
|
from .barcode_template import BarcodeTemplateRepository as BarcodeTemplateRepository
|
||||||
|
|||||||
113
modules/fulfillment_base/repositories/barcode_template.py
Normal file
113
modules/fulfillment_base/repositories/barcode_template.py
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
from sqlalchemy import update
|
||||||
|
from sqlalchemy.orm import joinedload, selectinload
|
||||||
|
|
||||||
|
from modules.fulfillment_base.models import (
|
||||||
|
BarcodeTemplate,
|
||||||
|
BarcodeTemplateAttribute,
|
||||||
|
BarcodeTemplateSize,
|
||||||
|
)
|
||||||
|
from modules.fulfillment_base.schemas.barcode_template import (
|
||||||
|
CreateBarcodeTemplateSchema,
|
||||||
|
UpdateBarcodeTemplateSchema,
|
||||||
|
)
|
||||||
|
from repositories.mixins import *
|
||||||
|
|
||||||
|
|
||||||
|
class BarcodeTemplateRepository(
|
||||||
|
RepCrudMixin[
|
||||||
|
BarcodeTemplate, CreateBarcodeTemplateSchema, UpdateBarcodeTemplateSchema
|
||||||
|
],
|
||||||
|
):
|
||||||
|
session: AsyncSession
|
||||||
|
entity_class = BarcodeTemplate
|
||||||
|
entity_not_found_msg = "Шаблон штрихкода не найден"
|
||||||
|
|
||||||
|
def _process_get_all_stmt(self, stmt: Select) -> Select:
|
||||||
|
return (
|
||||||
|
stmt.options(
|
||||||
|
selectinload(BarcodeTemplate.attributes),
|
||||||
|
joinedload(BarcodeTemplate.size),
|
||||||
|
)
|
||||||
|
.where(BarcodeTemplate.is_deleted.is_(False))
|
||||||
|
.order_by(BarcodeTemplate.id)
|
||||||
|
)
|
||||||
|
|
||||||
|
async def _get_size_by_id(self, size_id: int) -> Optional[BarcodeTemplateSize]:
|
||||||
|
stmt = select(BarcodeTemplateSize).where(BarcodeTemplateSize.id == size_id)
|
||||||
|
result = await self.session.scalars(stmt)
|
||||||
|
return result.one_or_none()
|
||||||
|
|
||||||
|
async def _get_attrs_by_ids(
|
||||||
|
self, attrs_ids: list[int]
|
||||||
|
) -> list[BarcodeTemplateAttribute]:
|
||||||
|
stmt = select(BarcodeTemplateAttribute).where(
|
||||||
|
BarcodeTemplateAttribute.id.in_(attrs_ids)
|
||||||
|
)
|
||||||
|
result = await self.session.execute(stmt)
|
||||||
|
return list(result.scalars().all())
|
||||||
|
|
||||||
|
async def create(self, data: CreateBarcodeTemplateSchema) -> int:
|
||||||
|
if data.is_default is not None and data.is_default:
|
||||||
|
await self._turn_off_defaults()
|
||||||
|
|
||||||
|
data_dict = data.model_dump()
|
||||||
|
data_dict["size"] = await self._get_size_by_id(data.size.id)
|
||||||
|
data_dict["attributes"] = await self._get_attrs_by_ids(
|
||||||
|
[a.id for a in data.attributes]
|
||||||
|
)
|
||||||
|
|
||||||
|
obj = BarcodeTemplate(**data_dict)
|
||||||
|
self.session.add(obj)
|
||||||
|
await self.session.commit()
|
||||||
|
await self.session.refresh(obj)
|
||||||
|
return obj.id
|
||||||
|
|
||||||
|
async def _turn_off_defaults(self):
|
||||||
|
stmt = (
|
||||||
|
update(BarcodeTemplate)
|
||||||
|
.where(BarcodeTemplate.is_default.is_(True))
|
||||||
|
.values({"is_default": False})
|
||||||
|
)
|
||||||
|
await self.session.execute(stmt)
|
||||||
|
|
||||||
|
async def _set_first_as_default(self, with_commit: bool = False):
|
||||||
|
stmt = select(BarcodeTemplate).limit(1)
|
||||||
|
result = await self.session.execute(stmt)
|
||||||
|
obj = result.scalar()
|
||||||
|
if not obj:
|
||||||
|
return
|
||||||
|
obj.is_default = True
|
||||||
|
self.session.add(obj)
|
||||||
|
if with_commit:
|
||||||
|
await self.session.commit()
|
||||||
|
await self.session.refresh(obj)
|
||||||
|
|
||||||
|
async def update(
|
||||||
|
self, template: BarcodeTemplate, data: UpdateBarcodeTemplateSchema
|
||||||
|
) -> BarcodeTemplate:
|
||||||
|
if data.size is not None:
|
||||||
|
data.size = await self._get_size_by_id(data.size.id)
|
||||||
|
if data.attributes is not None:
|
||||||
|
data.attributes = await self._get_attrs_by_ids(
|
||||||
|
[a.id for a in data.attributes]
|
||||||
|
)
|
||||||
|
if data.is_default is not None:
|
||||||
|
if data.is_default:
|
||||||
|
await self._turn_off_defaults()
|
||||||
|
else:
|
||||||
|
await self._set_first_as_default()
|
||||||
|
return await self._apply_update_data_to_model(template, data, True)
|
||||||
|
|
||||||
|
async def _before_delete(self, template: BarcodeTemplate):
|
||||||
|
if template.is_default:
|
||||||
|
await self._set_first_as_default()
|
||||||
|
|
||||||
|
async def get_attributes(self) -> list[BarcodeTemplateAttribute]:
|
||||||
|
stmt = select(BarcodeTemplateAttribute)
|
||||||
|
result = await self.session.execute(stmt)
|
||||||
|
return list(result.scalars().all())
|
||||||
|
|
||||||
|
async def get_sizes(self) -> list[BarcodeTemplateSize]:
|
||||||
|
stmt = select(BarcodeTemplateSize)
|
||||||
|
result = await self.session.execute(stmt)
|
||||||
|
return list(result.scalars().all())
|
||||||
77
modules/fulfillment_base/routers/barcode_template.py
Normal file
77
modules/fulfillment_base/routers/barcode_template.py
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
from fastapi import APIRouter, Path
|
||||||
|
|
||||||
|
from backend.dependecies import SessionDependency
|
||||||
|
from modules.fulfillment_base.schemas.barcode_template import *
|
||||||
|
from modules.fulfillment_base.services import BarcodeTemplateService
|
||||||
|
|
||||||
|
router = APIRouter(tags=["barcode_template"])
|
||||||
|
|
||||||
|
|
||||||
|
@router.get(
|
||||||
|
"/",
|
||||||
|
response_model=GetBarcodeTemplatesResponse,
|
||||||
|
operation_id="get_barcode_templates",
|
||||||
|
)
|
||||||
|
async def get_barcode_templates(
|
||||||
|
session: SessionDependency,
|
||||||
|
):
|
||||||
|
return await BarcodeTemplateService(session).get_all()
|
||||||
|
|
||||||
|
|
||||||
|
@router.post(
|
||||||
|
"/",
|
||||||
|
response_model=CreateBarcodeTemplateResponse,
|
||||||
|
operation_id="create_barcode_template",
|
||||||
|
)
|
||||||
|
async def create_barcode_template(
|
||||||
|
session: SessionDependency,
|
||||||
|
request: CreateBarcodeTemplateRequest,
|
||||||
|
):
|
||||||
|
return await BarcodeTemplateService(session).create(request)
|
||||||
|
|
||||||
|
|
||||||
|
@router.patch(
|
||||||
|
"/{pk}",
|
||||||
|
response_model=UpdateBarcodeTemplateResponse,
|
||||||
|
operation_id="update_barcode_template",
|
||||||
|
)
|
||||||
|
async def update_barcode_template(
|
||||||
|
session: SessionDependency,
|
||||||
|
request: UpdateBarcodeTemplateRequest,
|
||||||
|
pk: int = Path(),
|
||||||
|
):
|
||||||
|
return await BarcodeTemplateService(session).update(pk, request)
|
||||||
|
|
||||||
|
|
||||||
|
@router.delete(
|
||||||
|
"/{pk}",
|
||||||
|
response_model=DeleteBarcodeTemplateResponse,
|
||||||
|
operation_id="delete_barcode_template",
|
||||||
|
)
|
||||||
|
async def delete_barcode_template(
|
||||||
|
session: SessionDependency,
|
||||||
|
pk: int = Path(),
|
||||||
|
):
|
||||||
|
return await BarcodeTemplateService(session).delete(pk)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get(
|
||||||
|
"/attributes",
|
||||||
|
response_model=GetBarcodeAttributesResponse,
|
||||||
|
operation_id="get_barcode_template_attributes",
|
||||||
|
)
|
||||||
|
async def get_barcode_template_attributes(
|
||||||
|
session: SessionDependency,
|
||||||
|
):
|
||||||
|
return await BarcodeTemplateService(session).get_attributes()
|
||||||
|
|
||||||
|
|
||||||
|
@router.get(
|
||||||
|
"/sizes",
|
||||||
|
response_model=GetBarcodeTemplateSizesResponse,
|
||||||
|
operation_id="get_barcode_template_sizes",
|
||||||
|
)
|
||||||
|
async def get_barcode_template_sizes(
|
||||||
|
session: SessionDependency,
|
||||||
|
):
|
||||||
|
return await BarcodeTemplateService(session).get_sizes()
|
||||||
82
modules/fulfillment_base/schemas/barcode_template.py
Normal file
82
modules/fulfillment_base/schemas/barcode_template.py
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from schemas.base import BaseSchema, BaseResponse
|
||||||
|
|
||||||
|
|
||||||
|
# region Entity
|
||||||
|
|
||||||
|
|
||||||
|
class BarcodeTemplateAttributeSchema(BaseSchema):
|
||||||
|
id: int
|
||||||
|
key: str
|
||||||
|
name: str
|
||||||
|
|
||||||
|
|
||||||
|
class BarcodeTemplateSizeSchema(BaseSchema):
|
||||||
|
id: int
|
||||||
|
name: str
|
||||||
|
width: int
|
||||||
|
height: int
|
||||||
|
|
||||||
|
|
||||||
|
class CreateBarcodeTemplateSchema(BaseSchema):
|
||||||
|
name: str
|
||||||
|
attributes: list[BarcodeTemplateAttributeSchema]
|
||||||
|
is_default: bool
|
||||||
|
size: BarcodeTemplateSizeSchema
|
||||||
|
|
||||||
|
|
||||||
|
class BarcodeTemplateSchema(CreateBarcodeTemplateSchema):
|
||||||
|
id: int
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateBarcodeTemplateSchema(BaseSchema):
|
||||||
|
name: Optional[str] = None
|
||||||
|
attributes: Optional[list[BarcodeTemplateAttributeSchema]] = None
|
||||||
|
is_default: Optional[bool] = None
|
||||||
|
size: Optional[BarcodeTemplateSizeSchema] = None
|
||||||
|
|
||||||
|
|
||||||
|
# endregion
|
||||||
|
|
||||||
|
# region Request
|
||||||
|
|
||||||
|
|
||||||
|
class CreateBarcodeTemplateRequest(BaseSchema):
|
||||||
|
entity: CreateBarcodeTemplateSchema
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateBarcodeTemplateRequest(BaseSchema):
|
||||||
|
entity: UpdateBarcodeTemplateSchema
|
||||||
|
|
||||||
|
|
||||||
|
# endregion
|
||||||
|
|
||||||
|
# region Response
|
||||||
|
|
||||||
|
|
||||||
|
class GetBarcodeTemplatesResponse(BaseSchema):
|
||||||
|
items: list[BarcodeTemplateSchema]
|
||||||
|
|
||||||
|
|
||||||
|
class CreateBarcodeTemplateResponse(BaseResponse):
|
||||||
|
entity: BarcodeTemplateSchema
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateBarcodeTemplateResponse(BaseResponse):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteBarcodeTemplateResponse(BaseResponse):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class GetBarcodeAttributesResponse(BaseSchema):
|
||||||
|
items: list[BarcodeTemplateAttributeSchema]
|
||||||
|
|
||||||
|
|
||||||
|
class GetBarcodeTemplateSizesResponse(BaseSchema):
|
||||||
|
items: list[BarcodeTemplateSizeSchema]
|
||||||
|
|
||||||
|
|
||||||
|
# endregion
|
||||||
@ -5,3 +5,4 @@ from .product_service import ProductServiceService as ProductServiceService
|
|||||||
from .service import ServiceModelService as ServiceModelService
|
from .service import ServiceModelService as ServiceModelService
|
||||||
from .services_kit import ServicesKitService as ServicesKitService
|
from .services_kit import ServicesKitService as ServicesKitService
|
||||||
from .service_category import ServiceCategoryService as ServiceCategoryService
|
from .service_category import ServiceCategoryService as ServiceCategoryService
|
||||||
|
from .barcode_template import BarcodeTemplateService as BarcodeTemplateService
|
||||||
|
|||||||
39
modules/fulfillment_base/services/barcode_template.py
Normal file
39
modules/fulfillment_base/services/barcode_template.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
from modules.fulfillment_base.models import BarcodeTemplate
|
||||||
|
from modules.fulfillment_base.repositories import BarcodeTemplateRepository
|
||||||
|
from modules.fulfillment_base.schemas.barcode_template import *
|
||||||
|
from services.mixins import *
|
||||||
|
|
||||||
|
|
||||||
|
class BarcodeTemplateService(
|
||||||
|
ServiceCrudMixin[
|
||||||
|
BarcodeTemplate,
|
||||||
|
BarcodeTemplateSchema,
|
||||||
|
CreateBarcodeTemplateRequest,
|
||||||
|
UpdateBarcodeTemplateRequest,
|
||||||
|
]
|
||||||
|
):
|
||||||
|
schema_class = BarcodeTemplateSchema
|
||||||
|
entity_deleted_msg = "Шаблон штрихкода успешно удален"
|
||||||
|
entity_updated_msg = "Шаблон штрихкода успешно обновлен"
|
||||||
|
entity_created_msg = "Шаблон штрихкода успешно создан"
|
||||||
|
|
||||||
|
def __init__(self, session: AsyncSession):
|
||||||
|
self.repository = BarcodeTemplateRepository(session)
|
||||||
|
|
||||||
|
async def is_soft_delete(self, template: BarcodeTemplate) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
|
async def get_attributes(self) -> GetBarcodeAttributesResponse:
|
||||||
|
attributes = await self.repository.get_attributes()
|
||||||
|
return GetBarcodeAttributesResponse(
|
||||||
|
items=[
|
||||||
|
BarcodeTemplateAttributeSchema.model_validate(attr)
|
||||||
|
for attr in attributes
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
async def get_sizes(self) -> GetBarcodeTemplateSizesResponse:
|
||||||
|
sizes = await self.repository.get_sizes()
|
||||||
|
return GetBarcodeTemplateSizesResponse(
|
||||||
|
items=[BarcodeTemplateSizeSchema.model_validate(size) for size in sizes]
|
||||||
|
)
|
||||||
@ -17,7 +17,12 @@ class RepBaseMixin(Generic[EntityType]):
|
|||||||
|
|
||||||
|
|
||||||
class RepDeleteMixin(Generic[EntityType], RepBaseMixin[EntityType]):
|
class RepDeleteMixin(Generic[EntityType], RepBaseMixin[EntityType]):
|
||||||
|
async def _before_delete(self, obj: EntityType) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
async def delete(self, obj: EntityType, is_soft: bool) -> None:
|
async def delete(self, obj: EntityType, is_soft: bool) -> None:
|
||||||
|
await self._before_delete(obj)
|
||||||
|
|
||||||
if not is_soft:
|
if not is_soft:
|
||||||
await self.session.delete(obj)
|
await self.session.delete(obj)
|
||||||
await self.session.commit()
|
await self.session.commit()
|
||||||
|
|||||||
Reference in New Issue
Block a user