@@ -0,0 +1,65 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from app import db
|
||||
from app.lab.db_guard import retry_locked
|
||||
from app.lab.models import LabRationLine, LabRecipeRation
|
||||
from app.models import Recipe
|
||||
from app.models.base import default_uuid
|
||||
|
||||
|
||||
@retry_locked
|
||||
def upsert_ration(recipe_id: str, payload: dict[str, Any], user_id: str = "system") -> dict[str, Any]:
|
||||
recipe = Recipe.query.filter_by(id=recipe_id, is_deleted=False).first()
|
||||
if recipe is None:
|
||||
raise LookupError("Рецепт не найден")
|
||||
|
||||
header = LabRecipeRation.query.filter_by(recipe_id=recipe_id).first()
|
||||
if header is None:
|
||||
header = LabRecipeRation(recipe_id=recipe_id, created_by=user_id, updated_by=user_id)
|
||||
db.session.add(header)
|
||||
header.animal_profile_id = payload.get("animalProfileId") or payload.get("animal_profile_id")
|
||||
if "params" in payload:
|
||||
params = payload.get("params") or {}
|
||||
if isinstance(params, dict):
|
||||
seeded = params.get("seeded_from") or params.get("synced_from")
|
||||
if seeded:
|
||||
header.seed_source = str(seeded)
|
||||
if "rationType" in payload or "ration_type" in payload:
|
||||
recipe.ration_type = (payload.get("rationType") or payload.get("ration_type") or "").upper() or None
|
||||
header.updated_by = user_id
|
||||
|
||||
incoming = payload.get("lines") or []
|
||||
existing = {
|
||||
str(l.id): l
|
||||
for l in LabRationLine.query.filter_by(recipe_id=recipe_id, is_deleted=False).all()
|
||||
}
|
||||
seen_ids: set[str] = set()
|
||||
for idx, row in enumerate(incoming):
|
||||
line_id = str(row.get("id") or "")
|
||||
line = existing.get(line_id) if line_id else None
|
||||
if line is None:
|
||||
line = LabRationLine(
|
||||
id=default_uuid(),
|
||||
recipe_id=recipe_id,
|
||||
created_by=user_id,
|
||||
updated_by=user_id,
|
||||
)
|
||||
db.session.add(line)
|
||||
line.row_index = int(row.get("rowIndex", row.get("row_index", idx)))
|
||||
line.component_id = row.get("componentId") or row.get("component_id")
|
||||
line.ingredient_name = row.get("ingredientName") or row.get("ingredient_name")
|
||||
line.daily_kg = row.get("dailyKg", row.get("daily_kg"))
|
||||
line.in_ration = bool(row.get("inRation", row.get("in_ration", True)))
|
||||
line.in_compound = bool(row.get("inCompound", row.get("in_compound", False)))
|
||||
line.updated_by = user_id
|
||||
if line.id:
|
||||
seen_ids.add(str(line.id))
|
||||
|
||||
for lid, line in existing.items():
|
||||
if lid not in seen_ids:
|
||||
line.soft_delete(user_id)
|
||||
|
||||
db.session.commit()
|
||||
return {"recipeId": recipe_id, "ok": True}
|
||||
Reference in New Issue
Block a user