Académique Documents
Professionnel Documents
Culture Documents
de planification de voyage
Présenté par:
RAKOTONDRANAIVO Alain Rico ETU2011 - N°92
08 Février 2024
Membres du Jury:
● RAJAONARISON Baovola
● Mr Bruel
Sommaire
1
Mini soutenance pour présenter le développement et la conception d’une application
de gestion pour une entreprise de planification de voyages............................................1
I. Introduction......................................................................................................................3
II. Glossaire........................................................................................................................3
III. Architecture de l’application..........................................................................................4
1. Architecture logicielle................................................................................................5
2. Nombre de classes et de tables...............................................................................5
IV. Itérations.......................................................................................................................6
1. Gestion des bouquets + activités.............................................................................6
2. Gestion des voyages..............................................................................................12
3. Gestion des voyages + tarif activité.......................................................................17
4. Gestion des stocks.................................................................................................20
5. Gestion des employés............................................................................................24
6. Gestion des employés + poste grade.....................................................................27
7. Statistique...............................................................................................................32
8. Vente + mouvement de stock.................................................................................36
V. Conclusion...................................................................................................................39
2
I. Introduction
II. Glossaire
Terme Définition
API (Application Un ensemble de règles et de protocoles qui permettent à
Programming Interface) différents logiciels de communiquer entre eux. Les API
définissent les méthodes et les structures de données qui
peuvent être utilisées pour accéder et manipuler les
fonctionnalités d'un logiciel ou d'un service.
CRUD (Create, Read, Les opérations de base effectuées sur les données dans un
Update, Delete) système informatique. CRUD se réfère à la création (Create), la
lecture (Read), la mise à jour (Update) et la suppression (Delete)
des données. Ces opérations sont couramment utilisées dans
les applications de gestion de bases de données et les services
web pour manipuler les données.
CORS (Cross-Origin Un mécanisme de sécurité utilisé par les navigateurs web pour
Resource Sharing) autoriser les requêtes HTTP entre différents domaines. CORS
permet à un site web d'accéder à des ressources situées sur un
3
autre domaine que celui du site web d'origine. Cela permet de
sécuriser les communications entre les navigateurs et les
serveurs web tout en permettant le partage de ressources entre
différents sites.
DTO (Data Transfer Un objet utilisé pour transférer des données entre des
Object) composants d'une application. Les DTO sont généralement des
objets simples contenant des données sans logique métier. Ils
sont utilisés pour encapsuler et transférer des données entre les
différentes couches d'une application, telles que la couche de
présentation, la couche de service et la couche de persistance.
Pie Chart (Diagramme Un type de graphique utilisé pour représenter des données sous
Circulaire) forme de cercle divisé en segments proportionnels, chacun
représentant une catégorie ou une part de l'ensemble. Les
segments du cercle sont appelés "tranches" et la taille de
chaque tranche est proportionnelle à la valeur qu'elle représente
par rapport à l'ensemble. Les diagrammes circulaires sont
souvent utilisés pour visualiser la répartition des données
catégorielles ou pour illustrer la composition relative d'un
ensemble de données.
1. Architecture logicielle
a. Couche client
4
b. Couche métier
5
IV. Itérations
6
Les activités dépendent du bouquet.
a. Fonctionnalités
● CRUD activité
● CRUD bouquet
● CRUD activité-bouquet
● Filtre des activités selon bouquet
7
b. Tables/vues concernées
● Affichage:
8
● Base:
1. création de la table activity(id, name, description) avec une
contrainte unique et non null pour la colonne `name`.
2. création de la table subscription_tier(id, name, description) avec
une contrainte unique et non null pour la colonne `name`
3. création de la table tier_activity(id, subscription_tier_id,
activity_id) avec une contrainte non null et unique combinant
`subscription_tier_id` et `activity_id` (afin d'éviter la duplication
d’une activité dans un bouquet)
● Métier:
1. création des classes d’entités:
a. Activity
○ Long id
○ String name
○ String description
b. SubscriptionTier
○ Long id
○ String name
9
○ String description
○ Activity[] activities
c. TierActivity
○ Long id
○ Long subscriptionTierId
○ Long activityId
Note: Toutes les classes entités possèdent les méthodes CRUD
par défaut ainsi que quelques méthodes de filtre. Une classe
entité peut représenter une table ou une vue de la base de
données.
2. création des classes contrôleurs:
a. ActivityController
○ CRUD API ( + champ `name` non nullable dans la
méthode ‘create’ )
b. SubscriptionTierController
○ CRUD API ( + champ `name` non nullable dans la
méthode ‘create’ )
○ méthode one(Long id): retourne le bouquet
correspondant à l’ `id` passé en paramètre, avec la
liste des activités incluses dans le bouquet
c. TierActivityController
○ CRUD API ( + champ `subscriptionTierId` et
`activityId` non nullable dans la méthode ‘create’ )
● Intégration:
1. création des pages:
a. Activity et SubscriptionTier
○ création des méthodes pour créer, lire, mettre à jour
et supprimer des données à partir de l'API de
l'application
○ préparation des données nécessaires pour la table
CRUD globale, comme les noms des colonnes, leurs
types et les opérations supportées (ex: modification,
suppression, export pdf…)
b. TierActivity
○ création des méthodes pour créer et lire les données
○ création de la méthode pour filtrer les activités selon
le bouquet choisi
10
○ préparation des données nécessaires pour la table
CRUD globale pour afficher la liste des activités
filtrées
11
Un voyage est caractérisé par les points suivants:
● la durée (courte, moyenne, longue, ...)
● la catégorie (régionale, locale, internationale, …)
● le bouquet (silver, gold, premium, …)
● les activités (en fonction du bouquet choisi)
● son prix
12
a. Fonctionnalités
● CRUD voyages
● CRU nombre de l’activité selon le voyage
● CRUD durée
● CRUD catégorie
● Filtre des voyages à partir d’un activité choisi
b. Tables/vues concernées
● Base:
1. création de la table duration(id, label)
2. création de la table travel_category(id, category)
3. création de la table travel(id, name, duration_id,
travel_category_id, subscription_tier_id, sale_price) avec une
contrainte de non négativité sur la colonne `sale_price`
4. création de la table travel_activity(id, travel_id, tier_activity_id,
activity_count)
Note: Pour la table travel_activity, nous avons utilisé la liaison vers la
table tier_activity au lieu de la table activity pour assurer la conformité des
données (nous savons que les activités sont rattachés au bouquet)
13
5. création de la vue travel_activities(row_number, travel_id,
travel_name, duration_id, duration, travel_category_id, category,
subscription_tier_id, subscription_tier_name, activity_id,
activity_name, activity_count) à partir de la table travel et
travel_activity
● Métier:
1. création des classes d’entités:
a. Duration
○ Long id
○ String label
b. TravelCategory
○ Long id
○ String category
c. Travel
○ Long id
○ String name
○ Duration duration
○ TravelCategory travelCategory
○ SubscriptionTier subscriptionTier
○ Double salePrice
○ + control de positivité pour le setter
setSalePrice(Double p)
d. TravelActivity
○ Long id
○ Travel travel
○ TierActivity tierActivity
○ Integer activityCount
○ + control de positivité pour le setter
setActivityCount(Integer n)
e. TravelActivitiesView
○ Long rowId
○ Long travelId
○ String activity
○ String travel
○ String duration
○ String category
○ String subscriptionTier
○ Integer activityCount
14
2. création des classes contrôleurs:
a. DurationController
○ CRUD API ( + champ `label` non nullable dans la
méthode ‘create’ )
b. TravelCategoryController
○ CRUD API ( + champ `category` non nullable dans la
méthode ‘create’ )
c. TravelController
○ CRUD API ( + champ `name`, `duration`,
`travelCategory`, `subscriptionTier`, `salePrice` non
nullable dans la méthode ‘create’ )
Note: Les vues sont utilisées pour les méthodes ‘read’
d. TravelActivityController
○ CRUD API ( + champ `travelId`, `tierActivity`,
`activityCount` non nullable dans la méthode ‘create’
+ récupération de l’objet tierActivity correspondant
en fonction du voyage choisi et l’activité choisi pour
éviter l'incohérence de donnée )
○ méthode filter(Long activity_id): retourne la liste des
TravelActivitiesView à partir de la vue
travel_activities où `activity_id` correspond au
paramètre passé
Rappel: Nous avons utilisés la liaison vers la table tier_activity
donc ce control est nécessaire pour assurer la cohérence des
données
● Intégration:
1. création des pages:
a. Duration, TravelCategory et Travel
○ création des méthodes pour créer, lire, mettre à jour
et supprimer des données à partir de l'API de
l'application
○ préparation des données nécessaires pour la table
CRUD globale
b. TravelActivity
○ création des méthodes pour créer, lire et mettre à
jour les données
○ création de la méthode de filtre pour les voyages à
partir des activités
15
○ préparation des données nécessaires pour la table
CRUD globale
a. Fonctionnalités
b. Tables/vues concernées
16
c. Tâches assignés aux développeurs
● Affichage:
● Base:
1. création de la table activity_unit_price(id, activity_id, unit_price,
from_date) avec une contrainte de non négativité sur la colonne
`unit_price` et non null sur `from_date`
2. création de la vue activities(id, name, description, unit_price,
from_date) à partir de la table activity et activity_unit_price.
Cette vue sert à récupérer toutes les activités avec leur prix
unitaire le plus récent
3. création de la vue total_travel_activities_price(travel_id,
total_price), obtenue grâce à la jointure entre la vue
travel_activities et la précédente activities. Cette vue sert à
récupérer tous les voyages avec la totale des prix des activités
comprises dans son bouquet
4. création de la vue travels(id, name, duration_id,
travel_category_id, subscription_tier_id, sale_price, total_price) à
partir de la table travel et de la vue
total_travel_activities_price.
17
● Métier:
1. création des classes d’entités:
a. ActivityUnitPrice
○ Long id
○ Long activityId
○ Double unitPrice
○ Timestamp fromDate
○ + control de positivité pour le setter
setUnitPrice(Double u)
b. ActivityView
○ Long id
○ String name
○ String description
○ Double unitPrice
○ Timestamp fromDate
c. TravelView
○ Long id
○ String name
○ TravelCategory travelCategory
○ Duration duration
○ SubscriptionTier subscriptionTier
○ Double salePrice
○ Double totalPrice
18
● Intégration:
1. mise à jour des pages:
a. Activity
○ ajout d’une méthode pour modifier/ajouter le prix
unitaire d’une activité
○ ajout des colonnes prix unitaire et dernière date à la
table globale
b. Travel
○ ajout de la colonne prix de vente à la table globale
a. Fonctionnalités
19
b. Tables/vues concernées
● Affichage:
20
● Base:
1. création de la table stock_movement(id, action_date, activity_id,
in_quantity, out_quantity) avec une contrainte de non négativité
sur les colonnes `in_quantity` et `out_quantity`
2. création de la vue stock_state(activity_id, remaining_quantity) à
partir de la table stock_movement et une jointure à droite avec
la vue activities
3. création de la vue travel_activity_stock_state(row_number,
travel_id, travel_name, duration_id, duration, travel_category_id,
category, subscription_tier_id, subscription_tier, activity_id,
activity_name, activity_count, remaining_quantity) à partir de la
vue travel_activities et stock_state. Cette vue sert à savoir
l'état de stock de chaque billet d’activité de chaque voyage
● Métier
1. création des classes d”entités:
a. StockMovement
○ Long id
○ Timestamp actionDate
○ Activity activity
○ Integer inQuantity
○ Integer outQuantity
21
○ + control de positivité pour les setters
setInQuantity(Integer int) et setOutQuantity(Integer
out)
b. StockStateView
○ Long activityId
○ Activity activity
○ Integer remainingQuantity
c. TravelActivityStockStateView
○ Long rowId
○ Long travelId
○ Long activityId
○ String activity
○ String travel
○ String duration
○ String category
○ String subscriptionTier
○ Integer activityCount
○ Integer remainingQuantity
● Intégration:
1. création des pages:
a. Movement
○ création des méthodes pour récupérer l'état de stock,
créer un mouvement d'entrée et de sortie
○ nom et type des colonnes pour la table CRUD
globale pour l’état de stock
22
5. Gestion des employés
a. Fonctionnalité
● CRUD employés
● CRUD employé-voyage
23
b. Tables/vues concernées
Note: Les images représentent les dernières versions de l’application, il se
peut que dans les itérations antérieures, les tables aient une autre version due
au changement de conception.
● Affichage:
● Base:
1. création de la table employee(id, name, first_name, salary) avec
une contrainte de non négativité sur la colonne `salary` et non
null sur `name`
2. création de la table travel_employee(id, travel_id, employee_id,
duration)
3. création de la vue travel_employee_salaries(travel_id,
employee_id, salary) à partir de la table employee et
travel_employee. Cette vue sert à calculer le salaire de chaque
employé de chaque voyage
4. création de la vue total_travel_employee_salaries(travel_id,
total_salary) à partir de la vue travel_employee_salaries
24
5. modification de la vue travels. Jointure avec la vue
total_travel_employee_salaries et ajout de la colonne `profit`
qui n’est autre que: (prix de revient du voyage + salaire des
employés) - prix de vente du voyage
Note: la création de la vue total_travel_employee_salaries était
nécessaire pour faciliter la jointure avec la vue travels
● Métier:
1. création des classe d’entités:
a. Employee
○ Long id
○ String name
○ String firstName
○ Double salary
b. TravelEmployee
○ Long id
○ Long travelId
○ EmployeeView employee
○ Double duration
2. modification de la classe entité:
a. TravelView
○ Ajout d’un attribut Double profit
3. création des classes contrôleurs:
a. EmployeeController
○ CRUD API ( + champ `name` non nullable dans la
méthode ‘create’ )
4. modification de la classe contrôleur:
a. TravelController
○ Ajout CRUD API pour l’entité TravelEmployee, avec
une méthode pour filtrer les employés travaillant
dans un voyage à partir d’un `id` de voyage
● Intégration:
1. création des pages:
a. Employee et TravelEmployee
○ création des méthodes pour créer, lire, mettre à jour
et supprimer des données
○ création d’une méthode pour filtrer les employés par
voyage dans la page TravelEmployee
25
6. Gestion des employés + poste grade
a. Fonctionnalités
● CRUD grade
● CRUD poste
● Monté en grade automatique en fonction des années de service
26
b. Tables/vues concernées
● Affichage:
27
● Base:
1. modification de la table employee. Suppression de la colonne
`salaire` et ajout de la colonne `hiring_date`
2. création de la table employee_hourly_wage(id, employee_id,
from_date, salary) avec une contrainte de non négativité sur la
colonne `salary`
3. création de la table position(id, name) avec une contrainte
unique sur la colonne `name`
4. création de la table grade(id, name, increase, from_duration,
to_duration) avec une contrainte de non négativité sur la colonne
`from_duration`, et contrainte de supériorité entre la colonne
`to_duration` et `from_duration`
5. création de la table employee_position(id, employee_id,
position_id, from_date) avec une contrainte non null sur la
colonne `from_date`
6. création de la vue latest_employee_hourly_wage(employee_id,
salary, from_date) à partir de la table employee et
employee_hourly_wage. Cette vue sert à récupérer les
employés avec leurs tarifs horaires le plus récent
7. création de la vue latest_employee_position(employee_id,
position_id, from_date) à partir de la table employee et
employee_position. Cette vue sert à récupérer les employés
avec leurs postes le plus récent
8. création de la vue employee_salaries(id, name, first_name,
hiring_date, position_id, grade_id, salary) à partir de la table
employee, grade, de la vue latest_employee_position et
28
latest_employee_hourly_wage. Cette vue sert à récupérer les
employés tout en calculant leurs grades actuels et ainsi calculer
leurs vrais tarifs horaires en fonction de leur grade
9. création de la vue employees(id, name, first_name, hiring_date,
position_grade, salary) à partir de la table employee, position,
grade, et la vue employee_salaries. Cette sert de jointure et de
rassemblement d’information pour l’affichage.
10. modification de source de la vue travel_employee_salaries. La
jointure se fait avec la vue employees maintenant au lieu de la
table employee
● Métier:
1. modification de la classe entité:
a. Employee
○ suppression de l’attribut `salary` et ajout de l’attribut
Timestamp `hiringDate`
2. création des classes d’entités:
a. EmployeeHourlyWage
○ Long id
○ Long employeeId
○ Timestamp fromDate
○ Double salary
○ + control de positivité pour le setter setSalary(Double
s)
b. Position
○ Long id
○ String name
c. Grade
○ Long id
○ String name
○ Double increase
○ Double fromDuration
○ Double toDuration
d. EmployeePosition
○ Long id
○ Long employeeId
○ Long positionId
○ Timestamp fromDate*
e. EmployeeView
○ Long id
29
○ String name
○ String firstName
○ String positionGrade
○ Double salary
3. modification de la classe contrôleur:
a. EmployeeController:
○ Utilisation de l’entité EmployeeView pour la
méthode ‘read’ au lieu de Employee
○ Ajout de la méthode addSalary() pour l’insertion de
l’entité EmployeeHourlyWage
○ Ajout de la méthode addPosition() pour l’insertion de
l’entité EmployeePosition
4. création des classes contrôleurs:
a. PositionController
○ CRUD API ( + champ `label` non nullable dans la
méthode ‘create’ )
b. GradeController
○ CRUD API ( + champ `label` non nullable dans la
méthode `create` )
● Intégration
1. modification de la page
a. Employee
○ Ajout de la colonne `Date d’embauche`
○ création d’une méthode d’insertion de salaire horaire
d’un employé
○ création d’une méthode d’insertion de poste d’un
employé
2. création des pages:
a. Grade et Position
○ création des méthodes pour créer, lire, mettre à jour
et supprimer des données à partir de l'API de
l'application
○ préparation des données nécessaires pour la table
CRUD globale
30
7. Statistique
31
a. Fonctionnalités
● CRUD client
● Insertion réservation
● Statistique de genre
b. Tables/vues concernées
32
c. Tâches assignés aux développeurs
● Affichage:
● Base:
1. création de la table client(id, name, first_name, genre,
birth_date) avec une contrainte non null pour les colonnes `name`
et `genre`
2. création de la table client_reservation(id, client_id, travel_id,
quantity, reservation_date) avec une contrainte de non négativité
sur la colonne `quantity`
3. création de la vue travel_reservation_statistic(travel_id,
duration_id, category_id, total_reservation) à partir de la table
travel, duration, subscription_tier, travel_category et
client_reservation. Cette vue sert à récupérer la totalité de
réservation par voyage
4. création de la vue travel_male_reservation_statistic(travel_id,
male_reservation) à partir de la table client_reservation et
client. Cette vue sert à récupérer la totalité de la réservation
mâle par voyage
5. création de la vue
travel_female_reservation_statistic(travel_id,
33
female_reservation) à partir de la table client_reservation et
client. Cette vue sert à récupérer la totalité de la réservation
femelle par voyage
6. création de la vue travel_reservation_genre_statistic(travel_id,
travel_name, travel_duration, category, male_effective,
female_effective) à partir de la vue travel_reservation_statistic,
travel_male_reservation_statistic,
travel_female_reservation_statistic, de la table travel,
duration et travel_category. Cette vue est la statistique en
genre elle-même
● Métier:
1. création des classes d’entités:
a. Client
○ Long id
○ String name
○ String first_name
○ Integer genre
○ Date birthDate
b. ClientReservation
○ Long id
○ Long clientId
○ Long travelId
○ Timestamp reservationDate
○ Integer quantity
○ + control de positivité pour le setter
setQuantity(Integer q)
c. TravelGenreStatistic
○ Long travelId
○ String travelName
○ String duration
○ String category
○ Double maleEffective
○ Double femaleEffective
2. création des classes contrôleurs:
a. ClientController
○ CRUD API ( + champ `name` et genre non nullable
dans la méthode ‘create’ )
b. ClientReservationController
34
○ Ajout méthode d’insertion pour l’entité
ClientReservation
○ Ajout méthode read pour l’entité
TravelGenreStatistic
● Intégration:
1. création des pages:
○ Client
○ création des méthodes pour créer, lire, mettre à jour
et supprimer des données
○ ClientReservation
○ création de méthode pour créer une réservation
○ TravelGenreStatistic
○ création de méthode pour filtrer le statistique en
fonction du voyage choisi
○ intégration de la Pie Chart
a. Fonctionnalités
35
9. Tables/vues concernées
● Métier
1. modification de la classe contrôleur:
a. ClientReservationController
○ modification de la méthode create. Appel du fonction
de mouvement de sortie ( avec un control de l'état de
stock )
36
V. Conclusion
37