UNPKG

@universis/candidates

Version:

Universis api server plugin for study program candidates, internship selection etc

157 lines (150 loc) 7.02 kB
import {DataObjectState, DataCacheStrategy, DataConfigurationStrategy, ModelClassLoaderStrategy, SchemaLoaderStrategy} from "@themost/data"; import {DataError, AccessDeniedError, DataNotFoundError, TraceUtils, ApplicationService, Args} from "@themost/common"; import path from "path"; /** * @param {DataEventArgs} event */ async function afterSaveAsync(event) { const context = event.model.context; // get current status const actionStatus = await context.model('StudyProgramRegisterAction') .where('id').equal(event.target.id).select('actionStatus/alternateName').value(); if (actionStatus !== 'CompletedActionStatus') { return; } if (event.state === DataObjectState.Insert) { throw new AccessDeniedError('A study program registration cannot be completed automatically.', null); } if (event.state === DataObjectState.Update) { // get previous status let previousStatus = 'UnknownActionStatus'; if (event.previous) { previousStatus = event.previous.actionStatus.alternateName; } else { throw new DataError('E_STATE', 'The previous state of an object cannot be determined', null, 'StudyProgramRegisterAction'); } if (previousStatus === 'ActiveActionStatus') { // get register action const item = await context.model('StudyProgramRegisterAction') .where('id').equal(event.target.id) .expand('studyProgram', { name: 'candidate', options: { $expand: 'person($expand=gender)' } }, 'attachments', 'studyProgramEnrollmentEvent') .silent().getItem(); if (item == null) { throw new DataNotFoundError('Current item cannot be found or is inaccessible', null, 'StudyProgramRegisterAction'); } /** * @type {Student} */ let student = item.candidate.student ? context.model('Student').convert(item.candidate.student) : null; if (student==null) { /** * @type {CandidateStudent} */ const candidate = context.model('CandidateStudent').convert(item.candidate); student = await candidate.convertCandidateToStudent(context); // if the event requires automated obligatory courses registration if (item.studyProgramEnrollmentEvent && item.studyProgramEnrollmentEvent.autoRegisterCourses) { // autoRegisterClasses method is static, so load base class through ModelClassLoaderStrategy // to prevent direct import from the parent api const applicationConfiguration = context.getApplication().getConfiguration(); // get schema loader const schemaLoader = applicationConfiguration .getStrategy(SchemaLoaderStrategy); Args.notNull(schemaLoader, 'Schema loader'); // get student model definition const model = schemaLoader.getModelDefinition('Student'); Args.notNull(model, 'Student model'); // get model class loader const loader = applicationConfiguration .getStrategy(ModelClassLoaderStrategy); Args.notNull(loader, 'Model class loader'); // get student class const studentBaseClass = loader.resolve(model); if (studentBaseClass && typeof studentBaseClass.autoRegisterClasses === 'function') { // create an AutoRegisterClassesAction through autoRegisterClasses student method const autoRegistrationPayload = { students: [student.id], data: { // only obligatory courses of the student's semester onlyObligatory: true, department: student.department } } // start the async auto courses registration process await studentBaseClass.autoRegisterClasses(context, autoRegistrationPayload); } } } // add also student attachments if (item.attachments) { const attachments = []; // add to student attachments for (let i = 0; i < item.attachments.length; i++) { attachments.push(item.attachments[i].id); } student.attachments = attachments; if (attachments && attachments.length) { await context.model('Student').silent().save(student); } } const cache = context.getApplication().getConfiguration().getStrategy(DataCacheStrategy); if (cache != null) { cache.clear(); } } } } /** * @param {DataEventArgs} event * @param {Function} callback */ function afterSave(event, callback) { return afterSaveAsync(event).then(() => { return callback(); }).catch((err) => { return callback(err); }); } class CreateStudentAfterAcceptCandidate extends ApplicationService { constructor(app) { super(app); this.install('StudyProgramRegisterAction', __filename); } install() { /** * get data configuration * @type {DataConfigurationStrategy} */ const configuration = this.getApplication().getConfiguration().getStrategy(DataConfigurationStrategy); // get StudentRequestAction model definition const model = configuration.getModelDefinition('StudyProgramRegisterAction'); // get this file path relative to application execution path const listenerType = './' + path.relative(this.getApplication().getConfiguration().getExecutionPath(), __filename); // ensure model event listeners model.eventListeners = model.eventListeners || []; // try to find event listener const findIndex = model.eventListeners.findIndex(listener => { return listener.type === listenerType || listener.type === listenerType.replace(/\.js$/, ''); }); if (findIndex < 0) { // add event listener model.eventListeners.push({ type: listenerType }); // update StudentRequestAction model definition configuration.setModelDefinition(model); // write to log TraceUtils.info(`Services: ${this.constructor.name} service has been successfully installed`); } } } export { afterSave, CreateStudentAfterAcceptCandidate }