Files
zod-backend/src/task/repositories/task.repository.ts
2025-08-05 17:53:38 +03:00

119 lines
4.1 KiB
TypeScript

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<Task>) {}
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<Task>) {
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();
}
}