@universis/dining
Version:
Universis api for dining
170 lines (138 loc) • 6.34 kB
JavaScript
import { DataError } from '@themost/common';
import { DataObjectState } from '@themost/data';
import moment from 'moment';
/**
* @param {DataEventArgs} event
*/
async function beforeSaveAsync(event) {
//
const context = event.model.context;
const service = context.getApplication().getService(function DiningService() {});
let shouldInsert = false;
let currentActionStatus = 'UnknownActionStatus';
// check if dining request event is present on request
if (Object.prototype.hasOwnProperty.call(event.target, 'diningRequestEvent') === false) {
if (event && event.state === DataObjectState.Insert) {
throw new DataError('E_DATA', '', null, 'DiningRequestEvent');
} else {
// when dining request event is not present on dining request action
// load and set dining request event from dining request action
event.target.diningRequestEvent = await context.model('DiningRequestAction')
.where('id')
.equal(event.target.id)
.select('diningRequestEvent')
.silent()
.value();
}
}
// find dining request event and event status type
let diningRequestEvent = await context.model('DiningRequestEvent')
.where('id')
.equal(event.target.diningRequestEvent.id || event.target.diningRequestEvent)
.expand('eventStatus')
.expand('academicYear')
.silent()
.getItem();
if (diningRequestEvent == null) {
throw new DataError('E_EVENT', 'The specified dining request event cannot be found', null, 'DiningRequestEvent');
}
if (event && event.state === DataObjectState.Insert) {
// get action status
if (Object.prototype.hasOwnProperty.call(event.target, 'actionStatus') === false) {
throw new DataError('E_DATA', 'Action status is required while inserting new DiningRequestAction', null, 'DiningRequestAction');
}
currentActionStatus = await context.model('ActionStatusType').find(event.target.actionStatus).select('alternateName');
shouldInsert = (currentActionStatus === 'ActiveActionStatus');
if (validateDiningRequestEvent(diningRequestEvent) === false) {
throw new DataError('E_DATA', 'Dining request event has expired or is not yet available', null, 'DiningRequestEvent');
}
if (diningRequestEvent.eventStatus && diningRequestEvent.eventStatus.alternateName !== 'EventOpened') {
throw new DataError('E_DATA', 'Dining request event is not available', null, 'DiningRequestEvent');
}
// when event state is Insert then isert code as requestNumber
event.target.requestNumber = event.target.code;
} else if (event.state === DataObjectState.Update) {
// get current status
if (Object.prototype.hasOwnProperty.call(event.target, 'actionStatus') === false) {
return;
}
currentActionStatus = await context.model('ActionStatusType').find(event.target.actionStatus).select('alternateName').value();
const action = await context.model('DiningRequestAction').find(event.target.id).select('requestNumber', 'code').getItem();
if ( action.requestNumber !== action.code ) {
// if the current request has already a request number
// remove attribute
delete event.target.requestNumber;
// and exit
return;
} else {
// get dining request event
event.target.diningRequestEvent = await event.model
.where('id')
.equal(event.target.id)
.select('diningRequestEvent')
.value();
// get previous status
const previousActionStatus = (event.previous && event.previous.actionStatus && event.previous.actionStatus.alternateName) || 'UnknownActionStatus';
// if status has been changed and the current status is active
shouldInsert = (previousActionStatus !== currentActionStatus) && (currentActionStatus === 'ActiveActionStatus');
}
}
if (shouldInsert) {
if (validateDiningRequestEvent(diningRequestEvent) === false) {
throw new DataError('E_DATA', 'Dining request event has expired or is not yet available', null, 'DiningRequestEvent');
}
if (diningRequestEvent.eventStatus && diningRequestEvent.eventStatus.alternateName !== 'EventOpened') {
throw new DataError('E_DATA', 'Dining request event is not available', null, 'DiningRequestEvent');
}
// get next number
const nextNumber = await service.nextNumber(context, diningRequestEvent);
// format nextNumber with leading zeros
const formattedNextNumber = await zeroPad(nextNumber, 7);
// and set request number format
event.target.requestNumber = `${diningRequestEvent.academicYear.id}/${diningRequestEvent.id}/${formattedNextNumber}`;
}
}
// eslint-disable-next-line no-unused-vars
async function afterSaveAsync(event) {
//
}
/**
* @param {DataEventArgs} event
* @param {Function} callback
*/
export function beforeSave(event, callback) {
return beforeSaveAsync(event).then(() => {
return callback();
}).catch((err) => {
return callback(err);
});
}
/**
* @param {DataEventArgs} event
* @param {Function} callback
*/
export function afterSave(event, callback) {
return afterSaveAsync(event).then(() => {
return callback();
}).catch((err) => {
return callback(err);
});
}
function validateDiningRequestEvent(diningEvent) {
const now = moment(new Date()).startOf('day').toDate();
let isRequestPeriod = false;
if (diningEvent.startDate instanceof Date) {
if (diningEvent.endDate instanceof Date) {
isRequestPeriod = (now >= diningEvent.startDate) && diningEvent.endDate >= now;
} else {
isRequestPeriod = diningEvent.startDate <= now;
}
} else if (diningEvent.endDate instanceof Date) {
isRequestPeriod = diningEvent.endDate >= now;
}
return isRequestPeriod;
}
async function zeroPad(num, places) {
let zero = places - num.toString().length + 1;
return Array(+(zero > 0 && zero)).join("0") + num;
}