Dateien
Hetzner-Backup/v2_adminpanel/leads/routes.py

423 Zeilen
15 KiB
Python

# Routes for Lead Management
from flask import render_template, request, jsonify, redirect, url_for, flash
from auth.decorators import login_required
from flask import session as flask_session
from . import leads_bp
from .services import LeadService
from .repositories import LeadRepository
from db import get_db_connection
from uuid import UUID
import traceback
# Service will be initialized per request
lead_repository = None
lead_service = None
def get_lead_service():
"""Get or create lead service instance"""
global lead_repository, lead_service
if lead_service is None:
lead_repository = LeadRepository(get_db_connection) # Pass the function, not call it
lead_service = LeadService(lead_repository)
return lead_service
# HTML Routes
@leads_bp.route('/management')
@login_required
def lead_management():
"""Lead Management Dashboard"""
try:
# Get current user
current_user = flask_session.get('username', 'System')
other_user = 'w@rh@mm3r' if current_user == 'rac00n' else 'rac00n'
# Initialize defaults
total_institutions = 0
total_contacts = 0
my_entries = 0
other_entries = 0
activities = []
with get_db_connection() as conn:
cur = conn.cursor()
# Get statistics
cur.execute("SELECT COUNT(*) FROM lead_institutions")
result = cur.fetchone()
if result:
total_institutions = result[0]
cur.execute("SELECT COUNT(*) FROM lead_contacts")
result = cur.fetchone()
if result:
total_contacts = result[0]
# Count entries by current user
cur.execute("""
SELECT COUNT(*) FROM audit_log
WHERE username = %s
AND entity_type IN ('lead_institution', 'lead_contact')
AND action = 'CREATE'
""", (current_user,))
result = cur.fetchone()
if result:
my_entries = result[0]
# Count entries by other user
cur.execute("""
SELECT COUNT(*) FROM audit_log
WHERE username = %s
AND entity_type IN ('lead_institution', 'lead_contact')
AND action = 'CREATE'
""", (other_user,))
result = cur.fetchone()
if result:
other_entries = result[0]
# Get recent activities
cur.execute("""
SELECT timestamp, username, action, entity_type, additional_info
FROM audit_log
WHERE entity_type IN ('lead_institution', 'lead_contact')
ORDER BY timestamp DESC
LIMIT 10
""")
rows = cur.fetchall()
if rows:
for row in rows:
activities.append({
'timestamp': row[0],
'username': row[1],
'action': row[2],
'entity_type': row[3].replace('lead_', ''),
'additional_info': row[4]
})
cur.close()
return render_template('leads/lead_management.html',
total_institutions=total_institutions,
total_contacts=total_contacts,
my_entries=my_entries,
other_entries=other_entries,
other_user=other_user,
current_user=current_user,
recent_activities=activities)
except Exception as e:
import traceback
print(f"Error in lead_management: {str(e)}")
print(traceback.format_exc())
flash(f'Fehler beim Laden des Dashboards: {str(e)}', 'error')
current_user = flask_session.get('username', 'System')
return render_template('leads/lead_management.html',
total_institutions=0,
total_contacts=0,
my_entries=0,
other_entries=0,
other_user='',
current_user=current_user,
recent_activities=[])
@leads_bp.route('/')
@login_required
def institutions():
"""List all institutions"""
try:
institutions = get_lead_service().list_institutions()
return render_template('leads/institutions.html', institutions=institutions)
except Exception as e:
flash(f'Fehler beim Laden der Institutionen: {str(e)}', 'error')
return render_template('leads/institutions.html', institutions=[])
@leads_bp.route('/institution/add', methods=['POST'])
@login_required
def add_institution():
"""Add new institution from form"""
try:
name = request.form.get('name')
if not name:
flash('Name ist erforderlich', 'error')
return redirect(url_for('leads.lead_management'))
# Add institution
get_lead_service().create_institution(name, flask_session.get('username', 'System'))
flash(f'Institution "{name}" wurde erfolgreich hinzugefügt', 'success')
except Exception as e:
flash(f'Fehler beim Hinzufügen der Institution: {str(e)}', 'error')
return redirect(url_for('leads.lead_management'))
@leads_bp.route('/institution/<uuid:institution_id>')
@login_required
def institution_detail(institution_id):
"""Show institution with all contacts"""
try:
institution = lead_repository.get_institution_by_id(institution_id)
if not institution:
flash('Institution nicht gefunden', 'error')
return redirect(url_for('leads.institutions'))
contacts = get_lead_service().list_contacts_by_institution(institution_id)
return render_template('leads/institution_detail.html',
institution=institution,
contacts=contacts)
except Exception as e:
flash(f'Fehler beim Laden der Institution: {str(e)}', 'error')
return redirect(url_for('leads.institutions'))
@leads_bp.route('/contact/<uuid:contact_id>')
@login_required
def contact_detail(contact_id):
"""Show contact details with notes"""
try:
contact = get_lead_service().get_contact_details(contact_id)
return render_template('leads/contact_detail.html', contact=contact)
except Exception as e:
flash(f'Fehler beim Laden des Kontakts: {str(e)}', 'error')
return redirect(url_for('leads.institutions'))
@leads_bp.route('/contacts')
@login_required
def all_contacts():
"""Show all contacts across all institutions"""
try:
contacts = get_lead_service().list_all_contacts()
return render_template('leads/all_contacts.html', contacts=contacts)
except Exception as e:
flash(f'Fehler beim Laden der Kontakte: {str(e)}', 'error')
return render_template('leads/all_contacts.html', contacts=[])
# API Routes
@leads_bp.route('/api/institutions', methods=['POST'])
@login_required
def create_institution():
"""Create new institution"""
try:
data = request.get_json()
institution = get_lead_service().create_institution(
data['name'],
flask_session.get('username')
)
return jsonify({'success': True, 'institution': institution})
except ValueError as e:
return jsonify({'success': False, 'error': str(e)}), 400
except Exception as e:
return jsonify({'success': False, 'error': str(e)}), 500
@leads_bp.route('/api/institutions/<uuid:institution_id>', methods=['PUT'])
@login_required
def update_institution(institution_id):
"""Update institution"""
try:
data = request.get_json()
institution = get_lead_service().update_institution(
institution_id,
data['name'],
flask_session.get('username')
)
return jsonify({'success': True, 'institution': institution})
except ValueError as e:
return jsonify({'success': False, 'error': str(e)}), 400
except Exception as e:
return jsonify({'success': False, 'error': str(e)}), 500
@leads_bp.route('/api/contacts', methods=['POST'])
@login_required
def create_contact():
"""Create new contact"""
try:
data = request.get_json()
contact = get_lead_service().create_contact(data, flask_session.get('username'))
return jsonify({'success': True, 'contact': contact})
except ValueError as e:
return jsonify({'success': False, 'error': str(e)}), 400
except Exception as e:
return jsonify({'success': False, 'error': str(e)}), 500
@leads_bp.route('/api/contacts/<uuid:contact_id>', methods=['PUT'])
@login_required
def update_contact(contact_id):
"""Update contact"""
try:
data = request.get_json()
contact = get_lead_service().update_contact(
contact_id,
data,
flask_session.get('username')
)
return jsonify({'success': True, 'contact': contact})
except ValueError as e:
return jsonify({'success': False, 'error': str(e)}), 400
except Exception as e:
return jsonify({'success': False, 'error': str(e)}), 500
@leads_bp.route('/api/contacts/<uuid:contact_id>/phones', methods=['POST'])
@login_required
def add_phone(contact_id):
"""Add phone to contact"""
try:
data = request.get_json()
detail = get_lead_service().add_phone(
contact_id,
data['phone_number'],
data.get('phone_type'),
flask_session.get('username')
)
return jsonify({'success': True, 'detail': detail})
except ValueError as e:
return jsonify({'success': False, 'error': str(e)}), 400
except Exception as e:
return jsonify({'success': False, 'error': str(e)}), 500
@leads_bp.route('/api/contacts/<uuid:contact_id>/emails', methods=['POST'])
@login_required
def add_email(contact_id):
"""Add email to contact"""
try:
data = request.get_json()
detail = get_lead_service().add_email(
contact_id,
data['email'],
data.get('email_type'),
flask_session.get('username')
)
return jsonify({'success': True, 'detail': detail})
except ValueError as e:
return jsonify({'success': False, 'error': str(e)}), 400
except Exception as e:
return jsonify({'success': False, 'error': str(e)}), 500
@leads_bp.route('/api/details/<uuid:detail_id>', methods=['PUT'])
@login_required
def update_detail(detail_id):
"""Update contact detail (phone/email)"""
try:
data = request.get_json()
detail = get_lead_service().update_contact_detail(
detail_id,
data['detail_value'],
data.get('detail_label'),
flask_session.get('username')
)
return jsonify({'success': True, 'detail': detail})
except ValueError as e:
return jsonify({'success': False, 'error': str(e)}), 400
except Exception as e:
return jsonify({'success': False, 'error': str(e)}), 500
@leads_bp.route('/api/details/<uuid:detail_id>', methods=['DELETE'])
@login_required
def delete_detail(detail_id):
"""Delete contact detail"""
try:
success = get_lead_service().delete_contact_detail(
detail_id,
flask_session.get('username')
)
return jsonify({'success': success})
except Exception as e:
return jsonify({'success': False, 'error': str(e)}), 500
@leads_bp.route('/api/contacts/<uuid:contact_id>/notes', methods=['POST'])
@login_required
def add_note(contact_id):
"""Add note to contact"""
try:
data = request.get_json()
note = get_lead_service().add_note(
contact_id,
data['note_text'],
flask_session.get('username')
)
return jsonify({'success': True, 'note': note})
except ValueError as e:
return jsonify({'success': False, 'error': str(e)}), 400
except Exception as e:
return jsonify({'success': False, 'error': str(e)}), 500
@leads_bp.route('/api/notes/<uuid:note_id>', methods=['PUT'])
@login_required
def update_note(note_id):
"""Update note"""
try:
data = request.get_json()
note = get_lead_service().update_note(
note_id,
data['note_text'],
flask_session.get('username')
)
return jsonify({'success': True, 'note': note})
except ValueError as e:
return jsonify({'success': False, 'error': str(e)}), 400
except Exception as e:
return jsonify({'success': False, 'error': str(e)}), 500
@leads_bp.route('/api/notes/<uuid:note_id>', methods=['DELETE'])
@login_required
def delete_note(note_id):
"""Delete note"""
try:
success = get_lead_service().delete_note(
note_id,
flask_session.get('username')
)
return jsonify({'success': success})
except Exception as e:
return jsonify({'success': False, 'error': str(e)}), 500
# Export Routes
@leads_bp.route('/export')
@login_required
def export_leads():
"""Export leads data as Excel/CSV"""
from utils.export import create_excel_export, create_csv_export
try:
conn = get_db_connection()
cur = conn.cursor()
# Query institutions with contact counts
cur.execute("""
SELECT
i.id,
i.name,
i.type,
i.website,
i.address,
i.created_at,
i.created_by,
COUNT(DISTINCT c.id) as contact_count,
COUNT(DISTINCT cd.id) as contact_detail_count,
COUNT(DISTINCT n.id) as note_count
FROM lead_institutions i
LEFT JOIN lead_contacts c ON i.id = c.institution_id
LEFT JOIN lead_contact_details cd ON c.id = cd.contact_id
LEFT JOIN lead_notes n ON i.id = n.institution_id
GROUP BY i.id, i.name, i.type, i.website, i.address, i.created_at, i.created_by
ORDER BY i.name
""")
# Prepare data for export
data = []
columns = ['ID', 'Institution', 'Typ', 'Website', 'Adresse',
'Erstellt am', 'Erstellt von', 'Anzahl Kontakte',
'Anzahl Kontaktdetails', 'Anzahl Notizen']
for row in cur.fetchall():
data.append(list(row))
# Check format parameter
format_type = request.args.get('format', 'excel').lower()
if format_type == 'csv':
return create_csv_export(data, columns, 'leads')
else:
return create_excel_export(data, columns, 'leads')
except Exception as e:
flash(f'Fehler beim Export: {str(e)}', 'error')
return redirect(url_for('leads.institutions'))
finally:
cur.close()
conn.close()