From c5478b7e29917b740470c7f1dcd62d5fb5cc534b Mon Sep 17 00:00:00 2001 From: Christian Date: Sat, 16 May 2026 13:23:56 +0200 Subject: [PATCH] fix(telefoni): show legacy call history when telefoni_opkald is empty --- RELEASE_NOTES_v2.3.7.md | 10 ++++ app/modules/telefoni/backend/router.py | 65 ++++++++++++++++++++++++- app/modules/telefoni/templates/log.html | 34 ++++++++----- 3 files changed, 95 insertions(+), 14 deletions(-) create mode 100644 RELEASE_NOTES_v2.3.7.md diff --git a/RELEASE_NOTES_v2.3.7.md b/RELEASE_NOTES_v2.3.7.md new file mode 100644 index 0000000..02a7544 --- /dev/null +++ b/RELEASE_NOTES_v2.3.7.md @@ -0,0 +1,10 @@ +# Release Notes: v2.3.7 +**Date:** 16. maj 2026 + +## Changes +- fallback to mission_call_state when telefoni_opkald is empty +- legacy rows shown read-only in telefoni UI + +## Files changed +- app/modules/telefoni/backend/router.py +- app/modules/telefoni/templates/log.html diff --git a/app/modules/telefoni/backend/router.py b/app/modules/telefoni/backend/router.py index f151078..e602ffa 100644 --- a/app/modules/telefoni/backend/router.py +++ b/app/modules/telefoni/backend/router.py @@ -735,8 +735,69 @@ async def list_calls( """ params.extend([limit, offset]) - rows = execute_query(query, tuple(params)) - return rows or [] + rows = execute_query(query, tuple(params)) or [] + if rows: + return rows + + # Fallback: legacy mission call history (read-only rows) for environments + # where historical calls were stored before telefoni_opkald was populated. + if user_id is not None: + return [] + + legacy_where = [] + legacy_params = [] + if date_from: + legacy_where.append("m.started_at >= %s") + legacy_params.append(date_from) + if date_to: + legacy_where.append("m.started_at <= %s") + legacy_params.append(date_to) + + legacy_where_sql = ("WHERE " + " AND ".join(legacy_where)) if legacy_where else "" + + legacy_query = f""" + SELECT + -ROW_NUMBER() OVER (ORDER BY m.started_at DESC, m.call_id) AS id, + m.call_id AS callid, + NULL::INTEGER AS bruger_id, + CASE + WHEN LOWER(COALESCE(m.state, '')) IN ('outbound', 'udgaaende') THEN 'outbound' + ELSE 'inbound' + END AS direction, + m.caller_number AS ekstern_nummer, + m.caller_number AS display_number, + NULL::VARCHAR AS intern_extension, + NULL::INTEGER AS kontakt_id, + NULL::INTEGER AS sag_id, + m.started_at, + m.ended_at, + CASE + WHEN m.started_at IS NOT NULL AND m.ended_at IS NOT NULL + THEN GREATEST(EXTRACT(EPOCH FROM (m.ended_at - m.started_at))::int, 0) + ELSE NULL + END AS duration_sec, + m.updated_at AS created_at, + NULL::VARCHAR AS username, + NULL::VARCHAR AS full_name, + COALESCE(NULLIF(TRIM(m.contact_name), ''), NULL) AS contact_name, + COALESCE(NULLIF(TRIM(m.company_name), ''), NULL) AS contact_company, + NULL::VARCHAR AS sag_titel, + 'legacy_mission'::VARCHAR AS source + FROM mission_call_state m + {legacy_where_sql} + ORDER BY m.started_at DESC, m.call_id + LIMIT %s OFFSET %s + """ + legacy_params.extend([limit, offset]) + + try: + legacy_rows = execute_query(legacy_query, tuple(legacy_params)) or [] + except Exception: + legacy_rows = [] + + if without_case: + return [r for r in legacy_rows if not r.get("sag_id")] + return legacy_rows @router.patch("/telefoni/calls/{call_id}") diff --git a/app/modules/telefoni/templates/log.html b/app/modules/telefoni/templates/log.html index 7e077a2..c40ab5a 100644 --- a/app/modules/telefoni/templates/log.html +++ b/app/modules/telefoni/templates/log.html @@ -851,6 +851,8 @@ async function loadCalls() { } tbody.innerHTML = rows.map(r => { + const callId = Number(r.id); + const canMutateCall = Number.isInteger(callId) && callId > 0; const started = r.started_at ? new Date(r.started_at) : null; const dateTxt = started ? started.toLocaleString('da-DK') : '-'; const userTxt = escapeHtml(r.full_name || r.username || '-'); @@ -866,30 +868,38 @@ async function loadCalls() { const contactHtml = r.kontakt_id ? `
${escapeHtml(r.contact_name || ('Kontakt #' + r.kontakt_id))} - - + ${canMutateCall + ? ` + ` + : 'Historik'}
${r.contact_company ? `
${escapeHtml(r.contact_company)}
` : ''}` - : ``; + : (canMutateCall + ? `` + : 'Historisk opkald'); const numberForTitle = (r.display_number || r.ekstern_nummer || '').trim(); const createQs = new URLSearchParams(); if (r.kontakt_id) createQs.set('contact_id', String(r.kontakt_id)); - createQs.set('telefoni_opkald_id', String(r.id)); + if (canMutateCall) createQs.set('telefoni_opkald_id', String(callId)); createQs.set('title', `Telefonsamtale – ${numberForTitle || 'ukendt nummer'}`); const sagHtml = r.sag_id ? `
${escapeHtml(r.sag_titel || ('Sag #' + r.sag_id))} - - + ${canMutateCall + ? ` + ` + : 'Historik'}
` - : `
- Opret sag - -
`; + : (canMutateCall + ? `
+ Opret sag + +
` + : 'Ingen sag'); return `