first commit
This commit is contained in:
commit
e6c52820cd
227 changed files with 16156 additions and 0 deletions
849
modules/crm/cli.py
Normal file
849
modules/crm/cli.py
Normal file
|
|
@ -0,0 +1,849 @@
|
|||
import os
|
||||
from .client import Client
|
||||
from .handler import ClientHandler
|
||||
from .prospect import Prospect
|
||||
from .prospect_handler import ProspectHandler
|
||||
from datetime import date
|
||||
|
||||
def clear_screen():
|
||||
"""Efface l'écran du terminal"""
|
||||
os.system('cls' if os.name == 'nt' else 'clear')
|
||||
|
||||
def main():
|
||||
"""Point d'entrée pour l'application CRM"""
|
||||
client_handler = ClientHandler()
|
||||
prospect_handler = ProspectHandler()
|
||||
|
||||
while True:
|
||||
clear_screen()
|
||||
print("=== CRM - Gestion des Relations Clients ===\n")
|
||||
|
||||
print("1. Gestion des Clients")
|
||||
print("2. Gestion des Prospects")
|
||||
print("3. Tableau de bord")
|
||||
print("4. Retour au menu principal")
|
||||
|
||||
choice = input("\nSélectionnez une option (1-4): ")
|
||||
|
||||
if choice == "1":
|
||||
# Gestion des clients
|
||||
manage_clients(client_handler, prospect_handler)
|
||||
elif choice == "2":
|
||||
# Gestion des prospects
|
||||
manage_prospects(client_handler, prospect_handler)
|
||||
elif choice == "3":
|
||||
# Tableau de bord
|
||||
show_dashboard(client_handler, prospect_handler)
|
||||
elif choice == "4":
|
||||
# Retour au menu principal
|
||||
print("\nRetour au menu principal...")
|
||||
break
|
||||
else:
|
||||
print("\nOption invalide. Veuillez réessayer.")
|
||||
|
||||
input("\nAppuyez sur Entrée pour continuer...")
|
||||
|
||||
def display_all_clients(client_handler):
|
||||
"""Affiche tous les clients"""
|
||||
clear_screen()
|
||||
print("=== Liste des Clients ===\n")
|
||||
|
||||
clients = client_handler.get_all_clients()
|
||||
|
||||
if not clients:
|
||||
print("Aucun client trouvé.")
|
||||
return
|
||||
|
||||
for i, client in enumerate(clients, 1):
|
||||
print(f"{i}. {client.name} ({client.company})")
|
||||
print(f" Email: {client.email} | Téléphone: {client.phone}")
|
||||
print(f" Dernière interaction: {client.last_contact}")
|
||||
print(f" Documents: Devis ({len(client.linked_docs['devis'])}) | "
|
||||
f"Propositions ({len(client.linked_docs['propositions'])}) | "
|
||||
f"Factures ({len(client.linked_docs['factures'])})")
|
||||
print("")
|
||||
|
||||
def search_clients(client_handler):
|
||||
"""Recherche des clients par nom"""
|
||||
clear_screen()
|
||||
print("=== Recherche de Clients ===\n")
|
||||
|
||||
search_term = input("Entrez un terme de recherche (nom, email, entreprise): ")
|
||||
|
||||
if not search_term:
|
||||
print("Recherche annulée.")
|
||||
return
|
||||
|
||||
results = []
|
||||
clients = client_handler.get_all_clients()
|
||||
|
||||
for client in clients:
|
||||
if (search_term.lower() in client.name.lower() or
|
||||
search_term.lower() in client.email.lower() or
|
||||
search_term.lower() in client.company.lower()):
|
||||
results.append(client)
|
||||
|
||||
if not results:
|
||||
print(f"Aucun client trouvé pour '{search_term}'.")
|
||||
return
|
||||
|
||||
print(f"\n{len(results)} client(s) trouvé(s):\n")
|
||||
|
||||
for i, client in enumerate(results, 1):
|
||||
print(f"{i}. {client.name} ({client.company})")
|
||||
print(f" Email: {client.email} | Téléphone: {client.phone}")
|
||||
print("")
|
||||
|
||||
# Offrir la possibilité de voir les détails d'un client
|
||||
if results:
|
||||
choice = input("\nEntrez le numéro du client pour voir les détails (ou Entrée pour annuler): ")
|
||||
if choice.isdigit() and 1 <= int(choice) <= len(results):
|
||||
client = results[int(choice) - 1]
|
||||
display_client_details(client)
|
||||
|
||||
def add_new_client(client_handler):
|
||||
"""Ajoute un nouveau client"""
|
||||
clear_screen()
|
||||
print("=== Ajout d'un Nouveau Client ===\n")
|
||||
|
||||
# Recueillir les informations du client
|
||||
name = input("Nom du client: ")
|
||||
if not name:
|
||||
print("Le nom est obligatoire. Opération annulée.")
|
||||
return
|
||||
|
||||
company = input("Entreprise: ")
|
||||
email = input("Email: ")
|
||||
phone = input("Téléphone: ")
|
||||
notes = input("Notes: ")
|
||||
|
||||
# Créer le nouveau client
|
||||
new_client = Client(
|
||||
name=name,
|
||||
company=company,
|
||||
email=email,
|
||||
phone=phone,
|
||||
notes=notes
|
||||
)
|
||||
|
||||
# Ajouter le client
|
||||
client_handler.add_client(new_client)
|
||||
print(f"\nClient '{name}' ajouté avec succès!")
|
||||
|
||||
def edit_client(client_handler):
|
||||
"""Modifie un client existant"""
|
||||
clear_screen()
|
||||
print("=== Modification d'un Client ===\n")
|
||||
|
||||
# Afficher tous les clients pour sélection
|
||||
clients = client_handler.get_all_clients()
|
||||
|
||||
if not clients:
|
||||
print("Aucun client trouvé.")
|
||||
return
|
||||
|
||||
for i, client in enumerate(clients, 1):
|
||||
print(f"{i}. {client.name} ({client.company})")
|
||||
|
||||
# Sélectionner un client à modifier
|
||||
choice = input("\nEntrez le numéro du client à modifier (ou Entrée pour annuler): ")
|
||||
if not choice.isdigit() or int(choice) < 1 or int(choice) > len(clients):
|
||||
print("Opération annulée ou sélection invalide.")
|
||||
return
|
||||
|
||||
client = clients[int(choice) - 1]
|
||||
|
||||
# Afficher les détails actuels
|
||||
print(f"\nModification de '{client.name}':")
|
||||
print(f"1. Nom: {client.name}")
|
||||
print(f"2. Entreprise: {client.company}")
|
||||
print(f"3. Email: {client.email}")
|
||||
print(f"4. Téléphone: {client.phone}")
|
||||
print(f"5. Notes: {client.notes}")
|
||||
print("6. Tout modifier")
|
||||
print("7. Annuler")
|
||||
|
||||
# Choisir ce qu'il faut modifier
|
||||
edit_choice = input("\nQue souhaitez-vous modifier (1-7): ")
|
||||
|
||||
if edit_choice == "7":
|
||||
print("Modification annulée.")
|
||||
return
|
||||
|
||||
if edit_choice == "1" or edit_choice == "6":
|
||||
client.name = input(f"Nouveau nom [{client.name}]: ") or client.name
|
||||
|
||||
if edit_choice == "2" or edit_choice == "6":
|
||||
client.company = input(f"Nouvelle entreprise [{client.company}]: ") or client.company
|
||||
|
||||
if edit_choice == "3" or edit_choice == "6":
|
||||
client.email = input(f"Nouvel email [{client.email}]: ") or client.email
|
||||
|
||||
if edit_choice == "4" or edit_choice == "6":
|
||||
client.phone = input(f"Nouveau téléphone [{client.phone}]: ") or client.phone
|
||||
|
||||
if edit_choice == "5" or edit_choice == "6":
|
||||
client.notes = input(f"Nouvelles notes [{client.notes}]: ") or client.notes
|
||||
|
||||
# Mettre à jour le client
|
||||
client_handler.update_client(client)
|
||||
print(f"\nClient '{client.name}' mis à jour avec succès!")
|
||||
|
||||
def delete_client(client_handler):
|
||||
"""Supprime un client"""
|
||||
clear_screen()
|
||||
print("=== Suppression d'un Client ===\n")
|
||||
|
||||
# Afficher tous les clients pour sélection
|
||||
clients = client_handler.get_all_clients()
|
||||
|
||||
if not clients:
|
||||
print("Aucun client trouvé.")
|
||||
return
|
||||
|
||||
for i, client in enumerate(clients, 1):
|
||||
print(f"{i}. {client.name} ({client.company})")
|
||||
|
||||
# Sélectionner un client à supprimer
|
||||
choice = input("\nEntrez le numéro du client à supprimer (ou Entrée pour annuler): ")
|
||||
if not choice.isdigit() or int(choice) < 1 or int(choice) > len(clients):
|
||||
print("Opération annulée ou sélection invalide.")
|
||||
return
|
||||
|
||||
client = clients[int(choice) - 1]
|
||||
|
||||
# Confirmer la suppression
|
||||
confirm = input(f"Êtes-vous sûr de vouloir supprimer '{client.name}'? (o/n): ")
|
||||
|
||||
if confirm.lower() != 'o':
|
||||
print("Suppression annulée.")
|
||||
return
|
||||
|
||||
# Supprimer le client
|
||||
client_handler.delete_client(client.id)
|
||||
print(f"\nClient '{client.name}' supprimé avec succès!")
|
||||
|
||||
def view_client_documents(client_handler):
|
||||
"""Affiche les documents associés à un client"""
|
||||
clear_screen()
|
||||
print("=== Documents d'un Client ===\n")
|
||||
|
||||
# Afficher tous les clients pour sélection
|
||||
clients = client_handler.get_all_clients()
|
||||
|
||||
if not clients:
|
||||
print("Aucun client trouvé.")
|
||||
return
|
||||
|
||||
for i, client in enumerate(clients, 1):
|
||||
print(f"{i}. {client.name} ({client.company})")
|
||||
|
||||
# Sélectionner un client
|
||||
choice = input("\nEntrez le numéro du client pour voir ses documents (ou Entrée pour annuler): ")
|
||||
if not choice.isdigit() or int(choice) < 1 or int(choice) > len(clients):
|
||||
print("Opération annulée ou sélection invalide.")
|
||||
return
|
||||
|
||||
client = clients[int(choice) - 1]
|
||||
display_client_documents(client)
|
||||
|
||||
def display_client_details(client):
|
||||
"""Affiche les détails d'un client"""
|
||||
clear_screen()
|
||||
print(f"=== Détails du Client: {client.name} ===\n")
|
||||
|
||||
print(f"ID: {client.id}")
|
||||
print(f"Nom: {client.name}")
|
||||
print(f"Entreprise: {client.company}")
|
||||
print(f"Email: {client.email}")
|
||||
print(f"Téléphone: {client.phone}")
|
||||
print(f"Notes: {client.notes}")
|
||||
print(f"Dernière interaction: {client.last_contact}")
|
||||
print(f"Prochaine action: {client.next_action}")
|
||||
|
||||
if client.tags:
|
||||
print(f"Tags: {', '.join(client.tags)}")
|
||||
|
||||
# Afficher les documents
|
||||
display_client_documents(client)
|
||||
|
||||
def display_client_documents(client):
|
||||
"""Affiche les documents associés à un client"""
|
||||
print(f"\n=== Documents de {client.name} ===\n")
|
||||
|
||||
devis = client.linked_docs.get('devis', [])
|
||||
propositions = client.linked_docs.get('propositions', [])
|
||||
factures = client.linked_docs.get('factures', [])
|
||||
|
||||
if not devis and not propositions and not factures:
|
||||
print("Aucun document trouvé pour ce client.")
|
||||
return
|
||||
|
||||
if devis:
|
||||
print("Devis:")
|
||||
for i, doc in enumerate(devis, 1):
|
||||
print(f" {i}. {os.path.basename(doc)}")
|
||||
|
||||
if propositions:
|
||||
print("\nPropositions commerciales:")
|
||||
for i, doc in enumerate(propositions, 1):
|
||||
print(f" {i}. {os.path.basename(doc)}")
|
||||
|
||||
if factures:
|
||||
print("\nFactures:")
|
||||
for i, doc in enumerate(factures, 1):
|
||||
print(f" {i}. {os.path.basename(doc)}")
|
||||
|
||||
# Option pour ouvrir un document
|
||||
print("\n1. Ouvrir un document")
|
||||
print("2. Retour")
|
||||
|
||||
choice = input("\nQue souhaitez-vous faire (1-2): ")
|
||||
|
||||
if choice == "1":
|
||||
# Choisir le type de document
|
||||
print("\nType de document:")
|
||||
print("1. Devis")
|
||||
print("2. Proposition commerciale")
|
||||
print("3. Facture")
|
||||
|
||||
doc_type_choice = input("\nSélectionnez le type de document (1-3): ")
|
||||
|
||||
doc_list = []
|
||||
if doc_type_choice == "1" and devis:
|
||||
doc_list = devis
|
||||
doc_type_name = "devis"
|
||||
elif doc_type_choice == "2" and propositions:
|
||||
doc_list = propositions
|
||||
doc_type_name = "proposition commerciale"
|
||||
elif doc_type_choice == "3" and factures:
|
||||
doc_list = factures
|
||||
doc_type_name = "facture"
|
||||
else:
|
||||
print("Choix invalide ou aucun document de ce type.")
|
||||
return
|
||||
|
||||
# Afficher les documents du type sélectionné
|
||||
print(f"\n{doc_type_name.capitalize()}s disponibles:")
|
||||
for i, doc in enumerate(doc_list, 1):
|
||||
print(f" {i}. {os.path.basename(doc)}")
|
||||
|
||||
# Sélectionner un document à ouvrir
|
||||
doc_choice = input(f"\nSélectionnez un {doc_type_name} à ouvrir (1-{len(doc_list)}): ")
|
||||
|
||||
if doc_choice.isdigit() and 1 <= int(doc_choice) <= len(doc_list):
|
||||
selected_doc = doc_list[int(doc_choice) - 1]
|
||||
open_document(selected_doc)
|
||||
else:
|
||||
print("Sélection invalide.")
|
||||
|
||||
def open_document(document_path):
|
||||
"""Ouvre un document PDF"""
|
||||
try:
|
||||
if os.path.exists(document_path):
|
||||
if os.name == 'nt': # Windows
|
||||
os.startfile(document_path)
|
||||
elif os.name == 'posix': # macOS et Linux
|
||||
if 'darwin' in os.uname().sysname.lower(): # macOS
|
||||
os.system(f'open "{document_path}"')
|
||||
else: # Linux
|
||||
os.system(f'xdg-open "{document_path}"')
|
||||
print(f"Document ouvert: {os.path.basename(document_path)}")
|
||||
else:
|
||||
print(f"Erreur: Le document {document_path} n'existe pas.")
|
||||
except Exception as e:
|
||||
print(f"Erreur lors de l'ouverture du document: {e}")
|
||||
|
||||
def manage_clients(client_handler, prospect_handler):
|
||||
"""Gestion des clients"""
|
||||
while True:
|
||||
clear_screen()
|
||||
print("=== Gestion des Clients ===\n")
|
||||
|
||||
print("1. Afficher tous les clients")
|
||||
print("2. Rechercher un client")
|
||||
print("3. Ajouter un nouveau client")
|
||||
print("4. Modifier un client")
|
||||
print("5. Supprimer un client")
|
||||
print("6. Voir les documents d'un client")
|
||||
print("7. Retour")
|
||||
|
||||
choice = input("\nSélectionnez une option (1-7): ")
|
||||
|
||||
if choice == "1":
|
||||
# Afficher tous les clients
|
||||
display_all_clients(client_handler)
|
||||
elif choice == "2":
|
||||
# Rechercher un client
|
||||
search_clients(client_handler)
|
||||
elif choice == "3":
|
||||
# Ajouter un nouveau client
|
||||
add_new_client(client_handler)
|
||||
elif choice == "4":
|
||||
# Modifier un client
|
||||
edit_client(client_handler)
|
||||
elif choice == "5":
|
||||
# Supprimer un client
|
||||
delete_client(client_handler)
|
||||
elif choice == "6":
|
||||
# Voir les documents d'un client
|
||||
view_client_documents(client_handler)
|
||||
elif choice == "7":
|
||||
# Retour
|
||||
break
|
||||
else:
|
||||
print("\nOption invalide. Veuillez réessayer.")
|
||||
|
||||
input("\nAppuyez sur Entrée pour continuer...")
|
||||
|
||||
def manage_prospects(client_handler, prospect_handler):
|
||||
"""Gestion des prospects"""
|
||||
while True:
|
||||
clear_screen()
|
||||
print("=== Gestion des Prospects ===\n")
|
||||
|
||||
print("1. Afficher tous les prospects")
|
||||
print("2. Rechercher un prospect")
|
||||
print("3. Ajouter un nouveau prospect")
|
||||
print("4. Modifier un prospect")
|
||||
print("5. Supprimer un prospect")
|
||||
print("6. Convertir un prospect en client")
|
||||
print("7. Afficher les prospects par statut")
|
||||
print("8. Retour")
|
||||
|
||||
choice = input("\nSélectionnez une option (1-8): ")
|
||||
|
||||
if choice == "1":
|
||||
# Afficher tous les prospects
|
||||
display_all_prospects(prospect_handler)
|
||||
elif choice == "2":
|
||||
# Rechercher un prospect
|
||||
search_prospects(prospect_handler)
|
||||
elif choice == "3":
|
||||
# Ajouter un nouveau prospect
|
||||
add_new_prospect(prospect_handler)
|
||||
elif choice == "4":
|
||||
# Modifier un prospect
|
||||
edit_prospect(prospect_handler)
|
||||
elif choice == "5":
|
||||
# Supprimer un prospect
|
||||
delete_prospect(prospect_handler)
|
||||
elif choice == "6":
|
||||
# Convertir un prospect en client
|
||||
convert_prospect_to_client(prospect_handler, client_handler)
|
||||
elif choice == "7":
|
||||
# Afficher les prospects par statut
|
||||
display_prospects_by_status(prospect_handler)
|
||||
elif choice == "8":
|
||||
# Retour
|
||||
break
|
||||
else:
|
||||
print("\nOption invalide. Veuillez réessayer.")
|
||||
|
||||
input("\nAppuyez sur Entrée pour continuer...")
|
||||
|
||||
def show_dashboard(client_handler, prospect_handler):
|
||||
"""Affiche un tableau de bord avec des statistiques"""
|
||||
clear_screen()
|
||||
print("=== Tableau de Bord CRM ===\n")
|
||||
|
||||
# Récupérer les données
|
||||
clients = client_handler.get_all_clients()
|
||||
prospects = prospect_handler.get_all_prospects()
|
||||
|
||||
# Statistiques de base
|
||||
print(f"Nombre total de clients: {len(clients)}")
|
||||
print(f"Nombre total de prospects: {len(prospects)}")
|
||||
|
||||
# Statistiques des prospects par statut
|
||||
statuses = {}
|
||||
for prospect in prospects:
|
||||
status = prospect.status
|
||||
if status in statuses:
|
||||
statuses[status] += 1
|
||||
else:
|
||||
statuses[status] = 1
|
||||
|
||||
if statuses:
|
||||
print("\nProspects par statut:")
|
||||
for status, count in statuses.items():
|
||||
print(f" {status}: {count}")
|
||||
|
||||
# Derniers prospects ajoutés
|
||||
recent_prospects = prospect_handler.get_recent_prospects(days=30)
|
||||
if recent_prospects:
|
||||
print(f"\nNouveaux prospects (30 derniers jours): {len(recent_prospects)}")
|
||||
|
||||
# Activité récente
|
||||
print("\nRécapitulatif des activités récentes:")
|
||||
print(" Propositions commerciales en attente...")
|
||||
print(" Devis en cours...")
|
||||
|
||||
# Suggestions d'actions
|
||||
print("\nSuggestions d'actions:")
|
||||
if len(prospects) > 0:
|
||||
print(" • Suivez vos prospects pour augmenter votre taux de conversion")
|
||||
if len(clients) > 0:
|
||||
print(" • Contactez vos clients existants pour des opportunités de vente additionnelle")
|
||||
if len(prospects) == 0:
|
||||
print(" • Ajoutez des prospects pour développer votre portefeuille client")
|
||||
|
||||
def display_all_prospects(prospect_handler):
|
||||
"""Affiche tous les prospects"""
|
||||
clear_screen()
|
||||
print("=== Liste des Prospects ===\n")
|
||||
|
||||
prospects = prospect_handler.get_all_prospects()
|
||||
|
||||
if not prospects:
|
||||
print("Aucun prospect trouvé.")
|
||||
return
|
||||
|
||||
for i, prospect in enumerate(prospects, 1):
|
||||
print(f"{i}. {prospect.name} ({prospect.company})")
|
||||
print(f" Email: {prospect.email} | Téléphone: {prospect.phone}")
|
||||
print(f" Statut: {prospect.status} | Source: {prospect.source}")
|
||||
print(f" Dernière interaction: {prospect.last_contact}")
|
||||
print("")
|
||||
|
||||
def search_prospects(prospect_handler):
|
||||
"""Recherche des prospects par nom"""
|
||||
clear_screen()
|
||||
print("=== Recherche de Prospects ===\n")
|
||||
|
||||
search_term = input("Entrez un terme de recherche (nom, email, entreprise): ")
|
||||
|
||||
if not search_term:
|
||||
print("Recherche annulée.")
|
||||
return
|
||||
|
||||
results = []
|
||||
prospects = prospect_handler.get_all_prospects()
|
||||
|
||||
for prospect in prospects:
|
||||
if (search_term.lower() in prospect.name.lower() or
|
||||
search_term.lower() in prospect.email.lower() or
|
||||
search_term.lower() in prospect.company.lower()):
|
||||
results.append(prospect)
|
||||
|
||||
if not results:
|
||||
print(f"Aucun prospect trouvé pour '{search_term}'.")
|
||||
return
|
||||
|
||||
print(f"\n{len(results)} prospect(s) trouvé(s):\n")
|
||||
|
||||
for i, prospect in enumerate(results, 1):
|
||||
print(f"{i}. {prospect.name} ({prospect.company})")
|
||||
print(f" Email: {prospect.email} | Téléphone: {prospect.phone}")
|
||||
print(f" Statut: {prospect.status}")
|
||||
print("")
|
||||
|
||||
# Offrir la possibilité de voir les détails d'un prospect
|
||||
if results:
|
||||
choice = input("\nEntrez le numéro du prospect pour voir les détails (ou Entrée pour annuler): ")
|
||||
if choice.isdigit() and 1 <= int(choice) <= len(results):
|
||||
prospect = results[int(choice) - 1]
|
||||
display_prospect_details(prospect)
|
||||
|
||||
def add_new_prospect(prospect_handler):
|
||||
"""Ajoute un nouveau prospect"""
|
||||
clear_screen()
|
||||
print("=== Ajout d'un Nouveau Prospect ===\n")
|
||||
|
||||
# Recueillir les informations du prospect
|
||||
name = input("Nom du prospect: ")
|
||||
if not name:
|
||||
print("Le nom est obligatoire. Opération annulée.")
|
||||
return
|
||||
|
||||
company = input("Entreprise: ")
|
||||
email = input("Email: ")
|
||||
phone = input("Téléphone: ")
|
||||
source = input("Source (site web, référence, salon, etc.): ")
|
||||
notes = input("Notes: ")
|
||||
|
||||
# Statut du prospect
|
||||
print("\nStatut du prospect:")
|
||||
print("1. Nouveau")
|
||||
print("2. Contacté")
|
||||
print("3. Qualifié")
|
||||
print("4. Proposition envoyée")
|
||||
print("5. Non intéressé")
|
||||
|
||||
status_choice = input("\nSélectionnez le statut (1-5): ")
|
||||
status = "Nouveau" # Défaut
|
||||
|
||||
if status_choice == "1":
|
||||
status = "Nouveau"
|
||||
elif status_choice == "2":
|
||||
status = "Contacté"
|
||||
elif status_choice == "3":
|
||||
status = "Qualifié"
|
||||
elif status_choice == "4":
|
||||
status = "Proposition envoyée"
|
||||
elif status_choice == "5":
|
||||
status = "Non intéressé"
|
||||
|
||||
# Créer le nouveau prospect
|
||||
new_prospect = Prospect(
|
||||
name=name,
|
||||
company=company,
|
||||
email=email,
|
||||
phone=phone,
|
||||
source=source,
|
||||
notes=notes,
|
||||
status=status
|
||||
)
|
||||
|
||||
# Ajouter le prospect
|
||||
prospect_handler.add_prospect(new_prospect)
|
||||
print(f"\nProspect '{name}' ajouté avec succès!")
|
||||
|
||||
def edit_prospect(prospect_handler):
|
||||
"""Modifie un prospect existant"""
|
||||
clear_screen()
|
||||
print("=== Modification d'un Prospect ===\n")
|
||||
|
||||
# Afficher tous les prospects pour sélection
|
||||
prospects = prospect_handler.get_all_prospects()
|
||||
|
||||
if not prospects:
|
||||
print("Aucun prospect trouvé.")
|
||||
return
|
||||
|
||||
for i, prospect in enumerate(prospects, 1):
|
||||
print(f"{i}. {prospect.name} ({prospect.company}) - {prospect.status}")
|
||||
|
||||
# Sélectionner un prospect à modifier
|
||||
choice = input("\nEntrez le numéro du prospect à modifier (ou Entrée pour annuler): ")
|
||||
if not choice.isdigit() or int(choice) < 1 or int(choice) > len(prospects):
|
||||
print("Opération annulée ou sélection invalide.")
|
||||
return
|
||||
|
||||
prospect = prospects[int(choice) - 1]
|
||||
|
||||
# Afficher les détails actuels
|
||||
print(f"\nModification de '{prospect.name}':")
|
||||
print(f"1. Nom: {prospect.name}")
|
||||
print(f"2. Entreprise: {prospect.company}")
|
||||
print(f"3. Email: {prospect.email}")
|
||||
print(f"4. Téléphone: {prospect.phone}")
|
||||
print(f"5. Source: {prospect.source}")
|
||||
print(f"6. Statut: {prospect.status}")
|
||||
print(f"7. Notes: {prospect.notes}")
|
||||
print("8. Tout modifier")
|
||||
print("9. Annuler")
|
||||
|
||||
# Choisir ce qu'il faut modifier
|
||||
edit_choice = input("\nQue souhaitez-vous modifier (1-9): ")
|
||||
|
||||
if edit_choice == "9":
|
||||
print("Modification annulée.")
|
||||
return
|
||||
|
||||
if edit_choice == "1" or edit_choice == "8":
|
||||
prospect.name = input(f"Nouveau nom [{prospect.name}]: ") or prospect.name
|
||||
|
||||
if edit_choice == "2" or edit_choice == "8":
|
||||
prospect.company = input(f"Nouvelle entreprise [{prospect.company}]: ") or prospect.company
|
||||
|
||||
if edit_choice == "3" or edit_choice == "8":
|
||||
prospect.email = input(f"Nouvel email [{prospect.email}]: ") or prospect.email
|
||||
|
||||
if edit_choice == "4" or edit_choice == "8":
|
||||
prospect.phone = input(f"Nouveau téléphone [{prospect.phone}]: ") or prospect.phone
|
||||
|
||||
if edit_choice == "5" or edit_choice == "8":
|
||||
prospect.source = input(f"Nouvelle source [{prospect.source}]: ") or prospect.source
|
||||
|
||||
if edit_choice == "6" or edit_choice == "8":
|
||||
print("\nStatut du prospect:")
|
||||
print("1. Nouveau")
|
||||
print("2. Contacté")
|
||||
print("3. Qualifié")
|
||||
print("4. Proposition envoyée")
|
||||
print("5. Non intéressé")
|
||||
|
||||
status_choice = input(f"\nSélectionnez le statut (1-5) [Actuel: {prospect.status}]: ")
|
||||
|
||||
if status_choice == "1":
|
||||
prospect.status = "Nouveau"
|
||||
elif status_choice == "2":
|
||||
prospect.status = "Contacté"
|
||||
elif status_choice == "3":
|
||||
prospect.status = "Qualifié"
|
||||
elif status_choice == "4":
|
||||
prospect.status = "Proposition envoyée"
|
||||
elif status_choice == "5":
|
||||
prospect.status = "Non intéressé"
|
||||
|
||||
if edit_choice == "7" or edit_choice == "8":
|
||||
prospect.notes = input(f"Nouvelles notes [{prospect.notes}]: ") or prospect.notes
|
||||
|
||||
# Mettre à jour le prospect
|
||||
prospect_handler.update_prospect(prospect)
|
||||
print(f"\nProspect '{prospect.name}' mis à jour avec succès!")
|
||||
|
||||
def delete_prospect(prospect_handler):
|
||||
"""Supprime un prospect"""
|
||||
clear_screen()
|
||||
print("=== Suppression d'un Prospect ===\n")
|
||||
|
||||
# Afficher tous les prospects pour sélection
|
||||
prospects = prospect_handler.get_all_prospects()
|
||||
|
||||
if not prospects:
|
||||
print("Aucun prospect trouvé.")
|
||||
return
|
||||
|
||||
for i, prospect in enumerate(prospects, 1):
|
||||
print(f"{i}. {prospect.name} ({prospect.company}) - {prospect.status}")
|
||||
|
||||
# Sélectionner un prospect à supprimer
|
||||
choice = input("\nEntrez le numéro du prospect à supprimer (ou Entrée pour annuler): ")
|
||||
if not choice.isdigit() or int(choice) < 1 or int(choice) > len(prospects):
|
||||
print("Opération annulée ou sélection invalide.")
|
||||
return
|
||||
|
||||
prospect = prospects[int(choice) - 1]
|
||||
|
||||
# Confirmer la suppression
|
||||
confirm = input(f"Êtes-vous sûr de vouloir supprimer '{prospect.name}'? (o/n): ")
|
||||
|
||||
if confirm.lower() != 'o':
|
||||
print("Suppression annulée.")
|
||||
return
|
||||
|
||||
# Supprimer le prospect
|
||||
prospect_handler.delete_prospect(prospect.id)
|
||||
print(f"\nProspect '{prospect.name}' supprimé avec succès!")
|
||||
|
||||
def convert_prospect_to_client(prospect_handler, client_handler):
|
||||
"""Convertit un prospect en client"""
|
||||
clear_screen()
|
||||
print("=== Conversion d'un Prospect en Client ===\n")
|
||||
|
||||
# Afficher tous les prospects pour sélection
|
||||
prospects = prospect_handler.get_all_prospects()
|
||||
|
||||
if not prospects:
|
||||
print("Aucun prospect trouvé.")
|
||||
return
|
||||
|
||||
for i, prospect in enumerate(prospects, 1):
|
||||
print(f"{i}. {prospect.name} ({prospect.company}) - {prospect.status}")
|
||||
|
||||
# Sélectionner un prospect à convertir
|
||||
choice = input("\nEntrez le numéro du prospect à convertir en client (ou Entrée pour annuler): ")
|
||||
if not choice.isdigit() or int(choice) < 1 or int(choice) > len(prospects):
|
||||
print("Opération annulée ou sélection invalide.")
|
||||
return
|
||||
|
||||
prospect = prospects[int(choice) - 1]
|
||||
|
||||
# Confirmer la conversion
|
||||
confirm = input(f"Êtes-vous sûr de vouloir convertir '{prospect.name}' en client? (o/n): ")
|
||||
|
||||
if confirm.lower() != 'o':
|
||||
print("Conversion annulée.")
|
||||
return
|
||||
|
||||
# Convertir le prospect en client
|
||||
client = prospect_handler.convert_to_client(prospect.id, client_handler)
|
||||
if client:
|
||||
print(f"\nProspect '{prospect.name}' converti en client avec succès!")
|
||||
else:
|
||||
print("\nErreur lors de la conversion du prospect en client.")
|
||||
|
||||
def display_prospect_details(prospect):
|
||||
"""Affiche les détails d'un prospect"""
|
||||
clear_screen()
|
||||
print(f"=== Détails du Prospect: {prospect.name} ===\n")
|
||||
|
||||
print(f"ID: {prospect.id}")
|
||||
print(f"Nom: {prospect.name}")
|
||||
print(f"Entreprise: {prospect.company}")
|
||||
print(f"Email: {prospect.email}")
|
||||
print(f"Téléphone: {prospect.phone}")
|
||||
print(f"Source: {prospect.source}")
|
||||
print(f"Statut: {prospect.status}")
|
||||
print(f"Notes: {prospect.notes}")
|
||||
print(f"Dernière interaction: {prospect.last_contact}")
|
||||
print(f"Prochaine action: {prospect.next_action}")
|
||||
|
||||
if prospect.tags:
|
||||
print(f"Tags: {', '.join(prospect.tags)}")
|
||||
|
||||
def display_prospects_by_status(prospect_handler):
|
||||
"""Affiche les prospects regroupés par statut"""
|
||||
clear_screen()
|
||||
print("=== Prospects par Statut ===\n")
|
||||
|
||||
# Récupérer tous les prospects
|
||||
prospects = prospect_handler.get_all_prospects()
|
||||
|
||||
if not prospects:
|
||||
print("Aucun prospect trouvé.")
|
||||
return
|
||||
|
||||
# Regrouper les prospects par statut
|
||||
status_groups = {}
|
||||
for prospect in prospects:
|
||||
status = prospect.status
|
||||
if status not in status_groups:
|
||||
status_groups[status] = []
|
||||
status_groups[status].append(prospect)
|
||||
|
||||
# Afficher les prospects par groupe de statut
|
||||
for status, prospects_list in status_groups.items():
|
||||
print(f"\n=== {status} ({len(prospects_list)}) ===")
|
||||
for i, prospect in enumerate(prospects_list, 1):
|
||||
print(f"{i}. {prospect.name} ({prospect.company})")
|
||||
print(f" Email: {prospect.email} | Téléphone: {prospect.phone}")
|
||||
|
||||
print("\n")
|
||||
|
||||
# Option pour filtrer par un statut spécifique
|
||||
print("Voulez-vous voir les détails d'un statut spécifique?")
|
||||
print("1. Nouveau")
|
||||
print("2. Contacté")
|
||||
print("3. Qualifié")
|
||||
print("4. Proposition envoyée")
|
||||
print("5. Non intéressé")
|
||||
print("6. Retour")
|
||||
|
||||
choice = input("\nSélectionnez une option (1-6): ")
|
||||
|
||||
status_mapping = {
|
||||
"1": "Nouveau",
|
||||
"2": "Contacté",
|
||||
"3": "Qualifié",
|
||||
"4": "Proposition envoyée",
|
||||
"5": "Non intéressé"
|
||||
}
|
||||
|
||||
if choice in status_mapping:
|
||||
selected_status = status_mapping[choice]
|
||||
filtered_prospects = prospect_handler.get_prospects_by_status(selected_status)
|
||||
|
||||
if filtered_prospects:
|
||||
clear_screen()
|
||||
print(f"=== Prospects avec statut: {selected_status} ===\n")
|
||||
|
||||
for i, prospect in enumerate(filtered_prospects, 1):
|
||||
print(f"{i}. {prospect.name} ({prospect.company})")
|
||||
print(f" Email: {prospect.email} | Téléphone: {prospect.phone}")
|
||||
print(f" Dernière interaction: {prospect.last_contact}")
|
||||
print(f" Notes: {prospect.notes[:50]}..." if len(prospect.notes) > 50 else f" Notes: {prospect.notes}")
|
||||
print("")
|
||||
|
||||
# Option pour voir les détails d'un prospect spécifique
|
||||
detail_choice = input("\nEntrez le numéro du prospect pour voir les détails (ou Entrée pour annuler): ")
|
||||
if detail_choice.isdigit() and 1 <= int(detail_choice) <= len(filtered_prospects):
|
||||
prospect = filtered_prospects[int(detail_choice) - 1]
|
||||
display_prospect_details(prospect)
|
||||
else:
|
||||
print(f"\nAucun prospect avec le statut '{selected_status}' trouvé.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue