73 lines
3.1 KiB
Python
73 lines
3.1 KiB
Python
from sqlalchemy import Boolean, Column, DateTime, Float, ForeignKey, Integer, String
|
|
from sqlalchemy.orm import relationship
|
|
|
|
from app import db
|
|
from .base import SoftDeleteMixin, TimestampMixin, default_uuid
|
|
|
|
|
|
class Component(db.Model, TimestampMixin, SoftDeleteMixin):
|
|
"""Кормовой компонент (ингредиент как сущность склада/рецептов)."""
|
|
|
|
__tablename__ = "component"
|
|
|
|
id = Column(String(36), primary_key=True, default=default_uuid)
|
|
name = Column(String(100), nullable=False)
|
|
type = Column(String(100), nullable=False, default="")
|
|
is_active = Column(Boolean, default=True)
|
|
dry_matter = Column(Float, nullable=False, default=0.0)
|
|
protein = Column(Float, nullable=False, default=0.0)
|
|
energy = Column(Float, nullable=False, default=0.0)
|
|
price = Column(Float, nullable=False, default=0.0)
|
|
external_no = Column(Integer, nullable=True, index=True)
|
|
|
|
# Версионирование и аудит (минимальный набор для синхронизации)
|
|
version = Column(Integer, default=1, nullable=False)
|
|
created_by = Column(String(50), nullable=False, default="system")
|
|
updated_by = Column(String(50), nullable=False, default="system")
|
|
sync_timestamp = Column(DateTime, nullable=True)
|
|
sync_status = Column(String(20), default="pending", nullable=False)
|
|
content_hash = Column(String(64), nullable=False, default="")
|
|
|
|
# Связи
|
|
ingredients = relationship(
|
|
"Ingredient",
|
|
back_populates="component",
|
|
cascade="all, delete-orphan",
|
|
passive_deletes=True,
|
|
)
|
|
|
|
|
|
class Ingredient(db.Model, TimestampMixin, SoftDeleteMixin):
|
|
"""Строка рецепта (ингредиент в составе рецепта)."""
|
|
|
|
__tablename__ = "ingredient"
|
|
|
|
id = Column(String(36), primary_key=True, default=default_uuid)
|
|
name = Column(String(100), nullable=False)
|
|
amount = Column(Float, nullable=False)
|
|
# Новое поле в легаси: вес на голову
|
|
weight_per_head = Column(Float, nullable=True)
|
|
# Процент сухого вещества
|
|
dry_matter = Column(Float, nullable=False, default=0.0)
|
|
# СВ на голову (кг) - константа для режима "замок СВ"
|
|
dry_matter_per_head = Column(Float, nullable=True)
|
|
# Порядок ингредиента в рецепте
|
|
order = Column(Integer, nullable=False, default=0)
|
|
|
|
recipe_id = Column(String(36), ForeignKey("recipe.id"), nullable=False, index=True)
|
|
component_id = Column(
|
|
String(36), ForeignKey("component.id"), nullable=True, index=True
|
|
)
|
|
|
|
version = Column(Integer, default=1, nullable=False)
|
|
created_by = Column(String(50), nullable=False, default="system")
|
|
updated_by = Column(String(50), nullable=False, default="system")
|
|
sync_timestamp = Column(DateTime, nullable=True)
|
|
sync_status = Column(String(20), default="pending", nullable=False)
|
|
content_hash = Column(String(64), nullable=False, default="")
|
|
|
|
# Связи
|
|
recipe = relationship("Recipe", back_populates="ingredients")
|
|
component = relationship("Component", back_populates="ingredients")
|
|
|