File

src/user/user.service.ts

Index

Properties
Methods

Constructor

constructor(userRepository: Repository<User>, appUserRepository: Repository<ApplicationUser>, clientRepository: Repository<Client>, clientService: ClientService, userClientService: UserClientService, applicationService: ApplicationService, profileService: ApplicationProfileService, appUserService: ApplicationUserService)
Parameters :
Name Type Optional
userRepository Repository<User> No
appUserRepository Repository<ApplicationUser> No
clientRepository Repository<Client> No
clientService ClientService No
userClientService UserClientService No
applicationService ApplicationService No
profileService ApplicationProfileService No
appUserService ApplicationUserService No

Methods

Async create
create(body)
Parameters :
Name Optional
body No
Returns : Promise<number>
Async createUsersInBulkUpload
createUsersInBulkUpload(file: Express.Multer.File, session: Session)
Parameters :
Name Type Optional
file Express.Multer.File No
session Session No
Returns : unknown
Async delete
delete(id: number)
Parameters :
Name Type Optional
id number No
Returns : unknown
Async disable
disable(id: number)
Parameters :
Name Type Optional
id number No
Returns : Promise<User>
Async enable
enable(id: number)
Parameters :
Name Type Optional
id number No
Returns : Promise<User>
findAll
findAll()
Returns : Promise<User[]>
findOne
findOne(id: number)
Parameters :
Name Type Optional
id number No
Async findPaginate
findPaginate(filter: PaginateUserQueryDto)
Parameters :
Name Type Optional
filter PaginateUserQueryDto No
Async findPositions
findPositions(undefined: PaginateQuery)
Parameters :
Name Type Optional
PaginateQuery No
Returns : unknown
Async getApplicationId
getApplicationId(appName: string)
Parameters :
Name Type Optional
appName string No
Returns : Promise<number>
Async getApplicationOfClientId
getApplicationOfClientId(clientId: number, applicationId: number)
Parameters :
Name Type Optional
clientId number No
applicationId number No
Returns : unknown
Async getClientId
getClientId(client: ClientPostDto, session: Session)
Parameters :
Name Type Optional
client ClientPostDto No
session Session No
Returns : Promise<number>
Async getProfileId
getProfileId(profile: ApplicationProfileBodyDto, applicationId: number, profileName: string)
Parameters :
Name Type Optional
profile ApplicationProfileBodyDto No
applicationId number No
profileName string No
Returns : Promise<number>
Async getUserId
getUserId(user: UserCreateDTO)
Parameters :
Name Type Optional
user UserCreateDTO No
Returns : Promise<number>
Async update
update(id: number, body: UserUpdateDTO)
Parameters :
Name Type Optional
id number No
body UserUpdateDTO No
Returns : Promise<User>

Properties

