feat: modules, products, services, services kits

This commit is contained in:
2025-09-16 10:54:10 +04:00
parent be8052848c
commit 276626d6f7
55 changed files with 1791 additions and 34 deletions

View File

@ -1,7 +1,13 @@
from sqlalchemy.orm import configure_mappers
from modules.fulfillment_base.models import * # noqa: F401
from .base import BaseModel as BaseModel
from .board import Board as Board
from .built_in_module import ( # noqa: F401
BuiltInModule as BuiltInModule,
project_built_in_module as project_built_in_module,
built_in_module_dependencies as built_in_module_dependencies,
)
from .deal import Deal as Deal
from .project import Project as Project
from .status import Status as Status, CardStatusHistory as CardStatusHistory

58
models/built_in_module.py Normal file
View File

@ -0,0 +1,58 @@
from typing import TYPE_CHECKING, Optional
from sqlalchemy import Table, Column, ForeignKey
from sqlalchemy.orm import Mapped, mapped_column, relationship
from models.base import BaseModel
if TYPE_CHECKING:
from models import Project
project_built_in_module = Table(
"project_built_in_module",
BaseModel.metadata,
Column("project_id", ForeignKey("projects.id"), primary_key=True),
Column("module_id", ForeignKey("built_in_modules.id"), primary_key=True),
)
built_in_module_dependencies = Table(
"built_in_module_dependencies",
BaseModel.metadata,
Column("module_id", ForeignKey("built_in_modules.id"), primary_key=True),
Column("depends_on_id", ForeignKey("built_in_modules.id"), primary_key=True),
)
class BuiltInModule(BaseModel):
__tablename__ = "built_in_modules"
id: Mapped[int] = mapped_column(primary_key=True)
key: Mapped[str] = mapped_column(unique=True)
label: Mapped[str] = mapped_column()
description: Mapped[str] = mapped_column()
icon_name: Mapped[Optional[str]] = mapped_column(unique=True)
is_deleted: Mapped[bool] = mapped_column(default=False)
depends_on: Mapped[list["BuiltInModule"]] = relationship(
secondary=built_in_module_dependencies,
primaryjoin="BuiltInModule.id == built_in_module_dependencies.c.module_id",
secondaryjoin="BuiltInModule.id == built_in_module_dependencies.c.depends_on_id",
back_populates="depended_on_by",
lazy="immediate",
)
depended_on_by: Mapped[list["BuiltInModule"]] = relationship(
secondary="built_in_module_dependencies",
primaryjoin="BuiltInModule.id == built_in_module_dependencies.c.depends_on_id",
secondaryjoin="BuiltInModule.id == built_in_module_dependencies.c.module_id",
back_populates="depends_on",
lazy="noload",
)
projects: Mapped[list["Project"]] = relationship(
uselist=True,
secondary="project_built_in_module",
back_populates="built_in_modules",
lazy="noload",
)

View File

@ -1,6 +1,6 @@
from datetime import datetime, timezone
from sqlalchemy import DateTime
from sqlalchemy import DateTime, Numeric
from sqlalchemy.orm import Mapped, mapped_column
@ -21,3 +21,11 @@ class CreatedAtMixin:
default=lambda: datetime.now(timezone.utc),
nullable=False,
)
class PriceMixin:
price: Mapped[float] = mapped_column(Numeric(12, 2), comment="Стоимость")
class CostMixin:
cost: Mapped[float] = mapped_column(Numeric(12, 2), comment="Себестоимость")

View File

@ -6,7 +6,7 @@ from models.base import BaseModel
from models.mixins import SoftDeleteMixin, CreatedAtMixin, IdMixin
if TYPE_CHECKING:
from models import Board
from models import Board, BuiltInModule
class Project(BaseModel, IdMixin, SoftDeleteMixin, CreatedAtMixin):
@ -18,3 +18,10 @@ class Project(BaseModel, IdMixin, SoftDeleteMixin, CreatedAtMixin):
back_populates="project",
lazy="noload",
)
built_in_modules: Mapped[list["BuiltInModule"]] = relationship(
secondary="project_built_in_module",
back_populates="projects",
lazy="selectin",
order_by="asc(BuiltInModule.id)",
)