Files
btpxpress-frontend/services/executionGranulaireService.ts

301 lines
10 KiB
TypeScript
Executable File

/**
* 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<AvancementGranulaire> {
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<TacheExecution[]> {
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<TacheExecution[]> {
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<void> {
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<void> {
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<TacheExecution>
): Promise<void> {
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<StatistiquesExecution> {
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<TacheExecution[]> {
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<Blob> {
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<void> {
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<number> {
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();