112 lines
3.7 KiB
Python
112 lines
3.7 KiB
Python
|
|
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)
|