'use strict'; const moment = require('moment-timezone'); const db = require('../../models/index'); const Op = require('sequelize').Op; const { doorLockEvents, incidentType, unlockedIncidentLevelsPrices, UNSCHEDULED_CHARGE_PRICE, MAX_BACK_TO_BACK_DIFFERENCE, UNSCHEDULED_USE_INITIAL_TIME_SEGMENT_LENGTH, UNSCHEDULED_TIME_RESOLUTION, UI_TIMEZONE } = require('../../constants/constants'); const { getUnlockEntryForReservation, getLockEntryForReservation, getEntriesBetween, getLastEntryForReservation } = require('../doorLock/doorLock'); const { getAllFinishedBookings, getFirstPreviousBooking, getFirstNextBooking } = require('../officeRnD/bookings'); const getSortedIncidentsForMember = (memberId) => { const attributes = ['bookingStart', 'incidentLevel', 'incidentLevelPrice', 'unlockTimestamp']; const filters = { memberId, deleted: false }; const order = [['unlockTimestamp', 'DESC']]; return db.unlockedIncident.findAll({ attributes, where: filters, order, }) }; const insertUnscheduledIncidents = (incidents) => { const asyncJobs = []; incidents.forEach((incident) => { const { reservation, unlockTimestamp, lockTimestamp, memberId, resourceId, chargePrice, timeIntervalsToCharge, totalChargeFee } = incident; const { reservationId, start, end } = reservation; const incidentForDB = { reservationId, memberId, resourceId, bookingStart: start, bookingEnd: end, doorLockEventTimestamp: null, doorLockEventType: null, chargePrice, timeIntervalsToCharge, totalChargeFee, unlockTimestamp, lockTimestamp, }; asyncJobs.push(db.unscheduledIncident.findOrCreate({ where: { reservationId, memberId, resourceId, bookingStart: start, bookingEnd: end, unlockTimestamp, lockTimestamp, deleted: false }, defaults: {...incidentForDB}, })); }); return Promise.all(asyncJobs); }; const deleteUnscheduledIncidentsById = (incidentIds) => { const filters = { id: { [Op.in]: incidentIds } }; return db.unscheduledIncident.update({deleted: true},{where: filters}); }; const insertUnlockedIncidents = (incidents) => { const asyncJobs = []; incidents.forEach((incident) => { const { reservation, memberId, resourceId, unlockTimestamp, incidentLevel, incidentLevelPrice } = incident; const { reservationId, start, end} = reservation; const incidentForDB = { reservationId, memberId, resourceId, bookingStart: start, bookingEnd: end, unlockTimestamp, incidentLevel, incidentLevelPrice, }; asyncJobs.push(db.unlockedIncident.findOrCreate({ where: { reservationId, memberId, resourceId, bookingStart: start, bookingEnd: end, unlockTimestamp, incidentLevel, deleted: false }, defaults: {...incidentForDB}, })); }); return Promise.all(asyncJobs); }; const deleteUnlockedIncidentsById = (incidentIds) => { const filters = { id: { [Op.in]: incidentIds } }; return db.unlockedIncident.update({deleted: true},{where: filters}); }; const setUnlockedIncidentsLevel = (incidents) => { return new Promise ((resolve, reject) => { const sortingFunction = (incidentA, incidentB) => { const sortCondition = moment.utc(incidentA.unlockTimestamp).isBefore(moment.utc(incidentB.unlockTimestamp)); return sortCondition ? -1 : 1; }; incidents.sort(sortingFunction); const membersLastIncident = {}; incidents.forEach((incident) => { membersLastIncident[incident.memberId] = { incidentLevel: null, incidentTimestamp: null, }; }); const asyncJobs = []; Object.keys(membersLastIncident).forEach((memberId) => { asyncJobs.push(getSortedIncidentsForMember(memberId)); }); Promise.all(asyncJobs) .then((results) => { results.forEach((result) => { const lastIncident = result && result[0] ? result[0] : null; if (lastIncident) { membersLastIncident[lastIncident.memberId] = { incidentLevel: lastIncident.incidentLevel, incidentTimestamp: lastIncident.unlockTimestamp, } } }); const incidentsWithLevel = []; incidents.forEach((incident) => { const memberLastIncident = membersLastIncident[incident.memberId]; const formattedIncident = { reservation: incident.reservation, memberId: incident.memberId, resourceId: incident.resourceId, incidentLevel: undefined, incidentLevelPrice: undefined, unlockTimestamp: incident.unlockTimestamp, }; if (!memberLastIncident.incidentLevel) { formattedIncident.incidentLevel = unlockedIncidentLevelsPrices.UNLOCKED_0.title; formattedIncident.incidentLevelPrice = unlockedIncidentLevelsPrices.UNLOCKED_0.price; } else { const lastIncidentTime = moment.utc(memberLastIncident.incidentTimestamp).startOf('month'); const currentIncidentTime = moment.utc(incident.unlockTimestamp).startOf('month'); const timeDiff = Math.abs(lastIncidentTime.diff(currentIncidentTime, 'months')); if (timeDiff >= (parseInt(process.env.UNLOCK_STREAK_REPAIR_AFTER) || 6)){ formattedIncident.incidentLevel = unlockedIncidentLevelsPrices.UNLOCKED_0.title; formattedIncident.incidentLevelPrice = unlockedIncidentLevelsPrices.UNLOCKED_0.price; } else { const lastIncidentLevelId = unlockedIncidentLevelsPrices[memberLastIncident.incidentLevel].id; const maxId = 5; if ((lastIncidentLevelId && (lastIncidentLevelId >= maxId)) || (timeDiff === 0)){ formattedIncident.incidentLevel = memberLastIncident.incidentLevel; formattedIncident.incidentLevelPrice = unlockedIncidentLevelsPrices[formattedIncident.incidentLevel].price; } else { const nextId = lastIncidentLevelId + 1; Object.keys(unlockedIncidentLevelsPrices).forEach((key) => { if (unlockedIncidentLevelsPrices[key].id === nextId){ formattedIncident.incidentLevel = unlockedIncidentLevelsPrices[key].title; formattedIncident.incidentLevelPrice = unlockedIncidentLevelsPrices[key].price } }); } } } memberLastIncident.incidentLevel = formattedIncident.incidentLevel; memberLastIncident.incidentTimestamp = formattedIncident.unlockTimestamp; incidentsWithLevel.push(formattedIncident); }); resolve(incidentsWithLevel); }) .catch((error) => reject(error)); }); }; const analyseReservation = (reservation) => { return new Promise ((resolve, reject) => { const getNearBookingsAsync = [ getFirstPreviousBooking(reservation), getFirstNextBooking(reservation) ]; Promise.all(getNearBookingsAsync) .then(([previousReservation, nextReservation]) => { const getRelatedDoorLockEntriesAsync = [ getUnlockEntryForReservation(reservation, previousReservation), getLockEntryForReservation(reservation, nextReservation) ]; Promise.all(getRelatedDoorLockEntriesAsync) .then(([unlockEntry, lockEntry, entriesBetween]) => { const currentReservationStart = moment.utc(reservation.start); const currentReservationEnd = moment.utc(reservation.end); let timeDifferenceFromPreviousReservation = MAX_BACK_TO_BACK_DIFFERENCE + 100; if (previousReservation) { const previousReservationEnd = moment.utc(previousReservation.end); timeDifferenceFromPreviousReservation = currentReservationStart.diff(previousReservationEnd, 'minutes'); } const previousReservationIsBackToBack = timeDifferenceFromPreviousReservation < MAX_BACK_TO_BACK_DIFFERENCE; let timeDifferenceBeforeNextReservation = MAX_BACK_TO_BACK_DIFFERENCE + 100; if (nextReservation) { const nextReservationStart = moment.utc(nextReservation.start); timeDifferenceBeforeNextReservation = nextReservationStart.diff(currentReservationEnd, 'minutes'); } const nextReservationIsBackToBack = timeDifferenceBeforeNextReservation < MAX_BACK_TO_BACK_DIFFERENCE; let timeDifferenceFromUnlockEntry = 0; if (unlockEntry) { const unlockTime = moment.utc(unlockEntry.timestamp); timeDifferenceFromUnlockEntry = currentReservationStart.diff(unlockTime, 'minutes'); } let timeIntervalsToChargeBefore = Math.floor(timeDifferenceFromUnlockEntry / UNSCHEDULED_TIME_RESOLUTION); if (timeDifferenceFromUnlockEntry < UNSCHEDULED_USE_INITIAL_TIME_SEGMENT_LENGTH){ timeIntervalsToChargeBefore = 0; } const totalChargeFeeBefore = timeIntervalsToChargeBefore * UNSCHEDULED_CHARGE_PRICE; const chargeBefore = totalChargeFeeBefore > 0; let timeDifferenceFromLockEntry = 0; if (lockEntry) { const lockTime = moment.utc(lockEntry.timestamp); timeDifferenceFromLockEntry = lockTime.diff(currentReservationEnd, 'minutes'); } let timeIntervalsToChargeAfter = Math.floor(timeDifferenceFromLockEntry / UNSCHEDULED_TIME_RESOLUTION); if (timeDifferenceFromLockEntry < UNSCHEDULED_USE_INITIAL_TIME_SEGMENT_LENGTH){ timeIntervalsToChargeAfter = 0; } const totalChargeFeeAfter = timeIntervalsToChargeAfter * UNSCHEDULED_CHARGE_PRICE; const chargeAfter = totalChargeFeeAfter > 0; // const reservationMoment = moment.tz(reservation.start, reservation.timezone); // if (reservation.memberId === '5ce785af422bdd00967fb781' && reservationMoment.isAfter('2019-11-21 00:00:16+00')) { // console.log('\r\n\r\n==== ANALYSE RESERVATION ==== '); // console.log('\tStart : ', reservationMoment.format('DD.MM, HH:mm')); // console.log('\tEnd : ', moment.tz(reservation.end, reservation.timezone).format('DD.MM, HH:mm')); // console.log('\t----------------------------------'); // console.log('\tFirst previous reservation : '); // if (previousReservation) { // console.log('\t\tStart : ', moment.tz(previousReservation.start, previousReservation.timezone).format('DD.MM, HH:mm')); // console.log('\t\tEnd : ', moment.tz(previousReservation.end, previousReservation.timezone).format('DD.MM, HH:mm')); // } else { // console.log('\t\tNO PREVIOUS RESERVATION'); // } // // console.log('\tFirst next reservation : '); // if (nextReservation) { // console.log('\t\tStart : ', moment.tz(nextReservation.start, nextReservation.timezone).format('DD.MM, HH:mm')); // console.log('\t\tEnd : ', moment.tz(nextReservation.end, nextReservation.timezone).format('DD.MM, HH:mm')); // } else { // console.log('\t\tNO NEXT RESERVATION'); // } // console.log('\t----------------------------------'); // if (unlockEntry) { // console.log('\tUnlock entry : ', moment.tz(unlockEntry.timestamp, reservation.timezone).format('DD.MM, HH:mm')); // } else { // console.log('\tUnlock entry : NO UNLOCK ENTRY'); // } // if (lockEntry) { // console.log('\tLock entry : ', moment.tz(lockEntry.timestamp, reservation.timezone).format('DD.MM, HH:mm')); // } else { // console.log('\tLock entry : NO LOCK ENTRY'); // } // // console.log('\t----------------------------------'); // console.log('\tTime before : '); // console.log('\t\tOriginal : ', timeDifferenceFromUnlockEntry); // console.log('\t\tModified : ', timeIntervalsToChargeBefore); // console.log('\tTime after : '); // console.log('\t\tOriginal : ', timeDifferenceFromLockEntry); // console.log('\t\tModified : ', timeIntervalsToChargeAfter); // } const result = { currentReservation: reservation, previousReservation, nextReservation, unlockEntry, lockEntry, previousReservationIsBackToBack, nextReservationIsBackToBack, timeDifferenceFromPreviousReservation, timeDifferenceBeforeNextReservation, timeDifferenceFromUnlockEntry, timeDifferenceFromLockEntry, chargeBefore, chargeAfter, totalChargeFeeBefore, totalChargeFeeAfter, timeIntervalsToChargeBefore, timeIntervalsToChargeAfter, }; resolve(result); }) .catch((error) => reject(error)); }) .catch((error) => reject(error)); }); }; const getIncidentData = (reservation) => { return new Promise ((resolve, reject) => { analyseReservation(reservation) .then((result) => { const { currentReservation, previousReservation, nextReservation, unlockEntry, lockEntry, previousReservationIsBackToBack, nextReservationIsBackToBack, timeDifferenceFromPreviousReservation, timeDifferenceBeforeNextReservation, timeDifferenceFromUnlockEntry, timeDifferenceFromLockEntry, chargeBefore, chargeAfter, totalChargeFeeBefore, totalChargeFeeAfter, timeIntervalsToChargeBefore, timeIntervalsToChargeAfter, } = result; const incidents = []; const { resourceId } = currentReservation; // const reservationMoment = moment.tz(currentReservation.start, currentReservation.timezone); // if (currentReservation.memberId === '5ce785af422bdd00967fb781' && reservationMoment.isAfter('2019-11-23 00:00:16+00')) { // console.log('\r\n\r\n==== ANALYSE RESERVATION [GET INCIDENT DATA] ==== '); // console.log('\tStart : ', reservationMoment.format('DD.MM, HH:mm')); // console.log('\tEnd : ', moment.tz(currentReservation.end, currentReservation.timezone).format('DD.MM, HH:mm')); // console.log('\t----------------------------------'); // console.log('\tFirst previous reservation : is back to back [', previousReservationIsBackToBack ? 'T' : 'F' , ']'); // if (previousReservation) { // console.log('\t\tStart : ', moment.tz(previousReservation.start, previousReservation.timezone).format('DD.MM, HH:mm')); // console.log('\t\tEnd : ', moment.tz(previousReservation.end, previousReservation.timezone).format('DD.MM, HH:mm')); // } else { // console.log('\t\tNO PREVIOUS RESERVATION'); // } // // console.log('\tFirst next reservation : is back to back [', nextReservationIsBackToBack ? 'T' : 'F', ']'); // if (nextReservation) { // console.log('\t\tStart : ', moment.tz(nextReservation.start, nextReservation.timezone).format('DD.MM, HH:mm')); // console.log('\t\tEnd : ', moment.tz(nextReservation.end, nextReservation.timezone).format('DD.MM, HH:mm')); // } else { // console.log('\t\tNO NEXT RESERVATION'); // } // console.log('\t----------------------------------'); // if (unlockEntry) { // console.log('\tUnlock entry : ', moment.tz(unlockEntry.timestamp, reservation.timezone).format('DD.MM, HH:mm')); // } else { // console.log('\tUnlock entry : NO UNLOCK ENTRY'); // } // if (lockEntry) { // console.log('\tLock entry : ', moment.tz(lockEntry.timestamp, reservation.timezone).format('DD.MM, HH:mm')); // } else { // console.log('\tLock entry : NO LOCK ENTRY'); // } // } //********************** // 1. Check if member entered before reservation start time // console.log('\r\n\r\nChecking if member entered before reservation start time :'); // console.log('\tunlockEntry : ', unlockEntry && unlockEntry.timestamp ? unlockEntry.timestamp : 'NO UNLOCK ENTRY'); // console.log('\tCharge before : ', chargeBefore); // console.log('\tThere is prev. res : ', previousReservationIsBackToBack); if (unlockEntry && chargeBefore && !previousReservationIsBackToBack) { // console.log('\tIncident : YES'); incidents.push({ incidentType: incidentType.UNSCHEDULED_INCIDENT_BEFORE_RESERVATION, reservation, unlockTimestamp: unlockEntry.timestamp, lockTimestamp: null, memberId: reservation.memberId, resourceId: reservation.resourceId, chargePrice: UNSCHEDULED_CHARGE_PRICE, timeIntervalsToCharge: timeIntervalsToChargeBefore, totalChargeFee: totalChargeFeeBefore, }); }else{ // console.log('\tIncident : NO'); } // 2. Check if member left after reservation end time // console.log('\r\n\r\nChecking if member left after reservation end time :'); // console.log('\tlockEntry : ', lockEntry && lockEntry.timestamp ? lockEntry.timestamp : 'NO LOCK ENTRY'); // console.log('\tCharge after : ', chargeAfter); // console.log('\tThere is res after : ', nextReservationIsBackToBack); if (lockEntry && chargeAfter && !nextReservationIsBackToBack) { // console.log('\tIncident : YES'); incidents.push({ incidentType: incidentType.UNSCHEDULED_INCIDENT_AFTER_RESERVATION, reservation, unlockTimestamp: null, lockTimestamp: lockEntry.timestamp, memberId: reservation.memberId, resourceId: reservation.resourceId, chargePrice: UNSCHEDULED_CHARGE_PRICE, timeIntervalsToCharge: timeIntervalsToChargeAfter, totalChargeFee: totalChargeFeeAfter, }); }else{ // console.log('\tIncident : NO'); } // 3. Check if member forgot to lock the door // console.log('\r\n\r\nChecking if member left unlocked door :'); // console.log('\tunlockEntry : ', unlockEntry && unlockEntry.timestamp ? unlockEntry.timestamp : 'NO UNLOCK ENTRY'); // console.log('\tlockEntry : ', lockEntry && lockEntry.timestamp ? lockEntry.timestamp : 'NO LOCK ENTRY'); // console.log('\tThere is res before: ', previousReservationIsBackToBack); // console.log('\tThere is res after : ', nextReservationIsBackToBack); let forgotToLockAsyncCheck; if (!lockEntry && !nextReservationIsBackToBack){ const emptyReservation = { reservationId: null, start: null, end: null, }; if (unlockEntry){ // console.log('\tIncident : YES [#1]'); incidents.push({ incidentType: incidentType.UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION, unlockTimestamp: unlockEntry.timestamp, memberId: reservation.memberId, resourceId: unlockEntry.resourceId, reservation: reservation && reservation.dataValues ? reservation.dataValues : emptyReservation, }); } else { // No lock entry, no unlock entry and no reservation after this one // This is either : // 1. Last reservation in block of N reservations // 1a. Member locked before entering this reservation // 1b. Member forgot to lock the door <<< Only this is real incident // 2. One reservation, but member never entered if (previousReservationIsBackToBack){ // To ensure that this is last reservation in block (there is previous but no next reservation back to back) // Now, just check if member actually locked before in the reservation time forgotToLockAsyncCheck = getLastEntryForReservation(reservation); forgotToLockAsyncCheck .then((lastEntry) => { if (lastEntry && lastEntry.event === doorLockEvents.USER_UNLOCKED){ // console.log('\tIncident : YES [#2]'); incidents.push({ incidentType: incidentType.UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION, unlockTimestamp: lastEntry.timestamp, memberId: lastEntry.memberId, resourceId: lastEntry.resourceId, reservation: reservation && reservation.dataValues ? reservation.dataValues : emptyReservation, }); } }) .catch((error) => reject(error)); } } } // 4. Check for unscheduled use between current and previous reservation const analysePreviousJob = []; if (previousReservation && !previousReservationIsBackToBack){ analysePreviousJob.push(analyseReservation(previousReservation)); }else { analysePreviousJob.push(undefined); } Promise.all(analysePreviousJob) .then(([previousReservationResults]) => { let fromTimestamp; let toTimestamp; if (previousReservationResults){ const previousReservationLockEntry = previousReservationResults.lockEntry; fromTimestamp = previousReservationLockEntry && previousReservationLockEntry.timestamp ? previousReservationLockEntry.timestamp : previousReservation.end; toTimestamp = unlockEntry && unlockEntry.timestamp ? unlockEntry.timestamp : reservation.start; }else{ fromTimestamp = undefined; toTimestamp = unlockEntry && unlockEntry.timestamp ? unlockEntry.timestamp : reservation.start; } getEntriesBetween(fromTimestamp, toTimestamp, resourceId) .then((entriesBetween) => { // const reservationMoment = moment.tz(currentReservation.start, currentReservation.timezone); // if (currentReservation.memberId === '5ce785af422bdd00967fb781' && reservationMoment.isAfter('2019-11-23 00:00:16+00')) { // console.log('\r\n\r\n==== ANALYSE RESERVATION [GET INCIDENT DATA] ==== '); // console.log('\tStart : ', reservationMoment.format('DD.MM, HH:mm')); // console.log('\tEnd : ', moment.tz(currentReservation.end, currentReservation.timezone).format('DD.MM, HH:mm')); // console.log('\t----------------------------------'); // console.log('\tFirst previous reservation : is back to back [', previousReservationIsBackToBack ? 'T' : 'F', ']'); // if (previousReservation) { // console.log('\t\tStart : ', moment.tz(previousReservation.start, previousReservation.timezone).format('DD.MM, HH:mm')); // console.log('\t\tEnd : ', moment.tz(previousReservation.end, previousReservation.timezone).format('DD.MM, HH:mm')); // } else { // console.log('\t\tNO PREVIOUS RESERVATION'); // } // // console.log('\tFirst next reservation : is back to back [', nextReservationIsBackToBack ? 'T' : 'F', ']'); // if (nextReservation) { // console.log('\t\tStart : ', moment.tz(nextReservation.start, nextReservation.timezone).format('DD.MM, HH:mm')); // console.log('\t\tEnd : ', moment.tz(nextReservation.end, nextReservation.timezone).format('DD.MM, HH:mm')); // } else { // console.log('\t\tNO NEXT RESERVATION'); // } // // console.log('\t--------------------'); // // console.log('\tFrom timestamp : ', fromTimestamp ? moment.tz(fromTimestamp, UI_TIMEZONE).format('DD.MM, HH:mm') : '-'); // console.log('\tTo timestamp : ', toTimestamp ? moment.tz(toTimestamp, UI_TIMEZONE).format('DD.MM, HH:mm') : '-'); // console.log('\t--------------------'); // } let pairUnlockEntry = null; let pairLockEntry = null; //Inspect all entries and insert detected incidents entriesBetween.forEach((entry) => { // console.log('\tEvent : ', entry.event); // console.log('\tEvent : ', entry.timestamp ? moment.tz(entry.timestamp, UI_TIMEZONE).format('DD.MM, HH:mm') : '-'); if (entry && entry.event){ switch(entry.event){ case doorLockEvents.USER_UNLOCKED: if (!pairUnlockEntry){ pairUnlockEntry = entry; }else{ const emptyReservation = { reservationId: null, start: null, end: null, }; incidents.push({ incidentType: incidentType.UNLOCKED_INCIDENT_STANDALONE, reservation: emptyReservation, unlockTimestamp: pairUnlockEntry.timestamp, memberId: pairUnlockEntry.memberId, resourceId, }); pairLockEntry = null; pairUnlockEntry = entry; } break; case doorLockEvents.USER_LOCKED: if (pairUnlockEntry && !pairLockEntry){ pairLockEntry = entry; const emptyReservation = { reservationId: null, start: null, end: null, }; const unlockMoment = moment.utc(pairUnlockEntry.timestamp); const lockMoment = moment.utc(pairLockEntry.timestamp); if (lockMoment.tz(UI_TIMEZONE).isSame(unlockMoment.tz(UI_TIMEZONE), 'day')){ const timeDifference = lockMoment.diff(unlockMoment, 'minutes'); const timeIntervalsToCharge = Math.floor(timeDifference / UNSCHEDULED_TIME_RESOLUTION); const totalChargeFee = timeIntervalsToCharge * UNSCHEDULED_CHARGE_PRICE; if (timeIntervalsToCharge > 0){ incidents.push({ incidentType: incidentType.UNSCHEDULED_INCIDENT_STANDALONE, reservation: emptyReservation, unlockTimestamp: pairUnlockEntry.timestamp, lockTimestamp: pairLockEntry.timestamp, memberId: pairUnlockEntry.memberId, resourceId, chargePrice: UNSCHEDULED_CHARGE_PRICE, timeIntervalsToCharge, totalChargeFee, }); } }else{ const emptyReservation = { reservationId: null, start: null, end: null, }; incidents.push({ incidentType: incidentType.UNLOCKED_INCIDENT_STANDALONE, reservation: emptyReservation, unlockTimestamp: pairUnlockEntry.timestamp, memberId: pairUnlockEntry.memberId, resourceId, }); } pairUnlockEntry = null; pairLockEntry = null; }else{ if (!pairUnlockEntry){ pairLockEntry = entry; //Only lock entry, ignore now } pairLockEntry = null; pairUnlockEntry = null; } } } }); //Now wait also for "forgotToLockAsyncCheck" to finish Promise.all([forgotToLockAsyncCheck]) .then(() => { resolve(incidents); }) .catch(error => reject(error)); }) .catch((error) => reject(error)) }) .catch(error => reject(error)); // // Promise.all(incidentsAsyncJobs) // .then(() => { // // console.log('\tDone with Async jobs for reservation '); // // console.log('\t\tStart : ', reservationMoment.format('DD.MM, HH:mm')); // // console.log('\t\tEnd : ', moment.tz(currentReservation.end, currentReservation.timezone).format('DD.MM, HH:mm')); // // setTimeout(() => {resolve(incidents)}, 10000); // // resolve(incidents); // }) // .catch((error) => reject(error)); }) .catch((error) => reject(error)); }); }; const calculateDoorLockCharges = () => { return new Promise((resolve, reject) => { getAllFinishedBookings() .then((reservations) => { const unlockedIncidents = []; const unscheduledIncidents = []; const asyncCheckForIncidents = []; reservations.forEach((reservation) => { asyncCheckForIncidents.push(getIncidentData(reservation)); }); Promise.all(asyncCheckForIncidents) .then((allReservationsIncidents) => { allReservationsIncidents.forEach((reservationIncidents) => { reservationIncidents.forEach((incident) => { if (incident.error) { console.log('Error checking incident : ', incident.error); } else if (incident.incidentType) { switch (incident.incidentType) { case incidentType.UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION: case incidentType.UNLOCKED_INCIDENT_STANDALONE: unlockedIncidents.push(incident); break; case incidentType.UNSCHEDULED_INCIDENT_BEFORE_RESERVATION: case incidentType.UNSCHEDULED_INCIDENT_AFTER_RESERVATION: case incidentType.UNSCHEDULED_INCIDENT_STANDALONE: unscheduledIncidents.push(incident); break; } } }); }); setUnlockedIncidentsLevel(unlockedIncidents) .then((completedUnlockedIncidents) => { const insertIncidentsJobs = [insertUnscheduledIncidents(unscheduledIncidents), insertUnlockedIncidents(completedUnlockedIncidents)]; Promise.all(insertIncidentsJobs) .then(() => { resolve(true); }) .catch((error) => { reject(error); }); /* insertUnscheduledIncidents(unscheduledIncidents) .catch((error) => console.log(error)); insertUnlockedIncidents(completedUnlockedIncidents) .catch((error) => console.log(error)); */ }) .catch((error) => reject(error)); }) .catch((error) => reject(error)); }) .catch((error) => reject(error)); }); }; module.exports = { calculateDoorLockCharges, deleteUnlockedIncidentsById, deleteUnscheduledIncidentsById };