Files
WFL/repositories/coach_repository.py

418 lines
11 KiB
Python

from db import get_connection
from repositories.team_repository import get_team_id_by_external_id
def upsert_coach(
external_id: str,
team_external_id: str,
player: str,
lastname: str = "",
name: str = "",
born: str = "",
amplua: str = "",
is_active: bool = True,
) -> None:
team_id = get_team_id_by_external_id(str(team_external_id).strip())
if team_id is None:
raise ValueError(f"Team not found by external_id: {team_external_id}")
query = """
INSERT INTO coaches (
external_id,
team_id,
player,
lastname,
name,
born,
amplua,
is_active,
created_at,
updated_at
)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, NOW(), NOW())
ON CONFLICT (external_id)
DO UPDATE SET
team_id = EXCLUDED.team_id,
player = EXCLUDED.player,
lastname = EXCLUDED.lastname,
name = EXCLUDED.name,
born = EXCLUDED.born,
amplua = EXCLUDED.amplua,
is_active = EXCLUDED.is_active,
updated_at = NOW();
"""
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(
query,
(
str(external_id).strip(),
team_id,
player.strip(),
lastname.strip(),
name.strip(),
born.strip(),
amplua.strip(),
is_active,
),
)
conn.commit()
except Exception:
conn.rollback()
raise
finally:
conn.close()
def get_player_id_by_name_and_team(full_name: str, team_id: int) -> int | None:
query = """
SELECT id
FROM players
WHERE team_id = %s
AND LOWER(full_name) = LOWER(%s)
LIMIT 1;
"""
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(query, (team_id, full_name.strip()))
row = cur.fetchone()
return row[0] if row else None
finally:
conn.close()
def get_coach_id_by_name_and_team(full_name: str, team_id: int) -> int | None:
query = """
SELECT id
FROM coaches
WHERE team_id = %s
AND LOWER(player) = LOWER(%s)
LIMIT 1;
"""
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(query, (team_id, full_name.strip()))
row = cur.fetchone()
return row[0] if row else None
finally:
conn.close()
def get_coach_id_by_external_id(external_id: str) -> int | None:
query = """
SELECT id
FROM coaches
WHERE external_id = %s
LIMIT 1;
"""
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(query, (str(external_id).strip(),))
row = cur.fetchone()
return row[0] if row else None
finally:
conn.close()
def _split_coach_name_for_autocreate(full_name: str) -> tuple[str, str]:
parts = [p.strip() for p in str(full_name or "").replace("\xa0", " ").split() if p.strip()]
if not parts:
return "", ""
if len(parts) == 1:
return "", parts[0]
first_name = parts[0]
last_name = " ".join(parts[1:])
return first_name, last_name
def create_coach_from_lineup(
team_id: int,
external_id: str = "",
full_name: str = "",
role: str = "",
) -> int | None:
"""Создаёт минимальную карточку тренера из протокола матча."""
full_name = str(full_name or "").strip()
if not full_name:
return None
first_name, last_name = _split_coach_name_for_autocreate(full_name)
external_id = str(external_id or "").strip()
role = str(role or "").strip()
query = """
INSERT INTO coaches (
external_id,
team_id,
player,
lastname,
name,
amplua,
is_active,
created_at,
updated_at
)
VALUES (NULLIF(%s, ''), %s, %s, %s, %s, %s, TRUE, NOW(), NOW())
ON CONFLICT (external_id)
DO UPDATE SET
team_id = EXCLUDED.team_id,
player = COALESCE(NULLIF(EXCLUDED.player, ''), coaches.player),
lastname = COALESCE(NULLIF(EXCLUDED.lastname, ''), coaches.lastname),
name = COALESCE(NULLIF(EXCLUDED.name, ''), coaches.name),
amplua = COALESCE(NULLIF(EXCLUDED.amplua, ''), coaches.amplua),
is_active = TRUE,
updated_at = NOW()
RETURNING id;
"""
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(
query,
(
external_id,
team_id,
full_name,
last_name,
first_name,
role,
),
)
row = cur.fetchone()
conn.commit()
return row[0] if row else None
except Exception:
conn.rollback()
raise
finally:
conn.close()
def search_coaches_for_admin(q: str = "") -> list[dict]:
conn = get_connection()
try:
with conn.cursor() as cur:
if q.strip():
pattern = f"%{q.strip()}%"
cur.execute(
"""
SELECT
c.id,
c.player,
c.external_id,
c.amplua,
t.name AS team_name
FROM coaches c
LEFT JOIN teams t ON t.id = c.team_id
WHERE
c.player ILIKE %s
OR COALESCE(c.external_id, '') ILIKE %s
OR COALESCE(c.amplua, '') ILIKE %s
OR COALESCE(t.name, '') ILIKE %s
ORDER BY c.player ASC, c.id ASC
LIMIT 200
""",
(pattern, pattern, pattern, pattern),
)
else:
cur.execute(
"""
SELECT
c.id,
c.player,
c.external_id,
c.amplua,
t.name AS team_name
FROM coaches c
LEFT JOIN teams t ON t.id = c.team_id
ORDER BY c.id DESC
LIMIT 200
"""
)
rows = cur.fetchall()
return [
{
"id": row[0],
"full_name": row[1] or "",
"external_id": row[2] or "",
"role": row[3] or "",
"team_name": row[4] or "",
}
for row in rows
]
finally:
conn.close()
def get_coach_by_id(coach_id: int) -> dict | None:
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(
"""
SELECT
c.id,
c.player,
c.external_id,
c.amplua,
c.team_id,
t.name AS team_name
FROM coaches c
LEFT JOIN teams t ON t.id = c.team_id
WHERE c.id = %s
LIMIT 1
""",
(coach_id,),
)
row = cur.fetchone()
if not row:
return None
return {
"id": row[0],
"full_name": row[1] or "",
"external_id": row[2] or "",
"role": row[3] or "",
"team_id": row[4],
"team_name": row[5] or "",
}
finally:
conn.close()
def get_coach_by_id(coach_id: int) -> dict | None:
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(
"""
SELECT
c.id,
c.player,
c.external_id,
c.amplua,
c.team_id,
t.name AS team_name
FROM coaches c
LEFT JOIN teams t ON t.id = c.team_id
WHERE c.id = %s
LIMIT 1
""",
(coach_id,),
)
row = cur.fetchone()
if not row:
return None
return {
"id": row[0],
"full_name": row[1] or "",
"external_id": row[2] or "",
"role": row[3] or "",
"team_id": row[4],
"team_name": row[5] or "",
}
finally:
conn.close()
def update_coach_admin(
coach_id: int,
full_name: str = "",
external_id: str = "",
role: str = "",
) -> None:
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(
"""
UPDATE coaches
SET
player = %s,
external_id = NULLIF(%s, ''),
amplua = %s
WHERE id = %s
""",
(
full_name.strip(),
external_id.strip(),
role.strip(),
coach_id,
),
)
conn.commit()
except Exception:
conn.rollback()
raise
finally:
conn.close()
def create_coach_admin(
team_id: int,
full_name: str,
first_name: str = "",
last_name: str = "",
external_id: str = "",
birth_date: str = "",
role: str = "",
is_active: bool = True,
) -> int:
"""Создаёт тренера вручную из административного раздела."""
query = """
INSERT INTO coaches (
external_id,
team_id,
player,
lastname,
name,
born,
amplua,
is_active,
created_at,
updated_at
)
VALUES (
NULLIF(%s, ''), %s, %s, %s, %s, NULLIF(%s, ''), %s, %s, NOW(), NOW()
)
RETURNING id;
"""
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(
query,
(
external_id.strip(),
int(team_id),
full_name.strip(),
last_name.strip(),
first_name.strip(),
birth_date.strip(),
role.strip(),
bool(is_active),
),
)
row = cur.fetchone()
conn.commit()
return int(row[0])
except Exception:
conn.rollback()
raise
finally:
conn.close()