import { UnprocessableEntityException , BadRequestException , NotFoundException } from '@nestjs/common' ; import { Repository , EntityRepository } from 'typeorm' ; import { ObjectId } from 'mongodb' ; import slugify from 'slugify' ; import { TitlesEntity } from '../Entities/titles.entity' ; import { CreateTitleDto } from 'src/v1/Title/Dto/create-title.dto' ; import { UpdateTitleDto } from 'src/v1/Title/Dto/update-title.dto' ; @ EntityRepository ( TitlesEntity ) export class TitlesRepository extends Repository < TitlesEntity > { async getTitleBySlug ( titleSlug ) { try { const title = await this . findOneOrFail ( { slug : titleSlug } ) ; return title ; } catch ( err ) { throw new NotFoundException ( 'Title could not found by given slug' ) ; } } async getTitleById ( titleId ) { try { const title = await this . findOneOrFail ( titleId ) ; return title ; } catch ( err ) { throw new NotFoundException ( 'Title could not found by given id' ) ; } } async searchTitle ( { searchValue } ) { const [ titles ] = await this . findAndCount ( { where : { name : new RegExp ( searchValue , 'i' ) } , take : 5 , order : { entry_count : 'DESC' } } ) ; return { titles } ; } async updateEntryCount ( titleId , value ) { try { const title = await this . findOneOrFail ( titleId ) ; title . entry_count += value ; this . save ( title ) ; } catch ( err ) { throw new NotFoundException ( 'Title could not found by given id' ) ; } } async getTitleList ( query ) { const [ titles , total ] = await this . findAndCount ( { where : { ... query . author && { opened_by : query . author } , ... query . categoryIds && { $or : [ { category_id : { $in : query . categoryIds } } , { category_ancestors : { $in : query . categoryIds } } , ] } , ... query . sortBy === 'hot' && { created_at : { $gte : new Date ( new Date ( ) . setDate ( new Date ( ) . getDate ( ) - 1 ) ) } } , } , order : { ... query . sortBy === undefined && { created_at : 'DESC' , } , ... ( query . sortBy === 'top' || query . sortBy === 'hot' ) && { entry_count : 'DESC' , } } , take : 10 , skip : Number ( query . skip ) || 0 , } ) ; return { titles , count : total } ; } async getTitleListByIds ( idList ) { const [ titles , total ] = await this . findAndCount ( { where : { '_id' : { $in : idList } } , order : { entry_count : 'DESC' } , take : 5 , skip : 0 , } ) ; return { titles , count : total } ; } async createTitle ( openedBy , dto , categoryAncestors ) { const newTitle = new TitlesEntity ( { name : dto . name , slug : slugify ( dto . name , { lower : true } ) , category_id : dto . categoryId , category_ancestors : categoryAncestors , opened_by : openedBy , } ) ; try { return await this . save ( newTitle ) ; } catch ( err ) { throw new UnprocessableEntityException ( err . errmsg ) ; } } async rateTitle ( ratedBy , titleId , rateValue ) { let title ; try { title = await this . findOneOrFail ( titleId ) ; } catch ( error ) { throw new NotFoundException ( 'Title could not found by given id' ) ; } const docIfAlreadyRated = title . rate . find ( item => item . username === ratedBy ) ; if ( docIfAlreadyRated ) docIfAlreadyRated . rateValue = rateValue ; else title . rate . push ( { username : ratedBy , rateValue } ) ; this . save ( title ) ; } async getRateOfUser ( username , titleId ) { let title ; try { title = await this . findOneOrFail ( titleId ) ; } catch ( error ) { throw new NotFoundException ( 'Title could not found by given id' ) ; } const userRate = title . rate . find ( ( item ) => item . username === username ) ; if ( userRate ) return userRate ! . rateValue ; throw new BadRequestException ( 'This user did not rate this title yet' ) ; } async getAvarageRate ( titleId ) { let title ; try { title = await this . findOneOrFail ( titleId ) ; } catch ( error ) { throw new NotFoundException ( 'Title could not found by given id' ) ; } const averageRate = title . rate . reduce ( ( total , next ) => total + next . rateValue , 0 ) / title . rate . length ; return Math . round ( averageRate ) ; } async updateTitle ( updatedBy , title , dto , categoryAncestors ) { try { if ( dto . name ) { title . name = dto . name ; title . slug = slugify ( dto . name , { lower : true } ) ; } if ( dto . categoryId ) { title . category_id = dto . categoryId ; title . category_ancestors = categoryAncestors ; } title . updated_by = updatedBy ; await this . save ( title ) ; return title ; } catch ( err ) { throw new BadRequestException ( err . errmsg ) ; } } async deleteTitle ( titleId ) { try { const title = await this . findOneOrFail ( titleId ) ; await this . delete ( title ) ; } catch ( err ) { throw new NotFoundException ( 'Title could not found by given id' ) ; } } }