172 lines
No EOL
7.4 KiB
Python
172 lines
No EOL
7.4 KiB
Python
from datetime import date
|
|
import os
|
|
import json
|
|
from .client import Client
|
|
from core.data import Data
|
|
|
|
class ClientHandler:
|
|
def __init__(self, clients_folder="Data/clients"):
|
|
self.clients_folder = clients_folder
|
|
self.clients = []
|
|
self.load_clients()
|
|
|
|
def load_clients(self):
|
|
"""Charge tous les clients depuis les fichiers existants"""
|
|
self.clients = []
|
|
# Charger les clients depuis les fichiers JSON existants
|
|
if os.path.exists(self.clients_folder):
|
|
for filename in os.listdir(self.clients_folder):
|
|
if filename.endswith('.json'):
|
|
client_path = os.path.join(self.clients_folder, filename)
|
|
try:
|
|
# Utiliser le gestionnaire de données pour charger le fichier JSON
|
|
data_manager = Data(client_path)
|
|
client_data = data_manager.load_data()
|
|
|
|
# Si le fichier a la structure d'un client, créer un objet Client
|
|
if "client_name" in client_data:
|
|
# Conversion du format existant vers le format Client
|
|
client_obj = {
|
|
"name": client_data.get("client_name", ""),
|
|
"email": client_data.get("client_email", ""),
|
|
"phone": client_data.get("client_phone", ""),
|
|
"notes": client_data.get("additional_info", ""),
|
|
"company": client_data.get("project_name", ""),
|
|
"tags": [], # Pas de tags dans les données existantes
|
|
"next_action": "", # Pas d'action suivante dans les données existantes
|
|
"linked_docs": self._find_linked_docs(client_data.get("client_name", ""))
|
|
}
|
|
client = Client(**client_obj)
|
|
self.clients.append(client)
|
|
except Exception as e:
|
|
print(f"Erreur lors du chargement du client {filename}: {e}")
|
|
|
|
return self.clients
|
|
|
|
def _find_linked_docs(self, client_name):
|
|
"""Trouve les documents associés à un client"""
|
|
linked_docs = {"devis": [], "propositions": [], "factures": []}
|
|
client_name_normalized = client_name.replace(" ", "_").lower()
|
|
|
|
# Rechercher les devis
|
|
devis_folder = "output/devis"
|
|
if os.path.exists(devis_folder):
|
|
for filename in os.listdir(devis_folder):
|
|
if filename.startswith(client_name_normalized) and filename.endswith(".pdf"):
|
|
linked_docs["devis"].append(os.path.join(devis_folder, filename))
|
|
|
|
# Rechercher les propositions
|
|
propositions_folder = "output/propositions"
|
|
if os.path.exists(propositions_folder):
|
|
for filename in os.listdir(propositions_folder):
|
|
if filename.startswith(client_name_normalized) and filename.endswith(".pdf"):
|
|
linked_docs["propositions"].append(os.path.join(propositions_folder, filename))
|
|
|
|
# Rechercher les factures (si elles existent)
|
|
factures_folder = "output/factures"
|
|
if os.path.exists(factures_folder):
|
|
for filename in os.listdir(factures_folder):
|
|
if filename.startswith(client_name_normalized) and filename.endswith(".pdf"):
|
|
linked_docs["factures"].append(os.path.join(factures_folder, filename))
|
|
|
|
return linked_docs
|
|
|
|
def get_all_clients(self):
|
|
"""Retourne tous les clients"""
|
|
return self.clients
|
|
|
|
def get_client_by_id(self, client_id):
|
|
"""Retourne un client par son ID"""
|
|
for client in self.clients:
|
|
if client.id == client_id:
|
|
return client
|
|
return None
|
|
|
|
def get_client_by_name(self, client_name):
|
|
"""Retourne un client par son nom"""
|
|
for client in self.clients:
|
|
if client.name.lower() == client_name.lower():
|
|
return client
|
|
return None
|
|
|
|
def add_client(self, client):
|
|
"""Ajoute un nouveau client"""
|
|
self.clients.append(client)
|
|
# Sauvegarder le client dans un fichier JSON
|
|
self._save_client(client)
|
|
return client
|
|
|
|
def update_client(self, client):
|
|
"""Met à jour un client existant"""
|
|
for i, existing_client in enumerate(self.clients):
|
|
if existing_client.id == client.id:
|
|
self.clients[i] = client
|
|
# Sauvegarder le client mis à jour
|
|
self._save_client(client)
|
|
return client
|
|
return None
|
|
|
|
def delete_client(self, client_id):
|
|
"""Supprime un client"""
|
|
for i, client in enumerate(self.clients):
|
|
if client.id == client_id:
|
|
deleted_client = self.clients.pop(i)
|
|
# Supprimer le fichier JSON du client
|
|
client_file = os.path.join(self.clients_folder, f"{deleted_client.name.replace(' ', '_').lower()}.json")
|
|
if os.path.exists(client_file):
|
|
os.remove(client_file)
|
|
return deleted_client
|
|
return None
|
|
|
|
def _save_client(self, client):
|
|
"""Sauvegarde un client dans un fichier JSON"""
|
|
client_data = {
|
|
"client_name": client.name,
|
|
"client_email": client.email,
|
|
"client_phone": client.phone,
|
|
"additional_info": client.notes,
|
|
"project_name": client.company,
|
|
# Autres champs pour maintenir la compatibilité avec le format existant
|
|
"project_type": "",
|
|
"project_description": "",
|
|
"features": [],
|
|
"budget": "",
|
|
"payment_terms": "",
|
|
"contact_info": f"{client.name}, {client.phone}",
|
|
"deadline": ""
|
|
}
|
|
|
|
client_file = os.path.join(self.clients_folder, f"{client.name.replace(' ', '_').lower()}.json")
|
|
data_manager = Data(client_file)
|
|
data_manager.save_data(client_data)
|
|
|
|
return client_file
|
|
|
|
def add_task_for_client(self, client_id: str, title: str, due_date: str, description: str = "", priority: str = "normale", metadata: dict = None):
|
|
"""
|
|
Crée une tâche liée à un client.
|
|
:param client_id: ID du client
|
|
:param title: Titre de la tâche
|
|
:param due_date: Date d'échéance au format ISO (YYYY-MM-DD)
|
|
:param description: Description optionnelle
|
|
:param priority: 'basse' | 'normale' | 'haute'
|
|
:param metadata: métadonnées optionnelles
|
|
:return: ID de la tâche créée ou None si client introuvable
|
|
"""
|
|
client = self.get_client_by_id(client_id)
|
|
if not client:
|
|
return None
|
|
# Import local pour éviter dépendances circulaires au chargement
|
|
from modules.tasks.task import Task
|
|
from modules.tasks.task_handler import TaskHandler
|
|
|
|
task = Task(
|
|
title=title,
|
|
due_date=due_date,
|
|
description=description,
|
|
entity_type="client",
|
|
entity_id=client_id,
|
|
priority=priority,
|
|
metadata=metadata or {},
|
|
)
|
|
return TaskHandler().add_task(task) |