Private Readonly logger
Default value : new Logger(UserService.name)
import {
  Injectable,
  InternalServerErrorException,
  Logger,
  NotFoundException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { User } from 'src/entities/user';
import { ILike, Not, Repository } from 'typeorm';
import {
  PaginateUserQueryDto,
  UserCreateDTO,
  UserUpdateDTO,
} from './dto/user.dto';
import { ClientPostDto } from 'src/client/dto/client.dto'
import { ApplicationProfileBodyDto } from 'src/application-profile/dto/application-profile.dto'
import { PaginatedResult } from 'src/types/paginated-result';
import { GeneralException } from 'src/util/general.exception';
import { ApplicationUser } from 'src/entities/application-user';
import { Client } from 'src/entities/client';
import { ClientService } from 'src/client/client.service';
import { ApplicationService } from 'src/application/application.service';
import { ApplicationProfileService } from 'src/application-profile/application-profile.service'
import { ApplicationUserService } from 'src/application-user/application-user.service'
import type { BulkRegistration, ItemSheet } from 'src/types/client'
import { UserClientService } from './user-client/user-client.service';
import { Session } from 'src/types/Express'
import { ExceptionError } from 'src/util';
import { JobPosition } from 'src/entities/job-position';
import { PaginateQuery } from 'src/types/paginate-query';
import { excelToJson, excelToJsonAplication } from 'src/util/excelToJson';
import { statusDeployment } from 'src/types/statusDeployment';

@Injectable()
export class UserService {
  private readonly logger = new Logger(UserService.name);

  constructor(
    @InjectRepository(User)
    private userRepository: Repository<User>,
    @InjectRepository(ApplicationUser)
    private appUserRepository: Repository<ApplicationUser>,
    @InjectRepository(Client)
    private clientRepository: Repository<Client>,
    private readonly clientService: ClientService,
    private readonly userClientService: UserClientService,
    private readonly applicationService: ApplicationService,
    private readonly profileService: ApplicationProfileService,
    private readonly appUserService: ApplicationUserService,
  ) {}

  findOne(id: number): Promise<User | undefined> {
    return this.userRepository.findOneBy({ id });
  }

  async findPaginate(
    filter: PaginateUserQueryDto,
  ): Promise<PaginatedResult<User>> {
    const { size = 10, onlyActive, name, email } = filter;
    const page = +filter.page || 0;
    const skip = page * size;

    const queryBuilder = await this.userRepository
      .createQueryBuilder()
      .take(size)
      .skip(skip)
      .orderBy({ username: 'ASC' });

    if (onlyActive === 'true') {
      queryBuilder.andWhere({
        enabled: true,
      });
    }

    if (name && name.length > 0) {
      queryBuilder.andWhere({
        name: ILike(`%${name}%`),
      });
    }

    if (!!email) {
      queryBuilder.andWhere({
        email: ILike(`%${email.toLowerCase()}%`),
      });
    }

    const [content, total] = await queryBuilder.getManyAndCount();
    const lastPage = Math.ceil(total / size);
    const prevPage = page < 1 ? null : page;

    return {
      content,
      size: +size,
      totalElements: total,
      totalPages: lastPage,
      first: !prevPage,
      last: lastPage === page + 1,
      number: page + 1,
      numberOfElements: content.length,
    };
  }

  findAll(): Promise<User[]> {
    return this.userRepository.find({
      order: {
        username: 'asc',
      },
    });
  }

  async create(body: UserCreateDTO & { clientName?: string}): Promise<number> {
    const { username, email, clientName } = body;

    const emailLowerCase = email.toLowerCase();

    const emailExists = await this.userRepository.countBy({
      email: emailLowerCase,
    });

    if (emailExists > 0) {
      throw new GeneralException('user_email_already_exists');
    }

    const usernameExists = await this.userRepository.countBy({
      username,
    });
    if (usernameExists > 0) {
      throw new GeneralException('username_already_exists');
    }

    const response = await this.userRepository
      .insert({
        ...body,
        email: emailLowerCase,
      })
      .catch((error) => {
        this.logger.error(error);
        throw new InternalServerErrorException();
      });

    const userId = response.raw[0].id

    if (clientName) {
      const result = await this.clientRepository.findOneBy({ name: clientName })

      if (!result) {
        throw new NotFoundException({
          messageKey: 'client_not_found',
        });
      }

      await this.userClientService.addUserToClient({
        clientId: result.id,
        userId
      })
    }

    return userId;
  }

  async update(id: number, body: UserUpdateDTO): Promise<User> {
    const user = await this.userRepository.findOneBy({ id });
    if (!user) {
      throw new NotFoundException({ messageKey: 'user_not_found' });
    }
    const emailLowerCase = body.email?.toLowerCase() || user.email;

    const updateUser = {
      ...user,
      ...(body as UserUpdateDTO), // force only attrs accepted in UserUpdateDTO
      name: body.name,
      email: emailLowerCase,
    };

    if (body.email) {
      const emailExists = await this.userRepository.countBy({
        email: emailLowerCase,
        id: Not(id),
      });

      if (emailExists > 0) {
        throw new GeneralException('user_email_already_exists');
      }
    }

    await this.userRepository.save(updateUser).catch((error) => {
      this.logger.error(error);
      throw new InternalServerErrorException();
    });

    return this.userRepository.findOneByOrFail({ id });
  }

  async enable(id: number): Promise<User> {
    const user = await this.userRepository.findOneBy({ id });
    if (!user) {
      throw new NotFoundException({ messageKey: 'user_not_found' });
    }

    return this.userRepository.save({
      ...user,
      enabled: true,
    });
  }

  async disable(id: number): Promise<User> {
    const user = await this.userRepository.findOneBy({ id });
    if (!user) {
      throw new NotFoundException({ messageKey: 'user_not_found' });
    }

    return this.userRepository.save({
      ...user,
      enabled: false,
    });
  }

  async delete(id: number) {
    const user = await this.userRepository.findOneBy({ id });
    if (!user) {
      throw new NotFoundException({ messageKey: 'user_not_found' });
    }

    const applicationUserLinked = await this.appUserRepository.countBy({
      userId: id,
    });
    if (applicationUserLinked) {
      throw new GeneralException('user_delete_error_application_linked');
    }

    return this.userRepository.delete(id);
  }

  async getClientId(
    client: ClientPostDto,
    session: Session
  ): Promise<number> {
    const clientFound = await this.clientService.getClientByName(client.name)

    if (clientFound) {
      return clientFound.id
    }

    const { client: clientCreated } = await this.clientService.postClient(client, session)

    return clientCreated.id
  }

  async getUserId(user: UserCreateDTO): Promise<number> {
    const userFound = await this.userRepository.findOneBy({
      email: user.email
    });

    if (userFound) {
      return userFound.id
    }

    const userId = await this.create(user)
    return userId
  }

  async getApplicationId(appName: string): Promise<number> {
    const app = await this.applicationService.getApplicationByName(appName)

    if (!app) {
      throw ExceptionError(`Aplicação ${appName} não encontrada`, 404)
    }

    return app.id
  }

  async getProfileId(
    profile: ApplicationProfileBodyDto,
    applicationId: number,
    profileName: string,
  ): Promise<number> {
    const profileFound = await this.profileService.profileExists(applicationId, profileName)

    if (profileFound) {
      return profileFound.id
    }

    const profileId = await this.profileService.addProfile(applicationId, profile)

    return profileId
  }

  async getApplicationOfClientId(clientId: number, applicationId: number) {
    const applicationClient = await this.clientService
      .addApplicationForBulkRegistration(clientId, { applicationId, url: '' })

      return applicationClient.id
  }

  async createUsersInBulkUpload(file: Express.Multer.File, session: Session) {
    const result = await excelToJsonAplication<any>(file.path);

    const { applicationName, itens } = result;

    const applicationId = await this.getApplicationId(applicationName.B)

    const promises = itens.map(async (value)  => {
      const bulkRegistration: BulkRegistration & { user: { password: string } } = {
        user: {
          username: value.B,
          name: value.C,
          email: value.D,
          password: value.E,
          cpf: value.F,
          userRole: value.G,
          telephone1: value.H,
          telephone2: value.I,
          ramal1: Number(value.J) || undefined,
          ramal2: Number(value.K) || undefined,
          fax: value.L,
          observation: value.M,
        },
        profile: {
          name: value.O,
        },
        client: {
          name: value.Q,
          internalCode: value.R,
          mtrixCode: Number(value.S) || undefined,
          company: value.T,
          enabled: Boolean(value.U),
          type: value.V as 'F' | 'D',
          useChannel: false,
          statusDeploymentId: statusDeployment.HOMOLOGACAO,
        }
      };

     const  { client, user, profile } = bulkRegistration

      const clientId = await this.getClientId(client, session)
        .catch((err) => this.logger.error(`Falha ao buscar ou criar cliente - clientId: ${clientId.id} session: ${session}`, err))

      const userId = await this.getUserId(user)
        .catch((err) => this.logger.error(`Falha ao buscar ou criar usuário - user: ${user.name}`, err))

      if (!userId) {
        this.logger.error('userId não encontrado')
        return
      }

      await this.userClientService.addUserToClient({ clientId, userId })
      .catch((err) => this.logger.error('userToClientId não encontrado', err))

      const applicationProfileId = await this.getProfileId(
        profile,
        applicationId,
        profile.name,
      )
      .catch((err) => this.logger.error(`Falha ao buscar ou criar o perfil - perfil: ${profile.name}`, err))

      if (!applicationProfileId) {
        this.logger.error('applicationProfileId não encontrado')
        return
      }

      const applicationClientId = await this.getApplicationOfClientId(
        clientId,
        applicationId
      )
      .catch((err) => this.logger.error(`Falha ao buscar a aplicacao do cliente - applicationId: ${applicationId}`, err))

      if (!applicationClientId) {
        this.logger.error('applicationClientId não encontrado')
        return
      }

      const paramsAddUser = {
        applicationId,
        applicationProfileId,
        clientId,
        userId,
      }
      await this.appUserService.addUser(
        applicationClientId,
        paramsAddUser
      )
      .catch((err) => this.logger.error(`Falha ao vincular a aplicação no cliente - applicationClientId: ${applicationClientId}`, err))

      await this.appUserService.userSyncKeycloak({...paramsAddUser, password: {
        clientname: client.name,
        password: user.password,
        username: user.username,
      }})
      .catch((err) => this.logger.error(`Falha ao sincronizar com o Keycloak`, err));
    })

    return await Promise.all(promises)
  }
  async findPositions({ page = 0, size = 10, name }: PaginateQuery) {
    const _page = Number(page);
    const offset = _page * +size;
    const queryBuilder = this.userRepository.manager
      .createQueryBuilder(JobPosition, 'jb')
      .select('jb.id', 'id')
      .addSelect('jb.position_name', 'positionName')
      .orderBy('jb.position_name')
      .limit(+size)
      .offset(offset);

    if (name) {
      queryBuilder.andWhere('jb.position_name ILIKE :name', {
        name: '%' + name + '%',
      });
    }

    const content = await queryBuilder.getRawMany();
    const total = await queryBuilder.getCount();
    const lastPage = Math.ceil(total / +size);
    const prevPage = _page < 1 ? null : _page;

    return {
      content,
      size: +size,
      totalElements: total,
      totalPages: lastPage,
      first: !prevPage,
      last: lastPage === _page + 1,
      number: _page + 1,
      numberOfElements: content.length,
    };
  }
}

results matching ""

    No results matching ""