/** * Service pour la gestion de l'exécution granulaire des chantiers * Gère les tâches, leur completion et le calcul d'avancement basé sur les tâches */ import { apiClient } from './api-client'; export interface TacheExecution { id: string; tacheTemplateId: string; chantierID: string; nom: string; description?: string; ordreExecution: number; dureeEstimeeMinutes?: number; critique: boolean; bloquante: boolean; priorite: 'BASSE' | 'NORMALE' | 'HAUTE'; niveauQualification?: string; nombreOperateursRequis: number; conditionsMeteo: string; outilsRequis?: string[]; materiauxRequis?: string[]; // État d'exécution terminee: boolean; dateCompletion?: Date; completeepar?: string; commentaires?: string; tempsRealise?: number; difficulteRencontree?: 'AUCUNE' | 'FAIBLE' | 'MOYENNE' | 'ELEVEE'; } export interface AvancementGranulaire { chantierID: string; pourcentage: number; totalTaches: number; tachesTerminees: number; phasesAvancement: { phaseId: string; nom: string; pourcentage: number; sousPhases: { sousPhaseId: string; nom: string; pourcentage: number; tachesTerminees: number; totalTaches: number; }[]; }[]; derniereMAJ: Date; } export interface StatistiquesExecution { totalTachesTerminees: number; totalTaches: number; pourcentageGlobal: number; moyenneTempsByTache: number; tachesEnRetard: number; tachesCritiquesRestantes: number; estimationFinChantier?: Date; efficaciteEquipe: number; // % temps réalisé vs estimé } class ExecutionGranulaireService { private readonly basePath = '/chantiers'; /** * Récupère l'avancement granulaire d'un chantier */ async getAvancementGranulaire(chantierID: string): Promise { try { const response = await apiClient.get(`${this.basePath}/${chantierID}/avancement-granulaire`); return { ...response.data, derniereMAJ: new Date(response.data.derniereMAJ) }; } catch (error) { console.error('Erreur lors de la récupération de l\'avancement granulaire:', error); throw error; } } /** * Récupère toutes les tâches d'exécution pour un chantier */ async getTachesExecution(chantierID: string): Promise { try { const response = await apiClient.get(`${this.basePath}/${chantierID}/taches-execution`); return response.data.map((tache: any) => ({ ...tache, dateCompletion: tache.dateCompletion ? new Date(tache.dateCompletion) : undefined })); } catch (error) { console.error('Erreur lors de la récupération des tâches:', error); throw error; } } /** * Récupère les tâches d'exécution pour une sous-phase spécifique */ async getTachesExecutionBySousPhase(chantierID: string, sousPhaseId: string): Promise { try { const response = await apiClient.get(`${this.basePath}/${chantierID}/taches-execution/${sousPhaseId}`); return response.data.map((tache: any) => ({ ...tache, dateCompletion: tache.dateCompletion ? new Date(tache.dateCompletion) : undefined })); } catch (error) { console.error('Erreur lors de la récupération des tâches de la sous-phase:', error); throw error; } } /** * Marque une tâche comme terminée */ async marquerTacheTerminee( chantierID: string, tacheTemplateId: string, details: { commentaires?: string; tempsRealise?: number; difficulteRencontree?: 'AUCUNE' | 'FAIBLE' | 'MOYENNE' | 'ELEVEE'; completeepar?: string; } ): Promise { try { await apiClient.post(`${this.basePath}/${chantierID}/taches-execution`, { tacheTemplateId, terminee: true, dateCompletion: new Date().toISOString(), ...details }); } catch (error) { console.error('Erreur lors du marquage de la tâche comme terminée:', error); throw error; } } /** * Marque une tâche comme non terminée */ async marquerTacheNonTerminee(chantierID: string, tacheTemplateId: string): Promise { try { await apiClient.post(`${this.basePath}/${chantierID}/taches-execution`, { tacheTemplateId, terminee: false, dateCompletion: null, commentaires: '', tempsRealise: null, difficulteRencontree: 'AUCUNE' }); } catch (error) { console.error('Erreur lors du marquage de la tâche comme non terminée:', error); throw error; } } /** * Met à jour l'état d'exécution d'une tâche */ async updateTacheExecution( chantierID: string, tacheTemplateId: string, updates: Partial ): Promise { try { await apiClient.put(`${this.basePath}/${chantierID}/taches-execution/${tacheTemplateId}`, updates); } catch (error) { console.error('Erreur lors de la mise à jour de la tâche:', error); throw error; } } /** * Récupère les statistiques d'exécution d'un chantier */ async getStatistiquesExecution(chantierID: string): Promise { try { const response = await apiClient.get(`${this.basePath}/${chantierID}/statistiques-execution`); return { ...response.data, estimationFinChantier: response.data.estimationFinChantier ? new Date(response.data.estimationFinChantier) : undefined }; } catch (error) { console.error('Erreur lors de la récupération des statistiques:', error); throw error; } } /** * Récupère les tâches critiques en retard */ async getTachesCritiquesEnRetard(chantierID: string): Promise { try { const response = await apiClient.get(`${this.basePath}/${chantierID}/taches-critiques-retard`); return response.data.map((tache: any) => ({ ...tache, dateCompletion: tache.dateCompletion ? new Date(tache.dateCompletion) : undefined })); } catch (error) { console.error('Erreur lors de la récupération des tâches critiques:', error); throw error; } } /** * Génère un rapport d'avancement granulaire */ async genererRapportAvancement(chantierID: string, format: 'PDF' | 'EXCEL' = 'PDF'): Promise { try { const response = await apiClient.get( `${this.basePath}/${chantierID}/rapport-avancement-granulaire`, { params: { format }, responseType: 'blob' } ); return response.data; } catch (error) { console.error('Erreur lors de la génération du rapport:', error); throw error; } } /** * Initialise l'exécution granulaire pour un chantier * Crée les entrées de tâches basées sur les templates */ async initialiserExecutionGranulaire(chantierID: string): Promise { try { await apiClient.post(`${this.basePath}/${chantierID}/initialiser-execution-granulaire`); } catch (error) { console.error('Erreur lors de l\'initialisation de l\'exécution granulaire:', error); throw error; } } /** * Calcule l'avancement projeté basé sur la vitesse actuelle */ async calculerAvancementProjetee(chantierID: string, dateTarget: Date): Promise { try { const response = await apiClient.post( `${this.basePath}/${chantierID}/avancement-projete`, { dateTarget: dateTarget.toISOString() } ); return response.data.pourcentageProjecte; } catch (error) { console.error('Erreur lors du calcul de l\'avancement projeté:', error); throw error; } } /** * Récupère l'historique d'avancement du chantier */ async getHistoriqueAvancement(chantierID: string, periode: 'SEMAINE' | 'MOIS' = 'SEMAINE'): Promise<{ date: Date; pourcentage: number; tachesTermineesJour: number; efficaciteJour: number; }[]> { try { const response = await apiClient.get(`${this.basePath}/${chantierID}/historique-avancement`, { params: { periode } }); return response.data.map((entry: any) => ({ ...entry, date: new Date(entry.date) })); } catch (error) { console.error('Erreur lors de la récupération de l\'historique:', error); throw error; } } /** * Valide la completion d'une sous-phase * Toutes les tâches critiques doivent être terminées */ async validerCompletionSousPhase(chantierID: string, sousPhaseId: string): Promise<{ valide: boolean; tachesCritiquesRestantes: string[]; pourcentageCompletion: number; }> { try { const response = await apiClient.post(`${this.basePath}/${chantierID}/valider-sous-phase/${sousPhaseId}`); return response.data; } catch (error) { console.error('Erreur lors de la validation de la sous-phase:', error); throw error; } } } export const executionGranulaireService = new ExecutionGranulaireService();