Fix problems with door unlock charges

This commit is contained in:
Senad Uka
2019-07-01 09:31:13 +02:00
parent ffc8412d7c
commit 1d9d5ac684
5 changed files with 419 additions and 185 deletions

View File

@@ -69,6 +69,10 @@ const UI_TIMEZONE = process.env.UI_TIMEZONE || 'America/Los_Angeles';
const DEFAULT_DATE_FORMAT = 'YYYY-MM-DD'; const DEFAULT_DATE_FORMAT = 'YYYY-MM-DD';
const MAX_BACK_TO_BACK_DIFFERENCE = parseInt(process.env.MAX_BACK_TO_BACK_DIFFERENCE) || 0;
const UNSCHEDULED_TIME_RESOLUTION = parseInt(process.env.UNSCHEDULED_USE_TIME_RESOLUTION) || 5;
const UNSCHEDULED_CHARGE_PRICE = parseFloat(process.env.UNSCHEDULED_USE_CHARGE_PRICE) || 5;
module.exports = { module.exports = {
VALID_CSV_HEADERS, VALID_CSV_HEADERS,
USER_ENTRY_EVENT, USER_ENTRY_EVENT,
@@ -82,4 +86,7 @@ module.exports = {
incidentType, incidentType,
UI_TIMEZONE, UI_TIMEZONE,
DEFAULT_DATE_FORMAT, DEFAULT_DATE_FORMAT,
MAX_BACK_TO_BACK_DIFFERENCE,
UNSCHEDULED_TIME_RESOLUTION,
UNSCHEDULED_CHARGE_PRICE,
}; };

View File

@@ -8,7 +8,7 @@ EARLIEST_UNLOCK=Time in minutes
UI_TIMEZONE=Timezone for user interface | https://en.wikipedia.org/wiki/List_of_tz_database_time_zones | example : America/Los_Angeles UI_TIMEZONE=Timezone for user interface | https://en.wikipedia.org/wiki/List_of_tz_database_time_zones | example : America/Los_Angeles
UNSCHEDULED_USE_TIME_RESOLUTION=Time in minutes UNSCHEDULED_USE_TIME_RESOLUTION=Time in minutes
UNSCHEDULED_USE_CHARGE_FEE=Charge fee UNSCHEDULED_USE_CHARGE_PRICE=Charge price
UNLOCK_0=Price for unlocked door, first month UNLOCK_0=Price for unlocked door, first month
UNLOCK_1=Price for unlocked door, second month UNLOCK_1=Price for unlocked door, second month

View File

@@ -183,57 +183,186 @@ const writeDoorLockEvent = (entry) => {
return db.doorLockEvent.findOrCreate({where: {...entry}, defaults: {...entry}}); return db.doorLockEvent.findOrCreate({where: {...entry}, defaults: {...entry}});
}; };
const getUnlockEntryForReservation = (reservation) => { const getUnlockEntryForReservation = (reservation, previousReservation) => {
const { start, end, memberId, resourceId } = reservation; return new Promise((resolve, reject) => {
const { memberId, resourceId } = reservation;
const attributes = ['memberName', 'event', 'timestamp']; const attributes = ['memberName', 'event', 'timestamp', 'resourceId'];
const earliestUnlock = parseInt(process.env.EARLIEST_UNLOCK) || 0;
const fromTimestamp = moment(start).subtract(earliestUnlock).toISOString();
const toTimestamp = end;
const filters = { const fromTimestamp = previousReservation && previousReservation.end ?
memberId, previousReservation.end : moment.utc(reservation.start).tz(UI_TIMEZONE).startOf('Day').toISOString();
timestamp: { const toTimestamp = reservation.end;
[Op.and]: [
{[Op.gt]: fromTimestamp},
{[Op.lte]: toTimestamp}
]
},
event: doorLockEvents.USER_UNLOCKED,
resourceId,
};
return db.doorLockEvent.findOne({ const filters = {
attributes, memberId,
where: filters, timestamp: {
}) [Op.and]: [
{[Op.gt]: fromTimestamp},
{[Op.lte]: toTimestamp}
]
},
resourceId,
};
const order = [['timestamp', 'DESC']];
db.doorLockEvent.findAll({
attributes,
where: filters,
order,
})
.then((entries) => {
let candidateUnlockEntry = null;
let pairedLockEntry = null;
let eventFound = false;
// console.log('\r\n=?== SEARCH UNLOCK ==');
// console.log('ReservatioN : ', reservation.start);
const entriesBeforeReservationStart = entries.filter((entry) => moment.utc(entry.timestamp).isBefore(reservation.start));
// console.log('After end : ');
/*console.log(entriesBeforeReservationStart.map(e => {
return {
timestamp: e.timestamp,
event: e.event,
}
}));
*/
entriesBeforeReservationStart.forEach((entry) => {
if (!eventFound) {
if (entry.event === doorLockEvents.USER_UNLOCKED) {
if (pairedLockEntry) {
pairedLockEntry = null;
candidateUnlockEntry = null;
} else {
candidateUnlockEntry = entry;
eventFound = true;
}
}
if (entry.event === doorLockEvents.USER_LOCKED){
pairedLockEntry = entry;
}
}
});
if (eventFound){
// console.log('FOUND : ', candidateUnlockEntry.timestamp, candidateUnlockEntry.event);
resolve(candidateUnlockEntry);
} else {
// console.log('NOT FOUND IN FIRST ROUND');
candidateUnlockEntry = null;
const numberOfEntriesLeft = entries.length - entriesBeforeReservationStart.length;
const entriesAfterReservationStart = entries.slice(0, numberOfEntriesLeft);
// console.log('Entries in reservation time : ');
/*console.log(entriesAfterReservationStart.map(e => {
return {
timestamp: e.timestamp,
event: e.event,
}
}));
*/
entriesAfterReservationStart.forEach((entry) => {
if (!eventFound) {
if (entry.event === doorLockEvents.USER_UNLOCKED) {
//console.log('FOUND : ', entry.timestamp, entry.event);
eventFound = true;
candidateUnlockEntry = entry;
}
}
});
//console.log('===??==');
resolve(candidateUnlockEntry);
}
})
.catch((error) => reject(error));
});
}; };
const getRelatedDoorLockEntries = (fromTimestamp, toTimestamp, memberId, resourceId) => { const getLockEntryForReservation = (reservation, nextReservation) => {
const attributes = ['memberName', 'event', 'timestamp']; return new Promise((resolve, reject) => {
const { memberId, resourceId } = reservation;
const filters = { const attributes = ['memberName', 'event', 'timestamp'];
memberId,
timestamp: { const fromTimestamp = reservation.start;
[Op.and]: [ const toTimestamp = nextReservation && nextReservation.start ?
{[Op.gt]: fromTimestamp}, nextReservation.start : moment.utc(reservation.start).tz(UI_TIMEZONE).endOf('Day').toISOString();
{[Op.lte]: toTimestamp}
const filters = {
memberId,
timestamp: {
[Op.and]: [
{[Op.gt]: fromTimestamp},
{[Op.lte]: toTimestamp}
] ]
}, },
event: doorLockEvents.USER_LOCKED, resourceId,
resourceId, };
};
return db.doorLockEvent.findOne({ const order = [['timestamp', 'ASC']];
attributes,
where: filters db.doorLockEvent.findAll({
}) attributes,
where: filters,
order,
})
.then((entries) => {
let candidateLockEntry = null;
let pairedUnlockEntry = null;
let eventFound = false;
const entriesAfterReservationEnd = entries.filter((entry) => moment.utc(entry.timestamp).isAfter(reservation.end));
entriesAfterReservationEnd.forEach((entry) => {
if (!eventFound) {
if (entry.event === doorLockEvents.USER_LOCKED) {
if (pairedUnlockEntry) {
pairedUnlockEntry = null;
candidateLockEntry = null;
} else {
candidateLockEntry = entry;
eventFound = true;
}
}
if (entry.event === doorLockEvents.USER_UNLOCKED){
pairedUnlockEntry = entry;
}
}
});
if (eventFound){
resolve(candidateLockEntry);
} else {
candidateLockEntry = null;
const numberOfEntriesLeft = entries.length - entriesAfterReservationEnd.length;
const entriesBeforeReservationEnd = entries.slice(0, numberOfEntriesLeft);
entriesBeforeReservationEnd.reverse().forEach((entry) => {
if (!eventFound) {
if (entry.event === doorLockEvents.USER_LOCKED) {
eventFound = true;
candidateLockEntry = entry;
}
}
});
resolve(candidateLockEntry);
}
})
.catch((error) => reject(error));
});
}; };
module.exports = { module.exports = {
parseDoorLockDataFile, parseDoorLockDataFile,
writeDoorLockEvent, writeDoorLockEvent,
getRelatedDoorLockEntries,
getUnlockEntryForReservation, getUnlockEntryForReservation,
getLockEntryForReservation,
}; };

