diff --git a/services/integration/bookingChangeCharges.js b/services/integration/bookingChangeCharges.js index 108829d..086d0b0 100644 --- a/services/integration/bookingChangeCharges.js +++ b/services/integration/bookingChangeCharges.js @@ -12,6 +12,32 @@ const { incidentType } = require('../../constants/constants'); +const { getBookingChangeLogsForReservationId } = require('./bookingChangeLog'); + +const getShorteningIncidentsForReservationId = (reservationId) => { + const filter = { + reservationId, + incidentType: incidentType.BOOKING_SHORTENED, + deleted: false, + }; + + return db.bookingChangeIncident.findAll({where: filter}); +}; + +const getReservationIncidentsAndLogs = (reservationId) => { + return new Promise((resolve, reject) => { + const asyncDataFetch = [getShorteningIncidentsForReservationId(reservationId), getBookingChangeLogsForReservationId(reservationId)]; + + Promise.all(asyncDataFetch) + .then((reservationData) => { + resolve({ + incidents: reservationData[0], + changeLogs: reservationData[1], + }); + }) + .catch((error) => reject(error)); + }); +}; const bulkWriteBookingChangeIncidents = (incidents) => { //TODO: Check if this complete method can be replaced with @@ -33,6 +59,8 @@ const getIncidentsFromChanges = (changes) => { return new Promise((resolve, reject) => { if (Array.isArray(changes)){ const incidents = []; + const reservationsForAdditionalCheck = []; + changes.forEach((change) => { const { oldReservation, newReservation } = change; if (oldReservation && newReservation){ @@ -54,45 +82,45 @@ const getIncidentsFromChanges = (changes) => { const differenceFromNow = oldStart.diff(moment.utc(), 'minutes'); - console.log('Change detected : '); - console.log('\tOld reservation :'); - console.log('\t\tResource : ', oldResourceId); - console.log('\t\tStart : ', oldStart.format()); - console.log('\t\tEnd : ', oldEnd.format()); - console.log('\t\tLength : ', oldReservationLength); - console.log('\tNew Reservation :'); - console.log('\t\tResource : ', newReservation.resourceId); - console.log('\t\tStart : ', newStart.format()); - console.log('\t\tEnd : ', newEnd.format()); - console.log('\t\tLength : ', newReservationLength); - console.log('\t\tCanceled : ', canceled); - console.log('\t---------------------------------'); - console.log('\tDifference : ', differenceFromNow, 'minutes'); - console.log(''); - console.log('\tIs booking changed too late ? ', differenceFromNow, ' < ', CHARGE_BOOKING_CHANGE_UNDER_TIME); + // console.log('Change detected : '); + // console.log('\tOld reservation :'); + // console.log('\t\tResource : ', oldResourceId); + // console.log('\t\tStart : ', oldStart.format()); + // console.log('\t\tEnd : ', oldEnd.format()); + // console.log('\t\tLength : ', oldReservationLength); + // console.log('\tNew Reservation :'); + // console.log('\t\tResource : ', newReservation.resourceId); + // console.log('\t\tStart : ', newStart.format()); + // console.log('\t\tEnd : ', newEnd.format()); + // console.log('\t\tLength : ', newReservationLength); + // console.log('\t\tCanceled : ', canceled); + // console.log('\t---------------------------------'); + // console.log('\tDifference : ', differenceFromNow, 'minutes'); + // console.log(''); + // console.log('\tIs booking changed too late ? ', differenceFromNow, ' < ', CHARGE_BOOKING_CHANGE_UNDER_TIME); if (differenceFromNow < CHARGE_BOOKING_CHANGE_UNDER_TIME){ const { reservationId, memberId, resourceId } = newReservation; - console.log('\t\tYes'); + // console.log('\t\tYes'); - console.log('\tIs booking canceled ?'); + // console.log('\tIs booking canceled ?'); if (!canceled) { - console.log('\t\tNo'); + // console.log('\t\tNo'); // Check if new reservation is on same day const sameDay = oldStart.tz(reservationTimezone).isSame(newStart.tz(reservationTimezone), 'day'); - console.log('\tIs new reservation on the same day ?'); + // console.log('\tIs new reservation on the same day ?'); if (sameDay) { - console.log('\t\tYes'); + // console.log('\t\tYes'); // Reservation moved in same day // Check if member shortened the reservation - console.log('\tIs reservation shortened ? ', newReservationLength, ' < ', oldReservationLength); + // console.log('\tIs reservation shortened ? ', newReservationLength, ' < ', oldReservationLength); if (newReservationLength < oldReservationLength) { - console.log('\t\tYes'); + // console.log('\t\tYes'); const differenceInLength = oldReservationLength - newReservationLength; const chargeFee = differenceInLength * reservationHourlyRate * BOOKING_CHANGE_PERCENTAGE_CHARGE / 100; - console.log('\t\t\tThis is [shortened] incident ! Charge fee : ', chargeFee); + // console.log('\t\t\tThis is [shortened] incident ! Charge fee : ', chargeFee); const incident = { reservationId, memberId, @@ -108,14 +136,14 @@ const getIncidentsFromChanges = (changes) => { incidents.push(incident); }else{ - console.log('\t\tNo'); + reservationsForAdditionalCheck.push(reservationId); } } else { console.log('\t\tNo'); // Reservation moved to another day // Add cancellation charge const chargeFee = oldReservationLength * reservationHourlyRate * BOOKING_CHANGE_PERCENTAGE_CHARGE / 100; - console.log('\t\t\tThis is incident ! Charge fee : ', chargeFee); + // console.log('\t\t\tThis is incident ! Charge fee : ', chargeFee); const incident = { reservationId, memberId, @@ -132,15 +160,15 @@ const getIncidentsFromChanges = (changes) => { incidents.push(incident); } }else{ - console.log('\t\tYes'); + // console.log('\t\tYes'); const differenceFromCreation = moment.utc().diff(reservationCreationTimestamp, 'minutes'); - console.log('\tIs booking created in past ', ALLOWED_BOOKING_CANCELLATION_TIME, ' minutes ?', differenceFromCreation, ' > ', ALLOWED_BOOKING_CANCELLATION_TIME); + // console.log('\tIs booking created in past ', ALLOWED_BOOKING_CANCELLATION_TIME, ' minutes ?', differenceFromCreation, ' > ', ALLOWED_BOOKING_CANCELLATION_TIME); if (differenceFromCreation > ALLOWED_BOOKING_CANCELLATION_TIME){ - console.log('\t\tYes'); + // console.log('\t\tYes'); const chargeFee = reservationHourlyRate * oldReservationLength * BOOKING_CHANGE_PERCENTAGE_CHARGE / 100; - console.log('\t\t\tThis is [cancellation] incident ! charge fee : ', chargeFee); + // console.log('\t\t\tThis is [cancellation] incident ! charge fee : ', chargeFee); const incident = { reservationId, memberId, @@ -159,25 +187,69 @@ const getIncidentsFromChanges = (changes) => { } } else{ - console.log('\t\tNo'); + // console.log('\t\tNo'); } } } }); - resolve(incidents); + resolve({incidents, reservationsForAdditionalCheck}); }else{ reject('Input argument is not an array !'); } }); }; +const getReservationsIncidentsForRemoval = (reservations) => { + return new Promise((resolve, reject) => { + const asyncChecks = []; + reservations.forEach((reservationId) => { + asyncChecks.push(getReservationIncidentsAndLogs(reservationId)); + }); + + Promise.all(asyncChecks) + .then((possibleRemovals) => { + const incidentsToRemove = []; + possibleRemovals.forEach((possibleRemoval) => { + const { incidents, changeLogs } = possibleRemoval; + + if (incidents.length > 0){ + const initialReservation = changeLogs && changeLogs[0] ? changeLogs[0] : undefined; + const reservationLastChange = changeLogs && changeLogs[changeLogs.length-1] ? + changeLogs[changeLogs.length-1] : undefined; + + if (initialReservation && reservationLastChange){ + const initialNewStartMoment = moment.utc(initialReservation.newStart); + const initialNewEndMoment = moment.utc(initialReservation.newEnd); + const lastNewStartMoment = moment.utc(reservationLastChange.newStart); + const lastNewEndMoment = moment.utc(reservationLastChange.newEnd); + + if (initialNewStartMoment && initialNewEndMoment && + lastNewStartMoment && lastNewEndMoment){ + + const initialDuration = initialNewEndMoment.diff(initialNewStartMoment, 'hours', true); + const lastDuration = lastNewEndMoment.diff(lastNewStartMoment, 'hours', true); + + if (lastDuration > initialDuration){ + incidentsToRemove.push(...incidents); + } + } + } + } + }); + resolve(incidentsToRemove); + }) + .catch((error) => reject(error)); + }); +}; + const getChargedCanceledReservations = (reservationIds) => { const filters = { reservationId: { [Op.in]: reservationIds, }, incidentType: incidentType.BOOKING_CANCELED_LATE, + deleted: false, }; const attributes = ['memberId', 'oldBookingStart', 'oldBookingEnd', 'chargeFee']; @@ -185,8 +257,21 @@ const getChargedCanceledReservations = (reservationIds) => { return db.bookingChangeIncident.findAll({attributes, where: filters}); }; +const deleteBookingChangeIncidents = (incidents) => { + const asyncActions = []; + incidents.forEach((incident) => { + incident.set('deleted', true); + asyncActions.push(incident.save()); + }); + + return Promise.all(asyncActions); +}; + module.exports = { getChargedCanceledReservations, getIncidentsFromChanges, bulkWriteBookingChangeIncidents, + getShorteningIncidentsForReservationId, + getReservationsIncidentsForRemoval, + deleteBookingChangeIncidents, }; diff --git a/services/integration/bookingChangeLog.js b/services/integration/bookingChangeLog.js index 8ee8da5..be59dc3 100644 --- a/services/integration/bookingChangeLog.js +++ b/services/integration/bookingChangeLog.js @@ -50,6 +50,17 @@ const bulkWriteChanges = (changes) => { // return new Promise((resolve) => resolve()); }; +const getBookingChangeLogsForReservationId = (reservationId) => { + const filter = { + reservationId, + }; + + const order = [['createdAt', 'ASC']]; + + return db.bookingReservationChangeLog.findAll({where: filter, order}); +}; + module.exports = { bulkWriteChanges, + getBookingChangeLogsForReservationId, }; diff --git a/services/integration/checkBookingChange.js b/services/integration/checkBookingChange.js index 599c9df..2bb1031 100644 --- a/services/integration/checkBookingChange.js +++ b/services/integration/checkBookingChange.js @@ -2,7 +2,12 @@ const { fetchAllBookings, bulkWriteReservationsWithChangesTracking } = require('../officeRnD/bookings'); -const { getIncidentsFromChanges, bulkWriteBookingChangeIncidents } = require('./bookingChangeCharges'); +const { + getIncidentsFromChanges, + bulkWriteBookingChangeIncidents, + getReservationsIncidentsForRemoval, + deleteBookingChangeIncidents, +} = require('./bookingChangeCharges'); const { bulkWriteChanges } = require('./bookingChangeLog'); const checkBookingChanges = () => { @@ -14,10 +19,27 @@ const checkBookingChanges = () => { bulkWriteChanges(changes) .then(() => { getIncidentsFromChanges(changes) - .then((incidents) => { + .then(({incidents, reservationsForAdditionalCheck}) => { bulkWriteBookingChangeIncidents(incidents) - .then(() => resolve(true)) - .catch((error) => reject(error)); + .then(() => { + getReservationsIncidentsForRemoval(reservationsForAdditionalCheck) + .then((incidentsToRemove) => { + deleteBookingChangeIncidents(incidentsToRemove) + .then(() => resolve(true)) + .catch((error) => { + console.log('Error deleting incidents : ', error); + reject(error); + }); + }) + .catch((error) => { + console.log('Failed to fetch reservations possible incidents for removal', error); + reject(error); + }); + }) + .catch((error) => { + console.log('error', error); + reject(error); + }); }) .catch((error) => { console.log('Error creating charges ', error);