'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 incidentTypeExplanation = ''; 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'); bookingTimeExplanation = `${bookingStartMoment.clone().format('HH:mm a')} - ${bookingEndMoment.clone().format('HH:mm a')}`; incidentTimeExplanation = ''; // `UNLOCK : ${unlockMoment.clone().format('HH:mm a')}`; additionalIncidentExplanation = ` ${unlockedIncidentLevelsPrices[incidentLevel].description},`; incidentTypeExplanation = ''; date = bookingStartMoment.clone().startOf('day').format(); price = +incidentPrice.toFixed(2); quantity = 1.00; // priceExplanation = `$${price}, 1 x $${price.toFixed(2)}`; break; case incidentType.UNSCHEDULED_INCIDENT_BEFORE_RESERVATION: roomExplanation = resourceName; dateExplanation = bookingStartMoment.clone().startOf('day').format('MMM DD'); bookingTimeExplanation = `${bookingStartMoment.clone().format('HH:mm a')} - ${bookingEndMoment.clone().format('HH:mm a')}`; incidentTimeExplanation = ` Unlock : ${unlockMoment.clone().format('HH:mm a')},`; incidentTypeExplanation = ''; date = bookingStartMoment.clone().startOf('day').format(); price = +chargePrice.toFixed(2); quantity = +timeIntervalsToCharge.toFixed(2); // 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'); bookingTimeExplanation = `${bookingStartMoment.clone().format('HH:mm a')} - ${bookingEndMoment.clone().format('HH:mm a')}`; incidentTimeExplanation = ` Lock : ${lockMoment.clone().format('HH:mm a')},`; incidentTypeExplanation = ''; date = bookingStartMoment.clone().startOf('day').format(); price = +chargePrice.toFixed(2); quantity = +timeIntervalsToCharge.toFixed(2); // 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'); bookingTimeExplanation = `No reservation`; incidentTimeExplanation = ''; // `UNLOCK : ${unlockMoment.clone().format('HH:mm a')}`; additionalIncidentExplanation = ` ${unlockedIncidentLevelsPrices[incidentLevel].description},`; incidentTypeExplanation = ''; date = unlockMoment.clone().startOf('day').format(); price = +incidentPrice.toFixed(2); quantity = 1.00; // 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'); bookingTimeExplanation = `No reservation`; incidentTimeExplanation = ` Unlock : ${unlockMoment.clone().format('HH:mm a')} Lock : ${lockMoment.clone().format('HH:mm a')},`; incidentTypeExplanation = ''; date = unlockMoment.clone().startOf('day').format(); price = +chargePrice.toFixed(2); quantity = +timeIntervalsToCharge.toFixed(2); // 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')} -> ${newBookingStartMoment.clone().format('MMM DD')}`; 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, HH:mm a')},`; incidentTypeExplanation = '[Cancellation]'; date = incidentTimestampMoment.clone().startOf('day').format(); price = +totalChargeFee.toFixed(2); quantity = 1.00; // 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')}`; 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, HH:mm a')},`; incidentTypeExplanation = '[Cancellation]'; date = incidentTimestampMoment.clone().startOf('day').format(); price = +totalChargeFee.toFixed(2); quantity = 1.00; // priceExplanation = `$${totalChargeFee.toFixed(2)}, 1 x $${price.toFixed(2)}`; break; case incidentType.BOOKING_CANCELED_LATE: roomExplanation = oldResourceName; dateExplanation = `${oldBookingStartMoment.clone().format('MMM DD')}`; bookingTimeExplanation = `${oldBookingStartMoment.clone().format('HH:mm a')} - ${oldBookingEndMoment.clone().format('HH:mm a')}`; incidentTimeExplanation = ` Canceled on : ${incidentTimestampMoment.clone().format('MMM DD, HH:mm a')},`; incidentTypeExplanation = '[Cancellation]'; date = incidentTimestampMoment.clone().startOf('day').format(); price = +totalChargeFee.toFixed(2); quantity = 1.00; // priceExplanation = `$${totalChargeFee.toFixed(2)}, 1 x $${price.toFixed(2)}`; break; } const formattedName = `${incidentTypeExplanation} ${incidentExplanation},${additionalIncidentExplanation}${incidentTimeExplanation} ${officeName}, ${roomExplanation}, ${dateExplanation}, ${bookingTimeExplanation}`; 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 formattedDate = startMoment.clone().startOf('day').format('MMM DD'); const formattedStartTime = startMoment.format('HH:mm a'); const formattedEndTime = endMoment.format('HH:mm a'); const formattedName = `${officeName}, ${resourceName}, ${formattedDate} [${formattedStartTime} - ${formattedEndTime}]`; return { name: formattedName, price: +hourlyRate.toFixed(2), quantity: +reservationLength.toFixed(2), 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, };