@universis/dining
Version:
Universis api for dining
276 lines (198 loc) • 12.2 kB
JavaScript
"use strict";var _common = require("@themost/common");
var _data = require("@themost/data");var _dec, _dec2, _dec3, _dec4, _dec5, _class, _class2;function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {var desc = {};Object.keys(descriptor).forEach(function (key) {desc[key] = descriptor[key];});desc.enumerable = !!desc.enumerable;desc.configurable = !!desc.configurable;if ('value' in desc || desc.initializer) {desc.writable = true;}desc = decorators.slice().reverse().reduce(function (desc, decorator) {return decorator(target, property, desc) || desc;}, desc);if (context && desc.initializer !== void 0) {desc.value = desc.initializer ? desc.initializer.call(context) : void 0;desc.initializer = undefined;}if (desc.initializer === void 0) {Object.defineProperty(target, property, desc);desc = null;}return desc;}let
DiningRequestEvent = (_dec = _data.EdmMapping.entityType('DiningRequestEvent'), _dec2 =
_data.EdmMapping.param('data', 'Object', false, true), _dec3 =
_data.EdmMapping.action('remove', 'DiningRequestEvent'), _dec4 =
_data.EdmMapping.param("data", "Object", false, true), _dec5 =
_data.EdmMapping.action('extend', 'DiningRequestEvent'), _dec(_class = (_class2 = class DiningRequestEvent extends _data.DataObject {/**
* @constructor
*/constructor() {super();} /**
* POST DiningRequestEvents/:id/Remove
*/ //remove dining request event
async remove(data) {/**
* @type {import('@themost/data').DataModel}
*/const model = this.getModel();const item = await model.where('id').equal(this.getId()).getItem();const translateService = this.context.application.getStrategy(function TranslateService() {});if (item == null) {throw new _common.DataError('E_DINING_REQUEST_EVENT', translateService.translate('The specified DiningRequestEvent cannot be found or is inaccessible.'));}const hasActions = await this.context.model('DiningRequestAction').where('diningRequestEvent').equal(item.id).count();if (hasActions) {throw new _common.DataError('E_DINING_REQUESTS_EXISTS', translateService.translate('Cannot remove dining request event. Dining request event is related to requests.'), null, 'DiningRequestEvent');}return model.silent().remove(item);} /**
* POST DiningRequestEvents/:id/Extend
*/ /**
* @returns {DiningRequestEvent}
*/ //extend dining request event
async extend(data) {const model = this.getModel();const previous = await model.where('id').equal(this.getId()).getItem();const target = data.event;const translateService = this.context.application.getStrategy(function TranslateService() {});if (previous == null) {throw new _common.DataError('E_DINING_REQUEST_EVENT', translateService.translate('The specified DiningRequestEvent cannot be found or is inaccessible.'));
}
if (previous.eventStatus && previous.eventStatus.alternateName !== 'EventOpened' && target.eventStatus && target.eventStatus.alternateName !== 'EventOpened') {
throw new _common.DataError('E_EVENT_STATUS', translateService.translate('The DiningRequestEvent can only be extended when it is open.'));
}
if (target.validThrough && target.validFrom &&
target.validThrough < target.validFrom) {
throw new _common.DataError('E_DATES', translateService.translate('ValidThrough date cannot be earlier than validFrom date.'));
}
const today = new Date().toISOString();
if (previous.validThrough && previous.validThrough <= today) {
throw new _common.DataError('E_DATES', translateService.translate('The DiningRequestEvent can only be extended if it has not already expired.'));
}
if (previous.eventStatus && previous.eventStatus.alternateName === 'EventOpened') {
const validThroughChange = previous.validThrough && previous.validThrough.toISOString() !== target.validThrough.toISOString();
const endDateChange = previous.endDate && previous.endDate.toISOString() !== target.endDate.toISOString();
if (validThroughChange || endDateChange) {
const actionItem = {
object: previous.id,
currentValidThrough: validThroughChange === true ? previous.validThrough : null,
validThrough: validThroughChange === true ? target.validThrough : null,
currentEndDate: endDateChange === true ? previous.endDate : null,
endDate: endDateChange === true ? target.endDate : null,
status: previous.eventStatus,
description: validThroughChange === true ? endDateChange === true ? translateService.translate('END_DATE_VALID_THROUGH_DATE') : translateService.translate('VALID_THROUGH_DATE') : translateService.translate('END_DATE') };
const action = await this.context.model('UpdateDiningRequestEventAction').save(actionItem);
if (action) {
return await this.context.model('DiningRequestEvent').save(target).then(async res => {
if (res) {
const response = res;
let sseUser;
sseUser = this.context.user || (await this.context.model('User'));
// check if there are active cards to extend
const cards = await this.context.model('StudentDiningCards').
where('student/studentStatus/alternateName').equal('active').
or('student/studentStatus/alternateName').equal('declared').
prepare().
and('active').equal(true).
and('action/diningRequestEvent/id').equal(previous.id).
and('action/actionStatus/alternateName').equal('CompletedActionStatus').
count();
if (validThroughChange === true && cards) {
Promise.all([
action,
this.handleStudentDiningCards(res, action)]).
then(([actionResult]) => {
this.sendSse(sseUser, this.context, actionResult, null);
return;
}).catch(err => {
this.sendSse(sseUser, this.context, action, err);
});
} else {
action.totalCards = action.totalCardsAffected = 0;
action.actionResult = translateService.translate('The process was completed successfully.');
action.actionStatus = { alternateName: 'CompletedActionStatus' };
await this.context.model('UpdateDiningRequestEventAction').save(action);
this.sendSse(sseUser, this.context, action, null);
}
return response;
} else {
//set action status fail
action.actionResult = translateService.translate('Error occured while trying to extend DiningRequestEvent.');
action.actionStatus = { alternateName: 'FailedActionStatus' };
await this.context.model('UpdateDiningRequestEventAction').save(action);
return false;
}
});
}
} else {
return false;
}
}
}
sendSse(user, context, updateEventAction, error) {
// try to find ServerSentEventService
const sse = context.getApplication().getService(function ServerSentEventService() {});
// only if it exists - it is not required
if (sse != null) {
if (user != null && updateEventAction != null) {
// create an event
const event = {
entitySet: "UpdateDiningRequestEventActions",
entityType: "UpdateDiningRequestEventAction",
target: {
id: updateEventAction.id,
object: updateEventAction.object.id || updateEventAction.object,
actionResult: updateEventAction.actionResult },
status: {
success: true },
dateCreated: new Date() };
if (error) {
Object.assign(event, {
status: {
success: false },
error: {
message: error.code || error.message } });
}
// and send it to the user that is performing the approval (dining scope)
sse.emit(user.name, user.authenticationScope || "dining", event);
}
}
}
/**
* @returns Promise<ValidationResult[]>
*/
async handleStudentDiningCards(event, action) {
const translateService = this.context.application.getStrategy(function TranslateService() {});
const model = this.getModel();
const eventNext = await model.where('id').
equal(event.id).
getItem();
if (!eventNext) {
action.actionResult = translateService.translate('The specified DiningRequestEvent cannot be found or is inaccessible.');
action.actionStatus = { alternateName: 'FailedActionStatus' };
await this.context.model('UpdateDiningRequestEventAction').save(action);
throw new _common.DataError('E_DINING_REQUEST_EVENT', translateService.translate('The specified DiningRequestEvent cannot be found or is inaccessible.'));
}
/**
* Try to update valid through date of active student dining cards
* Do not throw errors, but catch the procedure errors
*/
let actionItem = action;
let cardResults = [];
const diningCardsToChange = await this.context.model('StudentDiningCards').
where('student/studentStatus/alternateName').equal('active').
or('student/studentStatus/alternateName').equal('declared').
prepare().
and('active').equal(true).
and('action/diningRequestEvent/id').equal(eventNext.id).
and('action/actionStatus/alternateName').equal('CompletedActionStatus').
expand({
name: 'student',
options: {
$expand: 'studentStatus' } }).
getItems();
// extend all active diningCards
// let index = 0; // debugging purposes
for (const item of diningCardsToChange) {
try {
// update only validThrough date
// property student is required
// check if studentStatus allows card to be updated (active and declared actionStatus)
if (item && item.student && item.student.studentStatus && item.student.studentStatus.alternateName && (
item.student.studentStatus.alternateName === 'active' || item.student.studentStatus.alternateName === 'declared')) {
const itemNext = {
id: item.id,
validThrough: eventNext.validThrough,
student: item.student };
await this.context.model('StudentDiningCards').save(itemNext);
}
} catch (err) {
// if err catch on cardResults
const res = item && item.action && item.action.requestNumber;
cardResults.push(res);
}
// index ++; // debugging purposes
}
// return result
try {
actionItem.totalCards = diningCardsToChange.length;
actionItem.totalCardsAffected = diningCardsToChange.length - cardResults.length;
if (cardResults && cardResults.length === 0) {
//set action status completed
actionItem.actionStatus = { alternateName: 'CompletedActionStatus' };
actionItem.actionResult = translateService.translate('The process was completed successfully.');
} else {
//set action status fail
actionItem.actionStatus = { alternateName: 'FailedActionStatus' };
actionItem.actionResult = translateService.translate('Error occured while trying to update student dining cards') + '<br>' + cardResults.join("<br>");
}
const res = await this.context.model('UpdateDiningRequestEventActions').save(actionItem);
} catch (err) {
let sseUser;
sseUser = this.context.user || (await this.context.model('User'));
this.sendSse(sseUser, this.context, action, null);
throw new _common.DataError('E_UPDATE_ACTION', 'Error occured while trying to update the UpdateDiningRequestEventAction.');
}
}}, (_applyDecoratedDescriptor(_class2.prototype, "remove", [_dec2, _dec3], Object.getOwnPropertyDescriptor(_class2.prototype, "remove"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "extend", [_dec4, _dec5], Object.getOwnPropertyDescriptor(_class2.prototype, "extend"), _class2.prototype)), _class2)) || _class);
module.exports = DiningRequestEvent;
//# sourceMappingURL=DiningRequestEvent.js.map