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

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();