fix: stabilize call->case prefill and migration status routing
This commit is contained in:
parent
9f563941e6
commit
5b24c5d978
@ -107,6 +107,21 @@ class MissionService:
|
||||
FROM contacts c
|
||||
WHERE RIGHT(regexp_replace(COALESCE(c.phone, ''), '\\D', '', 'g'), 8) = RIGHT(regexp_replace(%s, '\\D', '', 'g'), 8)
|
||||
OR RIGHT(regexp_replace(COALESCE(c.mobile, ''), '\\D', '', 'g'), 8) = RIGHT(regexp_replace(%s, '\\D', '', 'g'), 8)
|
||||
ORDER BY (
|
||||
SELECT COUNT(*)
|
||||
FROM sag_kontakter sk
|
||||
JOIN sag_sager s ON s.id = sk.sag_id
|
||||
WHERE sk.contact_id = c.id
|
||||
AND sk.deleted_at IS NULL
|
||||
AND s.deleted_at IS NULL
|
||||
AND LOWER(COALESCE(s.status, '')) <> 'lukket'
|
||||
) DESC,
|
||||
(
|
||||
SELECT MAX(t.started_at)
|
||||
FROM telefoni_opkald t
|
||||
WHERE t.kontakt_id = c.id
|
||||
) DESC NULLS LAST,
|
||||
c.id ASC
|
||||
LIMIT 1
|
||||
"""
|
||||
row = execute_query_single(query, (caller_number, caller_number))
|
||||
|
||||
@ -29,6 +29,14 @@ class TelefoniService:
|
||||
c.id,
|
||||
c.first_name,
|
||||
c.last_name,
|
||||
(
|
||||
SELECT cu.id
|
||||
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_id,
|
||||
(
|
||||
SELECT cu.name
|
||||
FROM contact_companies cc
|
||||
@ -36,11 +44,25 @@ class TelefoniService:
|
||||
WHERE cc.contact_id = c.id
|
||||
ORDER BY cc.is_primary DESC NULLS LAST, cc.id ASC
|
||||
LIMIT 1
|
||||
) AS company
|
||||
) AS company,
|
||||
(
|
||||
SELECT COUNT(*)
|
||||
FROM sag_kontakter sk
|
||||
JOIN sag_sager s ON s.id = sk.sag_id
|
||||
WHERE sk.contact_id = c.id
|
||||
AND sk.deleted_at IS NULL
|
||||
AND s.deleted_at IS NULL
|
||||
AND LOWER(COALESCE(s.status, '')) <> 'lukket'
|
||||
) AS open_case_count,
|
||||
(
|
||||
SELECT MAX(t.started_at)
|
||||
FROM telefoni_opkald t
|
||||
WHERE t.kontakt_id = c.id
|
||||
) AS last_call_at
|
||||
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
|
||||
ORDER BY open_case_count DESC, last_call_at DESC NULLS LAST, c.id ASC
|
||||
LIMIT 1
|
||||
"""
|
||||
row = execute_query_single(query, (suffix8, suffix8))
|
||||
@ -49,6 +71,7 @@ class TelefoniService:
|
||||
return {
|
||||
"id": row["id"],
|
||||
"name": f"{(row.get('first_name') or '').strip()} {(row.get('last_name') or '').strip()}".strip(),
|
||||
"company_id": row.get("company_id"),
|
||||
"company": row.get("company"),
|
||||
}
|
||||
|
||||
|
||||
@ -259,6 +259,14 @@ async def get_setting_categories():
|
||||
return [row['category'] for row in result] if result else []
|
||||
|
||||
|
||||
@router.get("/settings/migrations/status", tags=["Settings"])
|
||||
async def get_migration_statuses_api():
|
||||
"""Expose migration status via API router (served under /api/v1)."""
|
||||
from app.settings.backend.views import migration_statuses
|
||||
|
||||
return migration_statuses()
|
||||
|
||||
|
||||
@router.post("/settings/sync-from-env", tags=["Settings"])
|
||||
async def sync_settings_from_env():
|
||||
"""Sync settings from .env file into database (only updates empty values)"""
|
||||
|
||||
@ -281,12 +281,6 @@ def migration_statuses():
|
||||
release_db_connection(conn)
|
||||
|
||||
|
||||
@router.get("/api/v1/settings/migrations/status", tags=["Frontend"])
|
||||
def migration_statuses_api_v1_alias():
|
||||
"""API-prefixed alias for environments/routes expecting /api/v1 prefix."""
|
||||
return migration_statuses()
|
||||
|
||||
|
||||
@router.post("/settings/migrations/execute", tags=["Frontend"])
|
||||
def execute_migration(payload: MigrationExecution):
|
||||
"""Execute a migration SQL file"""
|
||||
|
||||
@ -0,0 +1,57 @@
|
||||
-- Migration 151: Reconcile opportunity comment attachments schema with migration 019 expectations
|
||||
-- Some environments already had pipeline_opportunity_comment_attachments with legacy columns,
|
||||
-- so migration 019 (CREATE TABLE IF NOT EXISTS) did not add these fields.
|
||||
|
||||
ALTER TABLE IF EXISTS pipeline_opportunity_comment_attachments
|
||||
ADD COLUMN IF NOT EXISTS content_type VARCHAR(100),
|
||||
ADD COLUMN IF NOT EXISTS stored_name TEXT,
|
||||
ADD COLUMN IF NOT EXISTS uploaded_by_user_id INTEGER;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'pipeline_opportunity_comment_attachments'
|
||||
AND column_name = 'file_path'
|
||||
) THEN
|
||||
UPDATE pipeline_opportunity_comment_attachments
|
||||
SET stored_name = COALESCE(stored_name, file_path)
|
||||
WHERE stored_name IS NULL;
|
||||
END IF;
|
||||
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'pipeline_opportunity_comment_attachments'
|
||||
AND column_name = 'file_type'
|
||||
) THEN
|
||||
UPDATE pipeline_opportunity_comment_attachments
|
||||
SET content_type = COALESCE(content_type, file_type)
|
||||
WHERE content_type IS NULL;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_constraint
|
||||
WHERE conname = 'pipeline_opportunity_comment_attachments_uploaded_by_fkey'
|
||||
) THEN
|
||||
ALTER TABLE pipeline_opportunity_comment_attachments
|
||||
ADD CONSTRAINT pipeline_opportunity_comment_attachments_uploaded_by_fkey
|
||||
FOREIGN KEY (uploaded_by_user_id)
|
||||
REFERENCES users(user_id)
|
||||
ON DELETE SET NULL;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
-- Keep existing rows valid while allowing future inserts to set explicit stored_name.
|
||||
UPDATE pipeline_opportunity_comment_attachments
|
||||
SET stored_name = COALESCE(stored_name, filename)
|
||||
WHERE stored_name IS NULL;
|
||||
@ -163,6 +163,7 @@
|
||||
if (action === 'create-case') {
|
||||
const qs = new URLSearchParams();
|
||||
if (contact?.id) qs.set('contact_id', String(contact.id));
|
||||
if (contact?.company_id) qs.set('customer_id', String(contact.company_id));
|
||||
qs.set('title', `Telefonsamtale – ${number}`);
|
||||
qs.set('telefoni_opkald_id', String(callId));
|
||||
window.location.href = `/sag/new?${qs.toString()}`;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user