You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
421 lines
14 KiB
421 lines
14 KiB
const { Reservation, Client, Table } = require('../models/associations');
|
|
const { Op } = require('sequelize');
|
|
|
|
class ReservationController {
|
|
// Get all reservations
|
|
async getAllReservations(req, res) {
|
|
try {
|
|
const {
|
|
page = 1,
|
|
limit = 10,
|
|
statut,
|
|
date_debut,
|
|
date_fin,
|
|
table_id,
|
|
sort_by = 'date_reservation',
|
|
sort_order = 'ASC'
|
|
} = req.query;
|
|
|
|
const offset = (parseInt(page) - 1) * parseInt(limit);
|
|
const whereClause = {};
|
|
|
|
// Status filter
|
|
if (statut) {
|
|
whereClause.statut = statut;
|
|
}
|
|
|
|
// Date range filter
|
|
if (date_debut && date_fin) {
|
|
whereClause.date_reservation = {
|
|
[Op.between]: [new Date(date_debut), new Date(date_fin)]
|
|
};
|
|
} else if (date_debut) {
|
|
whereClause.date_reservation = {
|
|
[Op.gte]: new Date(date_debut)
|
|
};
|
|
} else if (date_fin) {
|
|
whereClause.date_reservation = {
|
|
[Op.lte]: new Date(date_fin)
|
|
};
|
|
}
|
|
|
|
// Table filter
|
|
if (table_id) {
|
|
whereClause.table_id = table_id;
|
|
}
|
|
|
|
const { count, rows } = await Reservation.findAndCountAll({
|
|
where: whereClause,
|
|
include: [
|
|
{
|
|
model: Client,
|
|
as: 'client',
|
|
attributes: ['nom', 'prenom', 'email', 'telephone']
|
|
},
|
|
{
|
|
model: Table,
|
|
as: 'table',
|
|
attributes: ['nom', 'capacity', 'location']
|
|
}
|
|
],
|
|
limit: parseInt(limit),
|
|
offset: offset,
|
|
order: [[sort_by, sort_order.toUpperCase()]]
|
|
});
|
|
|
|
res.json({
|
|
success: true,
|
|
data: {
|
|
reservations: rows,
|
|
pagination: {
|
|
currentPage: parseInt(page),
|
|
totalPages: Math.ceil(count / parseInt(limit)),
|
|
totalItems: count,
|
|
itemsPerPage: parseInt(limit)
|
|
}
|
|
}
|
|
});
|
|
} catch (error) {
|
|
res.status(500).json({
|
|
success: false,
|
|
message: 'Erreur lors de la récupération des réservations',
|
|
error: error.message
|
|
});
|
|
}
|
|
}
|
|
|
|
// Get reservation by ID
|
|
async getReservationById(req, res) {
|
|
try {
|
|
const { id } = req.params;
|
|
|
|
const reservation = await Reservation.findByPk(id, {
|
|
include: [
|
|
{
|
|
model: Client,
|
|
as: 'client',
|
|
attributes: ['nom', 'prenom', 'email', 'telephone']
|
|
},
|
|
{
|
|
model: Table,
|
|
as: 'table',
|
|
attributes: ['nom', 'capacity', 'location']
|
|
},
|
|
{
|
|
association: 'commandes'
|
|
}
|
|
]
|
|
});
|
|
|
|
if (!reservation) {
|
|
return res.status(404).json({
|
|
success: false,
|
|
message: 'Réservation non trouvée'
|
|
});
|
|
}
|
|
|
|
res.json({
|
|
success: true,
|
|
data: reservation
|
|
});
|
|
} catch (error) {
|
|
res.status(500).json({
|
|
success: false,
|
|
message: 'Erreur lors de la récupération de la réservation',
|
|
error: error.message
|
|
});
|
|
}
|
|
}
|
|
|
|
// Create new reservation
|
|
async createReservation(req, res) {
|
|
try {
|
|
const reservationData = req.body;
|
|
|
|
// Check table availability
|
|
const existingReservation = await Reservation.findOne({
|
|
where: {
|
|
table_id: reservationData.table_id,
|
|
date_reservation: {
|
|
[Op.between]: [
|
|
new Date(new Date(reservationData.date_reservation).getTime() - 2 * 60 * 60 * 1000),
|
|
new Date(new Date(reservationData.date_reservation).getTime() + 2 * 60 * 60 * 1000)
|
|
]
|
|
},
|
|
statut: {
|
|
[Op.in]: ['confirmee', 'en_attente']
|
|
}
|
|
}
|
|
});
|
|
|
|
if (existingReservation) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
message: 'Table déjà réservée à cette heure'
|
|
});
|
|
}
|
|
|
|
// Check table capacity
|
|
const table = await Table.findByPk(reservationData.table_id);
|
|
if (!table) {
|
|
return res.status(404).json({
|
|
success: false,
|
|
message: 'Table non trouvée'
|
|
});
|
|
}
|
|
|
|
if (reservationData.nombre_personnes > table.capacity) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
message: 'Nombre de personnes supérieur à la capacité de la table'
|
|
});
|
|
}
|
|
|
|
const reservation = await Reservation.create(reservationData);
|
|
|
|
// Include related data in response
|
|
const createdReservation = await Reservation.findByPk(reservation.id, {
|
|
include: [
|
|
{
|
|
model: Client,
|
|
as: 'client',
|
|
attributes: ['nom', 'prenom', 'email', 'telephone']
|
|
},
|
|
{
|
|
model: Table,
|
|
as: 'table',
|
|
attributes: ['nom', 'capacity', 'location']
|
|
}
|
|
]
|
|
});
|
|
|
|
res.status(201).json({
|
|
success: true,
|
|
message: 'Réservation créée avec succès',
|
|
data: createdReservation
|
|
});
|
|
} catch (error) {
|
|
if (error.name === 'SequelizeValidationError') {
|
|
return res.status(400).json({
|
|
success: false,
|
|
message: 'Données invalides',
|
|
errors: error.errors.map(e => ({
|
|
field: e.path,
|
|
message: e.message
|
|
}))
|
|
});
|
|
}
|
|
|
|
res.status(500).json({
|
|
success: false,
|
|
message: 'Erreur lors de la création de la réservation',
|
|
error: error.message
|
|
});
|
|
}
|
|
}
|
|
|
|
// Update reservation
|
|
async updateReservation(req, res) {
|
|
try {
|
|
const { id } = req.params;
|
|
const updateData = req.body;
|
|
|
|
const reservation = await Reservation.findByPk(id);
|
|
if (!reservation) {
|
|
return res.status(404).json({
|
|
success: false,
|
|
message: 'Réservation non trouvée'
|
|
});
|
|
}
|
|
|
|
await reservation.update(updateData);
|
|
|
|
const updatedReservation = await Reservation.findByPk(id, {
|
|
include: [
|
|
{
|
|
model: Client,
|
|
as: 'client',
|
|
attributes: ['nom', 'prenom', 'email', 'telephone']
|
|
},
|
|
{
|
|
model: Table,
|
|
as: 'table',
|
|
attributes: ['nom', 'capacity', 'location']
|
|
}
|
|
]
|
|
});
|
|
|
|
res.json({
|
|
success: true,
|
|
message: 'Réservation mise à jour avec succès',
|
|
data: updatedReservation
|
|
});
|
|
} catch (error) {
|
|
res.status(500).json({
|
|
success: false,
|
|
message: 'Erreur lors de la mise à jour de la réservation',
|
|
error: error.message
|
|
});
|
|
}
|
|
}
|
|
|
|
// Delete reservation
|
|
async deleteReservation(req, res) {
|
|
try {
|
|
const { id } = req.params;
|
|
|
|
const reservation = await Reservation.findByPk(id);
|
|
if (!reservation) {
|
|
return res.status(404).json({
|
|
success: false,
|
|
message: 'Réservation non trouvée'
|
|
});
|
|
}
|
|
|
|
await reservation.destroy();
|
|
|
|
res.json({
|
|
success: true,
|
|
message: 'Réservation supprimée avec succès'
|
|
});
|
|
} catch (error) {
|
|
res.status(500).json({
|
|
success: false,
|
|
message: 'Erreur lors de la suppression de la réservation',
|
|
error: error.message
|
|
});
|
|
}
|
|
}
|
|
|
|
// Get reservations by status
|
|
async getReservationsByStatus(req, res) {
|
|
try {
|
|
const { status } = req.params;
|
|
const { page = 1, limit = 10 } = req.query;
|
|
|
|
const offset = (parseInt(page) - 1) * parseInt(limit);
|
|
|
|
const { count, rows } = await Reservation.findAndCountAll({
|
|
where: { statut: status },
|
|
include: [
|
|
{
|
|
model: Client,
|
|
as: 'client',
|
|
attributes: ['nom', 'prenom', 'email', 'telephone']
|
|
},
|
|
{
|
|
model: Table,
|
|
as: 'table',
|
|
attributes: ['nom', 'capacity', 'location']
|
|
}
|
|
],
|
|
limit: parseInt(limit),
|
|
offset: offset,
|
|
order: [['date_reservation', 'ASC']]
|
|
});
|
|
|
|
res.json({
|
|
success: true,
|
|
data: {
|
|
reservations: rows,
|
|
pagination: {
|
|
currentPage: parseInt(page),
|
|
totalPages: Math.ceil(count / parseInt(limit)),
|
|
totalItems: count,
|
|
itemsPerPage: parseInt(limit)
|
|
}
|
|
}
|
|
});
|
|
} catch (error) {
|
|
res.status(500).json({
|
|
success: false,
|
|
message: 'Erreur lors de la récupération des réservations',
|
|
error: error.message
|
|
});
|
|
}
|
|
}
|
|
|
|
// Get today's reservations
|
|
async getTodayReservations(req, res) {
|
|
try {
|
|
const today = new Date();
|
|
const startOfDay = new Date(today.getFullYear(), today.getMonth(), today.getDate());
|
|
const endOfDay = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
|
|
|
|
const reservations = await Reservation.findAll({
|
|
where: {
|
|
date_reservation: {
|
|
[Op.between]: [startOfDay, endOfDay]
|
|
}
|
|
},
|
|
include: [
|
|
{
|
|
model: Client,
|
|
as: 'client',
|
|
attributes: ['nom', 'prenom', 'email', 'telephone']
|
|
},
|
|
{
|
|
model: Table,
|
|
as: 'table',
|
|
attributes: ['nom', 'capacity', 'location']
|
|
}
|
|
],
|
|
order: [['date_reservation', 'ASC']]
|
|
});
|
|
|
|
res.json({
|
|
success: true,
|
|
data: reservations
|
|
});
|
|
} catch (error) {
|
|
res.status(500).json({
|
|
success: false,
|
|
message: 'Erreur lors de la récupération des réservations du jour',
|
|
error: error.message
|
|
});
|
|
}
|
|
}
|
|
|
|
// Get reservation statistics
|
|
async getReservationStats(req, res) {
|
|
try {
|
|
const total = await Reservation.count();
|
|
const confirmees = await Reservation.count({ where: { statut: 'confirmee' } });
|
|
const en_attente = await Reservation.count({ where: { statut: 'en_attente' } });
|
|
const annulees = await Reservation.count({ where: { statut: 'annulee' } });
|
|
const terminees = await Reservation.count({ where: { statut: 'terminee' } });
|
|
|
|
const today = new Date();
|
|
const startOfDay = new Date(today.getFullYear(), today.getMonth(), today.getDate());
|
|
const endOfDay = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
|
|
|
|
const todayCount = await Reservation.count({
|
|
where: {
|
|
date_reservation: {
|
|
[Op.between]: [startOfDay, endOfDay]
|
|
}
|
|
}
|
|
});
|
|
|
|
res.json({
|
|
success: true,
|
|
data: {
|
|
total,
|
|
confirmees,
|
|
en_attente,
|
|
annulees,
|
|
terminees,
|
|
todayCount
|
|
}
|
|
});
|
|
} catch (error) {
|
|
res.status(500).json({
|
|
success: false,
|
|
message: 'Erreur lors de la récupération des statistiques',
|
|
error: error.message
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = new ReservationController();
|
|
|