Files
dsc-api/src/modules/task-manager/providers/task.service.ts
T

138 lines
4.6 KiB
TypeScript

import { BadRequestException, ForbiddenException, Injectable, NotFoundException } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { In, Repository } from "typeorm";
import { TaskRepository } from "../repositories/task.repository";
import { TMTask } from "../entities/task.entity";
import { CreateTaskDto } from "../dto/task/create-task.dto";
import { UpdateTaskDto } from "../dto/task/update-task.dto";
import { ChangeTaskPhaseDto } from "../dto/task/change-task-phase.dto";
import { User } from "../../users/entities/user.entity";
import { TaskMessage, TaskPhaseMessage } from "../../../common/enums/message.enum";
import { TaskPhaseRepository } from "../repositories/task-phase.repository";
import { TMTaskPhase } from "../entities/task-phase.entity";
@Injectable()
export class TaskService {
constructor(
private readonly taskRepository: TaskRepository,
private readonly taskPhaseRepository: TaskPhaseRepository,
@InjectRepository(User)
private readonly userRepository: Repository<User>,
) {}
async findAll(): Promise<TMTask[]> {
return this.taskRepository.find({
relations: ["taskPhase", "remarks", "attachments", "checkListItems", "users"],
});
}
async findByPhase(taskPhaseId: string): Promise<TMTask[]> {
return this.taskRepository.find({ where: { taskPhaseId } });
}
async findOneOrFail(id: string): Promise<TMTask> {
const task = await this.taskRepository.findOne({
where: { id },
relations: {
taskPhase: true,
users: true
},
});
if (!task) throw new NotFoundException(TaskMessage.TASK_NOT_FOUND);
return task;
}
async findTaskPhaseOrFail(taskPhaseId: string): Promise<TMTaskPhase> {
const taskPhase = await this.taskPhaseRepository.findOne({
where: { id: taskPhaseId },
relations: {
project: {
users: true,
},
},
});
if (!taskPhase) throw new NotFoundException(TaskPhaseMessage.TASK_PHASE_NOT_FOUND);
return taskPhase;
}
async create(dto: CreateTaskDto): Promise<TMTask> {
const { userIds, startDate, endDate, ...rest } = dto;
const taskPhase = await this.findTaskPhaseOrFail(dto.taskPhaseId);
if (userIds?.length) {
const isUsersValid = userIds.every((userId) => taskPhase.project.users.some((user) => user.id === userId));
if (!isUsersValid) throw new BadRequestException(TaskMessage.USERS_ASSIGNED_TO_TASK_NOT_PROJECT_MEMBER);
}
const task = this.taskRepository.create({
...rest,
startDate: startDate ? new Date(startDate) : undefined,
endDate: endDate ? new Date(endDate) : undefined,
});
if (userIds?.length) {
task.users = await this.userRepository.findBy({ id: In(userIds) });
}
return this.taskRepository.save(task);
}
async update(id: string, dto: UpdateTaskDto): Promise<TMTask> {
const task = await this.findOneOrFail(id);
const { userIds, startDate, endDate, ...rest } = dto;
if (dto.taskPhaseId) {
const taskPhase = await this.findTaskPhaseOrFail(dto.taskPhaseId);
if (userIds?.length) {
const isUsersValid = userIds.every((userId) => taskPhase.project.users.some((user) => user.id === userId));
if (!isUsersValid) throw new BadRequestException(TaskMessage.USERS_ASSIGNED_TO_TASK_NOT_PROJECT_MEMBER);
}
}
Object.assign(task, {
...rest,
startDate: startDate ? new Date(startDate) : task.startDate,
endDate: endDate ? new Date(endDate) : task.endDate,
});
if (userIds) {
task.users = userIds.length ? await this.userRepository.findBy({ id: In(userIds) }) : [];
}
return this.taskRepository.save(task);
}
async changePhase(id: string, dto: ChangeTaskPhaseDto): Promise<TMTask> {
const task = await this.findOneOrFail(id);
const newPhase = await this.findTaskPhaseOrFail(dto.taskPhaseId);
if (task.taskPhase.projectId !== newPhase.projectId) {
throw new BadRequestException(TaskPhaseMessage.TASK_PHASE_NOT_SAME_PROJECT);
}
task.taskPhaseId = dto.taskPhaseId;
task.taskPhase = newPhase;
return this.taskRepository.save(task);
}
async remove(id: string): Promise<void> {
await this.findOneOrFail(id);
await this.taskRepository.delete(id);
}
async getTaskDetail(userId: string, taskId: string): Promise<TMTask | null> {
const task = await this.findOneOrFail(taskId);
const isTaskMember = task.users.some((user) => user.id === userId);
if(!isTaskMember) throw new ForbiddenException(TaskMessage.USER_NOT_TASK_MEMBER);
const taskDetail = await this.taskRepository.getTaskDetail(taskId);
return taskDetail;
}
}