Initial commit
Dieser Commit ist enthalten in:
397
v2_adminpanel/leads/routes.py
Normale Datei
397
v2_adminpanel/leads/routes.py
Normale Datei
@ -0,0 +1,397 @@
|
||||
# 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()
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren