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

111 lines
3.5 KiB
Python

import os
import json
from typing import Dict, List
from flask import Blueprint, render_template, request
from modules.projects.project_handler import ProjectHandler
projects_bp = Blueprint('projects', __name__)
_handler = ProjectHandler()
def _project_root() -> str:
# 3 niveaux au dessus de modules/projects/ = racine projet
return os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
def _clients_dir() -> str:
return os.path.join(_project_root(), 'Data', 'clients')
def _load_clients_index() -> Dict[str, str]:
"""
Retourne un dict {client_id: client_name lisible}
client_id = nom de fichier sans extension dans Data/clients
"""
idx: Dict[str, str] = {}
cdir = _clients_dir()
if not os.path.isdir(cdir):
return idx
for fname in os.listdir(cdir):
if not fname.endswith('.json'):
continue
client_id = os.path.splitext(fname)[0]
path = os.path.join(cdir, fname)
try:
with open(path, 'r', encoding='utf-8') as f:
data = json.load(f)
name = data.get('client_name') or client_id.replace('_', ' ').title()
idx[client_id] = name
except Exception:
idx[client_id] = client_id.replace('_', ' ').title()
return idx
def _list_all_projects() -> List:
"""
Parcourt Data/projects/<client_id> et retourne la liste des objets Project.
"""
base = _handler.base_dir
projects = []
if os.path.isdir(base):
for client_id in os.listdir(base):
client_path = os.path.join(base, client_id)
if os.path.isdir(client_path):
projects.extend(_handler.list_projects(client_id))
return projects
@projects_bp.route('/projects', methods=['GET'])
def projects_index():
clients_idx = _load_clients_index()
selected_client = request.args.get('client_id', '').strip()
query = request.args.get('q', '').strip().lower()
# Charger tous les projets
projects = _list_all_projects()
# Filtre par client
if selected_client:
projects = [p for p in projects if p.client_id == selected_client]
# Recherche plein texte basique
if query:
def match(p) -> bool:
hay = ' '.join([
p.name or '',
p.status or '',
p.description or ''
]).lower()
return query in hay
projects = [p for p in projects if match(p)]
# Tri par updated_at décroissante
projects.sort(key=lambda p: p.updated_at or '', reverse=True)
# Transformer pour la vue (nom client)
def client_name_for(pid: str) -> str:
return clients_idx.get(pid, pid.replace('_', ' ').title())
view_projects = []
for p in projects:
view_projects.append({
'id': p.id,
'client_id': p.client_id,
'client_name': client_name_for(p.client_id),
'name': p.name,
'status': p.status,
'start_date': p.start_date,
'end_date': p.end_date,
'budget': p.budget,
'updated_at': p.updated_at
})
# Liste triée des clients pour le sélecteur
clients_for_select = sorted(
[{'id': cid, 'name': cname} for cid, cname in clients_idx.items()],
key=lambda c: c['name'].lower()
)
return render_template(
'projects/all_projects.html',
projects=view_projects,
clients=clients_for_select,
selected_client=selected_client,
q=request.args.get('q', '').strip()
)