'use strict'; const db = require('../../models/index'); 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 fetchAllBookings = () => { return new Promise((resolve, reject) => { API.get('/bookings') .then((result) => { const cleanedBookingReservations = []; const bookingData = result && result.data ? result.data : []; bookingData.forEach((fullBookingEntry) => { cleanedBookingReservations.push({ reservationId: fullBookingEntry['_id'], memberId: fullBookingEntry.member, officeId: fullBookingEntry.office, resourceId: fullBookingEntry.resourceId, start: fullBookingEntry.start.dateTime, end: fullBookingEntry.end.dateTime, timezone: fullBookingEntry.timezone, canceled: fullBookingEntry.canceled || false, }); }); resolve(cleanedBookingReservations); }) .catch((error) => { console.log(officeRnDAPIErrors.FAILED_TO_FETCH_BOOKINGS); console.log('Details : ', error); reject(officeRnDAPIErrors.FAILED_TO_FETCH_BOOKINGS); }); }); }; const getAllFinishedBookings = () => { const attributes = ['reservationId', 'memberId', 'resourceId', 'start', 'end', 'timezone']; const filters = { canceled: false, end: { [Op.lt]: moment.utc().toISOString() } }; return db.bookingReservation.findAll({ attributes, where: filters, order: [ ['start', 'ASC'], ] }) }; const getFirstNextBooking = (reservation) => { return new Promise ((resolve, reject) => { const { resourceId, start } = reservation; const attributes = ['reservationId', 'memberId', 'resourceId', 'start', 'end', 'timezone']; const filters = { canceled: false, start: { [Op.gt]: start }, resourceId, }; const order = [['start', 'ASC']]; db.bookingReservation.findAll({ attributes, where: filters, order, }) .then((reservations) => { if (reservations && reservations[0]){ resolve(reservations[0]); }else{ resolve(undefined); } }) .catch((error) => reject(error)); }); }; const getFirstPreviousBooking = (reservation) => { return new Promise ((resolve, reject) => { const { resourceId, start } = reservation; const attributes = ['reservationId', 'memberId', 'resourceId', 'start', 'end', 'timezone']; const filters = { canceled: false, end: { [Op.lte]: start }, resourceId, }; const order = [['end', 'DESC']]; db.bookingReservation.findAll({ attributes, where: filters, order, }) .then((reservations) => { if (reservations && reservations[0]){ resolve(reservations[0]); }else{ resolve(undefined); } }) .catch((error) => reject(error)); }); }; const getFirstReservationInBlock = (reservation) => { return new Promise ((resolve, reject) => { const { resourceId, memberId, start } = reservation; const fromTimestamp = moment.utc(start).subtract(MAX_BACK_TO_BACK_DIFFERENCE).toISOString(); const toTimestamp = start; const filters = { resourceId, memberId, end: { [Op.and]: [ {[Op.gte]: fromTimestamp}, {[Op.lte]: toTimestamp} ] } }; db.bookingReservation.findOne({where: filters}) .then((previousReservation) => { if (!previousReservation) { resolve(reservation); } else { resolve(getFirstReservationInBlock(previousReservation)); } }) .catch((error) => reject(error)); }); }; const writeBookingReservation = (bookingReservation) => { return db.bookingReservation.findOrCreate({where: {...bookingReservation}, defaults: {...bookingReservation}}); }; module.exports = { fetchAllBookings, writeBookingReservation, getAllFinishedBookings, getFirstNextBooking, getFirstPreviousBooking, getFirstReservationInBlock };