From 6df1a798ee720a2614630cf4dd2bb49eb40d4db1 Mon Sep 17 00:00:00 2001 From: Bilal Catic Date: Wed, 4 Dec 2019 12:42:32 +0100 Subject: [PATCH] transform repeated booking to series of regular bookings --- constants/constants.js | 2 + services/officeRnD/bookings.js | 144 ++++++++++++++++++++++----------- 2 files changed, 98 insertions(+), 48 deletions(-) diff --git a/constants/constants.js b/constants/constants.js index 6291394..aaeff9f 100644 --- a/constants/constants.js +++ b/constants/constants.js @@ -57,6 +57,8 @@ const csvParserErrors = { const officeRnDAPIErrors = { FAILED_TO_FETCH_MEMBERS: 'Failed to fetch members', FAILED_TO_FETCH_BOOKINGS: 'Failed to fetch booking reservations', + FAILED_TO_CREATE_BOOKINGS: 'Failed to create booking reservations', + FAILED_TO_DELETE_BOOKINGS: 'Failed to delete booking reservations', FAILED_TO_FETCH_FEES: 'Failed to fetch existing fees from ORD', FAILED_TO_FETCH_PLANS: 'Failed to fetch plans from ORD', FAILED_TO_DELETE_FEES: 'Failed to delete fees in ORD', diff --git a/services/officeRnD/bookings.js b/services/officeRnD/bookings.js index d854e05..35b4fa5 100644 --- a/services/officeRnD/bookings.js +++ b/services/officeRnD/bookings.js @@ -5,7 +5,7 @@ const moment = require('moment-timezone'); const Op = require('sequelize').Op; const { API } = require('../../helpers/api'); -const { officeRnDAPIErrors, MAX_BACK_TO_BACK_DIFFERENCE } = require('../../constants/constants'); +const { officeRnDAPIErrors, MAX_BACK_TO_BACK_DIFFERENCE, UI_TIMEZONE } = require('../../constants/constants'); const fetchAllBookings = () => { return new Promise((resolve, reject) => { @@ -14,71 +14,119 @@ const fetchAllBookings = () => { const cleanedBookingReservations = []; const bookingData = result && result.data ? result.data : []; - bookingData.forEach((fullBookingEntry) => { - const fees = fullBookingEntry && fullBookingEntry.fees ? fullBookingEntry.fees : []; - const startMoment = fullBookingEntry && fullBookingEntry.start && fullBookingEntry.start.dateTime ? - moment.utc(fullBookingEntry.start.dateTime) : null; - const endMoment = fullBookingEntry && fullBookingEntry.end && fullBookingEntry.end.dateTime ? - moment.utc(fullBookingEntry.end.dateTime) : null; + const bookingsToCreate = []; + const bookingIdsToRemove = []; - // console.log('\r\n\r\nStart : ', startMoment.clone().tz(fullBookingEntry.timezone).format('DD.MM. HH:mm'), '[', startMoment.toISOString(),']'); - // console.log('End : ', endMoment.clone().tz(fullBookingEntry.timezone).format('DD.MM. HH:mm'), '[', endMoment.toISOString(), ']'); - // console.log('Fees : '); + bookingData.forEach(fullBookingEntry => { + if (!fullBookingEntry){ + return; + } + const fees = fullBookingEntry.fees ? fullBookingEntry.fees : []; - fees.forEach((feeElement, index) => { - const fee = feeElement.fee ? feeElement.fee : null; - const dateMoment = feeElement.date ? moment.utc(feeElement.date) : null; - const feeId = fee && fee['_id'] ? fee['_id'] : '0'; - const hourlyRate = fee && fee.price ? fee.price : 0; + if (fees.length > 1){ + // Recurring booking, let's create new booking + const member = fullBookingEntry.member ? fullBookingEntry.member : null; + const office = fullBookingEntry.office ? fullBookingEntry.office : null; + const resourceId = fullBookingEntry.resourceId ? fullBookingEntry.resourceId : null; + const team = fullBookingEntry.team ? fullBookingEntry.team : null; + const organization = fullBookingEntry.organization ? fullBookingEntry.organization : null; + const plan = fullBookingEntry.plan ? fullBookingEntry.plan : null; + const timezone = fullBookingEntry.timezone ? fullBookingEntry.timezone : UI_TIMEZONE; + const source = 'admin'; - if (startMoment && endMoment && dateMoment){ - // console.log('\tOriginal date : ', dateMoment.format('DD.MM')); + const startMoment = fullBookingEntry && fullBookingEntry.start && fullBookingEntry.start.dateTime ? + moment.utc(fullBookingEntry.start.dateTime) : null; + const endMoment = fullBookingEntry && fullBookingEntry.end && fullBookingEntry.end.dateTime ? + moment.utc(fullBookingEntry.end.dateTime) : null; - const yearPart = dateMoment.year(); - const monthPart = dateMoment.month(); - const dayPart = dateMoment.date(); + fees.forEach(fee => { + const dateMoment = fee.date ? moment.utc(fee.date) : null; - // console.log('\t\tYear part : ', yearPart); - // console.log('\t\tMonth part: ', monthPart); - // console.log('\t\tDay part : ', dayPart); + if (startMoment && endMoment && dateMoment){ + const yearPart = dateMoment.year(); + const monthPart = dateMoment.month(); + const dayPart = dateMoment.date(); - const newStartMoment = startMoment.clone().tz(fullBookingEntry.timezone).year(yearPart).month(monthPart).date(dayPart); - const newEndMoment = endMoment.clone().tz(fullBookingEntry.timezone).year(yearPart).month(monthPart).date(dayPart); + const newStartMoment = startMoment.clone().tz(fullBookingEntry.timezone).year(yearPart).month(monthPart).date(dayPart); + const newEndMoment = endMoment.clone().tz(fullBookingEntry.timezone).year(yearPart).month(monthPart).date(dayPart); - // console.log('\tNew start : ', newStartMoment.format('DD.MM. HH:mm'), '[', newStartMoment.toISOString(), ']'); - // console.log('\tNew end : ', newEndMoment.format('DD.MM. HH:mm'), '[', newEndMoment.toISOString(), ']'); - // console.log('\t----------------------------'); + bookingsToCreate.push({ + start: { + dateTime: newStartMoment.toISOString() + }, + end: { + dateTime: newEndMoment.toISOString() + }, + team, + member, + resourceId, + office, + source, + timezone, + organization, + plan + }) + } + }); + bookingIdsToRemove.push(fullBookingEntry['_id']); + } + }); + + //Here we now have possible bookings to create and then load again "check Booking changes" + + if (bookingIdsToRemove.length > 0){ + //First delete, wait until operation is done, than create bookings (to avoid conflicting date/time) + API.delete('bookings/?silent', { data: bookingIdsToRemove }) + .then(() => { + //Now, insert new bookings + API.post('bookings/?silent', bookingsToCreate) + .then(() => { + //And fetch again all bookings + resolve(fetchAllBookings()); + }) + .catch((error) => { + console.log(officeRnDAPIErrors.FAILED_TO_CREATE_BOOKINGS); + console.log('Details : ', error); + reject(officeRnDAPIErrors.FAILED_TO_CREATE_BOOKINGS); + }); + }) + .catch(error => { + console.log(officeRnDAPIErrors.FAILED_TO_DELETE_BOOKINGS); + console.log('Details : ', error); + reject(officeRnDAPIErrors.FAILED_TO_DELETE_BOOKINGS); + }); + }else{ + bookingData.forEach((fullBookingEntry) => { + const fees = fullBookingEntry && fullBookingEntry.fees ? fullBookingEntry.fees : []; + const firstFee = fees.length > 0 && fees[0].fee ? fees[0].fee : undefined; + const hourlyRate = firstFee && firstFee.price ? firstFee.price : 0; + + const startMoment = fullBookingEntry && fullBookingEntry.start && fullBookingEntry.start.dateTime ? + moment.utc(fullBookingEntry.start.dateTime) : null; + const endMoment = fullBookingEntry && fullBookingEntry.end && fullBookingEntry.end.dateTime ? + moment.utc(fullBookingEntry.end.dateTime) : null; + + // console.log('\r\n\r\nStart : ', startMoment.clone().tz(fullBookingEntry.timezone).format('DD.MM. HH:mm'), '[', startMoment.toISOString(),']'); + // console.log('End : ', endMoment.clone().tz(fullBookingEntry.timezone).format('DD.MM. HH:mm'), '[', endMoment.toISOString(), ']'); + // console.log('Fees : '); + + if (startMoment && endMoment){ cleanedBookingReservations.push({ - reservationId: `${fullBookingEntry['_id']}-${index}`, + reservationId: fullBookingEntry['_id'], memberId: fullBookingEntry.member, officeId: fullBookingEntry.office, resourceId: fullBookingEntry.resourceId, - start: newStartMoment.toISOString(), - end: newEndMoment.toISOString(), + start: startMoment.toISOString(), + end: endMoment.toISOString(), timezone: fullBookingEntry.timezone, canceled: fullBookingEntry.canceled || false, hourlyRate, }); } }); - - if (fees.length === 0){ - cleanedBookingReservations.push({ - reservationId: `${fullBookingEntry['_id']}-0`, - memberId: fullBookingEntry.member, - officeId: fullBookingEntry.office, - resourceId: fullBookingEntry.resourceId, - start: startMoment.toISOString(), - end: endMoment.toISOString(), - timezone: fullBookingEntry.timezone, - canceled: fullBookingEntry.canceled || false, - hourlyRate: 0, - }); - } - - }); - resolve(cleanedBookingReservations); + resolve(cleanedBookingReservations); + } }) .catch((error) => { console.log(officeRnDAPIErrors.FAILED_TO_FETCH_BOOKINGS);