PHASE 2 - Ajout DTOs et services Client/Coach

 NOUVELLES FONCTIONNALITÉS API :
- ClientDTO, CreateClientDTO, UpdateClientDTO
- CoachDTO, CreateCoachDTO, UpdateCoachDTO
- PagedResponseDTO générique pour pagination
- ClientService interface complète
- CoachService interface complète

🔧 CORRECTIONS TECHNIQUES :
- Correction import GBCMException (exceptions vs exception)
- Validation Jakarta sur tous les DTOs
- Javadoc français complet

📊 INTERFACES DE SERVICE :
- ClientService : CRUD complet + gestion métier
- CoachService : CRUD complet + gestion disponibilités
- Méthodes spécialisées (activation, conversion, notation)
- Gestion d'erreurs avec GBCMException

🎯 ARCHITECTURE SOLIDE :
- Séparation claire API/Implementation
- DTOs avec validation complète
- Interfaces de service bien définies
- Support pagination et recherche
This commit is contained in:
dahoud
2025-10-07 10:27:30 +00:00
parent ba9670b692
commit 561b3df218
9 changed files with 2231 additions and 0 deletions

View File

@@ -0,0 +1,352 @@
package com.gbcm.server.api.dto.client;
import com.gbcm.server.api.dto.user.UserDTO;
import com.gbcm.server.api.enums.ServiceType;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* DTO représentant un client de la plateforme GBCM.
* Utilisé pour les réponses API et les transferts de données.
*
* @author GBCM Development Team
* @version 1.0
* @since 1.0
*/
public class ClientDTO {
/**
* Identifiant unique du client.
*/
private Long id;
/**
* Utilisateur associé à ce client.
*/
@NotNull(message = "L'utilisateur associé est obligatoire")
private UserDTO user;
/**
* Nom de l'entreprise du client.
*/
@NotBlank(message = "Le nom de l'entreprise est obligatoire")
@Size(max = 200, message = "Le nom de l'entreprise ne peut pas dépasser 200 caractères")
private String companyName;
/**
* Secteur d'activité de l'entreprise.
*/
@Size(max = 100, message = "Le secteur d'activité ne peut pas dépasser 100 caractères")
private String industry;
/**
* Taille de l'entreprise (nombre d'employés).
*/
private Integer companySize;
/**
* Chiffre d'affaires annuel de l'entreprise.
*/
private BigDecimal annualRevenue;
/**
* Adresse de l'entreprise - ligne 1.
*/
@Size(max = 255, message = "L'adresse ligne 1 ne peut pas dépasser 255 caractères")
private String addressLine1;
/**
* Adresse de l'entreprise - ligne 2.
*/
@Size(max = 255, message = "L'adresse ligne 2 ne peut pas dépasser 255 caractères")
private String addressLine2;
/**
* Ville de l'entreprise.
*/
@Size(max = 100, message = "La ville ne peut pas dépasser 100 caractères")
private String city;
/**
* État/Province de l'entreprise.
*/
@Size(max = 100, message = "L'état ne peut pas dépasser 100 caractères")
private String state;
/**
* Code postal de l'entreprise.
*/
@Size(max = 20, message = "Le code postal ne peut pas dépasser 20 caractères")
private String postalCode;
/**
* Pays de l'entreprise.
*/
@Size(max = 100, message = "Le pays ne peut pas dépasser 100 caractères")
private String country;
/**
* Site web de l'entreprise.
*/
@Size(max = 255, message = "Le site web ne peut pas dépasser 255 caractères")
private String website;
/**
* Statut du client.
*/
@NotNull(message = "Le statut est obligatoire")
private String status;
/**
* Date de conversion de prospect à client.
*/
private LocalDateTime convertedAt;
/**
* Type de service principal du client.
*/
private ServiceType primaryServiceType;
/**
* Date de début de service.
*/
private LocalDate serviceStartDate;
/**
* Date de fin de service.
*/
private LocalDate serviceEndDate;
/**
* Notes sur le client.
*/
private String notes;
/**
* Date de création.
*/
private LocalDateTime createdAt;
/**
* Date de dernière mise à jour.
*/
private LocalDateTime updatedAt;
/**
* Créé par.
*/
private String createdBy;
/**
* Mis à jour par.
*/
private String updatedBy;
/**
* Constructeur par défaut.
*/
public ClientDTO() {
}
// Getters et Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public UserDTO getUser() {
return user;
}
public void setUser(UserDTO user) {
this.user = user;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public String getIndustry() {
return industry;
}
public void setIndustry(String industry) {
this.industry = industry;
}
public Integer getCompanySize() {
return companySize;
}
public void setCompanySize(Integer companySize) {
this.companySize = companySize;
}
public BigDecimal getAnnualRevenue() {
return annualRevenue;
}
public void setAnnualRevenue(BigDecimal annualRevenue) {
this.annualRevenue = annualRevenue;
}
public String getAddressLine1() {
return addressLine1;
}
public void setAddressLine1(String addressLine1) {
this.addressLine1 = addressLine1;
}
public String getAddressLine2() {
return addressLine2;
}
public void setAddressLine2(String addressLine2) {
this.addressLine2 = addressLine2;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getPostalCode() {
return postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getWebsite() {
return website;
}
public void setWebsite(String website) {
this.website = website;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public LocalDateTime getConvertedAt() {
return convertedAt;
}
public void setConvertedAt(LocalDateTime convertedAt) {
this.convertedAt = convertedAt;
}
public ServiceType getPrimaryServiceType() {
return primaryServiceType;
}
public void setPrimaryServiceType(ServiceType primaryServiceType) {
this.primaryServiceType = primaryServiceType;
}
public LocalDate getServiceStartDate() {
return serviceStartDate;
}
public void setServiceStartDate(LocalDate serviceStartDate) {
this.serviceStartDate = serviceStartDate;
}
public LocalDate getServiceEndDate() {
return serviceEndDate;
}
public void setServiceEndDate(LocalDate serviceEndDate) {
this.serviceEndDate = serviceEndDate;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}
public LocalDateTime getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public String getUpdatedBy() {
return updatedBy;
}
public void setUpdatedBy(String updatedBy) {
this.updatedBy = updatedBy;
}
@Override
public String toString() {
return "ClientDTO{" +
"id=" + id +
", companyName='" + companyName + '\'' +
", industry='" + industry + '\'' +
", status='" + status + '\'' +
", createdAt=" + createdAt +
'}';
}
}

View File

@@ -0,0 +1,270 @@
package com.gbcm.server.api.dto.client;
import com.gbcm.server.api.enums.ServiceType;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.math.BigDecimal;
import java.time.LocalDate;
/**
* DTO pour la création d'un nouveau client.
* Contient toutes les informations nécessaires pour créer un client.
*
* @author GBCM Development Team
* @version 1.0
* @since 1.0
*/
public class CreateClientDTO {
/**
* Identifiant de l'utilisateur à associer au client.
*/
@NotNull(message = "L'identifiant utilisateur est obligatoire")
private Long userId;
/**
* Nom de l'entreprise du client.
*/
@NotBlank(message = "Le nom de l'entreprise est obligatoire")
@Size(max = 200, message = "Le nom de l'entreprise ne peut pas dépasser 200 caractères")
private String companyName;
/**
* Secteur d'activité de l'entreprise.
*/
@Size(max = 100, message = "Le secteur d'activité ne peut pas dépasser 100 caractères")
private String industry;
/**
* Taille de l'entreprise (nombre d'employés).
*/
private Integer companySize;
/**
* Chiffre d'affaires annuel de l'entreprise.
*/
private BigDecimal annualRevenue;
/**
* Adresse de l'entreprise - ligne 1.
*/
@Size(max = 255, message = "L'adresse ligne 1 ne peut pas dépasser 255 caractères")
private String addressLine1;
/**
* Adresse de l'entreprise - ligne 2.
*/
@Size(max = 255, message = "L'adresse ligne 2 ne peut pas dépasser 255 caractères")
private String addressLine2;
/**
* Ville de l'entreprise.
*/
@Size(max = 100, message = "La ville ne peut pas dépasser 100 caractères")
private String city;
/**
* État/Province de l'entreprise.
*/
@Size(max = 100, message = "L'état ne peut pas dépasser 100 caractères")
private String state;
/**
* Code postal de l'entreprise.
*/
@Size(max = 20, message = "Le code postal ne peut pas dépasser 20 caractères")
private String postalCode;
/**
* Pays de l'entreprise.
*/
@Size(max = 100, message = "Le pays ne peut pas dépasser 100 caractères")
private String country;
/**
* Site web de l'entreprise.
*/
@Size(max = 255, message = "Le site web ne peut pas dépasser 255 caractères")
private String website;
/**
* Statut initial du client (par défaut PROSPECT).
*/
private String status = "PROSPECT";
/**
* Type de service principal du client.
*/
private ServiceType primaryServiceType;
/**
* Date de début de service.
*/
private LocalDate serviceStartDate;
/**
* Date de fin de service.
*/
private LocalDate serviceEndDate;
/**
* Notes sur le client.
*/
private String notes;
/**
* Constructeur par défaut.
*/
public CreateClientDTO() {
}
// Getters et Setters
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public String getIndustry() {
return industry;
}
public void setIndustry(String industry) {
this.industry = industry;
}
public Integer getCompanySize() {
return companySize;
}
public void setCompanySize(Integer companySize) {
this.companySize = companySize;
}
public BigDecimal getAnnualRevenue() {
return annualRevenue;
}
public void setAnnualRevenue(BigDecimal annualRevenue) {
this.annualRevenue = annualRevenue;
}
public String getAddressLine1() {
return addressLine1;
}
public void setAddressLine1(String addressLine1) {
this.addressLine1 = addressLine1;
}
public String getAddressLine2() {
return addressLine2;
}
public void setAddressLine2(String addressLine2) {
this.addressLine2 = addressLine2;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getPostalCode() {
return postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getWebsite() {
return website;
}
public void setWebsite(String website) {
this.website = website;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public ServiceType getPrimaryServiceType() {
return primaryServiceType;
}
public void setPrimaryServiceType(ServiceType primaryServiceType) {
this.primaryServiceType = primaryServiceType;
}
public LocalDate getServiceStartDate() {
return serviceStartDate;
}
public void setServiceStartDate(LocalDate serviceStartDate) {
this.serviceStartDate = serviceStartDate;
}
public LocalDate getServiceEndDate() {
return serviceEndDate;
}
public void setServiceEndDate(LocalDate serviceEndDate) {
this.serviceEndDate = serviceEndDate;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
@Override
public String toString() {
return "CreateClientDTO{" +
"userId=" + userId +
", companyName='" + companyName + '\'' +
", industry='" + industry + '\'' +
", status='" + status + '\'' +
'}';
}
}

View File

@@ -0,0 +1,252 @@
package com.gbcm.server.api.dto.client;
import com.gbcm.server.api.enums.ServiceType;
import jakarta.validation.constraints.Size;
import java.math.BigDecimal;
import java.time.LocalDate;
/**
* DTO pour la mise à jour d'un client existant.
* Tous les champs sont optionnels pour permettre des mises à jour partielles.
*
* @author GBCM Development Team
* @version 1.0
* @since 1.0
*/
public class UpdateClientDTO {
/**
* Nom de l'entreprise du client.
*/
@Size(max = 200, message = "Le nom de l'entreprise ne peut pas dépasser 200 caractères")
private String companyName;
/**
* Secteur d'activité de l'entreprise.
*/
@Size(max = 100, message = "Le secteur d'activité ne peut pas dépasser 100 caractères")
private String industry;
/**
* Taille de l'entreprise (nombre d'employés).
*/
private Integer companySize;
/**
* Chiffre d'affaires annuel de l'entreprise.
*/
private BigDecimal annualRevenue;
/**
* Adresse de l'entreprise - ligne 1.
*/
@Size(max = 255, message = "L'adresse ligne 1 ne peut pas dépasser 255 caractères")
private String addressLine1;
/**
* Adresse de l'entreprise - ligne 2.
*/
@Size(max = 255, message = "L'adresse ligne 2 ne peut pas dépasser 255 caractères")
private String addressLine2;
/**
* Ville de l'entreprise.
*/
@Size(max = 100, message = "La ville ne peut pas dépasser 100 caractères")
private String city;
/**
* État/Province de l'entreprise.
*/
@Size(max = 100, message = "L'état ne peut pas dépasser 100 caractères")
private String state;
/**
* Code postal de l'entreprise.
*/
@Size(max = 20, message = "Le code postal ne peut pas dépasser 20 caractères")
private String postalCode;
/**
* Pays de l'entreprise.
*/
@Size(max = 100, message = "Le pays ne peut pas dépasser 100 caractères")
private String country;
/**
* Site web de l'entreprise.
*/
@Size(max = 255, message = "Le site web ne peut pas dépasser 255 caractères")
private String website;
/**
* Statut du client.
*/
private String status;
/**
* Type de service principal du client.
*/
private ServiceType primaryServiceType;
/**
* Date de début de service.
*/
private LocalDate serviceStartDate;
/**
* Date de fin de service.
*/
private LocalDate serviceEndDate;
/**
* Notes sur le client.
*/
private String notes;
/**
* Constructeur par défaut.
*/
public UpdateClientDTO() {
}
// Getters et Setters
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public String getIndustry() {
return industry;
}
public void setIndustry(String industry) {
this.industry = industry;
}
public Integer getCompanySize() {
return companySize;
}
public void setCompanySize(Integer companySize) {
this.companySize = companySize;
}
public BigDecimal getAnnualRevenue() {
return annualRevenue;
}
public void setAnnualRevenue(BigDecimal annualRevenue) {
this.annualRevenue = annualRevenue;
}
public String getAddressLine1() {
return addressLine1;
}
public void setAddressLine1(String addressLine1) {
this.addressLine1 = addressLine1;
}
public String getAddressLine2() {
return addressLine2;
}
public void setAddressLine2(String addressLine2) {
this.addressLine2 = addressLine2;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getPostalCode() {
return postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getWebsite() {
return website;
}
public void setWebsite(String website) {
this.website = website;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public ServiceType getPrimaryServiceType() {
return primaryServiceType;
}
public void setPrimaryServiceType(ServiceType primaryServiceType) {
this.primaryServiceType = primaryServiceType;
}
public LocalDate getServiceStartDate() {
return serviceStartDate;
}
public void setServiceStartDate(LocalDate serviceStartDate) {
this.serviceStartDate = serviceStartDate;
}
public LocalDate getServiceEndDate() {
return serviceEndDate;
}
public void setServiceEndDate(LocalDate serviceEndDate) {
this.serviceEndDate = serviceEndDate;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
@Override
public String toString() {
return "UpdateClientDTO{" +
"companyName='" + companyName + '\'' +
", industry='" + industry + '\'' +
", status='" + status + '\'' +
'}';
}
}

View File

@@ -0,0 +1,373 @@
package com.gbcm.server.api.dto.coach;
import com.gbcm.server.api.dto.user.UserDTO;
import com.gbcm.server.api.enums.ServiceType;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Set;
/**
* DTO représentant un coach de la plateforme GBCM.
* Utilisé pour les réponses API et les transferts de données.
*
* @author GBCM Development Team
* @version 1.0
* @since 1.0
*/
public class CoachDTO {
/**
* Identifiant unique du coach.
*/
private Long id;
/**
* Utilisateur associé à ce coach.
*/
@NotNull(message = "L'utilisateur associé est obligatoire")
private UserDTO user;
/**
* Spécialisation principale du coach.
*/
@NotBlank(message = "La spécialisation est obligatoire")
@Size(max = 100, message = "La spécialisation ne peut pas dépasser 100 caractères")
private String specialization;
/**
* Années d'expérience du coach.
*/
private Integer yearsOfExperience;
/**
* Certifications du coach.
*/
private String certifications;
/**
* Biographie du coach.
*/
private String bio;
/**
* Tarif horaire du coach.
*/
private BigDecimal hourlyRate;
/**
* Statut du coach.
*/
@NotNull(message = "Le statut est obligatoire")
private String status;
/**
* Disponibilité pour les réservations.
*/
private Boolean availableForBooking;
/**
* Types de services offerts par le coach.
*/
private Set<ServiceType> serviceTypes;
/**
* Heures de travail - début.
*/
private LocalTime workingHoursStart;
/**
* Heures de travail - fin.
*/
private LocalTime workingHoursEnd;
/**
* Fuseau horaire du coach.
*/
private String timeZone;
/**
* Langues parlées par le coach.
*/
private String languagesSpoken;
/**
* Note moyenne du coach.
*/
private BigDecimal averageRating;
/**
* Nombre total d'évaluations.
*/
private Integer totalRatings;
/**
* Nombre total de sessions effectuées.
*/
private Integer totalSessions;
/**
* Revenus totaux générés.
*/
private BigDecimal totalRevenue;
/**
* Date de début d'activité.
*/
private LocalDate startDate;
/**
* Date de fin d'activité.
*/
private LocalDate endDate;
/**
* Notes internes sur le coach.
*/
private String notes;
/**
* Date de création.
*/
private LocalDateTime createdAt;
/**
* Date de dernière mise à jour.
*/
private LocalDateTime updatedAt;
/**
* Créé par.
*/
private String createdBy;
/**
* Mis à jour par.
*/
private String updatedBy;
/**
* Constructeur par défaut.
*/
public CoachDTO() {
}
// Getters et Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public UserDTO getUser() {
return user;
}
public void setUser(UserDTO user) {
this.user = user;
}
public String getSpecialization() {
return specialization;
}
public void setSpecialization(String specialization) {
this.specialization = specialization;
}
public Integer getYearsOfExperience() {
return yearsOfExperience;
}
public void setYearsOfExperience(Integer yearsOfExperience) {
this.yearsOfExperience = yearsOfExperience;
}
public String getCertifications() {
return certifications;
}
public void setCertifications(String certifications) {
this.certifications = certifications;
}
public String getBio() {
return bio;
}
public void setBio(String bio) {
this.bio = bio;
}
public BigDecimal getHourlyRate() {
return hourlyRate;
}
public void setHourlyRate(BigDecimal hourlyRate) {
this.hourlyRate = hourlyRate;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Boolean getAvailableForBooking() {
return availableForBooking;
}
public void setAvailableForBooking(Boolean availableForBooking) {
this.availableForBooking = availableForBooking;
}
public Set<ServiceType> getServiceTypes() {
return serviceTypes;
}
public void setServiceTypes(Set<ServiceType> serviceTypes) {
this.serviceTypes = serviceTypes;
}
public LocalTime getWorkingHoursStart() {
return workingHoursStart;
}
public void setWorkingHoursStart(LocalTime workingHoursStart) {
this.workingHoursStart = workingHoursStart;
}
public LocalTime getWorkingHoursEnd() {
return workingHoursEnd;
}
public void setWorkingHoursEnd(LocalTime workingHoursEnd) {
this.workingHoursEnd = workingHoursEnd;
}
public String getTimeZone() {
return timeZone;
}
public void setTimeZone(String timeZone) {
this.timeZone = timeZone;
}
public String getLanguagesSpoken() {
return languagesSpoken;
}
public void setLanguagesSpoken(String languagesSpoken) {
this.languagesSpoken = languagesSpoken;
}
public BigDecimal getAverageRating() {
return averageRating;
}
public void setAverageRating(BigDecimal averageRating) {
this.averageRating = averageRating;
}
public Integer getTotalRatings() {
return totalRatings;
}
public void setTotalRatings(Integer totalRatings) {
this.totalRatings = totalRatings;
}
public Integer getTotalSessions() {
return totalSessions;
}
public void setTotalSessions(Integer totalSessions) {
this.totalSessions = totalSessions;
}
public BigDecimal getTotalRevenue() {
return totalRevenue;
}
public void setTotalRevenue(BigDecimal totalRevenue) {
this.totalRevenue = totalRevenue;
}
public LocalDate getStartDate() {
return startDate;
}
public void setStartDate(LocalDate startDate) {
this.startDate = startDate;
}
public LocalDate getEndDate() {
return endDate;
}
public void setEndDate(LocalDate endDate) {
this.endDate = endDate;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}
public LocalDateTime getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public String getUpdatedBy() {
return updatedBy;
}
public void setUpdatedBy(String updatedBy) {
this.updatedBy = updatedBy;
}
@Override
public String toString() {
return "CoachDTO{" +
"id=" + id +
", specialization='" + specialization + '\'' +
", status='" + status + '\'' +
", availableForBooking=" + availableForBooking +
", averageRating=" + averageRating +
", totalSessions=" + totalSessions +
'}';
}
}

View File

@@ -0,0 +1,251 @@
package com.gbcm.server.api.dto.coach;
import com.gbcm.server.api.enums.ServiceType;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Set;
/**
* DTO pour la création d'un nouveau coach.
* Contient toutes les informations nécessaires pour créer un coach.
*
* @author GBCM Development Team
* @version 1.0
* @since 1.0
*/
public class CreateCoachDTO {
/**
* Identifiant de l'utilisateur à associer au coach.
*/
@NotNull(message = "L'identifiant utilisateur est obligatoire")
private Long userId;
/**
* Spécialisation principale du coach.
*/
@NotBlank(message = "La spécialisation est obligatoire")
@Size(max = 100, message = "La spécialisation ne peut pas dépasser 100 caractères")
private String specialization;
/**
* Années d'expérience du coach.
*/
private Integer yearsOfExperience;
/**
* Certifications du coach.
*/
private String certifications;
/**
* Biographie du coach.
*/
private String bio;
/**
* Tarif horaire du coach.
*/
private BigDecimal hourlyRate;
/**
* Statut initial du coach (par défaut ACTIVE).
*/
private String status = "ACTIVE";
/**
* Disponibilité pour les réservations (par défaut true).
*/
private Boolean availableForBooking = true;
/**
* Types de services offerts par le coach.
*/
private Set<ServiceType> serviceTypes;
/**
* Heures de travail - début.
*/
private LocalTime workingHoursStart;
/**
* Heures de travail - fin.
*/
private LocalTime workingHoursEnd;
/**
* Fuseau horaire du coach.
*/
private String timeZone;
/**
* Langues parlées par le coach.
*/
private String languagesSpoken;
/**
* Date de début d'activité.
*/
private LocalDate startDate;
/**
* Date de fin d'activité.
*/
private LocalDate endDate;
/**
* Notes internes sur le coach.
*/
private String notes;
/**
* Constructeur par défaut.
*/
public CreateCoachDTO() {
}
// Getters et Setters
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getSpecialization() {
return specialization;
}
public void setSpecialization(String specialization) {
this.specialization = specialization;
}
public Integer getYearsOfExperience() {
return yearsOfExperience;
}
public void setYearsOfExperience(Integer yearsOfExperience) {
this.yearsOfExperience = yearsOfExperience;
}
public String getCertifications() {
return certifications;
}
public void setCertifications(String certifications) {
this.certifications = certifications;
}
public String getBio() {
return bio;
}
public void setBio(String bio) {
this.bio = bio;
}
public BigDecimal getHourlyRate() {
return hourlyRate;
}
public void setHourlyRate(BigDecimal hourlyRate) {
this.hourlyRate = hourlyRate;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Boolean getAvailableForBooking() {
return availableForBooking;
}
public void setAvailableForBooking(Boolean availableForBooking) {
this.availableForBooking = availableForBooking;
}
public Set<ServiceType> getServiceTypes() {
return serviceTypes;
}
public void setServiceTypes(Set<ServiceType> serviceTypes) {
this.serviceTypes = serviceTypes;
}
public LocalTime getWorkingHoursStart() {
return workingHoursStart;
}
public void setWorkingHoursStart(LocalTime workingHoursStart) {
this.workingHoursStart = workingHoursStart;
}
public LocalTime getWorkingHoursEnd() {
return workingHoursEnd;
}
public void setWorkingHoursEnd(LocalTime workingHoursEnd) {
this.workingHoursEnd = workingHoursEnd;
}
public String getTimeZone() {
return timeZone;
}
public void setTimeZone(String timeZone) {
this.timeZone = timeZone;
}
public String getLanguagesSpoken() {
return languagesSpoken;
}
public void setLanguagesSpoken(String languagesSpoken) {
this.languagesSpoken = languagesSpoken;
}
public LocalDate getStartDate() {
return startDate;
}
public void setStartDate(LocalDate startDate) {
this.startDate = startDate;
}
public LocalDate getEndDate() {
return endDate;
}
public void setEndDate(LocalDate endDate) {
this.endDate = endDate;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
@Override
public String toString() {
return "CreateCoachDTO{" +
"userId=" + userId +
", specialization='" + specialization + '\'' +
", status='" + status + '\'' +
", availableForBooking=" + availableForBooking +
'}';
}
}

View File

@@ -0,0 +1,233 @@
package com.gbcm.server.api.dto.coach;
import com.gbcm.server.api.enums.ServiceType;
import jakarta.validation.constraints.Size;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Set;
/**
* DTO pour la mise à jour d'un coach existant.
* Tous les champs sont optionnels pour permettre des mises à jour partielles.
*
* @author GBCM Development Team
* @version 1.0
* @since 1.0
*/
public class UpdateCoachDTO {
/**
* Spécialisation principale du coach.
*/
@Size(max = 100, message = "La spécialisation ne peut pas dépasser 100 caractères")
private String specialization;
/**
* Années d'expérience du coach.
*/
private Integer yearsOfExperience;
/**
* Certifications du coach.
*/
private String certifications;
/**
* Biographie du coach.
*/
private String bio;
/**
* Tarif horaire du coach.
*/
private BigDecimal hourlyRate;
/**
* Statut du coach.
*/
private String status;
/**
* Disponibilité pour les réservations.
*/
private Boolean availableForBooking;
/**
* Types de services offerts par le coach.
*/
private Set<ServiceType> serviceTypes;
/**
* Heures de travail - début.
*/
private LocalTime workingHoursStart;
/**
* Heures de travail - fin.
*/
private LocalTime workingHoursEnd;
/**
* Fuseau horaire du coach.
*/
private String timeZone;
/**
* Langues parlées par le coach.
*/
private String languagesSpoken;
/**
* Date de début d'activité.
*/
private LocalDate startDate;
/**
* Date de fin d'activité.
*/
private LocalDate endDate;
/**
* Notes internes sur le coach.
*/
private String notes;
/**
* Constructeur par défaut.
*/
public UpdateCoachDTO() {
}
// Getters et Setters
public String getSpecialization() {
return specialization;
}
public void setSpecialization(String specialization) {
this.specialization = specialization;
}
public Integer getYearsOfExperience() {
return yearsOfExperience;
}
public void setYearsOfExperience(Integer yearsOfExperience) {
this.yearsOfExperience = yearsOfExperience;
}
public String getCertifications() {
return certifications;
}
public void setCertifications(String certifications) {
this.certifications = certifications;
}
public String getBio() {
return bio;
}
public void setBio(String bio) {
this.bio = bio;
}
public BigDecimal getHourlyRate() {
return hourlyRate;
}
public void setHourlyRate(BigDecimal hourlyRate) {
this.hourlyRate = hourlyRate;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Boolean getAvailableForBooking() {
return availableForBooking;
}
public void setAvailableForBooking(Boolean availableForBooking) {
this.availableForBooking = availableForBooking;
}
public Set<ServiceType> getServiceTypes() {
return serviceTypes;
}
public void setServiceTypes(Set<ServiceType> serviceTypes) {
this.serviceTypes = serviceTypes;
}
public LocalTime getWorkingHoursStart() {
return workingHoursStart;
}
public void setWorkingHoursStart(LocalTime workingHoursStart) {
this.workingHoursStart = workingHoursStart;
}
public LocalTime getWorkingHoursEnd() {
return workingHoursEnd;
}
public void setWorkingHoursEnd(LocalTime workingHoursEnd) {
this.workingHoursEnd = workingHoursEnd;
}
public String getTimeZone() {
return timeZone;
}
public void setTimeZone(String timeZone) {
this.timeZone = timeZone;
}
public String getLanguagesSpoken() {
return languagesSpoken;
}
public void setLanguagesSpoken(String languagesSpoken) {
this.languagesSpoken = languagesSpoken;
}
public LocalDate getStartDate() {
return startDate;
}
public void setStartDate(LocalDate startDate) {
this.startDate = startDate;
}
public LocalDate getEndDate() {
return endDate;
}
public void setEndDate(LocalDate endDate) {
this.endDate = endDate;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
@Override
public String toString() {
return "UpdateCoachDTO{" +
"specialization='" + specialization + '\'' +
", status='" + status + '\'' +
", availableForBooking=" + availableForBooking +
'}';
}
}

View File

@@ -0,0 +1,245 @@
package com.gbcm.server.api.dto.common;
import java.util.List;
/**
* DTO générique pour les réponses paginées.
* Contient les données paginées et les métadonnées de pagination.
*
* @param <T> le type des éléments contenus dans la page
* @author GBCM Development Team
* @version 1.0
* @since 1.0
*/
public class PagedResponseDTO<T> {
/**
* Liste des éléments de la page courante.
*/
private List<T> content;
/**
* Numéro de la page courante (commence à 0).
*/
private int page;
/**
* Taille de la page.
*/
private int size;
/**
* Nombre total d'éléments.
*/
private long totalElements;
/**
* Nombre total de pages.
*/
private int totalPages;
/**
* Indique si c'est la première page.
*/
private boolean first;
/**
* Indique si c'est la dernière page.
*/
private boolean last;
/**
* Nombre d'éléments dans la page courante.
*/
private int numberOfElements;
/**
* Indique si la page est vide.
*/
private boolean empty;
/**
* Critères de tri appliqués.
*/
private String sort;
/**
* Constructeur par défaut.
*/
public PagedResponseDTO() {
}
/**
* Constructeur avec tous les paramètres.
*
* @param content liste des éléments
* @param page numéro de page
* @param size taille de page
* @param totalElements nombre total d'éléments
*/
public PagedResponseDTO(List<T> content, int page, int size, long totalElements) {
this.content = content;
this.page = page;
this.size = size;
this.totalElements = totalElements;
this.totalPages = size > 0 ? (int) Math.ceil((double) totalElements / size) : 0;
this.first = page == 0;
this.last = page >= totalPages - 1;
this.numberOfElements = content != null ? content.size() : 0;
this.empty = numberOfElements == 0;
}
/**
* Constructeur avec tri.
*
* @param content liste des éléments
* @param page numéro de page
* @param size taille de page
* @param totalElements nombre total d'éléments
* @param sort critères de tri
*/
public PagedResponseDTO(List<T> content, int page, int size, long totalElements, String sort) {
this(content, page, size, totalElements);
this.sort = sort;
}
// Getters et Setters
public List<T> getContent() {
return content;
}
public void setContent(List<T> content) {
this.content = content;
this.numberOfElements = content != null ? content.size() : 0;
this.empty = numberOfElements == 0;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
this.first = page == 0;
this.last = page >= totalPages - 1;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
this.totalPages = size > 0 ? (int) Math.ceil((double) totalElements / size) : 0;
this.last = page >= totalPages - 1;
}
public long getTotalElements() {
return totalElements;
}
public void setTotalElements(long totalElements) {
this.totalElements = totalElements;
this.totalPages = size > 0 ? (int) Math.ceil((double) totalElements / size) : 0;
this.last = page >= totalPages - 1;
}
public int getTotalPages() {
return totalPages;
}
public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
}
public boolean isFirst() {
return first;
}
public void setFirst(boolean first) {
this.first = first;
}
public boolean isLast() {
return last;
}
public void setLast(boolean last) {
this.last = last;
}
public int getNumberOfElements() {
return numberOfElements;
}
public void setNumberOfElements(int numberOfElements) {
this.numberOfElements = numberOfElements;
}
public boolean isEmpty() {
return empty;
}
public void setEmpty(boolean empty) {
this.empty = empty;
}
public String getSort() {
return sort;
}
public void setSort(String sort) {
this.sort = sort;
}
/**
* Indique s'il y a une page suivante.
*
* @return true s'il y a une page suivante
*/
public boolean hasNext() {
return !last;
}
/**
* Indique s'il y a une page précédente.
*
* @return true s'il y a une page précédente
*/
public boolean hasPrevious() {
return !first;
}
/**
* Retourne le numéro de la page suivante.
*
* @return numéro de la page suivante ou -1 si pas de page suivante
*/
public int getNextPage() {
return hasNext() ? page + 1 : -1;
}
/**
* Retourne le numéro de la page précédente.
*
* @return numéro de la page précédente ou -1 si pas de page précédente
*/
public int getPreviousPage() {
return hasPrevious() ? page - 1 : -1;
}
@Override
public String toString() {
return "PagedResponseDTO{" +
"page=" + page +
", size=" + size +
", totalElements=" + totalElements +
", totalPages=" + totalPages +
", numberOfElements=" + numberOfElements +
", first=" + first +
", last=" + last +
", empty=" + empty +
'}';
}
}

View File

@@ -0,0 +1,118 @@
package com.gbcm.server.api.service;
import com.gbcm.server.api.dto.client.ClientDTO;
import com.gbcm.server.api.dto.client.CreateClientDTO;
import com.gbcm.server.api.dto.client.UpdateClientDTO;
import com.gbcm.server.api.dto.common.PagedResponseDTO;
import com.gbcm.server.api.exceptions.GBCMException;
/**
* Interface de service pour la gestion des clients de la plateforme GBCM.
* Définit toutes les opérations métier liées aux clients.
*
* @author GBCM Development Team
* @version 1.0
* @since 1.0
*/
public interface ClientService {
/**
* Récupère la liste paginée des clients avec filtres optionnels.
*
* @param page numéro de page (commence à 0)
* @param size taille de page
* @param sort critères de tri (ex: "companyName,asc")
* @param status filtre par statut
* @param industry filtre par secteur d'activité
* @param search terme de recherche (nom entreprise, email)
* @return liste paginée des clients
* @throws GBCMException si une erreur métier survient
*/
PagedResponseDTO<ClientDTO> getClients(int page, int size, String sort, Object status, String industry, String search) throws GBCMException;
/**
* Récupère un client par son identifiant.
*
* @param id l'identifiant du client
* @return le client trouvé
* @throws GBCMException si le client n'est pas trouvé
*/
ClientDTO getClientById(Long id) throws GBCMException;
/**
* Récupère un client par l'identifiant de son utilisateur associé.
*
* @param userId l'identifiant de l'utilisateur
* @return le client trouvé
* @throws GBCMException si le client n'est pas trouvé
*/
ClientDTO getClientByUserId(Long userId) throws GBCMException;
/**
* Crée un nouveau client.
*
* @param createClientDTO les données du nouveau client
* @return le client créé
* @throws GBCMException si une erreur métier survient
*/
ClientDTO createClient(CreateClientDTO createClientDTO) throws GBCMException;
/**
* Met à jour un client existant.
*
* @param id l'identifiant du client
* @param updateClientDTO les données de mise à jour
* @return le client mis à jour
* @throws GBCMException si le client n'est pas trouvé ou si une erreur métier survient
*/
ClientDTO updateClient(Long id, UpdateClientDTO updateClientDTO) throws GBCMException;
/**
* Supprime un client (suppression logique).
*
* @param id l'identifiant du client
* @throws GBCMException si le client n'est pas trouvé
*/
void deleteClient(Long id) throws GBCMException;
/**
* Active un client.
*
* @param id l'identifiant du client
* @throws GBCMException si le client n'est pas trouvé
*/
void activateClient(Long id) throws GBCMException;
/**
* Désactive un client.
*
* @param id l'identifiant du client
* @throws GBCMException si le client n'est pas trouvé
*/
void deactivateClient(Long id) throws GBCMException;
/**
* Convertit un prospect en client actif.
*
* @param id l'identifiant du client (prospect)
* @throws GBCMException si le client n'est pas trouvé ou n'est pas un prospect
*/
void convertProspectToClient(Long id) throws GBCMException;
/**
* Récupère les statistiques des clients.
*
* @return les statistiques des clients
* @throws GBCMException si une erreur survient
*/
Object getClientStatistics() throws GBCMException;
/**
* Recherche des clients par critères avancés.
*
* @param searchCriteria les critères de recherche
* @return liste des clients correspondants
* @throws GBCMException si une erreur survient
*/
PagedResponseDTO<ClientDTO> searchClients(Object searchCriteria) throws GBCMException;
}

View File

@@ -0,0 +1,137 @@
package com.gbcm.server.api.service;
import com.gbcm.server.api.dto.coach.CoachDTO;
import com.gbcm.server.api.dto.coach.CreateCoachDTO;
import com.gbcm.server.api.dto.coach.UpdateCoachDTO;
import com.gbcm.server.api.dto.common.PagedResponseDTO;
import com.gbcm.server.api.exceptions.GBCMException;
/**
* Interface de service pour la gestion des coaches de la plateforme GBCM.
* Définit toutes les opérations métier liées aux coaches.
*
* @author GBCM Development Team
* @version 1.0
* @since 1.0
*/
public interface CoachService {
/**
* Récupère la liste paginée des coaches avec filtres optionnels.
*
* @param page numéro de page (commence à 0)
* @param size taille de page
* @param sort critères de tri (ex: "specialization,asc")
* @param status filtre par statut
* @param specialization filtre par spécialisation
* @param availableOnly filtre coaches disponibles uniquement
* @param search terme de recherche (nom, spécialisation)
* @return liste paginée des coaches
* @throws GBCMException si une erreur métier survient
*/
PagedResponseDTO<CoachDTO> getCoaches(int page, int size, String sort, Object status, String specialization, boolean availableOnly, String search) throws GBCMException;
/**
* Récupère un coach par son identifiant.
*
* @param id l'identifiant du coach
* @return le coach trouvé
* @throws GBCMException si le coach n'est pas trouvé
*/
CoachDTO getCoachById(Long id) throws GBCMException;
/**
* Récupère un coach par l'identifiant de son utilisateur associé.
*
* @param userId l'identifiant de l'utilisateur
* @return le coach trouvé
* @throws GBCMException si le coach n'est pas trouvé
*/
CoachDTO getCoachByUserId(Long userId) throws GBCMException;
/**
* Crée un nouveau coach.
*
* @param createCoachDTO les données du nouveau coach
* @return le coach créé
* @throws GBCMException si une erreur métier survient
*/
CoachDTO createCoach(CreateCoachDTO createCoachDTO) throws GBCMException;
/**
* Met à jour un coach existant.
*
* @param id l'identifiant du coach
* @param updateCoachDTO les données de mise à jour
* @return le coach mis à jour
* @throws GBCMException si le coach n'est pas trouvé ou si une erreur métier survient
*/
CoachDTO updateCoach(Long id, UpdateCoachDTO updateCoachDTO) throws GBCMException;
/**
* Supprime un coach (suppression logique).
*
* @param id l'identifiant du coach
* @throws GBCMException si le coach n'est pas trouvé
*/
void deleteCoach(Long id) throws GBCMException;
/**
* Active un coach.
*
* @param id l'identifiant du coach
* @throws GBCMException si le coach n'est pas trouvé
*/
void activateCoach(Long id) throws GBCMException;
/**
* Désactive un coach.
*
* @param id l'identifiant du coach
* @throws GBCMException si le coach n'est pas trouvé
*/
void deactivateCoach(Long id) throws GBCMException;
/**
* Met un coach en congé.
*
* @param id l'identifiant du coach
* @throws GBCMException si le coach n'est pas trouvé
*/
void setCoachOnLeave(Long id) throws GBCMException;
/**
* Récupère les coaches disponibles pour un type de service.
*
* @param serviceType le type de service
* @return liste des coaches disponibles
* @throws GBCMException si une erreur survient
*/
PagedResponseDTO<CoachDTO> getAvailableCoachesForService(Object serviceType) throws GBCMException;
/**
* Récupère les statistiques des coaches.
*
* @return les statistiques des coaches
* @throws GBCMException si une erreur survient
*/
Object getCoachStatistics() throws GBCMException;
/**
* Met à jour la note d'un coach après une session.
*
* @param coachId l'identifiant du coach
* @param rating la nouvelle note
* @throws GBCMException si le coach n'est pas trouvé
*/
void updateCoachRating(Long coachId, Double rating) throws GBCMException;
/**
* Recherche des coaches par critères avancés.
*
* @param searchCriteria les critères de recherche
* @return liste des coaches correspondants
* @throws GBCMException si une erreur survient
*/
PagedResponseDTO<CoachDTO> searchCoaches(Object searchCriteria) throws GBCMException;
}