# services/vmix_json_service.py from db import get_connection from repositories.match_lineup_repository import get_match_lineup_for_vmix def build_lineup_json(match_id, home_team_id, away_team_id, name, team_a_name, team_b_name): lineups = get_match_lineup_for_vmix( match_id=match_id, home_team_id=home_team_id, away_team_id=away_team_id, ) players = lineups.get(name, []) result = [] for p in players: suffix = [] if "вратарь" in (p.get("pos") or "").lower(): suffix.append("ВР") if p.get("is_captain"): suffix.append("К") number = p.get("number", "") lastname = p.get("last_name", "") suffix_str = f'({", ".join(suffix)})' if suffix else "" result.append( { "number": p.get("number", ""), "number_lastname_amp_K": f"{number} {lastname} {suffix_str}".strip(), "first_name": p.get("first_name", ""), "last_name": p.get("last_name", ""), "number_fullname": f"{number} {p.get('first_name', '')} {p.get('last_name', '')}".strip(), "full_name": ( p.get("first_name", "") + " " + p.get("last_name", "") ).strip(), "full_name_K": ( p.get("first_name", "") + " " + p.get("last_name", "") ).strip() + (f" {', '.join(suffix)}" if suffix else ""), "pos": p.get("pos", ""), "position": p.get("position", ""), "photo": ( r"D:\Графика\ФУТБОЛ\Женская Суперлига 2026\Photo" + "\\" + (team_a_name if "home" in name else team_b_name) + "\\" + (p.get("last_name", "") + " " + p.get("first_name", "")).strip() + ".png" ), } ) return {"players": result} def get_vmix_match_info_by_token(session_token: str): query = """ SELECT ms.match_id, m.match_date, m.place, m.stadium_id, ht.id AS home_team_id, ht.name AS home_team_name, COALESCE(ht.full_name, ht.name) AS home_team_full_name, COALESCE(ht.short_name_3, '') AS home_team_short_name, at.id AS away_team_id, at.name AS away_team_name, COALESCE(at.full_name, at.name) AS away_team_full_name, COALESCE(at.short_name_3, '') AS away_team_short_name, COALESCE(s.stadium_gfx, s.name, m.place, '') AS stadium_name, m.tour, ht.logo_path AS home_logo, REPLACE(at.logo_path, 'HOME', 'AWAY') AS away_logo, ref1.referee_name AS referee1, ref2.referee_name AS referee2, ref3.referee_name AS referee3, ref4.referee_name AS referee4, CASE WHEN ht.name ILIKE '%%динамо%%' THEN REPLACE(REPLACE(ht.logo_path, 'HOME\\', ''), 'Динамо', 'Динамо_Белый') WHEN ht.name ILIKE '%%зенит%%' THEN REPLACE(REPLACE(ht.logo_path, 'HOME\\', ''), 'Зенит', 'Зенит_Белый') ELSE REPLACE(ht.logo_path, 'HOME\\', '') END AS home_logo1, CASE WHEN at.name ILIKE '%%динамо%%' THEN REPLACE(REPLACE(at.logo_path, 'HOME\\', ''), 'Динамо', 'Динамо_Белый') WHEN at.name ILIKE '%%зенит%%' THEN REPLACE(REPLACE(at.logo_path, 'HOME\\', ''), 'Зенит', 'Зенит_Белый') ELSE REPLACE(at.logo_path, 'HOME\\', '') END AS away_logo1, CASE WHEN ht.name ILIKE '%%динамо%%' THEN REPLACE(REPLACE(ht.logo_path, 'HOME\\', ''), 'Динамо', 'Динамо_Синий') WHEN ht.name ILIKE '%%зенит%%' THEN REPLACE(REPLACE(ht.logo_path, 'HOME\\', ''), 'Зенит', 'Зенит_Синий') ELSE REPLACE(ht.logo_path, 'HOME\\', '') END AS home_logo2, CASE WHEN at.name ILIKE '%%динамо%%' THEN REPLACE(REPLACE(at.logo_path, 'HOME\\', ''), 'Динамо', 'Динамо_Синий') WHEN at.name ILIKE '%%зенит%%' THEN REPLACE(REPLACE(at.logo_path, 'HOME\\', ''), 'Зенит', 'Зенит_Синий') ELSE REPLACE(at.logo_path, 'HOME\\', '') END AS away_logo2, ht.city AS home_city, at.city AS away_city, TRIM(COALESCE(c1.name, '') || ' ' || COALESCE(c1.lastname, '')) AS coach_name1, c1.amplua AS coach_amplua1, TRIM(COALESCE(c2.name, '') || ' ' || COALESCE(c2.lastname, '')) AS coach_name2, c2.amplua AS coach_amplua2 FROM match_sessions ms JOIN matches m ON m.id = ms.match_id JOIN teams ht ON ht.id = m.home_team_id JOIN teams at ON at.id = m.away_team_id LEFT JOIN match_referees ref1 ON ref1.match_id = m.id AND ref1.role = 'Главный судья' LEFT JOIN match_referees ref2 ON ref2.match_id = m.id AND ref2.role = 'Ассистент судьи №1' LEFT JOIN match_referees ref3 ON ref3.match_id = m.id AND ref3.role = 'Ассистент судьи №2' LEFT JOIN match_referees ref4 ON ref4.match_id = m.id AND ref4.role = 'Резервный судья' LEFT JOIN match_coaches mc1 ON mc1.match_id = m.id AND mc1.side = 'home' LEFT JOIN coaches c1 ON c1.id = mc1.coach_id LEFT JOIN match_coaches mc2 ON mc2.match_id = m.id AND mc2.side = 'away' LEFT JOIN coaches c2 ON c2.id = mc2.coach_id LEFT JOIN stadiums s ON s.id = m.stadium_id WHERE ms.session_token = %s LIMIT 1; """ conn = get_connection() try: with conn.cursor() as cur: cur.execute(query, (session_token,)) return cur.fetchone() finally: conn.close() def get_vmix_standings(session_token: str): query = """ SELECT s.position, t.full_name, CASE WHEN t.full_name ILIKE '%%динамо%%' THEN REPLACE(REPLACE(t.logo_path, 'HOME\\', ''), 'Динамо', 'Динамо_Белый') WHEN t.full_name ILIKE '%%зенит%%' THEN REPLACE(REPLACE(t.logo_path, 'HOME\\', ''), 'Зенит', 'Зенит_Белый') ELSE REPLACE(t.logo_path, 'HOME\\', '') END AS logo, s.played, s.wins, s.losses, s.draws, s.points_for || ' - ' || s.points_against AS score, s.points, s.team_id FROM standings s LEFT JOIN teams t ON s.team_id = t.id ORDER BY s.position """ conn = get_connection() try: with conn.cursor() as cur: cur.execute(query, (session_token,)) return cur.fetchall() finally: conn.close() def get_vmix_schedule(session_token: str): query = """ SELECT CASE WHEN t1.full_name ILIKE '%%динамо%%' THEN REPLACE(REPLACE(t1.logo_path, 'HOME\\', ''), 'Динамо', 'Динамо_Белый') WHEN t1.full_name ILIKE '%%зенит%%' THEN REPLACE(REPLACE(t1.logo_path, 'HOME\\', ''), 'Зенит', 'Зенит_Белый') ELSE REPLACE(t1.logo_path, 'HOME\\', '') END AS logo1, CASE WHEN t2.full_name ILIKE '%%динамо%%' THEN REPLACE(REPLACE(t2.logo_path, 'HOME\\', ''), 'Динамо', 'Динамо_Белый') WHEN t2.full_name ILIKE '%%зенит%%' THEN REPLACE(REPLACE(t2.logo_path, 'HOME\\', ''), 'Зенит', 'Зенит_Белый') ELSE REPLACE(t2.logo_path, 'HOME\\', '') END AS logo2, m.home_score, m.away_score, m.match_date, m.status, m.id, m.chanell FROM matches m LEFT JOIN teams t1 ON m.home_team_id = t1.id LEFT JOIN teams t2 ON m.away_team_id = t2.id WHERE m.tour = %s ORDER BY m.match_date, m.id """ conn = get_connection() try: with conn.cursor() as cur: cur.execute(query, (session_token[10],)) return cur.fetchall() finally: conn.close() def get_vmix_team_formations(session_token: str, team_id: int): query = """ SELECT p.last_name, mf.is_captain, p.number, p.position, p.first_name FROM match_formations mf LEFT JOIN players p ON p.id = mf.player_id WHERE mf.match_id = %s and mf.team_id = %s ORDER BY mf.id """ conn = get_connection() try: with conn.cursor() as cur: cur.execute(query, (session_token[1], team_id)) return cur.fetchall() finally: conn.close() def get_vmix_scoreboard_info(session_token: str): query = """ WITH yellow_reds AS ( SELECT side, player_id FROM match_events_ui WHERE match_id = %s AND type = 'yellow' AND player_id IS NOT NULL GROUP BY side, player_id HAVING COUNT(*) >= 2 ), direct_reds AS ( SELECT side, COUNT(*) AS cnt FROM match_events_ui WHERE match_id = %s AND type = 'red' GROUP BY side ), two_yellow_reds AS ( SELECT side, COUNT(*) AS cnt FROM yellow_reds GROUP BY side ), red_totals AS ( SELECT s.side, COALESCE(dr.cnt, 0) + COALESCE(tyr.cnt, 0) AS red_count FROM ( SELECT 'home' AS side UNION ALL SELECT 'away' AS side ) s LEFT JOIN direct_reds dr ON dr.side = s.side LEFT JOIN two_yellow_reds tyr ON tyr.side = s.side ) SELECT -- голы COALESCE(SUM( CASE WHEN m.side = 'home' AND m.type IN ('goal', 'penalty', 'own_goal') THEN 1 ELSE 0 END ), 0) AS home_goals, COALESCE(SUM( CASE WHEN m.side = 'away' AND m.type IN ('goal', 'penalty', 'own_goal') THEN 1 ELSE 0 END ), 0) AS away_goals, -- домашние карточки CASE WHEN (SELECT red_count FROM red_totals WHERE side = 'home') >= 1 THEN '#FF0000' ELSE '#FF000000' END AS home_red_1, CASE WHEN (SELECT red_count FROM red_totals WHERE side = 'home') >= 2 THEN '#FF0000' ELSE '#FF000000' END AS home_red_2, CASE WHEN (SELECT red_count FROM red_totals WHERE side = 'home') >= 3 THEN '#FF0000' ELSE '#FF000000' END AS home_red_3, CASE WHEN (SELECT red_count FROM red_totals WHERE side = 'home') >= 4 THEN '#FF0000' ELSE '#FF000000' END AS home_red_4, -- гостевые карточки CASE WHEN (SELECT red_count FROM red_totals WHERE side = 'away') >= 1 THEN '#FF0000' ELSE '#FF000000' END AS away_red_1, CASE WHEN (SELECT red_count FROM red_totals WHERE side = 'away') >= 2 THEN '#FF0000' ELSE '#FF000000' END AS away_red_2, CASE WHEN (SELECT red_count FROM red_totals WHERE side = 'away') >= 3 THEN '#FF0000' ELSE '#FF000000' END AS away_red_3, CASE WHEN (SELECT red_count FROM red_totals WHERE side = 'away') >= 4 THEN '#FF0000' ELSE '#FF000000' END AS away_red_4 FROM match_events_ui m WHERE m.match_id = %s; """ conn = get_connection() try: with conn.cursor() as cur: cur.execute(query, (session_token[1],session_token[1],session_token[1])) return cur.fetchone() finally: conn.close() def get_vmix_players_goal(match_id: int): query = """ WITH goal_events AS ( SELECT meu.side, COALESCE(p.last_name, meu.player_name) AS last_name, meu.seconds, meu.id, meu.type, CASE WHEN EXISTS ( SELECT 1 FROM match_events_ui m2 WHERE m2.match_id = meu.match_id AND m2.type = 'period_start_2h' AND m2.seconds <= meu.seconds ) THEN 2 WHEN EXISTS ( SELECT 1 FROM match_events_ui m2 WHERE m2.match_id = meu.match_id AND m2.type = 'period_start_1h' AND m2.seconds <= meu.seconds ) THEN 1 ELSE NULL END AS period_no FROM match_events_ui meu LEFT JOIN players p ON p.id = meu.player_id WHERE meu.match_id = %s AND meu.type IN ('goal', 'penalty', 'own_goal') ), grouped_players AS ( SELECT side, last_name, MIN(seconds) AS first_goal_seconds, STRING_AGG( ( CASE WHEN period_no = 1 AND seconds > 2700 THEN '45''' || '+ ' || ((seconds - 2700) / 60)::int::text WHEN period_no = 2 AND seconds > 5400 THEN '90''' || '+ ' || ((seconds - 5400) / 60)::int::text WHEN period_no = 2 THEN (46 + ((seconds - 2700) / 60)::int)::text || '''' ELSE (1 + (seconds / 60)::int)::text || '''' END ) || CASE WHEN type = 'own_goal' THEN ' (АГ)' WHEN type = 'penalty' THEN ' (П)' ELSE '' END, ', ' ORDER BY seconds, id ) AS goal_minutes FROM goal_events GROUP BY side, last_name ), home_rows AS ( SELECT ROW_NUMBER() OVER (ORDER BY first_goal_seconds, last_name) AS rn, last_name || ' ' || goal_minutes AS player_name1 FROM grouped_players WHERE side = 'home' ), away_rows AS ( SELECT ROW_NUMBER() OVER (ORDER BY first_goal_seconds, last_name) AS rn, last_name || ' ' || goal_minutes AS player_name2 FROM grouped_players WHERE side = 'away' ) SELECT COALESCE(h.player_name1, '') AS player_name1, COALESCE(a.player_name2, '') AS player_name2 FROM home_rows h FULL OUTER JOIN away_rows a ON a.rn = h.rn ORDER BY COALESCE(h.rn, a.rn); """ conn = get_connection() try: with conn.cursor() as cur: cur.execute(query, (match_id,)) return cur.fetchall() finally: conn.close()