301 lines
10 KiB
TypeScript
301 lines
10 KiB
TypeScript
/**
|
|
* 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(); |