Files
Claude Project Manager 0d7d888502 Initial commit
2025-07-05 17:51:16 +02:00

397 Zeilen
14 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 institutions with contact counts
institutions = get_lead_service().list_institutions()
# Get all contacts with institution names
all_contacts = get_lead_service().list_all_contacts()
# Calculate totals
total_institutions = len(institutions)
total_contacts = len(all_contacts)
return render_template('leads/lead_management.html',
total_institutions=total_institutions,
total_contacts=total_contacts,
institutions=institutions,
all_contacts=all_contacts)
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,
institutions=[],
all_contacts=[])
@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('/contact/add', methods=['POST'])
@login_required
def add_contact():
"""Add new contact from form"""
try:
data = {
'institution_id': request.form.get('institution_id'),
'first_name': request.form.get('first_name'),
'last_name': request.form.get('last_name'),
'position': request.form.get('position')
}
# Validate required fields
if not data['institution_id'] or not data['first_name'] or not data['last_name']:
flash('Institution, Vorname und Nachname sind erforderlich', 'error')
return redirect(url_for('leads.lead_management'))
# Create contact
contact = get_lead_service().create_contact(data, flask_session.get('username', 'System'))
# Add email if provided
email = request.form.get('email')
if email:
get_lead_service().add_email(contact['id'], email, 'Primär', flask_session.get('username', 'System'))
# Add phone if provided
phone = request.form.get('phone')
if phone:
get_lead_service().add_phone(contact['id'], phone, 'Primär', flask_session.get('username', 'System'))
flash(f'Kontakt "{data["first_name"]} {data["last_name"]}" wurde erfolgreich hinzugefügt', 'success')
except Exception as e:
flash(f'Fehler beim Hinzufügen des Kontakts: {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:
# Get institution through repository
service = get_lead_service()
institution = service.repo.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()