SuiteConsultance/modules/projects/project_handler.py
2025-09-20 13:18:04 +02:00

98 lines
3.8 KiB
Python

import json
import os
from typing import List, Optional
from modules.projects.project import Project
class ProjectHandler:
def __init__(self, base_dir: str = None):
# Par défaut, stocker sous Data/projects
self.base_dir = base_dir or os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), 'Data', 'projects')
os.makedirs(self.base_dir, exist_ok=True)
def _client_dir(self, client_id: str) -> str:
path = os.path.join(self.base_dir, client_id)
os.makedirs(path, exist_ok=True)
return path
def _project_path(self, client_id: str, project_id: str) -> str:
return os.path.join(self._client_dir(client_id), f"{project_id}.json")
def list_projects(self, client_id: str) -> List[Project]:
projects: List[Project] = []
directory = self._client_dir(client_id)
if not os.path.isdir(directory):
return projects
for filename in os.listdir(directory):
if filename.endswith('.json'):
try:
with open(os.path.join(directory, filename), 'r', encoding='utf-8') as f:
data = json.load(f)
projects.append(Project.from_dict(data))
except Exception:
# Ignorer fichiers corrompus
continue
# Tri par date de mise à jour décroissante
projects.sort(key=lambda p: p.updated_at or "", reverse=True)
return projects
def get_project(self, client_id: str, project_id: str) -> Optional[Project]:
path = self._project_path(client_id, project_id)
if not os.path.exists(path):
return None
with open(path, 'r', encoding='utf-8') as f:
data = json.load(f)
return Project.from_dict(data)
def add_project(self, project: Project) -> str:
path = self._project_path(project.client_id, project.id)
with open(path, 'w', encoding='utf-8') as f:
json.dump(project.to_dict(), f, ensure_ascii=False, indent=2)
return project.id
def update_project(self, project: Project) -> bool:
path = self._project_path(project.client_id, project.id)
if not os.path.exists(path):
return False
# mettre à jour updated_at
from datetime import datetime
project.updated_at = datetime.utcnow().isoformat()
with open(path, 'w', encoding='utf-8') as f:
json.dump(project.to_dict(), f, ensure_ascii=False, indent=2)
return True
def delete_project(self, client_id: str, project_id: str) -> bool:
path = self._project_path(client_id, project_id)
if os.path.exists(path):
try:
os.remove(path)
return True
except Exception:
return False
return False
def add_task_for_project(self, project_id: str, title: str, due_date: str, description: str = "", priority: str = "normale", metadata: dict = None):
"""
Crée une tâche liée à un projet.
:param project_id: ID du projet
: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
"""
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="project",
entity_id=project_id,
priority=priority,
metadata=metadata or {},
)
return TaskHandler().add_task(task)