mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-07-15 01:55:21 +00:00
fix: fix tasks submission journey
This commit is contained in:
@ -23,6 +23,7 @@ export class TaskController {
|
|||||||
@AllowedRoles(Roles.GUARDIAN)
|
@AllowedRoles(Roles.GUARDIAN)
|
||||||
async createTask(@AuthenticatedUser() { sub }: IJwtPayload, @Body() body: CreateTaskRequestDto) {
|
async createTask(@AuthenticatedUser() { sub }: IJwtPayload, @Body() body: CreateTaskRequestDto) {
|
||||||
const task = await this.taskService.createTask(sub, body);
|
const task = await this.taskService.createTask(sub, body);
|
||||||
|
console.log(task.dueDate);
|
||||||
return ResponseFactory.data(new TaskResponseDto(task));
|
return ResponseFactory.data(new TaskResponseDto(task));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1 +1,2 @@
|
|||||||
|
export * from './task-submission-details.response.dto';
|
||||||
export * from './task.response.dto';
|
export * from './task.response.dto';
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { DocumentMetaResponseDto } from '~/document/dtos/response';
|
||||||
|
import { TaskSubmission } from '~/task/entities/task-submissions.entity';
|
||||||
|
|
||||||
|
export class TaskSubmissionDetailsResponsetDto {
|
||||||
|
@ApiProperty()
|
||||||
|
submittedAt!: Date;
|
||||||
|
|
||||||
|
@ApiProperty({ type: DocumentMetaResponseDto })
|
||||||
|
proofOfCompletion!: DocumentMetaResponseDto | null;
|
||||||
|
|
||||||
|
constructor(taskSubmission: TaskSubmission) {
|
||||||
|
this.submittedAt = taskSubmission.submittedAt;
|
||||||
|
this.proofOfCompletion = taskSubmission.proofOfCompletion
|
||||||
|
? new DocumentMetaResponseDto(taskSubmission.proofOfCompletion)
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@ import { ApiProperty } from '@nestjs/swagger';
|
|||||||
import { DocumentMetaResponseDto } from '~/document/dtos/response';
|
import { DocumentMetaResponseDto } from '~/document/dtos/response';
|
||||||
import { JuniorResponseDto } from '~/junior/dtos/response';
|
import { JuniorResponseDto } from '~/junior/dtos/response';
|
||||||
import { Task } from '~/task/entities';
|
import { Task } from '~/task/entities';
|
||||||
import { TaskSubmission } from '~/task/entities/task-submissions.entity';
|
import { TaskSubmissionDetailsResponsetDto } from './task-submission-details.response.dto';
|
||||||
|
|
||||||
export class TaskResponseDto {
|
export class TaskResponseDto {
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
@ -24,7 +24,10 @@ export class TaskResponseDto {
|
|||||||
rewardAmount!: number;
|
rewardAmount!: number;
|
||||||
|
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
submission?: TaskSubmission;
|
isProofRequired!: boolean;
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
submission?: TaskSubmissionDetailsResponsetDto | null;
|
||||||
|
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
junior!: JuniorResponseDto;
|
junior!: JuniorResponseDto;
|
||||||
@ -45,7 +48,8 @@ export class TaskResponseDto {
|
|||||||
this.status = task.status;
|
this.status = task.status;
|
||||||
this.dueDate = task.dueDate;
|
this.dueDate = task.dueDate;
|
||||||
this.rewardAmount = task.rewardAmount;
|
this.rewardAmount = task.rewardAmount;
|
||||||
this.submission = task.submission;
|
this.isProofRequired = task.isProofRequired;
|
||||||
|
this.submission = task.submission ? new TaskSubmissionDetailsResponsetDto(task.submission) : null;
|
||||||
this.image = new DocumentMetaResponseDto(task.image);
|
this.image = new DocumentMetaResponseDto(task.image);
|
||||||
this.junior = new JuniorResponseDto(task.assignedTo);
|
this.junior = new JuniorResponseDto(task.assignedTo);
|
||||||
this.createdAt = task.createdAt;
|
this.createdAt = task.createdAt;
|
||||||
|
@ -36,9 +36,9 @@ export class TaskRepository {
|
|||||||
'image',
|
'image',
|
||||||
'assignedTo',
|
'assignedTo',
|
||||||
'assignedTo.customer',
|
'assignedTo.customer',
|
||||||
'assignedTo.customer.user',
|
'assignedTo.customer.profilePicture',
|
||||||
'assignedTo.customer.user.profilePicture',
|
|
||||||
'submission',
|
'submission',
|
||||||
|
'submission.proofOfCompletion',
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -50,9 +50,9 @@ export class TaskRepository {
|
|||||||
.leftJoinAndSelect('task.image', 'image')
|
.leftJoinAndSelect('task.image', 'image')
|
||||||
.leftJoinAndSelect('task.assignedTo', 'assignedTo')
|
.leftJoinAndSelect('task.assignedTo', 'assignedTo')
|
||||||
.leftJoinAndSelect('assignedTo.customer', 'customer')
|
.leftJoinAndSelect('assignedTo.customer', 'customer')
|
||||||
.leftJoinAndSelect('customer.user', 'user')
|
.leftJoinAndSelect('customer.profilePicture', 'profilePicture')
|
||||||
.leftJoinAndSelect('user.profilePicture', 'profilePicture')
|
.leftJoinAndSelect('task.submission', 'submission')
|
||||||
.leftJoinAndSelect('task.submission', 'submission');
|
.leftJoinAndSelect('submission.proofOfCompletion', 'proofOfCompletion');
|
||||||
|
|
||||||
if (roles.includes(Roles.GUARDIAN)) {
|
if (roles.includes(Roles.GUARDIAN)) {
|
||||||
queryBuilder.where('task.assignedById = :userId', { userId });
|
queryBuilder.where('task.assignedById = :userId', { userId });
|
||||||
@ -90,11 +90,12 @@ export class TaskRepository {
|
|||||||
|
|
||||||
createSubmission(task: Task, body: TaskSubmissionRequestDto) {
|
createSubmission(task: Task, body: TaskSubmissionRequestDto) {
|
||||||
const submission = task.submission || new TaskSubmission();
|
const submission = task.submission || new TaskSubmission();
|
||||||
submission.status = SubmissionStatus.PENDING;
|
submission.status = task.isProofRequired ? SubmissionStatus.PENDING : SubmissionStatus.APPROVED;
|
||||||
submission.submittedAt = new Date();
|
submission.submittedAt = new Date();
|
||||||
submission.taskId = task.id;
|
submission.taskId = task.id;
|
||||||
submission.proofOfCompletionId = body.imageId;
|
submission.proofOfCompletionId = body.imageId;
|
||||||
|
|
||||||
|
task.submission = submission;
|
||||||
return task.save();
|
return task.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { BadRequestException, Injectable } from '@nestjs/common';
|
import { BadRequestException, Injectable } from '@nestjs/common';
|
||||||
|
import moment from 'moment';
|
||||||
import { FindOptionsWhere } from 'typeorm';
|
import { FindOptionsWhere } from 'typeorm';
|
||||||
import { IJwtPayload } from '~/auth/interfaces';
|
import { IJwtPayload } from '~/auth/interfaces';
|
||||||
import { OciService } from '~/document/services';
|
import { OciService } from '~/document/services';
|
||||||
@ -11,6 +12,13 @@ import { TaskRepository } from '../repositories';
|
|||||||
export class TaskService {
|
export class TaskService {
|
||||||
constructor(private readonly taskRepository: TaskRepository, private readonly ociService: OciService) {}
|
constructor(private readonly taskRepository: TaskRepository, private readonly ociService: OciService) {}
|
||||||
async createTask(userId: string, body: CreateTaskRequestDto) {
|
async createTask(userId: string, body: CreateTaskRequestDto) {
|
||||||
|
if (moment(body.dueDate).isBefore(moment(body.startDate))) {
|
||||||
|
throw new BadRequestException('TASK.DUE_DATE_BEFORE_START_DATE');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moment(body.dueDate).isBefore(moment())) {
|
||||||
|
throw new BadRequestException('TASK.DUE_DATE_IN_PAST');
|
||||||
|
}
|
||||||
const task = await this.taskRepository.createTask(userId, body);
|
const task = await this.taskRepository.createTask(userId, body);
|
||||||
return this.findTask({ id: task.id });
|
return this.findTask({ id: task.id });
|
||||||
}
|
}
|
||||||
@ -22,12 +30,14 @@ export class TaskService {
|
|||||||
throw new BadRequestException('TASK.NOT_FOUND');
|
throw new BadRequestException('TASK.NOT_FOUND');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await this.prepareTasksPictures([task]);
|
||||||
|
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
async findTasks(user: IJwtPayload, query: TasksFilterOptions): Promise<[Task[], number]> {
|
async findTasks(user: IJwtPayload, query: TasksFilterOptions): Promise<[Task[], number]> {
|
||||||
const [tasks, count] = await this.taskRepository.findTasks(user, query);
|
const [tasks, count] = await this.taskRepository.findTasks(user, query);
|
||||||
|
console.log(tasks);
|
||||||
await this.prepareTasksPictures(tasks);
|
await this.prepareTasksPictures(tasks);
|
||||||
|
|
||||||
return [tasks, count];
|
return [tasks, count];
|
||||||
@ -53,7 +63,7 @@ export class TaskService {
|
|||||||
throw new BadRequestException('TASK.NO_SUBMISSION');
|
throw new BadRequestException('TASK.NO_SUBMISSION');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (task.submission.status !== SubmissionStatus.PENDING) {
|
if (task.submission.status == SubmissionStatus.APPROVED) {
|
||||||
throw new BadRequestException('TASK.SUBMISSION_ALREADY_REVIEWED');
|
throw new BadRequestException('TASK.SUBMISSION_ALREADY_REVIEWED');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +77,7 @@ export class TaskService {
|
|||||||
throw new BadRequestException('TASK.NO_SUBMISSION');
|
throw new BadRequestException('TASK.NO_SUBMISSION');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (task.submission.status !== SubmissionStatus.PENDING) {
|
if (task.submission.status == SubmissionStatus.REJECTED) {
|
||||||
throw new BadRequestException('TASK.SUBMISSION_ALREADY_REVIEWED');
|
throw new BadRequestException('TASK.SUBMISSION_ALREADY_REVIEWED');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +95,7 @@ export class TaskService {
|
|||||||
|
|
||||||
task.image.url = imageUrl;
|
task.image.url = imageUrl;
|
||||||
|
|
||||||
if (task.submission) {
|
if (task.submission?.proofOfCompletion) {
|
||||||
task.submission.proofOfCompletion.url = submissionUrl;
|
task.submission.proofOfCompletion.url = submissionUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user