50 lines
1.8 KiB
Python
50 lines
1.8 KiB
Python
from __future__ import annotations
|
|
|
|
from app import db
|
|
from app.lab.commands.write_audit import write_audit
|
|
from app.lab.db_guard import retry_locked
|
|
from app.lab.loaders.execution_loader import load_execution
|
|
from app.lab.models import LabRationLine, LabRecipeRation
|
|
from app.models import Component
|
|
from app.models.base import default_uuid
|
|
|
|
|
|
@retry_locked
|
|
def sync_from_execution(recipe_id: str, user_id: str = "system") -> dict:
|
|
"""Обновить мастер из execution (обратный перенос /recipes → lab)."""
|
|
execution = load_execution(recipe_id)
|
|
header = LabRecipeRation.query.filter_by(recipe_id=recipe_id, is_deleted=False).first()
|
|
if header is None:
|
|
header = LabRecipeRation(recipe_id=recipe_id, created_by=user_id, updated_by=user_id)
|
|
db.session.add(header)
|
|
else:
|
|
header.updated_by = user_id
|
|
|
|
existing = LabRationLine.query.filter_by(recipe_id=recipe_id, is_deleted=False).all()
|
|
for line in existing:
|
|
line.soft_delete(user_id)
|
|
|
|
created = 0
|
|
for idx, line in enumerate(execution.lines):
|
|
comp = Component.query.get(line.component_id) if line.component_id else None
|
|
db.session.add(
|
|
LabRationLine(
|
|
id=default_uuid(),
|
|
recipe_id=recipe_id,
|
|
component_id=line.component_id,
|
|
ingredient_name=line.name or (comp.name if comp else None),
|
|
row_index=idx,
|
|
daily_kg=line.daily_kg_total,
|
|
in_ration=True,
|
|
in_compound=False,
|
|
created_by=user_id,
|
|
updated_by=user_id,
|
|
)
|
|
)
|
|
created += 1
|
|
|
|
header.seed_source = "synced_from"
|
|
write_audit("SYNC_FROM_EXECUTION", "lab_recipe_ration", recipe_id, user_id)
|
|
db.session.commit()
|
|
return {"recipeId": recipe_id, "lines": created}
|