)
Dashboard PMS
Moteur d'analyse de revenue management pour hôteliers indépendants
Le problème
Un hôtel indépendant vit de quelques questions simples : est-ce qu'on remplit mieux que l'an dernier à la même période ? À quel prix ? Par quel canal ? Les réponses existent, mais elles sont enfermées dans le PMS (le logiciel de gestion de l'hôtel), et chaque PMS a son API, son format et ses particularités. Les rapports natifs sont souvent pauvres, et la comparaison d'une année sur l'autre reste un exercice manuel sur Excel.
L'objectif : centraliser automatiquement les réservations de plusieurs hôtels, quel que soit leur PMS, et en tirer des indicateurs fiables, comparables d'une année à l'autre.
Ce que j'ai construit
Un backend API qui :
se connecte à plusieurs PMS (Thais, MisterBooking) et accepte aussi des exports Excel/CSV (D-Edge) pour ceux qui n'ont pas d'API exploitable ;
normalise toutes les réservations dans un modèle unique : réservation → nuitées, avec chambre, tarif, canal d'origine, prix et annulations ;
calcule les indicateurs clés du revenue management : CA, taux d'occupation, prix moyen, RevPAR, durée de séjour, fenêtre de réservation ;
expose des analyses à un front : tableau de bord annuel, courbes cumulées, pickup (ce qui est entré en portefeuille ces N derniers jours) et ventilation par canal, tarif, chambre ou type de chambre.
)
Les défis intéressants
1. Comparer « le même jour » d'une année sur l'autre
Comparer le 14 mars 2025 au 14 mars 2024 n'a pas de sens pour un hôtel : l'un est un vendredi, l'autre un jeudi. J'ai donc implémenté deux modes de comparaison :
absolu : même date calendaire ;
relatif : même semaine ISO et même jour de la semaine, avec deux cas particuliers. Un jour férié est comparé au même jour férié de l'année précédente (le lundi de Pâques à l'autre lundi de Pâques, même s'il a bougé de trois semaines). Les fins décembre qui tombent dans la semaine ISO de l'année suivante sont aussi traitées à part.
Les dates de comparaison sont précalculées à l'enregistrement de chaque nuitée, ce qui évite de les recalculer à chaque requête d'analyse.
2. Synchroniser sans tout re-télécharger ni se faire bloquer
Les API des PMS sont lentes, limitées en débit et paginées par période. La synchronisation est découpée en fenêtres (semaine ou mois selon l'hôtel) traitées par des workers Celery :
au premier lancement, le système remonte le temps fenêtre par fenêtre jusqu'à ne plus trouver de réservations, puis fait la même chose vers le futur ;
ensuite, un cron toutes les 4 heures en journée récupère les nouveautés, et une resynchro complète tourne chaque semaine ;
chaque fenêtre synchronisée est journalisée, pour ne pas redemander une période déjà à jour ;
les appels sont limités en débit, et le jeton d'authentification Thais est partagé entre workers via un verrou Redis, pour éviter que dix workers se reconnectent en même temps.
Pour savoir si une réservation a réellement changé, je calcule une empreinte de son état (statut, annulation, canal, et pour chaque nuitée : chambre, tarif, prix). Seules les réservations dont l'empreinte change sont comptées comme modifiées et réanalysées.
3. Trois sources, un seul modèle
Thais parle REST + jeton, MisterBooking utilise une authentification WSSE signée, D-Edge arrive en export CSV avec des colonnes en français et un encodage parfois en latin-1. Chaque source a son adaptateur, et tout converge vers le même modèle de réservations et de nuitées. Les imports de fichiers tournent en tâche de fond, avec progression et journal consultables par l'utilisateur.
4. Des analyses rapides sur plusieurs années d'historique
Les indicateurs sont calculés directement en SQL via l'ORM Django (agrégations conditionnelles pour le pickup, annotations par date), plutôt qu'en Python, puis mis en cache dans Redis par hôtel, période, mode de comparaison et fenêtre de pickup.
Architecture
Des workers Celery, pilotés par des crons (Celery beat), interrogent les PMS (Thais, MisterBooking) et traitent les exports Excel/CSV (D-Edge). Les données normalisées sont stockées dans PostgreSQL et exposées par une API Django REST Framework sécurisée par JWT, consommée par le dashboard. Redis sert à la fois de cache, de broker et de gestionnaire de verrous ; Django Channels pousse les notifications en temps réel (fin d'import, synchronisation). Le tout tourne sous Docker Compose : Gunicorn, worker Celery, beat, Redis et Nginx.
What about you?
Is your data locked inside your business software? Let's talk about what it could tell you.
The technologies used on this project

Django & DRF
Python web framework and its REST toolkit: data model, JWT-secured API and SQL aggregations through the ORM.

PostgreSQL
Relational database storing several years of normalised bookings and room nights.

Python & Pandas
Reading and cleaning Excel/CSV exports from PMSs without an API (columns, encodings, date formats).
