Files
backend/src/project/services/project.service.ts
2024-12-29 22:31:56 -06:00

271 lines
8.1 KiB
TypeScript

import { ProjectRepository } from '@app/common/modules/project/repositiories';
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { CreateProjectDto } from '../dto';
import { BaseResponseDto } from '@app/common/dto/base.response.dto';
import { SuccessResponseDto } from '@app/common/dto/success.response.dto';
import { ProjectEntity } from '@app/common/modules/project/entities';
import {
TypeORMCustomModel,
TypeORMCustomModelFindAllQuery,
} from '@app/common/models/typeOrmCustom.model';
import { ProjectDto } from '@app/common/modules/project/dtos';
import { PageResponse } from '@app/common/dto/pagination.response.dto';
import { CommandBus } from '@nestjs/cqrs';
import { CreateOrphanSpaceCommand } from '../command/create-orphan-space-command';
import { InviteUserRepository } from '@app/common/modules/Invite-user/repositiories';
import { UserRepository } from '@app/common/modules/user/repositories';
import { UserStatusEnum } from '@app/common/constants/user-status.enum';
import { RoleType } from '@app/common/constants/role.type.enum';
@Injectable()
export class ProjectService {
constructor(
private readonly projectRepository: ProjectRepository,
private readonly inviteUserRepository: InviteUserRepository,
private readonly userRepository: UserRepository,
private commandBus: CommandBus,
) {}
async createProject(
createProjectDto: CreateProjectDto,
): Promise<BaseResponseDto> {
const { name } = createProjectDto;
try {
// Check if the project name already exists
const isNameExist = await this.validate(name);
if (isNameExist) {
throw new HttpException(
`Project with name ${name} already exists`,
HttpStatus.CONFLICT,
);
}
const newProject = this.projectRepository.create(createProjectDto);
const savedProject = await this.projectRepository.save(newProject);
await this.commandBus.execute(new CreateOrphanSpaceCommand(savedProject));
return new SuccessResponseDto({
message: `Project with ID ${savedProject.uuid} successfully created`,
data: savedProject,
statusCode: HttpStatus.CREATED,
});
} catch (error) {
if (error instanceof HttpException) {
throw error;
}
throw new HttpException(
`An error occurred while creating the project. Please try again later. ${error}`,
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
async deleteProject(uuid: string): Promise<BaseResponseDto> {
try {
// Find the project by UUID
const project = await this.findOne(uuid);
if (!project) {
throw new HttpException(
`Project with ID ${uuid} not found`,
HttpStatus.NOT_FOUND,
);
}
// Delete the project
await this.projectRepository.delete({ uuid });
return new SuccessResponseDto({
message: `Project with ID ${uuid} successfully deleted`,
statusCode: HttpStatus.OK,
});
} catch (error) {
if (error instanceof HttpException) {
throw error;
}
throw new HttpException(
`An error occurred while deleting the project ${uuid}`,
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
async listProjects(
pageable: Partial<TypeORMCustomModelFindAllQuery>,
): Promise<BaseResponseDto> {
try {
pageable.modelName = 'project';
const customModel = TypeORMCustomModel(this.projectRepository);
const { baseResponseDto, paginationResponseDto } =
await customModel.findAll(pageable);
return new PageResponse<ProjectDto>(
baseResponseDto,
paginationResponseDto,
);
} catch (error) {
throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
async getProject(uuid: string): Promise<BaseResponseDto> {
try {
// Find the project by UUID
const project = await this.findOne(uuid);
if (!project) {
throw new HttpException(
`Project with ID ${uuid} not found`,
HttpStatus.NOT_FOUND,
);
}
return new SuccessResponseDto({
message: `Project with ID ${uuid} retrieved successfully`,
data: project,
statusCode: HttpStatus.OK,
});
} catch (error) {
if (error instanceof HttpException) {
throw error;
}
throw new HttpException(
`An error occurred while retrieving the project with id ${uuid}`,
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
async updateProject(
uuid: string,
updateProjectDto: CreateProjectDto,
): Promise<BaseResponseDto> {
try {
// Find the project by UUID
const project = await this.findOne(uuid);
if (!project) {
throw new HttpException(
`Project with ID ${uuid} not found`,
HttpStatus.NOT_FOUND,
);
}
if (updateProjectDto.name && updateProjectDto.name !== project.name) {
const isNameExist = await this.validate(updateProjectDto.name);
if (isNameExist) {
throw new HttpException(
`Project with name ${updateProjectDto.name} already exists`,
HttpStatus.CONFLICT,
);
}
}
// Update the project details
Object.assign(project, updateProjectDto);
const updatedProject = await this.projectRepository.save(project);
return new SuccessResponseDto({
message: `Project with ID ${uuid} successfully updated`,
data: updatedProject,
statusCode: HttpStatus.OK,
});
} catch (error) {
if (error instanceof HttpException) {
throw error;
}
throw new HttpException(
`An error occurred while updating the project with ID ${uuid}`,
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
async getUsersByProject(uuid: string): Promise<BaseResponseDto> {
try {
// Fetch invited users
const invitedUsers = await this.inviteUserRepository.find({
where: { project: { uuid }, isActive: true },
select: [
'firstName',
'lastName',
'email',
'createdAt',
'status',
'phoneNumber',
'jobTitle',
'invitedBy',
'isEnabled',
],
relations: ['roleType'],
});
// Fetch project users
const users = await this.userRepository.find({
where: { project: { uuid }, isActive: true },
select: ['firstName', 'lastName', 'email', 'createdAt'],
relations: ['roleType'],
});
// Combine both arrays
const allUsers = [...users, ...invitedUsers];
const normalizedUsers = allUsers.map((user) => {
const createdAt = new Date(user.createdAt);
const createdDate = createdAt.toLocaleDateString();
const createdTime = createdAt.toLocaleTimeString();
// Normalize user properties
const normalizedProps = this.normalizeUserProperties(user);
// Return the normalized user object
return {
...user,
createdDate,
createdTime,
...normalizedProps,
};
});
return new SuccessResponseDto({
message: `Users in project with ID ${uuid} retrieved successfully`,
data: normalizedUsers,
statusCode: HttpStatus.OK,
});
} catch (error) {
if (error instanceof HttpException) {
throw error;
}
throw new HttpException(
`An error occurred while retrieving users in the project with id ${uuid}`,
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
normalizeUserProperties(user: any) {
return {
status: user.status ?? UserStatusEnum.ACTIVE,
invitedBy: user.invitedBy ?? RoleType.SPACE_MEMBER,
isEnabled: user.isEnabled ?? true,
phoneNumber: user.phoneNumber ?? null,
jobTitle: user.jobTitle ?? null,
roleType: user.roleType?.type ?? null,
};
}
async findOne(uuid: string): Promise<ProjectEntity> {
const project = await this.projectRepository.findOne({ where: { uuid } });
return project;
}
async validate(name: string): Promise<boolean> {
return await this.projectRepository.exists({ where: { name } });
}
}