View File

@@ -3,9 +3,9 @@
const moment = require('moment-timezone'); const moment = require('moment-timezone');
const db = require('../../models/index'); const db = require('../../models/index');
const { incidentType, unlockedIncidentLevelsPrices } = require('../../constants/constants'); const { incidentType, unlockedIncidentLevelsPrices, UNSCHEDULED_CHARGE_PRICE, MAX_BACK_TO_BACK_DIFFERENCE, UNSCHEDULED_TIME_RESOLUTION } = require('../../constants/constants');
const { getUnlockEntryForReservation, getRelatedDoorLockEntries } = require('../doorLock/doorLock'); const { getUnlockEntryForReservation, getLockEntryForReservation } = require('../doorLock/doorLock');
const { getFirstPreviousBooking, getFirstNextBooking, getAllFinishedBookings } = require('../officeRnD/bookings'); const { getAllFinishedBookings, getFirstReservationInBlock, getFirstPreviousBooking, getFirstNextBooking } = require('../officeRnD/bookings');
const getSortedIncidentsForMember = (memberId) => { const getSortedIncidentsForMember = (memberId) => {
const attributes = ['bookingStart', 'incidentLevel', 'incidentLevelPrice']; const attributes = ['bookingStart', 'incidentLevel', 'incidentLevelPrice'];
@@ -169,125 +169,199 @@ const setUnlockedIncidentsLevel = (incidentReservations) => {
}); });
}; };
const getUnlockEntryForBlockReservations = (lastReservation, firstReservation) => {
return new Promise ((resolve, reject) => {
analyseReservation(firstReservation)
.then((result) => {
const reservationBeforeFirstReservationInBlock = result.previousReservation;
const unlockEntryForFirstReservation = result.unlockEntry;
if (unlockEntryForFirstReservation){
resolve(unlockEntryForFirstReservation);
}else{
const fromTimestamp = reservationBeforeFirstReservationInBlock ?
reservationBeforeFirstReservationInBlock.end :
moment.utc(firstReservation.start).tz(UI_TIMEZONE).startOf('Day').toISOString();
const toTimestamp = lastReservation.end;
const { memberId, reservationId } = lastReservation;
const filters = {
memberId,
reservationId,
event: doorLockEvents.USER_UNLOCKED,
timestamp: {
[Op.and]: [
{[Op.gt]: fromTimestamp},
{[Op.lte]: toTimestamp}
]
},
};
db.doorLockEvent.findOne({where: filters})
.then((anyUnlockEntryInBlock) => {
resolve(anyUnlockEntryInBlock);
})
.catch((error) => reject(error));
}
})
.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]) => {
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');
}
const timeIntervalsToChargeBefore = Math.floor(timeDifferenceFromUnlockEntry / UNSCHEDULED_TIME_RESOLUTION);
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');
}
const timeIntervalsToChargeAfter = Math.floor(timeDifferenceFromLockEntry / UNSCHEDULED_TIME_RESOLUTION);
const totalChargeFeeAfter = timeIntervalsToChargeAfter * UNSCHEDULED_CHARGE_PRICE;
const chargeAfter = totalChargeFeeAfter > 0;
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 checkIfMemberEverEntered = (reservation) => {
return new Promise ((resolve, reject) => {
getFirstReservationInBlock(reservation)
.then((firstReservationInBlock) => {
getUnlockEntryForBlockReservations(reservation, firstReservationInBlock)
.then((unlockEntry) => {
resolve(!!unlockEntry);
})
.catch((error) => reject(error));
})
.catch((error) => reject(error));
});
};
const getIncidentData = (reservation) => { const getIncidentData = (reservation) => {
return new Promise ((resolve, reject) => { return new Promise ((resolve, reject) => {
getFirstNextBooking(reservation) analyseReservation(reservation)
.then(nextReservation => { .then((result) => {
const endOfTheDay = moment.tz(reservation.end, reservation.timezone).endOf('Day').toISOString(); const {
let doorLockEntriesEndTime = nextReservation ? nextReservation.start : endOfTheDay; currentReservation,
previousReservation,
nextReservation,
unlockEntry,
lockEntry,
previousReservationIsBackToBack,
nextReservationIsBackToBack,
timeDifferenceFromPreviousReservation,
timeDifferenceBeforeNextReservation,
timeDifferenceFromUnlockEntry,
timeDifferenceFromLockEntry,
chargeBefore,
chargeAfter,
totalChargeFeeBefore,
totalChargeFeeAfter,
timeIntervalsToChargeBefore,
timeIntervalsToChargeAfter,
} = result;
const incidents = [];
if (nextReservation){ // 1. Check if member entered before reservation start time
// Check if next reservations is immediately after (back to back reservation) if (unlockEntry && chargeBefore && !previousReservationIsBackToBack) {
// If yes, then there is no need to check door lock entries related to this booking incidents.push({
const firstReservationEnd = moment.utc(reservation.end); incidentType: incidentType.UNSCHEDULED_INCIDENT,
const secondReservationStart = moment.utc(nextReservation.start); reservation,
const timeDifference = Math.abs(secondReservationStart.diff(firstReservationEnd, 'minutes')); doorLockEntry: unlockEntry,
chargePrice: UNSCHEDULED_CHARGE_PRICE,
const maxBackToBackDifference = parseInt(process.env.MAX_BACK_TO_BACK_DIFFERENCE) || 0; timeIntervalsToCharge: timeIntervalsToChargeBefore,
if (timeDifference <= maxBackToBackDifference){ totalChargeFee: totalChargeFeeBefore,
// It is back to back reservation, no need to check door lock entries
resolve({
incidentType: incidentType.NOT_AN_INCIDENT,
});
return;
}
}
// Find door lock entries related to this member, between booking start time and
// next booking start time OR end of the day
getRelatedDoorLockEntries(reservation.start, doorLockEntriesEndTime, reservation.memberId, reservation.resourceId)
.then((lockEntry) => {
if (lockEntry){
const timeResolution = parseInt(process.env.UNSCHEDULED_USE_TIME_RESOLUTION) || 5
const chargePrice = parseFloat(process.env.UNSCHEDULED_USE_CHARGE_FEE) || 5;
const reservationEndTime = moment.utc(reservation.end);
const lockedTime = moment.utc(lockEntry.timestamp);
const timeDifference = Math.abs(reservationEndTime.diff(lockedTime, 'minutes'));
const timeIntervalsToCharge = Math.floor(timeDifference / timeResolution);
const totalChargeFee = timeIntervalsToCharge * chargePrice;
if (timeIntervalsToCharge > 0){
resolve({
incidentType: incidentType.UNSCHEDULED_INCIDENT,
reservation,
lockEntry,
chargePrice,
timeIntervalsToCharge,
totalChargeFee,
})
} else {
resolve({
incidentType: incidentType.NOT_AN_INCIDENT,
});
}
} else {
// Check if there is unlock entry for this reservation
getUnlockEntryForReservation(reservation)
.then((unlockEntry) => {
if (unlockEntry){
// This is unlocked incident
resolve({
incidentType: incidentType.UNLOCKED_INCIDENT,
reservation,
});
}else{
// Check if there is back-to-back booking before current one
getFirstPreviousBooking(reservation)
.then((previousReservation) => {
if (previousReservation){
const previousReservationEnd = moment.utc(previousReservation.end);
const currentReservationStart = moment.utc(reservation.start);
const timeDifference = Math.abs(currentReservationStart.diff(previousReservationEnd, 'minutes'));
const maxBackToBackDifference = parseInt(process.env.MAX_BACK_TO_BACK_DIFFERENCE) || 0;
if (timeDifference <= maxBackToBackDifference) {
resolve({
incidentType: incidentType.UNLOCKED_INCIDENT,
reservation,
});
}else{
resolve({
incidentType: incidentType.NOT_AN_INCIDENT,
});
}
}else{
resolve({
incidentType: incidentType.NOT_AN_INCIDENT,
});
}
})
.catch((error) => {
console.log('Error finding first previous reservation', error);
resolve({
error,
});
});
}
})
.catch((error) => {
console.log('Error finding unlock entry', error);
resolve({
error
});
});
}
})
.catch((error) => {
console.log('Error finding related door lock entry', error);
resolve({
error,
});
}); });
}
// 2. Check if member left after reservation end time
if (lockEntry && chargeAfter && !nextReservationIsBackToBack) {
incidents.push({
incidentType: incidentType.UNSCHEDULED_INCIDENT,
reservation,
doorLockEntry: lockEntry,
chargePrice: UNSCHEDULED_CHARGE_PRICE,
timeIntervalsToCharge: timeIntervalsToChargeAfter,
totalChargeFee: totalChargeFeeAfter,
});
}
// 3. Check if member forgot to lock door
if (unlockEntry && !lockEntry && !nextReservationIsBackToBack){
incidents.push({
incidentType: incidentType.UNLOCKED_INCIDENT,
reservation,
});
}
resolve(incidents);
}) })
.catch((error) => { .catch((error) => reject(error));
console.log('Error finding first next booking', error);
resolve({
error,
});
});
}); });
}; };
@@ -304,28 +378,29 @@ const calculateDoorLockCharges = () => {
}); });
Promise.all(asyncCheckForIncidents) Promise.all(asyncCheckForIncidents)
.then((results) => { .then((allReservationsIncidents) => {
results.forEach((result) => { allReservationsIncidents.forEach((reservationIncidents) => {
if (result.error){ reservationIncidents.forEach((incident) => {
console.log('Error checking incident : ', result.error); if (incident.error) {
}else if(result.incidentType) { console.log('Error checking incident : ', incident.error);
switch (result.incidentType) { } else if (incident.incidentType) {
case incidentType.UNLOCKED_INCIDENT: switch (incident.incidentType) {
unlockedIncidents.push(result.reservation); case incidentType.UNLOCKED_INCIDENT:
break; unlockedIncidents.push(incident.reservation);
case incidentType.UNSCHEDULED_INCIDENT: break;
const { reservation, lockEntry, chargePrice, timeIntervalsToCharge, totalChargeFee } = result; case incidentType.UNSCHEDULED_INCIDENT:
unscheduledIncidents.push({ const {reservation, doorLockEntry, chargePrice, timeIntervalsToCharge, totalChargeFee} = incident;
reservation, unscheduledIncidents.push({
lockEntry, reservation,
chargePrice, lockEntry: doorLockEntry,
timeIntervalsToCharge, chargePrice,
totalChargeFee, timeIntervalsToCharge,
}); totalChargeFee,
break; });
break;
}
} }
} });
}); });
insertUnscheduledIncidents(unscheduledIncidents) insertUnscheduledIncidents(unscheduledIncidents)

View File

@@ -5,7 +5,7 @@ const moment = require('moment-timezone');
const Op = require('sequelize').Op; const Op = require('sequelize').Op;
const { API } = require('../../helpers/api'); const { API } = require('../../helpers/api');
const { officeRnDAPIErrors } = require('../../constants/constants'); const { officeRnDAPIErrors, MAX_BACK_TO_BACK_DIFFERENCE } = require('../../constants/constants');
const fetchAllBookings = () => { const fetchAllBookings = () => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@@ -57,7 +57,6 @@ const getAllFinishedBookings = () => {
const getFirstNextBooking = (reservation) => { const getFirstNextBooking = (reservation) => {
return new Promise ((resolve, reject) => { return new Promise ((resolve, reject) => {
const { resourceId, start } = reservation; const { resourceId, start } = reservation;
const endOfTheDay = moment.utc(start).endOf('Day').toISOString();
const attributes = ['reservationId', 'memberId', 'resourceId', 'start', 'end', 'timezone']; const attributes = ['reservationId', 'memberId', 'resourceId', 'start', 'end', 'timezone'];
const filters = { const filters = {
@@ -65,9 +64,6 @@ const getFirstNextBooking = (reservation) => {
start: { start: {
[Op.gt]: start [Op.gt]: start
}, },
end: {
[Op.lte]: endOfTheDay
},
resourceId, resourceId,
}; };
const order = [['start', 'ASC']]; const order = [['start', 'ASC']];
@@ -91,14 +87,10 @@ const getFirstNextBooking = (reservation) => {
const getFirstPreviousBooking = (reservation) => { const getFirstPreviousBooking = (reservation) => {
return new Promise ((resolve, reject) => { return new Promise ((resolve, reject) => {
const { resourceId, start } = reservation; const { resourceId, start } = reservation;
const startOfTheDay = moment.utc(start).startOf('Day').toISOString();
const attributes = ['reservationId', 'memberId', 'resourceId', 'start', 'end', 'timezone']; const attributes = ['reservationId', 'memberId', 'resourceId', 'start', 'end', 'timezone'];
const filters = { const filters = {
canceled: false, canceled: false,
start: {
[Op.gte]: startOfTheDay
},
end: { end: {
[Op.lte]: start [Op.lte]: start
}, },
@@ -122,6 +114,36 @@ const getFirstPreviousBooking = (reservation) => {
}); });
}; };
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 = reservation.end;
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) => { const writeBookingReservation = (bookingReservation) => {
return db.bookingReservation.findOrCreate({where: {...bookingReservation}, defaults: {...bookingReservation}}); return db.bookingReservation.findOrCreate({where: {...bookingReservation}, defaults: {...bookingReservation}});
}; };
@@ -132,4 +154,5 @@ module.exports = {
getAllFinishedBookings, getAllFinishedBookings,
getFirstNextBooking, getFirstNextBooking,
getFirstPreviousBooking, getFirstPreviousBooking,
getFirstReservationInBlock
}; };