- UserController: endpoint GET /users/pending (rôles SUPER_ADMIN, ADMINISTRATEUR, GESTIONNAIRE) - UserService: findPendingUsers(role?) avec filtre statut EN_ATTENTE - GestionnairesService: retrait date_consentement_photo (non présent dans DTO) Made-with: Cursor
105 lines
3.4 KiB
TypeScript
105 lines
3.4 KiB
TypeScript
import {
|
||
ConflictException,
|
||
Injectable,
|
||
NotFoundException,
|
||
} from '@nestjs/common';
|
||
import { InjectRepository } from '@nestjs/typeorm';
|
||
import { Repository } from 'typeorm';
|
||
import { RoleType, StatutUtilisateurType, Users } from 'src/entities/users.entity';
|
||
import { CreateGestionnaireDto } from '../dto/create_gestionnaire.dto';
|
||
import { UpdateGestionnaireDto } from '../dto/update_gestionnaire.dto';
|
||
import * as bcrypt from 'bcrypt';
|
||
import { MailService } from 'src/modules/mail/mail.service';
|
||
|
||
@Injectable()
|
||
export class GestionnairesService {
|
||
constructor(
|
||
@InjectRepository(Users)
|
||
private readonly gestionnaireRepository: Repository<Users>,
|
||
private readonly mailService: MailService,
|
||
) { }
|
||
|
||
// Création d’un gestionnaire
|
||
async create(dto: CreateGestionnaireDto): Promise<Users> {
|
||
const exist = await this.gestionnaireRepository.findOneBy({ email: dto.email });
|
||
if (exist) throw new ConflictException('Email déjà utilisé');
|
||
|
||
const salt = await bcrypt.genSalt();
|
||
const hashedPassword = await bcrypt.hash(dto.password, salt);
|
||
|
||
const entity = this.gestionnaireRepository.create({
|
||
email: dto.email,
|
||
password: hashedPassword,
|
||
prenom: dto.prenom,
|
||
nom: dto.nom,
|
||
// genre: dto.genre, // Retiré
|
||
// statut: dto.statut, // Retiré
|
||
statut: StatutUtilisateurType.ACTIF,
|
||
telephone: dto.telephone,
|
||
// adresse: dto.adresse, // Retiré
|
||
// photo_url: dto.photo_url, // Retiré
|
||
// consentement_photo: dto.consentement_photo ?? false, // Retiré
|
||
// date_consentement_photo: dto.date_consentement_photo // Retiré
|
||
// ? new Date(dto.date_consentement_photo)
|
||
// : undefined,
|
||
changement_mdp_obligatoire: true,
|
||
role: RoleType.GESTIONNAIRE,
|
||
relaisId: dto.relaisId,
|
||
});
|
||
|
||
const savedUser = await this.gestionnaireRepository.save(entity);
|
||
|
||
// Envoi de l'email de bienvenue
|
||
try {
|
||
await this.mailService.sendGestionnaireWelcomeEmail(
|
||
savedUser.email,
|
||
savedUser.prenom || '',
|
||
savedUser.nom || '',
|
||
);
|
||
} catch (error) {
|
||
// On ne bloque pas la création si l'envoi d'email échoue, mais on log l'erreur
|
||
console.error('Erreur lors de l\'envoi de l\'email de bienvenue au gestionnaire', error);
|
||
}
|
||
|
||
return savedUser;
|
||
}
|
||
|
||
// Liste des gestionnaires
|
||
async findAll(): Promise<Users[]> {
|
||
return this.gestionnaireRepository.find({
|
||
where: { role: RoleType.GESTIONNAIRE },
|
||
relations: ['relais'],
|
||
});
|
||
}
|
||
|
||
// Récupérer un gestionnaire par ID
|
||
async findOne(id: string): Promise<Users> {
|
||
const gestionnaire = await this.gestionnaireRepository.findOne({
|
||
where: { id, role: RoleType.GESTIONNAIRE },
|
||
relations: ['relais'],
|
||
});
|
||
if (!gestionnaire) throw new NotFoundException('Gestionnaire introuvable');
|
||
return gestionnaire;
|
||
}
|
||
|
||
// Mise à jour d’un gestionnaire
|
||
async update(id: string, dto: UpdateGestionnaireDto): Promise<Users> {
|
||
const gestionnaire = await this.findOne(id);
|
||
|
||
if (dto.password) {
|
||
const salt = await bcrypt.genSalt();
|
||
gestionnaire.password = await bcrypt.hash(dto.password, salt);
|
||
}
|
||
|
||
const { password, ...rest } = dto;
|
||
Object.entries(rest).forEach(([key, value]) => {
|
||
if (value !== undefined) {
|
||
(gestionnaire as any)[key] = value;
|
||
}
|
||
});
|
||
|
||
return this.gestionnaireRepository.save(gestionnaire);
|
||
}
|
||
|
||
}
|