diff --git a/src/modules/task-manager/providers/task.service.ts b/src/modules/task-manager/providers/task.service.ts new file mode 100644 index 0000000..9e635e3 --- /dev/null +++ b/src/modules/task-manager/providers/task.service.ts @@ -0,0 +1,100 @@ +import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { In, Repository } from 'typeorm'; +import { TaskRepository } from '../repositories/task.repository'; +import { TaskPhaseRepository } from '../repositories/task-phase.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'; + +@Injectable() +export class TaskService { + constructor( + private readonly taskRepository: TaskRepository, + private readonly taskPhaseRepository: TaskPhaseRepository, + @InjectRepository(User) + private readonly userRepository: Repository, + ) {} + + findAll(): Promise { + return this.taskRepository.findAll(); + } + + findByPhase(taskPhaseId: string): Promise { + return this.taskRepository.findByPhase(taskPhaseId); + } + + async findOne(id: string): Promise { + const task = await this.taskRepository.findOneById(id); + if (!task) throw new NotFoundException(`Task #${id} not found`); + return task; + } + + async create(dto: CreateTaskDto): Promise { + const { userIds, startDate, endDate, ...rest } = dto; + + const taskPhase = await this.taskPhaseRepository.findOneById(dto.taskPhaseId); + if (!taskPhase) throw new NotFoundException(`TaskPhase #${dto.taskPhaseId} not found`); + + 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 { + const task = await this.findOne(id); + const { userIds, startDate, endDate, ...rest } = dto; + + if (dto.taskPhaseId) { + const taskPhase = await this.taskPhaseRepository.findOneById(dto.taskPhaseId); + if (!taskPhase) throw new NotFoundException(`TaskPhase #${dto.taskPhaseId} not found`); + } + + 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 { + const task = await this.findOne(id); + + const newPhase = await this.taskPhaseRepository.findOneById(dto.taskPhaseId); + if (!newPhase) throw new NotFoundException(`TaskPhase #${dto.taskPhaseId} not found`); + + if (task.taskPhase.projectId !== newPhase.projectId) { + throw new BadRequestException( + `TaskPhase #${dto.taskPhaseId} does not belong to the same project as the current phase`, + ); + } + + task.taskPhaseId = dto.taskPhaseId; + task.taskPhase = newPhase; + + return this.taskRepository.save(task); + } + + async remove(id: string): Promise { + await this.findOne(id); + await this.taskRepository.delete(id); + } +} \ No newline at end of file