156 lines
5.1 KiB
Python
156 lines
5.1 KiB
Python
"""Импорт и загрузка справочников RACION из БД."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from dataclasses import dataclass, field
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
from app import db
|
|
from app.lab.calc.racion.tables import clear_tables_cache
|
|
from app.lab.models.racion_normy import (
|
|
LabRacionNormyInfo,
|
|
LabRacionNormyMoskwa,
|
|
LabRacionNormyMoskwaMeta,
|
|
LabRacionNormyPiter,
|
|
LabRacionNormyPiterMeta,
|
|
)
|
|
from app.models.base import default_uuid
|
|
|
|
_SEED_DIR = Path(__file__).resolve().parents[3] / "data" / "seed" / "racion"
|
|
|
|
|
|
@dataclass
|
|
class RacionReferenceImportStats:
|
|
moskwa_rows: int = 0
|
|
piter_rows: int = 0
|
|
info_rows: int = 0
|
|
errors: list[str] = field(default_factory=list)
|
|
|
|
|
|
def _read_seed(name: str) -> dict:
|
|
path = _SEED_DIR / name
|
|
return json.loads(path.read_text(encoding="utf-8"))
|
|
|
|
|
|
def import_racion_reference(*, replace: bool = True) -> RacionReferenceImportStats:
|
|
stats = RacionReferenceImportStats()
|
|
try:
|
|
moskwa = _read_seed("moskwa_lactir.json")
|
|
piter = _read_seed("piter_lactir.json")
|
|
info = _read_seed("normy_info.json")
|
|
except (OSError, json.JSONDecodeError) as exc:
|
|
stats.errors.append(str(exc))
|
|
return stats
|
|
|
|
if replace:
|
|
LabRacionNormyMoskwa.query.delete(synchronize_session=False)
|
|
LabRacionNormyMoskwaMeta.query.delete(synchronize_session=False)
|
|
LabRacionNormyPiter.query.delete(synchronize_session=False)
|
|
LabRacionNormyPiterMeta.query.delete(synchronize_session=False)
|
|
LabRacionNormyInfo.query.delete(synchronize_session=False)
|
|
|
|
for row in moskwa.get("rows") or []:
|
|
db.session.add(
|
|
LabRacionNormyMoskwa(
|
|
id=default_uuid(),
|
|
npitv=int(row["npitv"]),
|
|
pom=int(row.get("pom") or 1),
|
|
koef=row.get("koef"),
|
|
popr_k_json=json.dumps(row.get("popr_k") or [], ensure_ascii=False),
|
|
)
|
|
)
|
|
stats.moskwa_rows += 1
|
|
|
|
db.session.add(
|
|
LabRacionNormyMoskwaMeta(
|
|
id=default_uuid(),
|
|
meta_key="udoy_boundaries",
|
|
meta_json=json.dumps(moskwa.get("udoy_boundaries") or [], ensure_ascii=False),
|
|
)
|
|
)
|
|
|
|
for entry in piter.get("entries") or []:
|
|
db.session.add(
|
|
LabRacionNormyPiter(
|
|
id=default_uuid(),
|
|
npitv=int(entry["npitv"]),
|
|
konc=float(entry["konc"]),
|
|
udoy=float(entry["udoy"]),
|
|
normy_json=json.dumps(entry.get("normy") or [], ensure_ascii=False),
|
|
)
|
|
)
|
|
stats.piter_rows += 1
|
|
|
|
db.session.add(
|
|
LabRacionNormyPiterMeta(
|
|
id=default_uuid(),
|
|
meta_key="mass_kg_values",
|
|
meta_json=json.dumps(piter.get("mass_kg_values") or [], ensure_ascii=False),
|
|
)
|
|
)
|
|
|
|
for row in info.get("rows") or []:
|
|
db.session.add(
|
|
LabRacionNormyInfo(
|
|
id=default_uuid(),
|
|
nperem=int(row["nperem"]),
|
|
znachenie_json=json.dumps(row.get("znachenie") or [], ensure_ascii=False),
|
|
)
|
|
)
|
|
stats.info_rows += 1
|
|
|
|
db.session.commit()
|
|
clear_tables_cache()
|
|
return stats
|
|
|
|
|
|
def load_moskwa_lactir_from_db() -> dict | None:
|
|
if LabRacionNormyMoskwa.query.count() == 0:
|
|
return None
|
|
rows = []
|
|
for r in LabRacionNormyMoskwa.query.order_by(LabRacionNormyMoskwa.npitv, LabRacionNormyMoskwa.pom).all():
|
|
rows.append(
|
|
{
|
|
"npitv": r.npitv,
|
|
"pom": r.pom,
|
|
"koef": r.koef,
|
|
"popr_k": json.loads(r.popr_k_json or "[]"),
|
|
}
|
|
)
|
|
meta = LabRacionNormyMoskwaMeta.query.filter_by(meta_key="udoy_boundaries").first()
|
|
boundaries = json.loads(meta.meta_json or "[]") if meta else []
|
|
return {"udoy_boundaries": boundaries, "rows": rows}
|
|
|
|
|
|
def load_piter_lactir_from_db() -> dict | None:
|
|
if LabRacionNormyPiter.query.count() == 0:
|
|
return None
|
|
entries = []
|
|
for r in LabRacionNormyPiter.query.order_by(
|
|
LabRacionNormyPiter.npitv, LabRacionNormyPiter.konc, LabRacionNormyPiter.udoy
|
|
).all():
|
|
entries.append(
|
|
{
|
|
"npitv": r.npitv,
|
|
"konc": r.konc,
|
|
"udoy": r.udoy,
|
|
"normy": json.loads(r.normy_json or "[]"),
|
|
}
|
|
)
|
|
meta = LabRacionNormyPiterMeta.query.filter_by(meta_key="mass_kg_values").first()
|
|
masses = json.loads(meta.meta_json or "[]") if meta else [400, 450, 500, 550, 600, 650, 700, 750]
|
|
return {"mass_kg_values": masses, "entries": entries}
|
|
|
|
|
|
def load_normy_info_from_db() -> dict | None:
|
|
if LabRacionNormyInfo.query.count() == 0:
|
|
return None
|
|
rows = []
|
|
for r in LabRacionNormyInfo.query.order_by(LabRacionNormyInfo.nperem).all():
|
|
rows.append({"nperem": r.nperem, "znachenie": json.loads(r.znachenie_json or "[]")})
|
|
by_nperem = {row["nperem"]: row["znachenie"] for row in rows}
|
|
mass_kg_values = by_nperem.get(14) or by_nperem.get(13) or [400, 450, 500, 550, 600, 650, 700, 750]
|
|
return {"rows": rows, "mass_kg_values": mass_kg_values}
|