171 Zeilen
6.4 KiB
Python
171 Zeilen
6.4 KiB
Python
# Business Logic Service for Lead Management
|
|
from typing import List, Dict, Any, Optional
|
|
from uuid import UUID
|
|
from datetime import datetime
|
|
from .repositories import LeadRepository
|
|
|
|
class LeadService:
|
|
def __init__(self, repository: LeadRepository):
|
|
self.repo = repository
|
|
|
|
# Institution Services
|
|
def list_institutions(self) -> List[Dict[str, Any]]:
|
|
"""Get all institutions with contact counts"""
|
|
return self.repo.get_institutions_with_counts()
|
|
|
|
def create_institution(self, name: str, user: str) -> Dict[str, Any]:
|
|
"""Create a new institution"""
|
|
# Validation
|
|
if not name or len(name.strip()) == 0:
|
|
raise ValueError("Institution name cannot be empty")
|
|
|
|
# Create institution
|
|
institution = self.repo.create_institution(name.strip(), user)
|
|
|
|
# Note: Audit logging removed as it requires different implementation
|
|
# Can be added later with proper audit system integration
|
|
|
|
return institution
|
|
|
|
def update_institution(self, institution_id: UUID, name: str, user: str) -> Dict[str, Any]:
|
|
"""Update institution name"""
|
|
# Validation
|
|
if not name or len(name.strip()) == 0:
|
|
raise ValueError("Institution name cannot be empty")
|
|
|
|
# Get current institution
|
|
current = self.repo.get_institution_by_id(institution_id)
|
|
if not current:
|
|
raise ValueError("Institution not found")
|
|
|
|
# Update
|
|
institution = self.repo.update_institution(institution_id, name.strip())
|
|
|
|
return institution
|
|
|
|
# Contact Services
|
|
def list_contacts_by_institution(self, institution_id: UUID) -> List[Dict[str, Any]]:
|
|
"""Get all contacts for an institution"""
|
|
return self.repo.get_contacts_by_institution(institution_id)
|
|
|
|
def create_contact(self, data: Dict[str, Any], user: str) -> Dict[str, Any]:
|
|
"""Create a new contact"""
|
|
# Validation
|
|
if not data.get('first_name') or not data.get('last_name'):
|
|
raise ValueError("First and last name are required")
|
|
|
|
if not data.get('institution_id'):
|
|
raise ValueError("Institution ID is required")
|
|
|
|
# Create contact
|
|
contact = self.repo.create_contact(data)
|
|
|
|
return contact
|
|
|
|
def get_contact_details(self, contact_id: UUID) -> Dict[str, Any]:
|
|
"""Get full contact information including details and notes"""
|
|
contact = self.repo.get_contact_with_details(contact_id)
|
|
if not contact:
|
|
raise ValueError("Contact not found")
|
|
|
|
# Group details by type
|
|
contact['phones'] = [d for d in contact.get('details', []) if d['detail_type'] == 'phone']
|
|
contact['emails'] = [d for d in contact.get('details', []) if d['detail_type'] == 'email']
|
|
|
|
return contact
|
|
|
|
def update_contact(self, contact_id: UUID, data: Dict[str, Any], user: str) -> Dict[str, Any]:
|
|
"""Update contact information"""
|
|
# Validation
|
|
if not data.get('first_name') or not data.get('last_name'):
|
|
raise ValueError("First and last name are required")
|
|
|
|
# Update contact
|
|
contact = self.repo.update_contact(contact_id, data)
|
|
|
|
return contact
|
|
|
|
# Contact Details Services
|
|
def add_phone(self, contact_id: UUID, phone_number: str,
|
|
phone_type: str = None, user: str = None) -> Dict[str, Any]:
|
|
"""Add phone number to contact"""
|
|
if not phone_number:
|
|
raise ValueError("Phone number is required")
|
|
|
|
detail = self.repo.add_contact_detail(
|
|
contact_id, 'phone', phone_number, phone_type
|
|
)
|
|
|
|
return detail
|
|
|
|
def add_email(self, contact_id: UUID, email: str,
|
|
email_type: str = None, user: str = None) -> Dict[str, Any]:
|
|
"""Add email to contact"""
|
|
if not email:
|
|
raise ValueError("Email is required")
|
|
|
|
# Basic email validation
|
|
if '@' not in email:
|
|
raise ValueError("Invalid email format")
|
|
|
|
detail = self.repo.add_contact_detail(
|
|
contact_id, 'email', email, email_type
|
|
)
|
|
|
|
return detail
|
|
|
|
def update_contact_detail(self, detail_id: UUID, detail_value: str,
|
|
detail_label: str = None, user: str = None) -> Dict[str, Any]:
|
|
"""Update a contact detail (phone/email)"""
|
|
if not detail_value or len(detail_value.strip()) == 0:
|
|
raise ValueError("Detail value cannot be empty")
|
|
|
|
# Get current detail to check type
|
|
current_detail = self.repo.get_contact_detail_by_id(detail_id)
|
|
if not current_detail:
|
|
raise ValueError("Contact detail not found")
|
|
|
|
# Validation based on type
|
|
if current_detail['detail_type'] == 'email' and '@' not in detail_value:
|
|
raise ValueError("Invalid email format")
|
|
|
|
detail = self.repo.update_contact_detail(
|
|
detail_id, detail_value.strip(), detail_label
|
|
)
|
|
|
|
return detail
|
|
|
|
def delete_contact_detail(self, detail_id: UUID, user: str) -> bool:
|
|
"""Delete a contact detail (phone/email)"""
|
|
success = self.repo.delete_contact_detail(detail_id)
|
|
|
|
return success
|
|
|
|
# Note Services
|
|
def add_note(self, contact_id: UUID, note_text: str, user: str) -> Dict[str, Any]:
|
|
"""Add a note to contact"""
|
|
if not note_text or len(note_text.strip()) == 0:
|
|
raise ValueError("Note text cannot be empty")
|
|
|
|
note = self.repo.create_note(contact_id, note_text.strip(), user)
|
|
|
|
return note
|
|
|
|
def update_note(self, note_id: UUID, note_text: str, user: str) -> Dict[str, Any]:
|
|
"""Update a note (creates new version)"""
|
|
if not note_text or len(note_text.strip()) == 0:
|
|
raise ValueError("Note text cannot be empty")
|
|
|
|
note = self.repo.update_note(note_id, note_text.strip(), user)
|
|
|
|
return note
|
|
|
|
def delete_note(self, note_id: UUID, user: str) -> bool:
|
|
"""Delete a note (soft delete)"""
|
|
success = self.repo.delete_note(note_id)
|
|
|
|
return success
|
|
|
|
def list_all_contacts(self) -> List[Dict[str, Any]]:
|
|
"""Get all contacts across all institutions with summary info"""
|
|
return self.repo.get_all_contacts_with_institutions() |