Initial commit
Dieser Commit ist enthalten in:
359
v2_adminpanel/leads/repositories.py
Normale Datei
359
v2_adminpanel/leads/repositories.py
Normale Datei
@ -0,0 +1,359 @@
|
||||
# Database Repository for Lead Management
|
||||
import psycopg2
|
||||
from psycopg2.extras import RealDictCursor
|
||||
from uuid import UUID
|
||||
from typing import List, Optional, Dict, Any
|
||||
from datetime import datetime
|
||||
|
||||
class LeadRepository:
|
||||
def __init__(self, get_db_connection):
|
||||
self.get_db_connection = get_db_connection
|
||||
|
||||
# Institution Methods
|
||||
def get_institutions_with_counts(self) -> List[Dict[str, Any]]:
|
||||
with self.get_db_connection() as conn:
|
||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||
|
||||
query = """
|
||||
SELECT
|
||||
i.id,
|
||||
i.name,
|
||||
i.metadata,
|
||||
i.created_at,
|
||||
i.updated_at,
|
||||
i.created_by,
|
||||
COUNT(c.id) as contact_count
|
||||
FROM lead_institutions i
|
||||
LEFT JOIN lead_contacts c ON c.institution_id = i.id
|
||||
GROUP BY i.id
|
||||
ORDER BY i.name
|
||||
"""
|
||||
|
||||
cur.execute(query)
|
||||
results = cur.fetchall()
|
||||
cur.close()
|
||||
|
||||
return results
|
||||
|
||||
def create_institution(self, name: str, created_by: str) -> Dict[str, Any]:
|
||||
with self.get_db_connection() as conn:
|
||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||
|
||||
query = """
|
||||
INSERT INTO lead_institutions (name, created_by)
|
||||
VALUES (%s, %s)
|
||||
RETURNING *
|
||||
"""
|
||||
|
||||
cur.execute(query, (name, created_by))
|
||||
result = cur.fetchone()
|
||||
cur.close()
|
||||
|
||||
return result
|
||||
|
||||
def get_institution_by_id(self, institution_id: UUID) -> Optional[Dict[str, Any]]:
|
||||
with self.get_db_connection() as conn:
|
||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||
|
||||
query = """
|
||||
SELECT * FROM lead_institutions WHERE id = %s
|
||||
"""
|
||||
|
||||
cur.execute(query, (str(institution_id),))
|
||||
result = cur.fetchone()
|
||||
cur.close()
|
||||
|
||||
return result
|
||||
|
||||
def update_institution(self, institution_id: UUID, name: str) -> Dict[str, Any]:
|
||||
with self.get_db_connection() as conn:
|
||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||
|
||||
query = """
|
||||
UPDATE lead_institutions
|
||||
SET name = %s, updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = %s
|
||||
RETURNING *
|
||||
"""
|
||||
|
||||
cur.execute(query, (name, str(institution_id)))
|
||||
result = cur.fetchone()
|
||||
cur.close()
|
||||
|
||||
return result
|
||||
|
||||
# Contact Methods
|
||||
def get_contacts_by_institution(self, institution_id: UUID) -> List[Dict[str, Any]]:
|
||||
with self.get_db_connection() as conn:
|
||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||
|
||||
query = """
|
||||
SELECT
|
||||
c.*,
|
||||
i.name as institution_name
|
||||
FROM lead_contacts c
|
||||
JOIN lead_institutions i ON i.id = c.institution_id
|
||||
WHERE c.institution_id = %s
|
||||
ORDER BY c.last_name, c.first_name
|
||||
"""
|
||||
|
||||
cur.execute(query, (str(institution_id),))
|
||||
results = cur.fetchall()
|
||||
cur.close()
|
||||
|
||||
return results
|
||||
|
||||
def create_contact(self, data: Dict[str, Any]) -> Dict[str, Any]:
|
||||
with self.get_db_connection() as conn:
|
||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||
|
||||
query = """
|
||||
INSERT INTO lead_contacts
|
||||
(institution_id, first_name, last_name, position, extra_fields)
|
||||
VALUES (%s, %s, %s, %s, %s)
|
||||
RETURNING *
|
||||
"""
|
||||
|
||||
cur.execute(query, (
|
||||
str(data['institution_id']),
|
||||
data['first_name'],
|
||||
data['last_name'],
|
||||
data.get('position'),
|
||||
psycopg2.extras.Json(data.get('extra_fields', {}))
|
||||
))
|
||||
result = cur.fetchone()
|
||||
cur.close()
|
||||
|
||||
return result
|
||||
|
||||
def get_contact_with_details(self, contact_id: UUID) -> Dict[str, Any]:
|
||||
with self.get_db_connection() as conn:
|
||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||
|
||||
# Get contact base info
|
||||
query = """
|
||||
SELECT
|
||||
c.*,
|
||||
i.name as institution_name
|
||||
FROM lead_contacts c
|
||||
JOIN lead_institutions i ON i.id = c.institution_id
|
||||
WHERE c.id = %s
|
||||
"""
|
||||
|
||||
cur.execute(query, (str(contact_id),))
|
||||
contact = cur.fetchone()
|
||||
|
||||
if contact:
|
||||
# Get contact details (phones, emails)
|
||||
details_query = """
|
||||
SELECT * FROM lead_contact_details
|
||||
WHERE contact_id = %s
|
||||
ORDER BY detail_type, is_primary DESC, created_at
|
||||
"""
|
||||
cur.execute(details_query, (str(contact_id),))
|
||||
contact['details'] = cur.fetchall()
|
||||
|
||||
# Get notes
|
||||
notes_query = """
|
||||
SELECT * FROM lead_notes
|
||||
WHERE contact_id = %s AND is_current = true
|
||||
ORDER BY created_at DESC
|
||||
"""
|
||||
cur.execute(notes_query, (str(contact_id),))
|
||||
contact['notes'] = cur.fetchall()
|
||||
|
||||
cur.close()
|
||||
|
||||
return contact
|
||||
|
||||
def update_contact(self, contact_id: UUID, data: Dict[str, Any]) -> Dict[str, Any]:
|
||||
with self.get_db_connection() as conn:
|
||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||
|
||||
query = """
|
||||
UPDATE lead_contacts
|
||||
SET first_name = %s, last_name = %s, position = %s,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = %s
|
||||
RETURNING *
|
||||
"""
|
||||
|
||||
cur.execute(query, (
|
||||
data['first_name'],
|
||||
data['last_name'],
|
||||
data.get('position'),
|
||||
str(contact_id)
|
||||
))
|
||||
result = cur.fetchone()
|
||||
cur.close()
|
||||
|
||||
return result
|
||||
|
||||
# Contact Details Methods
|
||||
def add_contact_detail(self, contact_id: UUID, detail_type: str,
|
||||
detail_value: str, detail_label: str = None) -> Dict[str, Any]:
|
||||
with self.get_db_connection() as conn:
|
||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||
|
||||
query = """
|
||||
INSERT INTO lead_contact_details
|
||||
(contact_id, detail_type, detail_value, detail_label)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
RETURNING *
|
||||
"""
|
||||
|
||||
cur.execute(query, (
|
||||
str(contact_id),
|
||||
detail_type,
|
||||
detail_value,
|
||||
detail_label
|
||||
))
|
||||
result = cur.fetchone()
|
||||
cur.close()
|
||||
|
||||
return result
|
||||
|
||||
def get_contact_detail_by_id(self, detail_id: UUID) -> Optional[Dict[str, Any]]:
|
||||
with self.get_db_connection() as conn:
|
||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||
|
||||
query = "SELECT * FROM lead_contact_details WHERE id = %s"
|
||||
cur.execute(query, (str(detail_id),))
|
||||
result = cur.fetchone()
|
||||
cur.close()
|
||||
|
||||
return result
|
||||
|
||||
def update_contact_detail(self, detail_id: UUID, detail_value: str,
|
||||
detail_label: str = None) -> Dict[str, Any]:
|
||||
with self.get_db_connection() as conn:
|
||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||
|
||||
query = """
|
||||
UPDATE lead_contact_details
|
||||
SET detail_value = %s, detail_label = %s, updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = %s
|
||||
RETURNING *
|
||||
"""
|
||||
|
||||
cur.execute(query, (detail_value, detail_label, str(detail_id)))
|
||||
result = cur.fetchone()
|
||||
cur.close()
|
||||
|
||||
return result
|
||||
|
||||
def delete_contact_detail(self, detail_id: UUID) -> bool:
|
||||
with self.get_db_connection() as conn:
|
||||
cur = conn.cursor()
|
||||
|
||||
query = "DELETE FROM lead_contact_details WHERE id = %s"
|
||||
cur.execute(query, (str(detail_id),))
|
||||
|
||||
deleted = cur.rowcount > 0
|
||||
cur.close()
|
||||
|
||||
return deleted
|
||||
|
||||
# Notes Methods
|
||||
def create_note(self, contact_id: UUID, note_text: str, created_by: str) -> Dict[str, Any]:
|
||||
with self.get_db_connection() as conn:
|
||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||
|
||||
query = """
|
||||
INSERT INTO lead_notes
|
||||
(contact_id, note_text, created_by)
|
||||
VALUES (%s, %s, %s)
|
||||
RETURNING *
|
||||
"""
|
||||
|
||||
cur.execute(query, (
|
||||
str(contact_id),
|
||||
note_text,
|
||||
created_by
|
||||
))
|
||||
result = cur.fetchone()
|
||||
cur.close()
|
||||
|
||||
return result
|
||||
|
||||
def update_note(self, note_id: UUID, note_text: str, updated_by: str) -> Dict[str, Any]:
|
||||
with self.get_db_connection() as conn:
|
||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||
|
||||
# First, mark current version as not current
|
||||
update_old = """
|
||||
UPDATE lead_notes
|
||||
SET is_current = false
|
||||
WHERE id = %s
|
||||
"""
|
||||
cur.execute(update_old, (str(note_id),))
|
||||
|
||||
# Create new version
|
||||
create_new = """
|
||||
INSERT INTO lead_notes
|
||||
(contact_id, note_text, created_by, parent_note_id, version)
|
||||
SELECT contact_id, %s, %s, %s, version + 1
|
||||
FROM lead_notes
|
||||
WHERE id = %s
|
||||
RETURNING *
|
||||
"""
|
||||
|
||||
cur.execute(create_new, (
|
||||
note_text,
|
||||
updated_by,
|
||||
str(note_id),
|
||||
str(note_id)
|
||||
))
|
||||
result = cur.fetchone()
|
||||
cur.close()
|
||||
|
||||
return result
|
||||
|
||||
def delete_note(self, note_id: UUID) -> bool:
|
||||
with self.get_db_connection() as conn:
|
||||
cur = conn.cursor()
|
||||
|
||||
# Soft delete by marking as not current
|
||||
query = """
|
||||
UPDATE lead_notes
|
||||
SET is_current = false
|
||||
WHERE id = %s
|
||||
"""
|
||||
cur.execute(query, (str(note_id),))
|
||||
|
||||
deleted = cur.rowcount > 0
|
||||
cur.close()
|
||||
|
||||
return deleted
|
||||
|
||||
def get_all_contacts_with_institutions(self) -> List[Dict[str, Any]]:
|
||||
"""Get all contacts with their institution information"""
|
||||
with self.get_db_connection() as conn:
|
||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||
|
||||
query = """
|
||||
SELECT
|
||||
c.id,
|
||||
c.first_name,
|
||||
c.last_name,
|
||||
c.position,
|
||||
c.created_at,
|
||||
c.updated_at,
|
||||
c.institution_id,
|
||||
i.name as institution_name,
|
||||
(SELECT COUNT(*) FROM lead_contact_details
|
||||
WHERE contact_id = c.id AND detail_type = 'phone') as phone_count,
|
||||
(SELECT COUNT(*) FROM lead_contact_details
|
||||
WHERE contact_id = c.id AND detail_type = 'email') as email_count,
|
||||
(SELECT COUNT(*) FROM lead_notes
|
||||
WHERE contact_id = c.id AND is_current = true) as note_count
|
||||
FROM lead_contacts c
|
||||
JOIN lead_institutions i ON i.id = c.institution_id
|
||||
ORDER BY c.last_name, c.first_name
|
||||
"""
|
||||
|
||||
cur.execute(query)
|
||||
results = cur.fetchall()
|
||||
cur.close()
|
||||
|
||||
return results
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren