Legyen 3 foglalás. Adott két meglévő foglalás:
Szeretnénk 5-től 7-ig foglalni.
A másik lehetőség, hogy a meglévő foglalások:
Amit szeretnénk foglalni: 6-tól 8-ig.
Lássuk a következő ábrán.
Az alábbiakban szállodai foglalásra látunk példát. Ha április 5-én elmegy egy vendég, akkor 5-től már lehet foglalni.
A Sequelize ORM lekérdezési és operátorhasználati lehetőségeit használjuk, amelyről többet olvashatsz itt:
A következő részlet egy kontrollerben helyezhető el, például egy Create művelet esetén.
Implicit ÉS kapcsolattal:
const { startDate, endDate } = req.body const overlappingRental = await Rental.findAll({ where: { startDate: { [Op.lt]: endDate }, endDate: { [Op.gt]: startDate } } }) if(overlappingRental.length > 0) { throw new Error('Hiba! Átfedés a foglalásban!') }
Explicit, egyértelműen megadva az és kapcsolat:
const { startDate, endDate } = req.body const overlappingRental = await Rental.findAll({ where: { [Op.and]: [ { startDate: { [Op.lt]: endDate } }, { endDate: { [Op.gt]: startDate } } ] } }) if(overlappingRental.length > 0) { throw new Error('Hiba! Átfedés a foglalásban!') }
Csak adott felhasználónál vizsgáljuk:
const { userId, startDate, endDate } = req.body const overlappingRental = await Rental.findAll({ where: { userId: userId, [Op.and]: [ { startDate: { [Op.lt]: endDate } }, { endDate: { [Op.gt]: startDate } } ] } }) if(overlappingRental.length > 0) { throw new Error('Hiba! Átfedés a foglalásban!') }
Szigorú kizárásról beszélünk, amikor április 5-ig van foglalva valami, és csak másnaptól lehet újra foglalni.
where: { [Op.and]: [ { startDate: { [Op.lte]: endDate } }, { endDate: { [Op.gte]: startDate } } ] }
Legyen egy foglalás, ahol minimum 3 napot, maximum 21 napot foglalhatunk.
Mivel nem szükséges lekérdezést végezni az adatbázisból, ezért az ilyen érvényességet vizsgálhatjuk a modellben is.
import { DataTypes } from 'sequelize' import sequelize from '../database/database.js' const Rental = sequelize.define('rental', { id: { type: DataTypes.INTEGER, autoIncrement: true, primaryKey: true }, userId: { type: DataTypes.STRING, allowNull: false, validate: { len: [1,] } }, startDate: { type: DataTypes.DATE, allowNull: true, validate: { isDate: true } }, endDate: { type: DataTypes.DATE, allowNull: true, validate: { isDate: true, checkDateRange(value) { if(this.startDate && value) { const startDate = new Date(this.startDate) const endDate = new Date(value) startDate.setHours(0, 0, 0, 0) endDate.setHours(0, 0, 0, 0) const diffInDays = Math.round((endDate - startDate) / (1000 * 60 * 60 * 24)) if(diffInDays < 2) { throw new Error('Hiba! A bérlés időtartalma legalább 3 nap') } if(diffInDays > 20) { throw new Error('Hiba! A bérlés maximum 21 nap') } } } } }, duration: { type: DataTypes.VIRTUAL, get() { if (this.endDate && this.startDate) { const millisecondsPerDay = 1000 * 60 * 60 * 24; return Math.floor((this.endDate - this.startDate) / millisecondsPerDay); } return null; } }, totalCost: { type: DataTypes.VIRTUAL, get() { let total = 0 if (this.rentalItems) { for(let i = 0; i < this.rentalItems.length; i++) { total += this.rentalItems[i].dailyPrice * this.duration } } return total } } }) sequelize.sync({ force: false }) export default Rental
A duration és a totalCost mezők számított mezők, amelyeket virtuális mezőként hoztunk létre. Ezekről többet olvashatsz A Sequelize dokumentációjában: