"""Фабрики данных для тестов кормораздатчика (period_recipes).""" from __future__ import annotations from datetime import datetime from typing import List, Tuple from sqlalchemy import select from app import db from app.models import ( Component, FeedDispenser, FeedingPeriod, Ingredient, PeriodRecipe, Recipe, UnloadingGroup, ) E2E_DISP_ID = "e2e-disp-1" E2E_PERIOD_A = "e2e-period-a" E2E_PERIOD_B = "e2e-period-b" E2E_DISP_RECIPE_1 = "e2e-disp-recipe-1" E2E_DISP_RECIPE_2 = "e2e-disp-recipe-2" E2E_DISP_COMP = "e2e-disp-comp" def seed_dispenser_period_recipes() -> Tuple[str, str, List[str]]: """Кормораздатчик + 2 периода + 2 рецепта в period A. Возвращает (disp_id, period_a_id, recipe_ids).""" now = datetime.now() db.session.add_all( [ FeedDispenser( id=E2E_DISP_ID, name="E2E Раздатчик", farm="Ферма", operator="Тест", type="dispenser", content_hash="", ), FeedingPeriod(id=E2E_PERIOD_A, name="E2E Утро", dispenser_id=E2E_DISP_ID), FeedingPeriod(id=E2E_PERIOD_B, name="E2E Вечер", dispenser_id=E2E_DISP_ID), Component( id=E2E_DISP_COMP, name="E2E Disp компонент", type="grain", dry_matter=55.0, protein=0.0, energy=0.0, price=0.0, ), Recipe( id=E2E_DISP_RECIPE_1, name="E2E Рейс 1", heads_per_trip=20, mixing_time=3, trip_percent=100.0, target_component_id=E2E_DISP_COMP, content_hash="", ), Recipe( id=E2E_DISP_RECIPE_2, name="E2E Рейс 2", heads_per_trip=15, mixing_time=4, trip_percent=100.0, target_component_id=E2E_DISP_COMP, content_hash="", ), ] ) db.session.flush() for idx, (rid, ing_id) in enumerate( ((E2E_DISP_RECIPE_1, "e2e-disp-ing-1"), (E2E_DISP_RECIPE_2, "e2e-disp-ing-2")), 1, ): db.session.add( Ingredient( id=ing_id, name=f"Ing {idx}", weight_per_head=float(idx), amount=float(idx * 10), dry_matter=55.0, component_id=E2E_DISP_COMP, order=1, recipe_id=rid, created_by="system", updated_by="system", ) ) db.session.add( UnloadingGroup( id=f"e2e-disp-grp-{idx}", name=f"Г{idx}", distribution_type="percent", value=100.0, weight=10.0, order=1, recipe_id=rid, created_by="system", updated_by="system", ) ) for ord_, rid in enumerate((E2E_DISP_RECIPE_1, E2E_DISP_RECIPE_2), 0): db.session.add( PeriodRecipe( period_id=E2E_PERIOD_A, recipe_id=rid, order=ord_, created_at=now, created_by="system", updated_by="system", ) ) db.session.commit() return E2E_DISP_ID, E2E_PERIOD_A, [E2E_DISP_RECIPE_1, E2E_DISP_RECIPE_2] def reset_e2e_dispenser_period_state() -> None: """Восстановить рейсы 1–2 в period A после мутирующих E2E (перенос, удаление, порядок).""" now = datetime.now() period_b_rows = db.session.execute( select(PeriodRecipe).where( PeriodRecipe.period_id == E2E_PERIOD_B, PeriodRecipe.is_deleted.is_(False), ) ).scalars().all() for row in period_b_rows: db.session.delete(row) db.session.flush() for rid in (E2E_DISP_RECIPE_1, E2E_DISP_RECIPE_2): row = db.session.get(PeriodRecipe, {"period_id": E2E_PERIOD_A, "recipe_id": rid}) if row is not None: db.session.delete(row) db.session.flush() for ord_, rid in enumerate((E2E_DISP_RECIPE_1, E2E_DISP_RECIPE_2)): db.session.add( PeriodRecipe( period_id=E2E_PERIOD_A, recipe_id=rid, order=ord_, created_at=now, updated_at=now, created_by="system", updated_by="system", ) ) db.session.commit() def get_period_recipe_order(period_id: str) -> List[str]: rows = db.session.execute( select(PeriodRecipe.recipe_id) .where( PeriodRecipe.period_id == period_id, PeriodRecipe.is_deleted.is_(False), ) .order_by(PeriodRecipe.order.asc()) ).scalars().all() return [str(x) for x in rows]