import { HttpStatus, Injectable } from '@nestjs/common'; import { filterQuestions } from '../helpers/filter-questions.helper'; import Utils from '@/common/utils'; import { FindQuestionsDTO } from '../dtos/find-questions.dto'; import { Test } from '@nestjs/testing'; import { AppTimeoutException } from '@/common/exceptions/app-timeout.exception'; import { PaginatedResponse } from '@/common/responses'; import { InjectRepository } from '@nestjs/typeorm'; import { Question } from '../entities/question.entity'; import { FindManyOptions, FindOneOptions, Repository } from 'typeorm'; import { TestsService } from '@/modules/tests/providers/tests.service'; import { AppException } from '@/common/exceptions/app.exception'; @Injectable() export class QuestionsQueryProvider { constructor( /** * Inject Questions Repository */ @InjectRepository(Question) private readonly questionsRepository: Repository, /** * Inject Tests Service */ private readonly testsService: TestsService, ) {} public async findAllForAdmin(query: FindQuestionsDTO) { const filters = filterQuestions(query); const { limit, page, skip, take } = Utils.PaginationUtils.getPaginationOptions(query); let selectedTest: Test | null = null; if (query.test) { selectedTest = await this.testsService.adminGetOne(query.test, { relations: { questions: true }, }); } try { const [questions, total] = await this.questionsRepository.findAndCount({ where: { ...filters, ...(selectedTest && { test: selectedTest, }), }, loadRelationIds: true, skip, take, order: query.sortBy ? { [query.sortBy]: query.order ?? 'ASC', } : { createdAt: 'DESC' }, }); return new PaginatedResponse(questions, { page, limit, total, }); } catch (err) { throw new AppTimeoutException(err); } } public async findByOptionsForAdmin(options: FindManyOptions) { let questions: Array = []; try { questions = await this.questionsRepository.find(options); } catch (err) { throw new AppTimeoutException(err); } return questions; } public async findOneByIdForAdmin(id: number) { let question: Question | null = null; try { question = await this.questionsRepository.findOne({ where: { id }, relations: { test: true, rangeRules: true, choices: true }, }); } catch (err) { throw new AppTimeoutException(err); } if (!question) { throw new AppException( 'common.errors.entityNotFound', HttpStatus.NOT_FOUND, { entity: '$t(questions.fields.question)' }, ); } return question; } public async findOneForAdmin(options: FindOneOptions) { let question: Question | null = null; try { question = await this.questionsRepository.findOne(options); } catch (err) { throw new AppTimeoutException(err); } return question; } }