Merge branch 'fix-undetected-unschedule-use-in-brake-between-bookings' into 'master'
Fix undetected unschedule use in brake between bookings See merge request saburly/psihologija!80
This commit was merged in pull request #80.
This commit is contained in:
@@ -19,7 +19,7 @@ const {
|
||||
|
||||
const { fetchAllMembers } = require('../officeRnD/members');
|
||||
const { getMappingsFromDatabase } = require('../officeRnD/resources');
|
||||
const { getFirstReservationInBlock } = require('../officeRnD/bookings');
|
||||
const { getFirstReservationInBlock, getFirstPreviousBooking } = require('../officeRnD/bookings');
|
||||
|
||||
const extractMappingFromFileName = (fileName) => {
|
||||
const contentBetweenBracketsRegex = /\[(.*?)\]/;
|
||||
@@ -425,11 +425,25 @@ const getLastEntryForReservation = (reservation) => {
|
||||
const order = [['timestamp', 'DESC']];
|
||||
|
||||
db.doorLockEvent.findAll({where: filters, order})
|
||||
.then((entries) => {
|
||||
.then(async(entries) => {
|
||||
if (entries && entries.length > 0){
|
||||
resolve(entries[0]);
|
||||
} else {
|
||||
resolve (undefined);
|
||||
//No entry found in this block of reservations, now check if there is unlock entry for the first reservation in block, before reservation start time
|
||||
|
||||
try {
|
||||
const firstPreviousBookingBeforeFirstInBlock = await getFirstPreviousBooking(firstReservationInBlock);
|
||||
const unlockEntryForFirstInBlock = await getUnlockEntryForReservation(firstReservationInBlock, firstPreviousBookingBeforeFirstInBlock);
|
||||
|
||||
if (unlockEntryForFirstInBlock){
|
||||
resolve(unlockEntryForFirstInBlock);
|
||||
}else{
|
||||
resolve(undefined);
|
||||
}
|
||||
|
||||
}catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((error) => reject(error));
|
||||
|
||||
@@ -15,7 +15,7 @@ const {
|
||||
UI_TIMEZONE
|
||||
} = require('../../constants/constants');
|
||||
const { getUnlockEntryForReservation, getLockEntryForReservation, getEntriesBetween, getLastEntryForReservation } = require('../doorLock/doorLock');
|
||||
const { getAllFinishedBookings, getFirstPreviousBooking, getFirstNextBooking } = require('../officeRnD/bookings');
|
||||
const { getAllFinishedBookings, getFirstPreviousBooking, getFirstNextBooking, getLastReservationInBlock } = require('../officeRnD/bookings');
|
||||
|
||||
const getSortedIncidentsForMember = (memberId) => {
|
||||
const attributes = ['bookingStart', 'incidentLevel', 'incidentLevelPrice', 'unlockTimestamp'];
|
||||
@@ -368,7 +368,7 @@ const getIncidentData = (reservation) => {
|
||||
const { resourceId } = currentReservation;
|
||||
|
||||
// const reservationMoment = moment.tz(currentReservation.start, currentReservation.timezone);
|
||||
// if (currentReservation.memberId === '5ce785af422bdd00967fb781' && reservationMoment.isAfter('2019-11-23 00:00:16+00')) {
|
||||
// if (currentReservation.memberId === '5d240cd34a3efa00882d9526') {
|
||||
// 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'));
|
||||
@@ -474,7 +474,89 @@ const getIncidentData = (reservation) => {
|
||||
// console.log('\tThere is res after : ', nextReservationIsBackToBack);
|
||||
// }
|
||||
let forgotToLockAsyncCheck;
|
||||
let asyncUnscheduledUseTest = [];
|
||||
if (!lockEntry && !nextReservationIsBackToBack){
|
||||
|
||||
// Special check
|
||||
|
||||
const checkForUnscheduledUseInBrakeBetweenReservations = async () => {
|
||||
try {
|
||||
if (nextReservation) {
|
||||
const lastReservationInBlockAfterBrake = await getLastReservationInBlock(nextReservation);
|
||||
|
||||
const fromTimestamp = nextReservation.start;
|
||||
const toTimestamp = lastReservationInBlockAfterBrake.end;
|
||||
|
||||
const entriesInBlock = await getEntriesBetween(fromTimestamp, toTimestamp, reservation.resourceId);
|
||||
|
||||
// const reservationMoment = moment.tz(reservation.start, reservation.timezone);
|
||||
// if (reservation.memberId === '5d240cd34a3efa00882d9526') {
|
||||
// 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(reservation.end, reservation.timezone).format('DD.MM, HH:mm'));
|
||||
// console.log('\t----------------------------------');
|
||||
// console.log('\tLast reservation in block after brake :');
|
||||
// console.log('\t\tStart : ', moment.tz(lastReservationInBlockAfterBrake.start, UI_TIMEZONE).format('DD.MM, HH:mm'));
|
||||
// console.log('\t\tEnd : ', moment.tz(lastReservationInBlockAfterBrake.end, UI_TIMEZONE).format('DD.MM, HH:mm'));
|
||||
// console.log('\tSearch entries : ');
|
||||
// console.log('\t\tFrom :', moment.tz(fromTimestamp, UI_TIMEZONE).format('DD.MM, HH:mm'));
|
||||
// console.log('\t\tTo :', moment.tz(toTimestamp, UI_TIMEZONE).format('DD.MM, HH:mm'));
|
||||
// console.log('\tFirst entry : ');
|
||||
// }
|
||||
|
||||
const addStandaloneUnscheduledIncident = () => {
|
||||
|
||||
const unlockMoment = reservation.end ? moment.utc(reservation.end) : null;
|
||||
const lockMoment = nextReservation.start ? moment.utc(nextReservation.start) : null;
|
||||
|
||||
if (unlockMoment && lockMoment) {
|
||||
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: reservation.end,
|
||||
lockTimestamp: nextReservation.start,
|
||||
memberId: reservation.memberId,
|
||||
resourceId: reservation.resourceId,
|
||||
chargePrice: UNSCHEDULED_CHARGE_PRICE,
|
||||
timeIntervalsToCharge,
|
||||
totalChargeFee,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (Array.isArray(entriesInBlock) && entriesInBlock.length > 0) {
|
||||
const firstEntry = entriesInBlock[0];
|
||||
// console.log('\t\tTimestamp : ', moment.tz(firstEntry.timestamp, UI_TIMEZONE).format('DD.MM, HH:mm'));
|
||||
// console.log('\t\tEvent : ', firstEntry.event);
|
||||
if (firstEntry && firstEntry.event &&
|
||||
firstEntry.memberId === reservation.memberId &&
|
||||
firstEntry.event === doorLockEvents.USER_LOCKED) {
|
||||
|
||||
addStandaloneUnscheduledIncident();
|
||||
}
|
||||
} else {
|
||||
const reservationAfterLastReservationInBlock = await getFirstNextBooking(nextReservation);
|
||||
|
||||
if (reservationAfterLastReservationInBlock) {
|
||||
const lastReservationLockEntry = await getLockEntryForReservation(lastReservationInBlockAfterBrake, reservationAfterLastReservationInBlock);
|
||||
if (lastReservationLockEntry) {
|
||||
addStandaloneUnscheduledIncident();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch (e) {
|
||||
console.log('ERROR while checking for unscheduled use in brake between reservations ');
|
||||
console.log(e);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
if (unlockEntry){
|
||||
// if (currentReservation.memberId === '5ce785af422bdd00967fb781' && reservationMoment.isAfter('2019-12-01 00:00:16+00')) {
|
||||
// console.log('\tIncident : YES [#1]');
|
||||
@@ -486,6 +568,8 @@ const getIncidentData = (reservation) => {
|
||||
resourceId: unlockEntry.resourceId,
|
||||
reservation: reservation && reservation.dataValues ? reservation.dataValues : emptyReservation,
|
||||
});
|
||||
|
||||
asyncUnscheduledUseTest.push(checkForUnscheduledUseInBrakeBetweenReservations());
|
||||
} else {
|
||||
// No lock entry, no unlock entry and no reservation after this one
|
||||
// This is either :
|
||||
@@ -501,17 +585,18 @@ const getIncidentData = (reservation) => {
|
||||
forgotToLockAsyncCheck = getLastEntryForReservation(reservation);
|
||||
forgotToLockAsyncCheck
|
||||
.then((lastEntry) => {
|
||||
if (lastEntry && lastEntry.event === doorLockEvents.USER_UNLOCKED){
|
||||
// if (currentReservation.memberId === '5ce785af422bdd00967fb781' && reservationMoment.isAfter('2019-12-01 00:00:16+00')) {
|
||||
// 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,
|
||||
});
|
||||
if (lastEntry) {
|
||||
if (lastEntry && lastEntry.event === doorLockEvents.USER_UNLOCKED) {
|
||||
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,
|
||||
});
|
||||
|
||||
asyncUnscheduledUseTest.push(checkForUnscheduledUseInBrakeBetweenReservations());
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((error) => reject(error));
|
||||
@@ -539,35 +624,36 @@ const getIncidentData = (reservation) => {
|
||||
const previousReservationUnlockEntry = previousReservationResults.unlockEntry;
|
||||
|
||||
//Special check for bookings with break between
|
||||
if (previousReservation &&
|
||||
!previousReservationIsBackToBack &&
|
||||
previousReservation.memberId === currentReservation.memberId &&
|
||||
previousReservationUnlockEntry && !previousReservationLockEntry &&
|
||||
!unlockEntry && lockEntry //current reservation unlock / lock entries
|
||||
) {
|
||||
|
||||
const unlockMoment = previousReservation.end ? moment.utc(previousReservation.end) : null;
|
||||
const lockMoment = currentReservation.start ? moment.utc(currentReservation.start) : null;
|
||||
|
||||
if (unlockMoment && lockMoment){
|
||||
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: previousReservation.end,
|
||||
lockTimestamp: currentReservation.start,
|
||||
memberId: currentReservation.memberId,
|
||||
resourceId,
|
||||
chargePrice: UNSCHEDULED_CHARGE_PRICE,
|
||||
timeIntervalsToCharge,
|
||||
totalChargeFee,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check this for duplication, previous special check in step 3. can catch this scenario
|
||||
// if (previousReservation &&
|
||||
// !previousReservationIsBackToBack &&
|
||||
// previousReservation.memberId === currentReservation.memberId &&
|
||||
// previousReservationUnlockEntry && !previousReservationLockEntry &&
|
||||
// !unlockEntry && lockEntry //current reservation unlock / lock entries
|
||||
// ) {
|
||||
//
|
||||
// const unlockMoment = previousReservation.end ? moment.utc(previousReservation.end) : null;
|
||||
// const lockMoment = currentReservation.start ? moment.utc(currentReservation.start) : null;
|
||||
//
|
||||
// if (unlockMoment && lockMoment){
|
||||
// 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: previousReservation.end,
|
||||
// lockTimestamp: currentReservation.start,
|
||||
// memberId: currentReservation.memberId,
|
||||
// resourceId,
|
||||
// chargePrice: UNSCHEDULED_CHARGE_PRICE,
|
||||
// timeIntervalsToCharge,
|
||||
// totalChargeFee,
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
fromTimestamp = previousReservationLockEntry && previousReservationLockEntry.timestamp ?
|
||||
previousReservationLockEntry.timestamp : previousReservation.end;
|
||||
@@ -588,7 +674,7 @@ const getIncidentData = (reservation) => {
|
||||
}
|
||||
|
||||
//Now wait for "forgotToLockAsyncCheck", and possible "getEntriesBetween" to finish
|
||||
Promise.all([forgotToLockAsyncCheck, getEntriesAsyncCheck])
|
||||
Promise.all([forgotToLockAsyncCheck, getEntriesAsyncCheck, asyncUnscheduledUseTest])
|
||||
.then((asyncActionResults) => {
|
||||
const entriesBetween = asyncActionResults[1];
|
||||
if (Array.isArray(entriesBetween)){
|
||||
|
||||
@@ -244,6 +244,32 @@ const getFirstReservationInBlock = (reservation) => {
|
||||
});
|
||||
};
|
||||
|
||||
const getLastReservationInBlock = async (reservation) => {
|
||||
const { resourceId, memberId, end } = reservation;
|
||||
|
||||
const toTimestamp = moment.utc(end).add(MAX_BACK_TO_BACK_DIFFERENCE).toISOString();
|
||||
const fromTimestamp = end;
|
||||
|
||||
const filters = {
|
||||
resourceId,
|
||||
memberId,
|
||||
start: {
|
||||
[Op.and]: [
|
||||
{[Op.gte]: fromTimestamp},
|
||||
{[Op.lte]: toTimestamp}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
const nextReservation = await db.bookingReservation.findOne({where: filters});
|
||||
if (!nextReservation) {
|
||||
return reservation;
|
||||
} else {
|
||||
return getLastReservationInBlock(nextReservation);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const writeBookingReservation = (bookingReservation) => {
|
||||
const { reservationId, memberId, officeId, resourceId, start, end, timezone, canceled, hourlyRate } = bookingReservation;
|
||||
const bookingReservationForDB = {
|
||||
@@ -369,5 +395,6 @@ module.exports = {
|
||||
getFirstNextBooking,
|
||||
getFirstPreviousBooking,
|
||||
getFirstReservationInBlock,
|
||||
getLastReservationInBlock,
|
||||
bulkWriteReservationsWithChangesTracking,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user