'use strict'; const moment = require('moment-timezone'); const db = require('../../models/index'); const { UI_TIMEZONE, BOOKING_CHANGE_PERCENTAGE_CHARGE, incidentType } = require('../../constants/constants'); const bulkWriteBookingChangeIncidents = (incidents) => { return new Promise((resolve, reject) => { const asyncJobs = []; incidents.forEach((incident) => { asyncJobs.push(db.bookingChangeIncident.findOrCreate({where: incident, defaults: incident})); }); Promise.all(asyncJobs) .then(() => { resolve(); }) .catch((error) => reject(error)); }); }; const chargeBookingChanges = (changes) => { return new Promise((resolve, reject) => { if (Array.isArray(changes)){ const incidents = []; const errors = []; changes.forEach((change) => { const { oldReservation, newReservation } = change; if (oldReservation && newReservation){ const oldStart = oldReservation.start ? moment.utc(oldReservation.start) : null; const oldEnd = oldReservation.end ? moment.utc(oldReservation.end) : null; const newStart = newReservation.start ? moment.utc(newReservation.start) : null; const newEnd = newReservation.end ? moment.utc(newReservation.end) : null; const reservationTimezone = newReservation.timezone ? newReservation.timezone : UI_TIMEZONE; const reservationHourlyRate = newReservation.hourlyRate ? newReservation.hourlyRate : undefined; if (oldStart && oldEnd && newStart && newEnd && reservationHourlyRate){ const oldReservationLength = oldEnd.diff(oldStart, 'hours', true); const newReservationLength = newEnd.diff(newStart, 'hours', true); const differenceFromNow = oldStart.diff(moment.utc(), 'hours'); if (differenceFromNow && (differenceFromNow < 24)){ // Changed reservation that was within 24hrs from now // Check if new reservation is on same day const sameDay = oldStart.tz(reservationTimezone).isSame(newStart.tz(reservationTimezone), 'day'); const { reservationId, memberId, resourceId, hourlyRate } = newReservation; if (sameDay){ // Reservation moved in same day // Check if member shortened the reservation if (newReservationLength < oldReservationLength){ const differenceInLength = oldReservationLength - newReservationLength; const chargeFee = differenceInLength*hourlyRate*BOOKING_CHANGE_PERCENTAGE_CHARGE/100; const incident = { reservationId, memberId, resourceId, oldBookingStart: oldReservation.start, oldBookingEnd: oldReservation.end, newBookingStart: newReservation.start, newBookingEnd: newReservation.end, incidentType: incidentType.BOOKING_SHORTENED, chargeFee, }; incidents.push(incident); } }else{ // Reservation moved to another day // Add cancellation charge const chargeFee = oldReservationLength*hourlyRate*BOOKING_CHANGE_PERCENTAGE_CHARGE/100; const incident = { reservationId, memberId, resourceId, oldBookingStart: oldReservation.start, oldBookingEnd: oldReservation.end, newBookingStart: newReservation.start, newBookingEnd: newReservation.end, incidentType: incidentType.BOOKING_MOVED_TO_ANOTHER_DAY, chargeFee, }; incidents.push(incident); } } }else{ errors.push(change); } } }); if (errors.length > 0){ console.log('There were some errors with incomplete bookings : '); console.log(errors); } resolve(bulkWriteBookingChangeIncidents(incidents)); }else{ reject('Input argument is not an array !'); } }); }; module.exports = { chargeBookingChanges, };