Files
old-psihologija/services/integration/reports.js
2019-07-08 18:50:10 +02:00

263 lines
8.8 KiB
JavaScript

'use strict';
const moment = require('moment-timezone');
const db = require('../../models/index');
const Op = require('sequelize').Op;
const { incidentType, UI_TIMEZONE, DEFAULT_DATE_FORMAT, integrationServiceErrors } = require('../../constants/constants');
const { fetchAllMembers } = require('../officeRnD/members');
const { fetchOffices, fetchResources } = require('../officeRnD/resources');
const getUnlockedIncidents = (startDate, endDate, memberId) => {
const attributes = ['id', 'reservationId', 'memberId', 'resourceId', 'bookingStart', 'bookingEnd', 'unlockTimestamp', 'incidentLevel', 'incidentLevelPrice'];
const filters = {};
if (startDate && endDate) {
const bookingStartCondition = {
bookingStart: {
[Op.and]: {
[Op.gte]: startDate.toISOString(),
[Op.lte]: endDate.toISOString(),
}
}
};
const unlockTimestampCondition = {
unlockTimestamp: {
[Op.and]: {
[Op.gte]: startDate.toISOString(),
[Op.lte]: endDate.toISOString(),
}
}
};
const bookingStartOrUnlockTimestamp = {
[Op.or]: [bookingStartCondition, unlockTimestampCondition]
};
Object.assign(filters, bookingStartOrUnlockTimestamp);
}
if (memberId){
filters.memberId = memberId;
}
return db.unlockedIncident.findAll({
attributes,
where: filters,
sort: [
['bookingStart', 'ASC']
]
});
};
const getUnscheduledIncidents = (startDate, endDate, memberId) => {
const attributes = [
'id',
'reservationId',
'memberId',
'resourceId',
'bookingStart',
'bookingEnd',
'unlockTimestamp',
'lockTimestamp',
'timeIntervalsToCharge',
'chargePrice',
'totalChargeFee'
];
const filters = {};
if (startDate && endDate) {
const bookingStartCondition = {
bookingStart: {
[Op.and]: {
[Op.gte]: startDate.toISOString(),
[Op.lte]: endDate.toISOString(),
}
}
};
const unlockTimestampCondition = {
unlockTimestamp: {
[Op.and]: {
[Op.gte]: startDate.toISOString(),
[Op.lte]: endDate.toISOString(),
}
}
};
const bookingStartOrUnlockTimestamp = {
[Op.or]: [bookingStartCondition, unlockTimestampCondition]
};
Object.assign(filters, bookingStartOrUnlockTimestamp);
}
if (memberId){
filters.memberId = memberId;
}
return db.unscheduledIncident.findAll({
attributes,
where: filters,
sort: [
['bookingStart', 'ASC']
]
});
};
const getBookingChangeIncidents = (startDate, endDate, memberId) => {
const attributes = [
'id',
'reservationId',
'memberId',
'resourceId',
'oldBookingStart',
'oldBookingEnd',
'newBookingStart',
'newBookingEnd',
'incidentType',
'chargeFee',
'createdAt'
];
const filters = {};
if (startDate && endDate) {
filters.createdAt = {
[Op.and]: {
[Op.gte]: startDate.toISOString(),
[Op.lte]: endDate.toISOString(),
}
}
}
if (memberId){
filters.memberId = memberId;
}
return db.bookingChangeIncident.findAll({
attributes,
where: filters,
sort: [
['createdAt', 'ASC']
]
});
};
const formatTime = (timestamp) => {
const momentObject = moment.tz(timestamp, UI_TIMEZONE);
if (momentObject.isValid()){
return momentObject.format('MM/DD/YYYY hh:mm a');
}else{
return null;
}
};
const getAllIncidents = (dateRange, memberId) => {
return new Promise ((resolve, reject) => {
let startDate, endDate;
if (dateRange.startDate && dateRange.endDate){
startDate = moment.tz(dateRange.startDate, DEFAULT_DATE_FORMAT, UI_TIMEZONE).startOf('day');
endDate = moment.tz(dateRange.endDate, DEFAULT_DATE_FORMAT, UI_TIMEZONE).endOf('day');
if (!startDate.isValid() || !endDate.isValid() || endDate.isBefore(startDate)){
reject(integrationServiceErrors.INVALID_DATE_RANGE);
return;
}
}
const dataFetchJobs = [
fetchAllMembers(),
fetchOffices(),
fetchResources(),
getUnlockedIncidents(startDate, endDate, memberId),
getUnscheduledIncidents(startDate, endDate, memberId),
getBookingChangeIncidents(startDate, endDate, memberId)
];
Promise.all(dataFetchJobs)
.then((data) => {
const members = data[0];
const offices = data[1];
const resources = data[2];
const unlockedIncidents = data[3];
const unscheduledIncidents = data[4];
const bookingChangeIncidents = data[5];
const membersMap = {};
const officesMap = {};
const resourcesMap = {};
members.forEach((member) => membersMap[member.memberId] = member);
offices.forEach((office) => officesMap[office.officeId] = office);
resources.forEach((resource) => resourcesMap[resource.resourceId] = resource);
const allIncidents = [];
unlockedIncidents.forEach((unlockedIncident) => {
const incidentTypeNumber = unlockedIncident.reservationId ?
incidentType.UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION : incidentType.UNLOCKED_INCIDENT_STANDALONE;
allIncidents.push({
incidentId: unlockedIncident.id,
memberId: unlockedIncident.memberId,
memberName: membersMap[unlockedIncident.memberId].name,
resourceName: resourcesMap[unlockedIncident.resourceId].resourceName,
officeName: officesMap[resourcesMap[unlockedIncident.resourceId].officeId].officeName,
bookingStart: formatTime(unlockedIncident.bookingStart),
bookingEnd: formatTime(unlockedIncident.bookingEnd),
unlockTimestamp: formatTime(unlockedIncident.unlockTimestamp),
incidentType: incidentTypeNumber,
incidentLevel: unlockedIncident.incidentLevel,
incidentPrice: unlockedIncident.incidentLevelPrice,
});
});
unscheduledIncidents.forEach((unscheduledIncident) => {
let incidentTypeNumber;
if (unscheduledIncident.reservationId){
if (unscheduledIncident.unlockTimestamp && !unscheduledIncident.lockTimestamp){
incidentTypeNumber = incidentType.UNSCHEDULED_INCIDENT_BEFORE_RESERVATION;
}else{
incidentTypeNumber = incidentType.UNSCHEDULED_INCIDENT_AFTER_RESERVATION;
}
}else{
incidentTypeNumber = incidentType.UNSCHEDULED_INCIDENT_STANDALONE;
}
allIncidents.push({
incidentId: unscheduledIncident.id,
memberId: unscheduledIncident.memberId,
memberName: membersMap[unscheduledIncident.memberId].name,
resourceName: resourcesMap[unscheduledIncident.resourceId].resourceName,
officeName: officesMap[resourcesMap[unscheduledIncident.resourceId].officeId].officeName,
bookingStart: formatTime(unscheduledIncident.bookingStart),
bookingEnd: formatTime(unscheduledIncident.bookingEnd),
unlockTimestamp: formatTime(unscheduledIncident.unlockTimestamp),
lockTimestamp: formatTime(unscheduledIncident.lockTimestamp),
incidentType: incidentTypeNumber,
timeIntervalsToCharge: unscheduledIncident.timeIntervalsToCharge,
chargePrice: unscheduledIncident.chargePrice,
totalChargeFee: unscheduledIncident.totalChargeFee,
});
});
allIncidents.push(...bookingChangeIncidents);
resolve(allIncidents);
})
.catch((error) => reject(error));
});
};
module.exports = {
getUnlockedIncidents,
getUnscheduledIncidents,
getAllIncidents,
};