F3.1: persistir perfil personal y exigir email al Inspector
This commit is contained in:
@@ -41,6 +41,10 @@ export interface AdministrativeUserView {
|
||||
id: string;
|
||||
username: string;
|
||||
email: string | null;
|
||||
dni: string | null;
|
||||
phone: string | null;
|
||||
jobTitle: string | null;
|
||||
employeeNumber: string | null;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
status: UserStatus;
|
||||
@@ -72,6 +76,13 @@ function roleSelectionInvalid(): BadRequestException {
|
||||
});
|
||||
}
|
||||
|
||||
function inspectorEmailRequired(): BadRequestException {
|
||||
return new BadRequestException({
|
||||
code: 'INSPECTOR_EMAIL_REQUIRED',
|
||||
message: 'Los usuarios con rol Inspector deben tener un email válido para recibir la documentación de sus inspecciones',
|
||||
});
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class UsersService {
|
||||
constructor(
|
||||
@@ -96,6 +107,10 @@ export class UsersService {
|
||||
OR user_account.email ILIKE $${parameters.length}
|
||||
OR user_account.first_name ILIKE $${parameters.length}
|
||||
OR user_account.last_name ILIKE $${parameters.length}
|
||||
OR user_account.dni ILIKE $${parameters.length}
|
||||
OR user_account.phone ILIKE $${parameters.length}
|
||||
OR user_account.job_title ILIKE $${parameters.length}
|
||||
OR user_account.employee_number ILIKE $${parameters.length}
|
||||
)
|
||||
`);
|
||||
}
|
||||
@@ -115,6 +130,10 @@ export class UsersService {
|
||||
user_account.id,
|
||||
user_account.username,
|
||||
user_account.email,
|
||||
user_account.dni,
|
||||
user_account.phone,
|
||||
user_account.job_title AS "jobTitle",
|
||||
user_account.employee_number AS "employeeNumber",
|
||||
user_account.first_name AS "firstName",
|
||||
user_account.last_name AS "lastName",
|
||||
user_account.status,
|
||||
@@ -176,9 +195,14 @@ export class UsersService {
|
||||
try {
|
||||
return await this.dataSource.transaction(async (manager) => {
|
||||
const roles = await this.resolveRoles(manager, dto.roleIds);
|
||||
this.assertInspectorHasEmail(roles, dto.email ?? null);
|
||||
const user = manager.getRepository(User).create({
|
||||
username: dto.username.trim().toLowerCase(),
|
||||
email: dto.email?.trim().toLowerCase() || null,
|
||||
dni: dto.dni ?? null,
|
||||
phone: dto.phone ?? null,
|
||||
jobTitle: dto.jobTitle ?? null,
|
||||
employeeNumber: dto.employeeNumber ?? null,
|
||||
passwordHash,
|
||||
firstName: dto.firstName.trim(),
|
||||
lastName: dto.lastName.trim(),
|
||||
@@ -227,6 +251,10 @@ export class UsersService {
|
||||
if (
|
||||
dto.username === undefined &&
|
||||
dto.email === undefined &&
|
||||
dto.dni === undefined &&
|
||||
dto.phone === undefined &&
|
||||
dto.jobTitle === undefined &&
|
||||
dto.employeeNumber === undefined &&
|
||||
dto.firstName === undefined &&
|
||||
dto.lastName === undefined
|
||||
) {
|
||||
@@ -240,6 +268,9 @@ export class UsersService {
|
||||
return await this.dataSource.transaction(async (manager) => {
|
||||
const user = await this.lockUser(manager, id);
|
||||
const before = await this.loadUserView(manager, id);
|
||||
if (dto.email !== undefined && !dto.email && before.roles.some((role) => role.code === 'inspector')) {
|
||||
throw inspectorEmailRequired();
|
||||
}
|
||||
|
||||
if (dto.username !== undefined) {
|
||||
user.username = dto.username.trim().toLowerCase();
|
||||
@@ -247,6 +278,10 @@ export class UsersService {
|
||||
if (dto.email !== undefined) {
|
||||
user.email = dto.email?.trim().toLowerCase() || null;
|
||||
}
|
||||
if (dto.dni !== undefined) user.dni = dto.dni ?? null;
|
||||
if (dto.phone !== undefined) user.phone = dto.phone ?? null;
|
||||
if (dto.jobTitle !== undefined) user.jobTitle = dto.jobTitle ?? null;
|
||||
if (dto.employeeNumber !== undefined) user.employeeNumber = dto.employeeNumber ?? null;
|
||||
if (dto.firstName !== undefined) user.firstName = dto.firstName.trim();
|
||||
if (dto.lastName !== undefined) user.lastName = dto.lastName.trim();
|
||||
user.updatedBy = principal.userId;
|
||||
@@ -379,6 +414,7 @@ export class UsersService {
|
||||
await this.lockUser(manager, id);
|
||||
const roles = await this.resolveRoles(manager, dto.roleIds);
|
||||
const before = await this.loadUserView(manager, id);
|
||||
this.assertInspectorHasEmail(roles, before.email);
|
||||
const beforeIds = before.roles.map((role) => role.id).sort();
|
||||
const afterIds = roles.map((role) => role.id).sort();
|
||||
if (beforeIds.join(',') === afterIds.join(',')) return before;
|
||||
@@ -417,6 +453,12 @@ export class UsersService {
|
||||
return roles;
|
||||
}
|
||||
|
||||
private assertInspectorHasEmail(roles: Role[], email: string | null | undefined): void {
|
||||
if (roles.some((role) => role.code === 'inspector') && !email?.trim()) {
|
||||
throw inspectorEmailRequired();
|
||||
}
|
||||
}
|
||||
|
||||
private async insertUserRoles(
|
||||
manager: EntityManager,
|
||||
userId: string,
|
||||
@@ -455,6 +497,10 @@ export class UsersService {
|
||||
user_account.id,
|
||||
user_account.username,
|
||||
user_account.email,
|
||||
user_account.dni,
|
||||
user_account.phone,
|
||||
user_account.job_title AS "jobTitle",
|
||||
user_account.employee_number AS "employeeNumber",
|
||||
user_account.first_name AS "firstName",
|
||||
user_account.last_name AS "lastName",
|
||||
user_account.status,
|
||||
@@ -491,7 +537,7 @@ export class UsersService {
|
||||
private userConflict(): ConflictException {
|
||||
return new ConflictException({
|
||||
code: 'USER_ALREADY_EXISTS',
|
||||
message: 'El usuario o email ya está registrado',
|
||||
message: 'El usuario, email o DNI ya está registrado',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user