import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Brackets, FindOptionsWhere, Repository } from 'typeorm'; import { Roles } from '~/auth/enums'; import { IJwtPayload } from '~/auth/interfaces'; import { CreateTaskRequestDto, TasksFilterOptions, TaskSubmissionRequestDto } from '../dtos/request'; import { Task } from '../entities'; import { TaskSubmission } from '../entities/task-submissions.entity'; import { SubmissionStatus, TaskStatus } from '../enums'; const ONE = 1; @Injectable() export class TaskRepository { constructor(@InjectRepository(Task) private readonly taskRepository: Repository) {} createTask(userId: string, body: CreateTaskRequestDto) { return this.taskRepository.save( this.taskRepository.create({ title: body.title, description: body.description, rewardAmount: body.rewardAmount, taskFrequency: body.frequency, startDate: body.startDate, dueDate: body.dueDate, assignedById: userId, assignedToId: body.juniorId, imageId: body.imageId, isProofRequired: body.isProofRequired, }), ); } findTask(where: FindOptionsWhere) { return this.taskRepository.findOne({ where, relations: [ 'image', 'assignedTo', 'assignedTo.customer', 'assignedTo.customer.user', 'assignedTo.customer.user.profilePicture', 'submission', 'submission.proofOfCompletion', ], }); } findTasks({ roles, sub: userId }: IJwtPayload, query: TasksFilterOptions) { const queryBuilder = this.taskRepository.createQueryBuilder('task'); queryBuilder .leftJoinAndSelect('task.image', 'image') .leftJoinAndSelect('task.assignedTo', 'assignedTo') .leftJoinAndSelect('assignedTo.customer', 'customer') .leftJoinAndSelect('customer.user', 'user') .leftJoinAndSelect('user.profilePicture', 'profilePicture') .leftJoinAndSelect('task.submission', 'submission') .leftJoinAndSelect('submission.proofOfCompletion', 'proofOfCompletion'); if (roles.includes(Roles.GUARDIAN)) { queryBuilder.where('task.assignedById = :userId', { userId }); // Add a condition for juniorId if it exists if (query.juniorId) { queryBuilder.andWhere('task.assignedToId = :juniorId', { juniorId: query.juniorId }); } } else { queryBuilder.where('task.assignedToId = :userId', { userId }); } if (query.status === TaskStatus.PENDING) { queryBuilder.andWhere('task.dueDate >= :today', { today: new Date() }); queryBuilder.andWhere('submission IS NULL'); } if (query.status === TaskStatus.IN_PROGRESS) { queryBuilder.andWhere('submission IS NOT NULL'); queryBuilder.andWhere('submission.status != :status', { status: SubmissionStatus.APPROVED }); queryBuilder.andWhere('task.dueDate >= :today', { today: new Date() }); } if (query.status === TaskStatus.COMPLETED) { queryBuilder.andWhere( new Brackets((qb) => { qb.where('task.dueDate < :today', { today: new Date() }).orWhere('submission.status = :status', { status: SubmissionStatus.APPROVED, }); }), ); } queryBuilder.orderBy('task.createdAt', 'DESC'); queryBuilder.skip((query.page - ONE) * query.size); queryBuilder.take(query.size); return queryBuilder.getManyAndCount(); } createSubmission(task: Task, body: TaskSubmissionRequestDto) { const submission = task.submission || new TaskSubmission(); submission.status = task.isProofRequired ? SubmissionStatus.PENDING : SubmissionStatus.APPROVED; submission.submittedAt = new Date(); submission.taskId = task.id; submission.proofOfCompletionId = body.imageId; task.submission = submission; return task.save(); } approveSubmission(submission: TaskSubmission) { submission.status = SubmissionStatus.APPROVED; return submission.save(); } rejectSubmission(submission: TaskSubmission) { submission.status = SubmissionStatus.REJECTED; return submission.save(); } }