import * as mongoose from 'mongoose' ; import { ILecture } from '../../../shared/models/ILecture' ; import { IUnitModel , Unit } from './units/Unit' ; import { IUnit } from '../../../shared/models/units/IUnit' ; import { IUser } from '../../../shared/models/IUser' ; import { InternalServerError } from 'routing-controllers' ; import { Course } from './Course' ; interface ILectureModel extends ILecture , mongoose . Document { exportJSON : ( ) => Promise < ILecture > ; processUnitsFor : ( user : IUser ) => Promise < this > ; } const lectureSchema = new mongoose . Schema ( { name : { type : String , required : true } , description : { type : String } , units : [ { type : mongoose . Schema . Types . ObjectId , ref : 'Unit' } ] } , { timestamps : true , toObject : { transform : function ( doc , ret ) { ret . _id = ret . _id . toString ( ) ; } } } ) ; lectureSchema . pre ( 'remove' , async function ( ) { const localLecture = < ILectureModel > < any > this ; try { await Unit . deleteMany ( { '_id' : { $in : localLecture . units } } ) . exec ( ) ; } catch ( err ) { throw new Error ( 'Delete Error: ' + err . toString ( ) ) ; } } ) ; lectureSchema . methods . exportJSON = async function ( ) { const obj = this . toObject ( ) ; delete obj . _id ; delete obj . createdAt ; delete obj . __v ; delete obj . updatedAt ; const units = obj . units ; obj . units = [ ] ; for ( const unitId of units ) { const unit = await Unit . findById ( unitId ) ; if ( unit ) { const unitExport = await unit . exportJSON ( ) ; obj . units . push ( unitExport ) ; } } return obj ; } ; lectureSchema . methods . processUnitsFor = async function ( user ) { this . units = await Promise . all ( this . units . map ( async ( unit ) => { unit = await unit . populateUnit ( ) ; return unit . secureData ( user ) ; } ) ) ; return this ; } ; lectureSchema . statics . importJSON = async function ( lecture , courseId ) { const units = lecture . units ; lecture . units = [ ] ; try { const savedLecture = await new Lecture ( lecture ) . save ( ) ; const course = await Course . findById ( courseId ) ; course . lectures . push ( savedLecture ) ; await course . save ( ) ; for ( const unit of units ) { await Unit . schema . statics . importJSON ( unit , courseId , savedLecture . _id ) ; } const newLecture = await Lecture . findById ( savedLecture . _id ) ; return newLecture . toObject ( ) ; } catch ( err ) { const newError = new InternalServerError ( 'Failed to import lecture' ) ; newError . stack += '\nCaused by: ' + err . message + '\n' + err . stack ; throw newError ; } } ; const Lecture = mongoose . model < ILectureModel > ( 'Lecture' , lectureSchema ) ; export { Lecture , ILectureModel } ;