import logging from datetime import datetime from typing import Any, Optional from app.core.database import execute_query, execute_query_single logger = logging.getLogger(__name__) class TelefoniService: @staticmethod def find_user_by_extension(extension: Optional[str]) -> Optional[int]: if not extension: return None row = execute_query_single( "SELECT user_id FROM users WHERE telefoni_aktiv = TRUE AND telefoni_extension = %s LIMIT 1", (extension,), ) return int(row["user_id"]) if row and row.get("user_id") is not None else None @staticmethod def find_contact_by_phone_suffix(suffix8: Optional[str]) -> Optional[dict]: if not suffix8: return None query = """ SELECT c.id, c.first_name, c.last_name, ( SELECT cu.name FROM contact_companies cc JOIN customers cu ON cu.id = cc.customer_id WHERE cc.contact_id = c.id ORDER BY cc.is_primary DESC NULLS LAST, cc.id ASC LIMIT 1 ) AS company FROM contacts c WHERE RIGHT(regexp_replace(COALESCE(c.phone, ''), '\\D', '', 'g'), 8) = %s OR RIGHT(regexp_replace(COALESCE(c.mobile, ''), '\\D', '', 'g'), 8) = %s ORDER BY c.id ASC LIMIT 1 """ row = execute_query_single(query, (suffix8, suffix8)) if not row: return None return { "id": row["id"], "name": f"{(row.get('first_name') or '').strip()} {(row.get('last_name') or '').strip()}".strip(), "company": row.get("company"), } @staticmethod def upsert_call( *, callid: str, user_id: Optional[int], direction: str, ekstern_nummer: Optional[str], intern_extension: Optional[str], kontakt_id: Optional[int], raw_payload: Any, started_at: datetime, ) -> dict: query = """ INSERT INTO telefoni_opkald (callid, bruger_id, direction, ekstern_nummer, intern_extension, kontakt_id, started_at, raw_payload) VALUES (%s, %s, %s, %s, %s, %s, %s, %s::jsonb) ON CONFLICT (callid) DO UPDATE SET raw_payload = EXCLUDED.raw_payload, direction = EXCLUDED.direction, intern_extension = COALESCE(telefoni_opkald.intern_extension, EXCLUDED.intern_extension), ekstern_nummer = COALESCE(telefoni_opkald.ekstern_nummer, EXCLUDED.ekstern_nummer), bruger_id = COALESCE(telefoni_opkald.bruger_id, EXCLUDED.bruger_id), kontakt_id = COALESCE(telefoni_opkald.kontakt_id, EXCLUDED.kontakt_id), started_at = LEAST(telefoni_opkald.started_at, EXCLUDED.started_at) RETURNING * """ rows = execute_query( query, ( callid, user_id, direction, ekstern_nummer, intern_extension, kontakt_id, started_at, raw_payload, ), ) return rows[0] if rows else {} @staticmethod def terminate_call(callid: str, duration_sec: Optional[int]) -> bool: if not callid: return False rows = execute_query( """ UPDATE telefoni_opkald SET ended_at = NOW(), duration_sec = %s WHERE callid = %s RETURNING id """, (duration_sec, callid), ) return bool(rows)