@universis/evaluations
Version:
Universis evaluations library
197 lines (187 loc) • 7.53 kB
JavaScript
import { DataObjectState } from '@themost/data';
/**
*
* @param {DataEventArgs} event
*/
async function beforeSaveAsync(event) {
// get organizer from courseClass
const context = event.model.context;
if (event.target.courseClass) {
const organizer = await context.model('CourseClass')
.where('id').equal(event.target.courseClass)
.select('course/department').value();
event.target.organizer = organizer;
}
if (event.state === DataObjectState.Update) {
let startDateChanged = false;
let endDateChanged = false;
// check if endDate is changed and update expired field for tokens
if (event.target.startDate) {
const prevStartDate = event.previous.startDate;
const startDate = event.target.startDate;
prevStartDate.setHours(0, 0, 0, 0);
startDate.setHours(0, 0, 0, 0)
startDateChanged = prevStartDate - startDate !== 0
}
if (event.target.endDate) {
const prevEndDate = event.previous.endDate;
const endDate = event.target.endDate;
prevEndDate.setHours(0, 0, 0, 0);
endDate.setHours(0, 0, 0, 0);
endDateChanged = prevEndDate - endDate !== 0;
}
if (startDateChanged || endDateChanged) {
if (endDateChanged) {
let tokens = await context.model('EvaluationAccessToken').where('evaluationEvent').equal(event.target.id)
.and('used').notEqual(1)
.silent().getItems();
if (tokens.length > 0) {
tokens = tokens.map(x => {
x.expires = event.target.endDate;
return x;
});
// update tokens
await context.model('EvaluationAccessToken').silent().save(tokens);
}
}
// change startDate and endDate of related ClassInstructorEvaluationEvent - if any
const events = await context.model('ClassInstructorEvaluationEvent')
.where('superEvent').equal(event.target.id)
.silent()
.getItems();
if (events && events.length > 0) {
events.map(x => {
x.endDate = event.target.endDate ? event.target.endDate : x.endDate;
x.startDate = event.target.startDate ? event.target.startDate : x.startDate;
return x;
});
await context.model('ClassInstructorEvaluationEvent').silent().save(events);
}
}
}
}
/**
* @param {DataEventArgs} event
* @param {Function} callback
*/
export function beforeSave(event, callback) {
beforeSaveAsync(event).then(() => {
return callback()
}).catch( err => {
return callback(err);
})
}
/**
*
* @param {DataEventArgs} event
*/
async function afterSaveAsync(event) {
// get organizer from courseClass
const context = event.model.context;
if (event.state === DataObjectState.Insert) {
// get all courseClassInstructors and check if ClassInstructorEvaluationEvents should be created
const evaluationEvent = await context.model('CourseClassEvaluationEvent')
.where('id').equal(event.target.id).flatten()
.silent().getItem();
const childEvaluationDocument = await context.model('EvaluationDocument')
.where('parentDocument').equal(evaluationEvent.evaluationDocument).getItem();
if (childEvaluationDocument) {
const classInstructors = await context.model('CourseClassInstructor')
.where('courseClass').equal(evaluationEvent.courseClass).getAllItems();
const events = classInstructors.map(x => {
x.courseClassInstructor = x.id;
x.superEvent = event.target.id;
x.evaluationDocument = childEvaluationDocument
x.startDate = event.target.startDate;
x.endDate = event.target.endDate;
delete x.id;
return x;
});
await context.model('ClassInstructorEvaluationEvent').silent().save(events);
}
}
}
export function afterExecute(event, callback) {
return afterExecuteAsync(event).then(() => {
return callback();
}).catch(err => {
return callback(err);
});
}
export async function afterExecuteAsync(event) {
// calculate total tokens and total used tokens if events are expanded
if (event.emitter && event.emitter.$expand && Array.isArray(event.emitter.$expand)) {
// if tokens of classInstructorEvaluationEvents are expanded and $select and $groupby are present to mapping options
if (event.emitter.$expand.find(mapping => {
// $select and $groupby are present to mapping options
return typeof mapping === 'object'
? mapping.name === 'tokens' && (mapping.options && mapping.options.$select && mapping.options.$groupby)
: mapping === 'tokens'
})) {
const results = Array.isArray(event.result) ? event.result : [event.result]
for (const result of results) {
if (Array.isArray(result.tokens) && result.tokens.length) {
// calculate total and used tokens
result.calculatedTotal = result.tokens.reduce((partial_sum, a) => partial_sum + a.total, 0)
const findUsed = result.tokens.find(x=>{
return x.used;
});
result.calculatedUsed = findUsed?findUsed.total:0;
}
}
}
}
}
/**
* @async
* @param {DataEventArgs} event
*/
async function beforeRemoveAsync(event) {
// ensure associations
const context = event.model.context;
const evaluationEvent = context.model('EvaluationEvent').convert(event.target);
const form = await evaluationEvent.property('evaluationDocument').getItem();
if (form && form.resultType) {
if (context.model(form.resultType) == null) {
// ensure model is added to configuration
await evaluationEvent.getForm();
}
const answers = await context.model(form.resultType)
.where('evaluationEvent').equal(event.target.id)
.silent().count();
if (answers) {
throw new Error('Cannot remove evaluation event since there are responses associated with it')
}
}
// remove also related ClassInstructorEvaluationEvents
const relatedEvents = await context.model('ClassInstructorEvaluationEvent')
.where('superEvent').equal(event.target.id).select('id')
.getItems();
if (relatedEvents && relatedEvents.length > 0) {
await context.model('ClassInstructorEvaluationEvent').remove(relatedEvents);
}
}
/**
* @param {DataEventArgs} event
* @param {Function} callback
*/
export function beforeRemove(event, callback) {
// execute async method
return beforeRemoveAsync(event).then(() => {
return callback();
}).catch(err => {
return callback(err);
});
}
/**
* @param {DataEventArgs} event
* @param {Function} callback
*/
export function afterSave(event, callback) {
// execute async method
return afterSaveAsync(event).then(() => {
return callback();
}).catch(err => {
return callback(err);
});
}