Files
2026-07-17 12:57:18 +03:00

63 lines
3.0 KiB
Python

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 LabAnimalProfile
from app.lab.calc.nutrients import parse_num
from app.lab.calc.norms_resolver import normalize_norms_method
from app.lab.services.norms_params import save_norms_params
from app.lab.services.profile_norms import save_norms_from_payload, sync_racion_norms_to_profile
from app.models.base import default_uuid
@retry_locked
def upsert_animal_profile(profile_id: str | None, payload: dict[str, Any], user_id: str = "system") -> dict:
pid = (profile_id or payload.get("id") or "").strip() or default_uuid()
profile = LabAnimalProfile.query.filter_by(id=pid, is_deleted=False).first()
is_new = profile is None
if is_new:
profile = LabAnimalProfile(id=pid, created_by=user_id)
db.session.add(profile)
key = (payload.get("profileKey") or payload.get("profile_key") or "").strip()
label = (payload.get("label") or "").strip()
ration_type = (payload.get("rationType") or payload.get("ration_type") or "BEEF").strip().upper()
if not key or not label:
raise ValueError("profileKey и label обязательны")
profile.profile_key = key
profile.label = label
profile.ration_type = ration_type
if "normsMethod" in payload or "norms_method" in payload:
profile.norms_method = normalize_norms_method(
payload.get("normsMethod", payload.get("norms_method"))
)
if "normsParams" in payload or "norms_params" in payload:
raw_params = payload.get("normsParams", payload.get("norms_params"))
save_norms_params(profile, raw_params if isinstance(raw_params, dict) else None)
if "milkYieldKg" in payload or "milk_yield_kg" in payload:
profile.milk_yield_kg = parse_num(payload.get("milkYieldKg", payload.get("milk_yield_kg")))
norms_payload: dict[str, Any] = {}
if "normsData" in payload or "norms_data" in payload:
raw = payload.get("normsData") if "normsData" in payload else payload.get("norms_data")
if isinstance(raw, dict):
norms_payload = dict(raw)
if payload.get("massKg") is not None or payload.get("mass_kg") is not None:
norms_payload["massKg"] = payload.get("massKg", payload.get("mass_kg"))
if "milkYieldKg" in payload or "milk_yield_kg" in payload:
norms_payload["milkYieldKg"] = payload.get("milkYieldKg", payload.get("milk_yield_kg"))
if payload.get("externalNo") is not None or payload.get("external_no") is not None:
norms_payload["externalNo"] = payload.get("externalNo", payload.get("external_no"))
if isinstance(payload.get("indicators"), dict):
norms_payload["indicators"] = payload["indicators"]
if norms_payload:
save_norms_from_payload(profile, norms_payload)
profile.updated_by = user_id
sync_racion_norms_to_profile(profile)
db.session.commit()
return {"id": profile.id, "profileKey": profile.profile_key, "label": profile.label}