Files
old-psihologija/services/integration/invoiceIntegration.js
2019-07-25 02:36:38 +02:00

258 lines
11 KiB
JavaScript

'use strict';
const moment = require('moment-timezone');
const { getAllIncidents } = require('./reports');
const { getActiveBookingsForMembersInDateRange } = require('./bookings');
const { DEFAULT_DATE_FORMAT, UI_TIMEZONE, incidentTypeExplanations, incidentType, unlockedIncidentLevelsPrices } = require('../../constants/constants');
const { getResourceMappings } = require('../officeRnD/resources');
const { fetchAllMembers } = require('../officeRnD/members');
const createFeeFromIncident = (incident) => {
const {
memberId,
officeId,
officeName,
resourceName,
oldResourceName,
newResourceName,
bookingStartRaw,
bookingEndRaw,
oldBookingStartRaw,
oldBookingEndRaw,
newBookingStartRaw,
newBookingEndRaw,
unlockTimestampRaw,
lockTimestampRaw,
incidentLevel,
timeIntervalsToCharge,
incidentPrice,
chargePrice,
totalChargeFee,
incidentTimestampRaw
} = incident;
const incidentTypeNumber = incident.incidentType;
const incidentExplanation = incidentTypeExplanations[incidentTypeNumber];
let date = '';
let price = 0;
let quantity = 0;
let priceExplanation = '';
let bookingTimeExplanation = '';
let incidentTimeExplanation = '';
let additionalIncidentExplanation = '';
let roomExplanation = '';
let dateExplanation = '';
const bookingStartMoment = moment.tz(bookingStartRaw, UI_TIMEZONE);
const bookingEndMoment = moment.tz(bookingEndRaw, UI_TIMEZONE);
const unlockMoment = moment.tz(unlockTimestampRaw, UI_TIMEZONE);
const lockMoment = moment.tz(lockTimestampRaw, UI_TIMEZONE);
const oldBookingStartMoment = moment.tz(oldBookingStartRaw, UI_TIMEZONE);
const oldBookingEndMoment = moment.tz(oldBookingEndRaw, UI_TIMEZONE);
const newBookingStartMoment = moment.tz(newBookingStartRaw, UI_TIMEZONE);
const newBookingEndMoment = moment.tz(newBookingEndRaw, UI_TIMEZONE);
const incidentTimestampMoment = moment.tz(incidentTimestampRaw, UI_TIMEZONE);
switch (incidentTypeNumber){
case incidentType.UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION:
roomExplanation = resourceName;
dateExplanation = bookingStartMoment.clone().startOf('day').format('MMM DD, YYYY');
bookingTimeExplanation = `${bookingStartMoment.clone().format('HH:mm a')} - ${bookingEndMoment.clone().format('HH:mm a')}`;
incidentTimeExplanation = `UNLOCK : ${unlockMoment.clone().format('HH:mm a')}`;
unlockedIncidentLevelsPrices[incidentLevel].description
additionalIncidentExplanation = unlockedIncidentLevelsPrices[incidentLevel].description;
date = bookingStartMoment.clone().startOf('day').format();
price = incidentPrice;
quantity = 1;
priceExplanation = `$${price.toFixed(2)}, 1 x $${price.toFixed(2)}`;
break;
case incidentType.UNSCHEDULED_INCIDENT_BEFORE_RESERVATION:
roomExplanation = resourceName;
dateExplanation = bookingStartMoment.clone().startOf('day').format('MMM DD, YYYY');
bookingTimeExplanation = `${bookingStartMoment.clone().format('HH:mm a')} - ${bookingEndMoment.clone().format('HH:mm a')}`;
incidentTimeExplanation = `UNLOCK : ${unlockMoment.clone().format('HH:mm a')}`;
date = bookingStartMoment.clone().startOf('day').format();
price = chargePrice;
quantity = timeIntervalsToCharge;
priceExplanation = `$${totalChargeFee.toFixed(2)}, ${quantity} x $${price.toFixed(2)}`;
break;
case incidentType.UNSCHEDULED_INCIDENT_AFTER_RESERVATION:
roomExplanation = resourceName;
dateExplanation = bookingStartMoment.clone().startOf('day').format('MMM DD, YYYY');
bookingTimeExplanation = `${bookingStartMoment.clone().format('HH:mm a')} - ${bookingEndMoment.clone().format('HH:mm a')}`;
incidentTimeExplanation = `LOCK : ${lockMoment.clone().format('HH:mm a')}`;
date = bookingStartMoment.clone().startOf('day').format();
price = chargePrice;
quantity = timeIntervalsToCharge;
priceExplanation = `$${totalChargeFee.toFixed(2)}, ${quantity} x $${price.toFixed(2)}`;
break;
case incidentType.UNLOCKED_INCIDENT_STANDALONE:
roomExplanation = resourceName;
dateExplanation = unlockMoment.clone().startOf('day').format('MMM DD, YYYY');
bookingTimeExplanation = `NO RESERVATION`;
incidentTimeExplanation = `UNLOCK : ${unlockMoment.clone().format('HH:mm a')}`;
additionalIncidentExplanation = unlockedIncidentLevelsPrices[incidentLevel].description;
date = unlockMoment.clone().startOf('day').format();
price = incidentPrice;
quantity = 1;
priceExplanation = `$${price.toFixed(2)}, 1 x $${price.toFixed(2)}`;
break;
case incidentType.UNSCHEDULED_INCIDENT_STANDALONE:
roomExplanation = resourceName;
dateExplanation = unlockMoment.clone().startOf('day').format('MMM DD, YYYY');
bookingTimeExplanation = `NO RESERVATION`;
incidentTimeExplanation = `UNLOCK : ${unlockMoment.clone().format('HH:mm a')} LOCK : ${lockMoment.clone().format('HH:mm a')}`;
additionalIncidentExplanation = '';
date = unlockMoment.clone().startOf('day').format();
price = chargePrice;
quantity = timeIntervalsToCharge;
priceExplanation = `$${totalChargeFee.toFixed(2)}, ${quantity} x $${price.toFixed(2)}`;
break;
case incidentType.BOOKING_MOVED_TO_ANOTHER_DAY:
if (oldResourceName !== newResourceName){
roomExplanation = `${oldResourceName} -> ${newResourceName}`;
}else{
roomExplanation = oldResourceName;
}
dateExplanation = `${oldBookingStartMoment.clone().format('MMM DD, YYYY')} -> ${newBookingStartMoment.clone().format('MMM DD, YYYY')}`;
bookingTimeExplanation = `(${oldBookingStartMoment.clone().format('HH:mm a')} - ${oldBookingEndMoment.clone().format('HH:mm a')}) -> (${newBookingStartMoment.clone().format('HH:mm a')} - ${newBookingEndMoment.clone().format('HH:mm a')})`;
incidentTimeExplanation = `MOVED ON : ${incidentTimestampMoment.clone().format('MMM DD, YYYY')}`;
date = incidentTimestampMoment.clone().startOf('day').format();
price = totalChargeFee;
quantity = 1;
priceExplanation = `$${totalChargeFee.toFixed(2)}, 1 x $${price.toFixed(2)}`;
break;
case incidentType.BOOKING_SHORTENED:
if (oldResourceName !== newResourceName){
roomExplanation = `${oldResourceName} -> ${newResourceName}`;
}else{
roomExplanation = oldResourceName;
}
dateExplanation = `${oldBookingStartMoment.clone().format('MMM DD, YYYY')}`;
bookingTimeExplanation = `(${oldBookingStartMoment.clone().format('HH:mm a')} - ${oldBookingEndMoment.clone().format('HH:mm a')}) -> (${newBookingStartMoment.clone().format('HH:mm a')} - ${newBookingEndMoment.clone().format('HH:mm a')})`;
incidentTimeExplanation = `SHORTENED ON : ${incidentTimestampMoment.clone().format('MMM DD, YYYY')}`;
date = incidentTimestampMoment.clone().startOf('day').format();
price = totalChargeFee;
quantity = 1;
priceExplanation = `$${totalChargeFee.toFixed(2)}, 1 x $${price.toFixed(2)}`;
break;
case incidentType.BOOKING_CANCELED_LATE:
roomExplanation = oldResourceName;
dateExplanation = `${oldBookingStartMoment.clone().format('MMM DD, YYYY')}`;
bookingTimeExplanation = `${oldBookingStartMoment.clone().format('HH:mm a')} - ${oldBookingEndMoment.clone().format('HH:mm a')}`;
incidentTimeExplanation = `CANCELED ON : ${incidentTimestampMoment.clone().format('MMM DD, YYYY')}`;
date = incidentTimestampMoment.clone().startOf('day').format();
price = totalChargeFee;
quantity = 1;
priceExplanation = `$${totalChargeFee.toFixed(2)}, 1 x $${price.toFixed(2)}`;
break;
}
const formattedName = `[INCIDENT FEES] ${officeName}, ${roomExplanation}, ${dateExplanation}, ${bookingTimeExplanation}, ${incidentTimeExplanation}, ${incidentExplanation}, ${additionalIncidentExplanation} ${additionalIncidentExplanation !== '' ? ',' : ''} ${priceExplanation}`;
return {
name: formattedName,
price,
quantity,
date,
member: memberId,
team: null,
office: officeId,
isPersonal: false,
}
};
const createFeeFromBooking = (booking, resourceMappings) => {
const { officeId, resourceId, memberId, start, end, timezone, hourlyRate } = booking;
const { officesMap, resourcesMap } = resourceMappings;
const startMoment = moment.tz(start, DEFAULT_DATE_FORMAT, timezone);
const endMoment = moment.tz(end, DEFAULT_DATE_FORMAT, timezone);
const reservationLength = endMoment.diff(startMoment, 'hours', true);
const officeName = officesMap[officeId].officeName || 'Unknown';
const resourceName = resourcesMap[resourceId].resourceName || 'Unknown';
const totalCost = (hourlyRate*reservationLength).toFixed(2);
const formattedDate = startMoment.clone().startOf('day').format('MMM DD, YYYY');
const formattedStartTime = startMoment.format('HH:mm a');
const formattedEndTime = endMoment.format('HH:mm a');
const formattedName = `[BOOKING FEES] ${officeName}, ${resourceName}, $${totalCost}, ${reservationLength.toFixed(2)} x $${hourlyRate.toFixed(2)}, ${formattedDate} [${formattedStartTime} - ${formattedEndTime}]`;
return {
name: formattedName,
price: hourlyRate,
quantity: reservationLength,
date: startMoment.startOf('day').toISOString(),
member: memberId,
team: null,
office: officeId,
isPersonal: false,
}
};
const getMembersFeesForDateRange = (dateRange, memberIds) => {
return new Promise((resolve, reject) => {
const collectData = [getAllIncidents(dateRange, memberIds), getActiveBookingsForMembersInDateRange(dateRange, memberIds), getResourceMappings(), fetchAllMembers()];
Promise.all(collectData)
.then((result) => {
const allIncidents = result[0];
const allActiveBookings = result[1];
const resourceMappings = result[2];
const membersList = result[3];
const memberIdTeamMappings = {};
membersList.forEach((member) => {
memberIdTeamMappings[member.memberId] = member.teamId;
});
const allFees = [];
allIncidents.forEach((incident) => allFees.push(createFeeFromIncident(incident)));
allActiveBookings.forEach((booking) => allFees.push(createFeeFromBooking(booking, resourceMappings)));
allFees.forEach((fee) => {
fee.team = memberIdTeamMappings[fee.member] || null;
});
resolve(allFees);
})
.catch((error) => {
console.log(error);
reject(error);
});
});
};
module.exports = {
getMembersFeesForDateRange,
};