# 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 # Initialize service lead_repository = LeadRepository(get_db_connection) lead_service = LeadService(lead_repository) # HTML Routes @leads_bp.route('/') @login_required def institutions(): """List all institutions""" try: institutions = 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/') @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 = 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/') @login_required def contact_detail(contact_id): """Show contact details with notes""" try: contact = 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 = 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 = 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/', methods=['PUT']) @login_required def update_institution(institution_id): """Update institution""" try: data = request.get_json() institution = 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 = 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/', methods=['PUT']) @login_required def update_contact(contact_id): """Update contact""" try: data = request.get_json() contact = 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//phones', methods=['POST']) @login_required def add_phone(contact_id): """Add phone to contact""" try: data = request.get_json() detail = 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//emails', methods=['POST']) @login_required def add_email(contact_id): """Add email to contact""" try: data = request.get_json() detail = 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/', methods=['PUT']) @login_required def update_detail(detail_id): """Update contact detail (phone/email)""" try: data = request.get_json() detail = 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/', methods=['DELETE']) @login_required def delete_detail(detail_id): """Delete contact detail""" try: success = 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//notes', methods=['POST']) @login_required def add_note(contact_id): """Add note to contact""" try: data = request.get_json() note = 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/', methods=['PUT']) @login_required def update_note(note_id): """Update note""" try: data = request.get_json() note = 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/', methods=['DELETE']) @login_required def delete_note(note_id): """Delete note""" try: success = 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()