# 🔧 CONCEPT: MATERIEL
## 📌 Vue d'ensemble
Le concept **MATERIEL** gère l'ensemble des équipements, outils, véhicules et matériaux de l'entreprise BTP. Il inclut la gestion du stock, de la maintenance, des réservations, et des caractéristiques techniques ultra-détaillées.
**Importance**: ⭐⭐⭐⭐⭐ (Concept stratégique)
---
## 🗂️ Fichiers concernés
### **Entités JPA** (`domain/core/entity/`)
| Fichier | Description | Lignes |
|---------|-------------|--------|
| `Materiel.java` | Entité principale du matériel | 226 |
| `MaterielBTP.java` | Matériel BTP ultra-détaillé (spécifications techniques) | ~300 |
| `StatutMateriel.java` | Enum statuts (DISPONIBLE, UTILISE, MAINTENANCE, etc.) | 15 |
| `TypeMateriel.java` | Enum types (VEHICULE, OUTIL_ELECTRIQUE, etc.) | 20 |
| `ProprieteMateriel.java` | Enum propriété (PROPRE, LOUE, SOUS_TRAITANCE) | ~25 |
| `MarqueMateriel.java` | Entité marque de matériel | ~80 |
| `CompetenceMateriel.java` | Compétences requises pour utiliser le matériel | ~60 |
| `OutillageMateriel.java` | Outillage associé au matériel | ~70 |
| `TestQualiteMateriel.java` | Tests qualité du matériel | ~90 |
| `DimensionsTechniques.java` | Dimensions techniques détaillées | ~100 |
| `AdaptationClimatique.java` | Adaptation aux zones climatiques | ~80 |
| `ContrainteConstruction.java` | Contraintes de construction | ~70 |
### **Services** (`application/service/`)
| Fichier | Description |
|---------|-------------|
| `MaterielService.java` | Service métier principal |
| `MaterielFournisseurService.java` | Gestion relation matériel-fournisseur |
### **Resources (API REST)** (`adapter/http/`)
| Fichier | Description |
|---------|-------------|
| `MaterielResource.java` | Endpoints REST pour le matériel |
---
## 📊 Modèle de données
### **Entité Materiel**
````java
@Entity
@Table(name = "materiels")
@Data
@Builder
public class Materiel extends PanacheEntityBase {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private UUID id;
@NotBlank(message = "Le nom du matériel est obligatoire")
@Column(name = "nom", nullable = false, length = 100)
private String nom;
@Column(name = "marque", length = 100)
private String marque;
@Column(name = "modele", length = 100)
private String modele;
@Column(name = "numero_serie", unique = true, length = 100)
private String numeroSerie;
@NotNull
@Enumerated(EnumType.STRING)
@Column(name = "type", nullable = false)
private TypeMateriel type;
@Enumerated(EnumType.STRING)
@Column(name = "statut", nullable = false)
private StatutMateriel statut = StatutMateriel.DISPONIBLE;
@Column(name = "quantite_stock", precision = 10, scale = 3)
private BigDecimal quantiteStock = BigDecimal.ZERO;
@Column(name = "seuil_minimum", precision = 10, scale = 3)
private BigDecimal seuilMinimum = BigDecimal.ZERO;
// Relations
@OneToMany(mappedBy = "materiel", cascade = CascadeType.ALL)
private List maintenances;
@ManyToMany(mappedBy = "materiels")
private List planningEvents;
}
````
### **Enum StatutMateriel**
````java
public enum StatutMateriel {
DISPONIBLE, // Disponible pour utilisation
UTILISE, // Actuellement utilisé
MAINTENANCE, // En maintenance préventive
HORS_SERVICE, // Hors service (panne)
RESERVE, // Réservé pour un chantier
EN_REPARATION // En cours de réparation
}
````
### **Enum TypeMateriel**
````java
public enum TypeMateriel {
VEHICULE, // Véhicules (camions, fourgons)
OUTIL_ELECTRIQUE, // Outils électriques (perceuse, scie)
OUTIL_MANUEL, // Outils manuels (marteau, pelle)
ECHAFAUDAGE, // Échafaudages
BETONIERE, // Bétonnières
GRUE, // Grues
COMPRESSEUR, // Compresseurs
GENERATEUR, // Générateurs électriques
ENGIN_CHANTIER, // Engins de chantier (pelleteuse, bulldozer)
MATERIEL_MESURE, // Matériel de mesure (niveau laser, théodolite)
EQUIPEMENT_SECURITE, // Équipements de sécurité (casques, harnais)
OUTILLAGE, // Outillage général
MATERIAUX_CONSTRUCTION, // Matériaux de construction
AUTRE // Autre type
}
````
### **Champs principaux**
| Champ | Type | Obligatoire | Description |
|-------|------|-------------|-------------|
| `id` | UUID | Oui | Identifiant unique |
| `nom` | String(100) | Oui | Nom du matériel |
| `marque` | String(100) | Non | Marque du matériel |
| `modele` | String(100) | Non | Modèle |
| `numeroSerie` | String(100) | Non | Numéro de série (unique) |
| `type` | TypeMateriel | Oui | Type de matériel |
| `description` | String(1000) | Non | Description détaillée |
| `dateAchat` | LocalDate | Non | Date d'achat |
| `valeurAchat` | BigDecimal | Non | Valeur d'achat |
| `valeurActuelle` | BigDecimal | Non | Valeur actuelle (amortissement) |
| `statut` | StatutMateriel | Oui | Statut actuel (défaut: DISPONIBLE) |
| `localisation` | String(200) | Non | Localisation actuelle |
| `proprietaire` | String(200) | Non | Propriétaire (si location) |
| `coutUtilisation` | BigDecimal | Non | Coût d'utilisation (par heure/jour) |
| `quantiteStock` | BigDecimal | Oui | Quantité en stock (défaut: 0) |
| `seuilMinimum` | BigDecimal | Oui | Seuil minimum de stock (défaut: 0) |
| `unite` | String(20) | Non | Unité de mesure (pièce, kg, m, etc.) |
| `actif` | Boolean | Oui | Matériel actif (défaut: true) |
| `dateCreation` | LocalDateTime | Auto | Date de création |
| `dateModification` | LocalDateTime | Auto | Date de modification |
### **Relations**
| Relation | Type | Entité cible | Description |
|----------|------|--------------|-------------|
| `maintenances` | OneToMany | MaintenanceMateriel | Historique des maintenances |
| `planningEvents` | ManyToMany | PlanningEvent | Événements de planning |
| `catalogueEntrees` | OneToMany | CatalogueFournisseur | Offres fournisseurs |
| `reservations` | OneToMany | ReservationMateriel | Réservations |
---
## 🔌 API REST
### **Base URL**: `/api/v1/materiels`
### **Endpoints disponibles**
| Méthode | Endpoint | Description | Permission |
|---------|----------|-------------|------------|
| GET | `/api/v1/materiels` | Liste tous les matériels | MATERIELS_READ |
| GET | `/api/v1/materiels/{id}` | Détails d'un matériel | MATERIELS_READ |
| POST | `/api/v1/materiels` | Créer un matériel | MATERIELS_CREATE |
| PUT | `/api/v1/materiels/{id}` | Modifier un matériel | MATERIELS_UPDATE |
| DELETE | `/api/v1/materiels/{id}` | Supprimer un matériel | MATERIELS_DELETE |
| GET | `/api/v1/materiels/disponibles` | Matériels disponibles | MATERIELS_READ |
| GET | `/api/v1/materiels/type/{type}` | Matériels par type | MATERIELS_READ |
| GET | `/api/v1/materiels/stock-faible` | Matériels en stock faible | MATERIELS_READ |
| GET | `/api/v1/materiels/stats` | Statistiques matériel | MATERIELS_READ |
---
## 💻 Exemples d'utilisation
### **1. Récupérer tous les matériels**
```bash
curl -X GET http://localhost:8080/api/v1/materiels \
-H "Accept: application/json"
```
**Réponse** (200 OK):
```json
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"nom": "Perceuse sans fil Makita",
"marque": "Makita",
"modele": "DHP484",
"numeroSerie": "MAK-2025-001",
"type": "OUTIL_ELECTRIQUE",
"statut": "DISPONIBLE",
"quantiteStock": 5,
"seuilMinimum": 2,
"unite": "pièce",
"valeurAchat": 250.00,
"valeurActuelle": 200.00,
"actif": true
},
{
"id": "660e8400-e29b-41d4-a716-446655440001",
"nom": "Camion benne Renault",
"marque": "Renault",
"modele": "Master",
"numeroSerie": "REN-2024-042",
"type": "VEHICULE",
"statut": "UTILISE",
"quantiteStock": 1,
"coutUtilisation": 150.00,
"localisation": "Chantier Villa Moderne",
"actif": true
}
]
```
### **2. Créer un nouveau matériel**
```bash
curl -X POST http://localhost:8080/api/v1/materiels \
-H "Content-Type: application/json" \
-d '{
"nom": "Bétonnière électrique",
"marque": "Altrad",
"modele": "B180",
"type": "BETONIERE",
"description": "Bétonnière électrique 180L",
"dateAchat": "2025-09-15",
"valeurAchat": 450.00,
"quantiteStock": 2,
"seuilMinimum": 1,
"unite": "pièce",
"statut": "DISPONIBLE"
}'
```
**Réponse** (201 Created):
```json
{
"id": "generated-uuid",
"nom": "Bétonnière électrique",
"type": "BETONIERE",
"statut": "DISPONIBLE",
"quantiteStock": 2,
"dateCreation": "2025-09-30T15:10:00"
}
```
### **3. Rechercher matériels disponibles**
```bash
curl -X GET http://localhost:8080/api/v1/materiels/disponibles
```
### **4. Matériels en stock faible**
```bash
curl -X GET http://localhost:8080/api/v1/materiels/stock-faible
```
**Réponse**:
```json
[
{
"id": "uuid",
"nom": "Casques de sécurité",
"quantiteStock": 3,
"seuilMinimum": 10,
"unite": "pièce",
"alerte": "STOCK_CRITIQUE"
}
]
```
### **5. Statistiques matériel**
```bash
curl -X GET http://localhost:8080/api/v1/materiels/stats
```
**Réponse**:
```json
{
"totalMateriels": 245,
"disponibles": 180,
"utilises": 45,
"enMaintenance": 12,
"horsService": 8,
"valeurTotale": 125000.00,
"stockFaible": 15,
"parType": {
"OUTIL_ELECTRIQUE": 85,
"VEHICULE": 12,
"ENGIN_CHANTIER": 8,
"ECHAFAUDAGE": 45
}
}
```
---
## 🔧 Services métier
### **MaterielService**
**Méthodes principales**:
| Méthode | Description | Retour |
|---------|-------------|--------|
| `findAll()` | Récupère tous les matériels | `List` |
| `findById(UUID id)` | Récupère par ID | `Optional` |
| `create(MaterielDTO dto)` | Crée un matériel | `Materiel` |
| `update(UUID id, MaterielDTO dto)` | Met à jour | `Materiel` |
| `delete(UUID id)` | Supprime (soft delete) | `void` |
| `findDisponibles()` | Matériels disponibles | `List` |
| `findByType(TypeMateriel type)` | Filtre par type | `List` |
| `findStockFaible()` | Stock sous seuil minimum | `List` |
| `changerStatut(UUID id, StatutMateriel statut)` | Change le statut | `Materiel` |
| `ajusterStock(UUID id, BigDecimal quantite)` | Ajuste le stock | `Materiel` |
| `getStatistics()` | Statistiques globales | `Object` |
---
## 🔐 Permissions requises
| Permission | Description | Rôles autorisés |
|------------|-------------|-----------------|
| `MATERIELS_READ` | Lecture du matériel | ADMIN, MANAGER, CHEF_CHANTIER, OUVRIER |
| `MATERIELS_CREATE` | Création de matériel | ADMIN, MANAGER |
| `MATERIELS_UPDATE` | Modification de matériel | ADMIN, MANAGER, CHEF_CHANTIER |
| `MATERIELS_DELETE` | Suppression de matériel | ADMIN, MANAGER |
| `MATERIELS_STOCK` | Gestion du stock | ADMIN, MANAGER, CHEF_CHANTIER |
---
## 📈 Relations avec autres concepts
### **Dépendances directes**:
- **MAINTENANCE** ➡️ Un matériel a un historique de maintenances
- **RESERVATION_MATERIEL** ➡️ Un matériel peut être réservé
- **PLANNING** ➡️ Un matériel apparaît dans le planning
- **FOURNISSEUR** ➡️ Un matériel peut avoir plusieurs fournisseurs (catalogue)
- **LIVRAISON** ➡️ Un matériel peut être livré
### **Utilisé par**:
- **CHANTIER** - Matériel affecté aux chantiers
- **EMPLOYE** - Matériel utilisé par les employés
- **BON_COMMANDE** - Matériel commandé
---
## ✅ Validations
### **Validations automatiques**:
- ✅ **Nom** : Obligatoire, max 100 caractères
- ✅ **Type** : Obligatoire, valeur de l'enum TypeMateriel
- ✅ **Numéro de série** : Unique si renseigné
- ✅ **Quantité stock** : Nombre positif ou zéro
- ✅ **Seuil minimum** : Nombre positif ou zéro
### **Règles métier**:
- Le stock ne peut pas être négatif
- Alerte si quantiteStock < seuilMinimum
- Un matériel HORS_SERVICE ne peut pas être réservé
- Un matériel en MAINTENANCE ne peut pas être utilisé
---
## 🧪 Tests
### **Tests unitaires**
- Fichier: `MaterielServiceTest.java`
- Couverture: Logique métier, gestion stock, validations
### **Tests d'intégration**
- Fichier: `MaterielResourceTest.java`
- Couverture: Endpoints REST, sérialisation JSON
### **Commande pour exécuter les tests**:
```bash
cd btpxpress-server
./mvnw test -Dtest=MaterielServiceTest
./mvnw test -Dtest=MaterielResourceTest
```
---
## 📚 Références
- [API Documentation complète](../API.md#materiels)
- [Schéma de base de données](../DATABASE.md#table-materiels)
- [Concept MAINTENANCE](./12-MAINTENANCE.md)
- [Concept RESERVATION_MATERIEL](./04-RESERVATION_MATERIEL.md)
- [Service MaterielService](../../src/main/java/dev/lions/btpxpress/application/service/MaterielService.java)
---
**Dernière mise à jour**: 2025-09-30
**Version**: 1.0
**Auteur**: Documentation BTPXpress