Encadrants
: Mr. Tabone
Mr. Frossini
Historique :
Préambule
Je tiens ici à remercier vivement toutes les personnes de Sopra Group qui ont contribué de près ou de loin
au bon déroulement de mon stage, pour le temps qu’elles ont bien voulu me consacrer, les conseils qu’elles m’ont
donné ou tout simplement le soutient qu’elles m’ont apporté.
Mes remerciements s’adressent plus particulièrement à Mr. Philippe FROSSINI, mon tuteur en entreprise,
Mr. Patrick Meyer, architecte et spécialiste des technologies J2EE pour l’agence EST, et Mr. Tabonne, mon
encadrant universitaire.
Je souhaite également remercier Mme. Christine PEYROT, assistante de l’agence de Metz, Mme. Pascale
LUCAS, ingénieur commercial et Mr. Jean-Philippe Muller, directeur de l’agence EST pour leur accueil, leur
disponibilité, l’ambiance studieuse et conviviale qu’ils m’ont offerte afin que mon stage se déroule dans les meilleures
conditions possibles.
Paul CLEMENT
Sommaire :
1. INTRODUCTION 5
2. L’ENTREPRISE 6
2.1. G é n é r a l it é s 6
2.2. Chiffres clés (3 1 /1 2/ 2 00 7 ) 9
2.3. L ’agence E S T 10
3. PRESENTATION DU PROJET 12
3.1. L e s be so in s 12
3 .2 . L e s ob je ct if s 13
3 .3 . L e s co n t r a in t e s 14
3 .4 . L ’o r g a n i sa t io n d u p ro je t 14
3.5. T e c h n o l o g i e s e t m é t h o d e s e m p l o y é e s 16
3.6. P l a n n i n g p ré visio n ne l 17
3.7. L’équipe d u projet M A G I C C A 18
5. PROGRAMMES REALISES 27
6. B I L A N 40
6.1. B ila n T e c h n i q u e 40
6.2. B ilan h u m a i n 41
BIBLIOGRAPHIE 42
ANNEXES 43
1. INTRODUCTION
Mon stage de fin de DUT ayant été réalisé en interne au Centre Psychothérapique de Nancy, j’ai
choisit d’effectuer celui de licence dans un autre environnement, celui d’une SSII. Sopra Group m’a donné
la chance de découvrir et de comprendre le fonctionnement d’une société de service en m’offrant un
stage, en interne au sein d’une de ses agences.
Ce rapport sera composé de quatre parties. La première décrira l’entreprise et la situera sur le marché.
La deuxième expliquera partie présentera le sujet du stage. La troisième partie proposera une analyse et
une résolution du problème. Et enfin, la quatrième partie décriera les travaux.
2. L’ENTREPRISE
2.1. G é n é ra li t é s
En Europe
Sopra Group fait des acquisitions afin de mettre en place sa politique de développement européen sur
le métier de l’Intégration de Systèmes :
après avoir créé sa première implantation internationale en Suisse et obtenu par l’achat de SG2
en 1996 son équivalent en Belgique, Sopra Group démarre dans les années 1999 à 2001 la
réalisation de son réseau international avec les acquisitions de Mentor au Royaume-Uni, de
Organizacion Guver, Dipisa, Newpath Consulting et Newpath GS en Espagne et de ITI SpA en
Italie;
en 2005, Sopra Group accélère son développement au Royaume-Uni et en Espagne :
acquisition de la société Newell & Budge au Royaume-Uni et de ses filiales irlandaise
et indienne. Leader en Écosse, et forte de plus de 600 personnes (dont plus de 100
personnes en Inde dans sa filiale Momentum Technologies), elle dispose d’une gamme
complète de services informatiques allant du conseil à la
mise en œuvre;
début 2006, acquisition de Cyclone Commerce aux États-Unis. Ce rapprochement s’inscrit dans la
stratégie de développement mondial d’Axway. La complémentarité des deux sociétés permet
l’émergence d’un leader mondial capable de servir les besoins des plus grands clients dans les
domaines du B2B, du SOA et sur le marché des services collaboratifs ;
début 2007, acquisition des activités « logiciels B2B » d’Atos Origin en Allemagne.
Cette acquisition procure à Axway un leadership européen indiscutable dans le domaine des
plates- formes logicielles B2B et renforce significativement sa présence en Allemagne, qui
constitue le premier marché européen.
Pour le Groupe, la stratégie de développement à l’international consiste, en synergie avec Axway et les
filiales européennes d’Intégration de Systèmes, à poursuivre et à amplifier la démarche initialisée par
Sopra Group, en ciblant prioritairement le renforcement dans les principaux pays européens.
Globalement, le Groupe bénéficie des synergies possibles qui lui permettent d’exporter ses acquis d’un
pays sur un autre. Il constitue l’un des premiers groupes français de Conseil et d’Intégration de
Systèmes et de Solutions, significativement présent dans le secteur Banque et Assurance avec une forte
implantation régionale et un projet ambitieux au plan international.
Implantations
Benelux
Espagne
France (34 sites)
Inde
Irlande
Italie
Maroc
Portugal
Royaume-Uni
Suisse
Filiale Axway (Amérique du nord, Amérique du sud, Europe du nord, Europe du sud, Asie,
Afrique)
Chiffre d'affaires par activité (en %) Chiffre d'affaires par métier (en %)
2.3. L’agence E S T
L’agence EST, composée des sites de Metz, Strasbourg est composée de plus de cent
collaborateurs. Elle appartient à la division Nord.
Une division comporte des agences rassemblées par secteur géographique puis par type de marché pour les
plus importantes d’entre elles.
Exemple :
Sopra Group (France)
Division Nord (au sens Nord de Paris)
Agence de Lille (+/- 450 collaborateurs)
Outsourcing
Tertiaire
Industrie
…
Agence EST (Site de Metz et Strasbourg, +/- 120 collaborateurs)
Agence Luxembourg
…
Division Ouest
Agence Bordeaux
Agence Nantes
…
…
Cette organisation bipolaire pour l’agence EST s’explique par la présence des « grands comptes »
essentiellement localisés en Lorraine (CORA Informatique, Arcelor, Saint-Gobain, …) et en
Alsace (Unedic, PSA, Kronenbourg). Cependant, l’implantation de Sopra Group dans l’Est est trop
faible pour justifier la présence de deux agences totalement différentes.
Positionné sur le site de Metz (Technopôle), j’ai pu constater la principale particularité des SSII : les
collaborateurs travaillent chez le client. En effet, ne travaillaient à l’agence que l’assistance de direction
Christine Peyrot, l’ingénieur commercial Pascale Lucas, parfois le directeur d’agence Jean-Philippe Muller,
les collaborateurs en inter-chantier (très rare), et les collaborateurs qui assistaient aux différentes
réunions (recrutement, …).
Mon tuteur, Mr. Philippe Frossini, Responsable Qualité de l’agence, me consacrait une demi-journée
par semaine afin de faire des points d’avancement, valider les différentes étapes du cahier des charges, …
Les locaux, modernes, étaient constitués que de deux bureaux, une salle de réunion et une salle appelée
« plateau » comportant 12 mini-bureaux. J’étais installé à l’un deux, avec un ordinateur portable récent,
un accès internet/réseaux ethernet, et un téléphone. Salle climatisée et assise confortable ont fait
que l’environnement était parfait pour un travail efficace.
J’ai évolué avec comme système d’exploitation Windows XP Professionnel, comme IDE principal Eclipse,
comme SGBD MySQL et sa console d’administration « phpmyadmin ». J’ai également utilisé
MySQL Workbench pour les schémas de base de données, DB designer pour le MPD, ainsi que
MagicDraw pour la documentation UML. Tous les rapports, cahiers des charges et documents étaient
réalisés sous office, accompagnés du logiciel DOCS (modèles de document officiels à la charte Sopra
Group). J’ai également utilisé un logiciel de « versioning » : SVN. Il m’a notamment permis de partager
avec des collaborateurs Lillois et Strasbourgeois.
La méthode de gestion de projet utilisée est décrite dans la partie suivante.
3. PRESENTATION D U PROJET
Tout d’abord, il faut savoir qu’il est rare que Sopra Group emploie les stagiaires issus de licence.
Cette année, exceptionnellement, un besoin interne, nécessite l’intervention d’un collaborateur. Cependant,
le projet ne justifie pas le fait d’y consacrer un collaborateur en inter-chantier, c’est pour cela que Sopra
Group a fait appel à moi.
Afin de vous présenter le projet, nous allons tout d’abord aborder le point des besoins, puis des
objectifs, celui des contraintes. Vient alors l’organisation du projet, les technologies utilisées, et les
différents acteurs.
3.1. L e s b eso in s
Actuellement, toutes les activités de l’agence sont stockées dans des fichiers Word et Excel
difficiles à partager, à maintenir et peu pratiques.
L’activité de l’agence est composée de plusieurs domaines :
Activité commerciale
RH
Suivi qualité
Gestions des candidats
Gestion des collaborateurs
Gestion des clients
Un besoin qui est venu s’ajouter au cours du stage est la gestion d’un tableau de disponibilité,
permettant aux commerciaux et acteurs des comités d’affectations des collaborateurs, de gérer au
mieux les intermissions et les affectations des collaborateurs aux missions. Un export MS Excel de ce
tableau est également un besoin.
En effet, après discussion avec Mr. Patrick Meyer et Mme. Pascale Lucas, nous nous sommes rendu
compte que sans réel chiffre d’affaire généré par l’application, elle ne serait pas maintenue. Ce dernier
besoin permet donc l’assurance d’une maintenant des profils des collaborateurs par eux-mêmes ainsi
que par leurs managers/relais puisqu’il se situe au cœur de métier d’une SSII.
3 .2 . L e s obje ct if s
Mes objectifs :
Enrichir ma formation
Capitaliser de nouvelles technologies
Renforcer mes capacités d’analyse fonctionnelle
Avoir un premier vrai contact projet, avec le formalisme et la rigueur que cela
demande Comprendre le fonctionnement d’une SSII
3.3. L e s co n t r a in t e s
A l’initialisation du projet, il existait certaines contraintes qui pouvaient nuire au bon avancement du
projet. Pour les contourner, il m’a été demandé une certaine autonomie. Ces contraintes étaient
principalement :
La disponibilité des principaux acteurs, en mission en dehors du site de Metz. Une demi-journée
hebdomadaire pour faire le point avec Mr Frossini étaient prévu. Les coordonnées des autres
contacts m’ont été transmises.
Certaines lacunes dans les technologies employées : JSP & XML étaient à
assimiler. Une modélisation UML et Merise était à effectuer.
Le choix des technologies n’était pas libre, et le schéma de la base de données était déjà réalisé.
3.4. L ’o rg a n is a t i o n d u p rojet
On réalise d’abord un premier noyau (PoC), on s’assure qu’il fonctionne et que les liens entre les
différents modules fonctionnent, puis on réalise un prototype qui contient quelques fonctionnalités du
projet futur.
Une fois ce prototype validé et fonctionnel, on étoffe le prototype jusqu'à ce qu’il représente
l’application réalisée et on procède à son intégration.
C’est une méthode prémisse de la conception. Elle consiste à réaliser des successions d’écran et à les
présenter au fur et à mesure, puis les faire valider.
La méthode choisie en concertation est la méthode projet agile, très proche de ce qu’il se fait
aujourd’hui. Le projet aura une structure particulière :
3.5. T e c h n o l o g i e s e t m é t h o d e s e m p l o y é e s
Architecture3-tiersutilisée
3.6. P la n n in g p ré vision n e l
Un planning prévisionnel a été établi en initialisation de projet. Nous avons essayé de s’y
conformer le maximum qu’il était possible mais nous avons dut le remanier pour pallier aux
disponibilités des intervenant, s’adapter aux nouveaux besoin intervenus en cours de développement,
s’arranger par rapports aux périodes de vacances des intervenants, …
Chef de projet :
Philippe Frossini
Architecte :
Patrick Meyer
Chef de projet :
Yannick Stachnik
Strasbourg
Développeur : Développeur :
Développeur :
Romain Saracéno Thomas Hertenstein
Paul Clément
Les technologies employées pour ce projet étant pratiquement toutes nouvelles pour moi, il a fallut
procéder par étapes avant de me lancer pleinement dans la réalisation.
Les différentes étapes étaient :
l’étude des documents et de la base déjà produits
l’apprentissage et la mise à niveau dans les technologies
l’analyse et la définition d’un prototype
la réalisation du prototype
l’analyse et la définition d’un prototype à paramètre étendu
la réalisation du prototype avec paramètre étendu
mise en place de tests unitaires
le recettage
4.1. P r e m i è r e é t a p e : é t u d e d e s d o c u m e n t s e t d e la b a s e e xista n t s
A mon arrivée, le projet était déjà entamé. Deux collaborateurs avaient déjà dégrossi l’analyse avec
la création d’un premier MCD, sous format PowerPoint, ainsi qu’avec la création de la base
correspondante sous MySQL. Ils avaient également généré le dictionnaire de données correspondant et
crée une TODO List.
J’ai donc étudié le MCD, nous en avons discuté avec Mr. Frossini et cela m’a permit d’avoir un premier
solide visu sur l’organisation d’une SSII.
De plus, les deux collaborateurs avaient commencé à créer l’architecture du projet sous Eclipse 3.3.0, ce
qui m’a été d’une très grande aide, car je ne savais pas du tout comment faire cela. Ils ont utilisé le
générateur de SEAM : seam-gen. Ils avaient également configuré Ant pour le déploiement et automatiser
les « builds », et commencé à se faire la main sur le Framework Seam via la redéfinition d’un système
d’identification, pourtant très simplifié et automatisé par SEAM.
Quelques documents Excel m’ont été fournis. Le but de l’application étant de les remplacer totalement,
il fallait que j’étudie précisément leur utilité, la façon dont ils étaient remplis, par qui.
4.2. L ’a p p r e n t i s sa g e et la m i s e à n i ve a u d a n s le s t e ch n o l o g i e s
Les deux premières semaines furent donc consacrées à la mise a niveau technique, la lecture de
tutoriels (la plupart en anglais), la compréhension des notions de persistance (Hibernate), de « Bean »,
de couche métier, service, de modèle, de la façon dont est implémenté le MVC sous Seam, des
annotations Java 5.0, de la compréhension des librairies graphique utilisées (Facelets, RichFaces), de
l’utilisation d’une librairie pour faire de l’Ajax (Ajax4JSF), des « expression language » (E.L.).
Autrement dit, ces deux premières semaines furent très dense en informations.
Je me suis fait la main sur un premier module SCRUD (Search, Create, Read, Update, Delete),
qui permettait donc de chercher des données dans la base de données, d’en insérer, modifier,
supprimer, et bien entendu, lire.
4 .3 . A n a l y s e e t déf in it ion d ’ u n p r o t o t yp e
Nous avons décidé que le prototype à périmètre réduit serait centré autour du collaborateur.
Cela représente bien Sopra Group qui est une entreprise qui place le collaborateur au centre de son
activité.
Un collaborateur possède un C.V. certifié Sopra Group, sur lequel figurent :
Ses informations générales :
Prénom, Nom
Adresse électronique professionnelle, téléphone professionnel
Site et agence d’appartenance
Nombres d’années d’expérience pré-Sopra
Date d’embauche
Les écoles qu’il a fréquentées
Son parcours :
Les filières suivies par le passé ou actuellement
La filière que le collaborateur souhaiterait
suivre
Ses compétences métier :
Gestion bancaire
Gestion de production
Gestion de stocks
Comptabilité
Etc.
Ses compétences fonctionnelles :
Industrie
Grande distribution
Services
Etc.
Ses compétences techniques :
J2EE, Java 5.0
Technologies .NET
Mainframes
Etc.
Ses formations (non développé durant le stage, faute de temps)
Ses missions (Client, Mission, Dates)
Il fallait également qu’une technologie réponde à certains critères. En effet une technologie devait être
rattaché à :
Une catégorie de technologie :
Langage de programmation
ERP (enterprise ressource planning)
Progiciel
Système d’exploitation
Etc.
Un éditeur ou une communauté
Une ou plusieurs offres (Sopra Group classes ses projets services et conseil par offre) :
AXAPTA
BI (business intelligence)
OUTSOURCING X-
NET
Etc.
Une version
Chaque offre possède un responsable par agence. Les responsables d’offre doivent pouvoir administrer
les référentiels d’offres, d’éditeurs de technologies, de catégorise de technologies et de technologies
tout court.
4 .4 . L a ré a lisa t io n d u p r o t o t y p e à p a r a m è t r e s re st re int s
De plus, une des spécificités des JSF (et des JSP) c’est que la navigation est entièrement réalisée grâce
aux servlet. On ne peut donc jamais passer directement une adresse sur son navigateur pour accéder à
une page.
Un principe qu’il fallu que je respecte est celui de la non-suppression en base de données. Lorsqu’un
utilisateur non administrateur supprime une données, celle-ci est désactivée. En effet, un booléen indique
si l’enregistrement est actif dans chaque table de la base. De plus, on garde une référence de la dernière
action fait sur un enregistrement en sauvegardant le matricule du collaborateur ayant fait la
modification, et la date. Par souci de lisibilité, sur le MPD, l’association entre les tables et la table
Personne (en réalité Connection, mais simplifions) n’apparait pas.
4 .5 . L ’ a n a l y s e e t la définition d ’ u n p r o t o t yp e à p a r a m è t r e é t e n d u
Comme dit auparavant, nous nous sommes rendu compte, après discussion avec des collaborateurs
ayant un point de vue plus commercial de l’outil qu’il n’y avait pas de valeur ajoutée directe, et donc
que l’outil ne serait surement pas maintenu. Nous avons donc décidé d’ajouter au prototype un
module de gestion qui est central au cœur de métier de l’entreprise, la gestion des missions des
collaborateurs.
De façon simplifiée, un collaborateur effectue des missions d’assistance technique (AT), ou d’assistance
à maitrise d’ouvrage (AO). Les missions AT sont en interne chez le client, dans une équipe du client
avec un chef de projet du client. Les missions AO sont en interne chez le client dans une équipe Sopra
Group, avec un chef de projet Sopra Group. Dans une mission AO, appelée plus communément
mission au forfait, Sopra Group gère le projet de A à Z, et rentre dans une vraie problématique projet
avec les délais, les coups et les risque que cela comporte.
Entre deux missions, un collaborateur ne rapporte aucun chiffre d’affaire à Sopra Group. C’est même le
contraire puisque Sopra Group paie le salaire et les différentes charges du collaborateur. Ainsi, il est
primordial pour Sopra Group que les collaborateurs passent le moins possible de temps en intermission.
C’est la qu’interviennent les ingénieurs commerciaux. Ils sont chargés de démarcher les clients afin de
trouver des missions pour les collaborateurs. Ils répondent aux appels d’offre, montent des dossiers afin
d’assurer contrats et partenariat avec les clients. Les propositions commerciales sont donc faites par ces
mêmes ingénieurs commerciaux aux clients pour des profils particuliers.
C’est la qu’intervient la première partie du projet. Les C.V. auparavant sous format Excel, peu pratique
à manipuler, possédant des informations non capitalisées et mutualisées, sont gérés par l’outil.
Un commercial peut donc émettre des propositions commerciales pour un collaborateur. Si une
proposition commerciale abouti, on peut affecter une mission à un collaborateur et définir sa date de
disponibilité.
Un tableau, utilisé en réunion, liste les collaborateurs disponibles pour les prochains mois, avec leur date
de disponibilité, leur nom, éventuellement un commentaire, et leur taux de disponibilité pour la date
indiqué (un collaborateur peut être affecté à mi-temps sur une mission par exemple).
Un collaborateur possède également un état. En fin de mission, son état peut être :
En disponibilité « ferme », c'est-à-dire qu’il y’a de grande chance que la mission ne soit pas
renouvelée et que le manager soit à la recherche d’une mission pour le collaborateur
Manager à consulter
Forte probabilité de prolongation
Techniquement parlant, cette partie de la programmation fût sans aucun doute la plus
intéressante. En effet, à cette étape du développement, le Framework commençait à être plutôt bien
maitrisé dans la plupart des solutions qu’il apportait. J’ai remarqué que mon code des premiers
modules n’était pas optimisé, plutôt compliqué car il existait des solutions plus simples que j’ai
découvert par la suite. Malheureusement, le temps m’ayant fait défaut, je n’ai pas eut le temps de
revenir sur le code produit en début de stage. Comme m’a dit un collaborateur, « on n’est jamais content
de son code ».
C’est également dans ce module que j’ai été le plus assisté, notamment au niveau de la conception des
modèles de données, du maquettage, de la réflexion sur les fonctionnalités.
Par exemple, nous avions dans un premier temps décidé de gérer les dates d’un point de vue applicatif. Si
la date de fin de mission d’un collaborateur était le jour n° X, sa date de disponibilité serait le jour n°
X+1, sauf si le jour X est un week-end. Nous nous sommes dans un deuxième temps rendu compte qu’il
fallait gérer les jours fériés, et puis aussi les congés et RTT des collaborateurs. Bref, après en avoir discuté
avec les ingénieurs commerciaux et en interne dans l’équipe, nous avons adopté la solution de gérer la
date de disponibilité du coté humain, pour permettre une certaine souplesse.
Accompagné de Mr. Yannick Stachnick, nous avons, par téléphone, monté une première
maquette. L’aspect du tableau et des différents écrans devait se rapprocher au maximum de l’existant
afin de faciliter son utilisation par les collaborateurs concernés. Une fois la maquette validée, la
programmation du tableau fut une étape compliquée niveau technique. Il fallut tout d’abord trouver le
modèle d’une ligne du tableau. J’ai opté de représenter chaque ligne du tableau par un objet de type
Tab_DispoRow ayant pour attributs
Un site (par exemple Metz)
Six listes de type Personne (List<Personne>) représentant chacune la liste des personne du site
concerné dont la date de disponibilité tombe un mois donné. Les six listes représentent les 6
prochains mois.
Il résulte donc un tableau de liste qui doivent générer des liens dynamiques et être rafraichies dès qu’il
y’a une modification.
Un composant de la librairie RichFaces m’a été énormément utile, le tag dataTable.
La deuxième étape de la réalisation est de faire une maquette d’une fiche collaborateur, accessible lors
d’un clic sur un collaborateur présent dans le tableau. Après de nombreuses retouches, la maquette
validée, la réalisation se fait, avec une grosse proportion d’Ajax, afin de rendre la manipulation la
plus simple et agréable possible.
La dernière étape était de gérer la création de clients, de missions et de faire des propositions pour les
collaborateurs. Pas de grosse difficultés la dedans.
4.7. M i s e e n p l a c e d e t e st s u n it a ire s
Afin de tester les différents modules de l’application, des tests unitaires ont été fait après
le développement de chaque module. Etant seul pour la réalisation, les tests ont été réalisés et
vérifiés seulement par moi-même (malheureusement). De plus, en fin de réalisation, des tests ont été
fait sur une base de développement, et une base de production a été conçue.
Du fait que j’étais seul, je suis persuadé qu’il reste un certain nombre de bugs à éradiquer mais j’espère
ce nombre très limité, ce qui prouverait une certaine rigueur dans mes tests. J’ai essayé de me mettre
dans la peau de l’utilisateur le plus naïf possible, cliquant n’ importe où, n’ayant aucune logique dans la
suite de ses actions.
4.8. R e c e t t a g e
Le recettage n’a pas pu être effectué, du fait que mon stage finissant début août tombait en même
temps que les vacances de mon tuteur. J’indique donc qu’il aurait été au programme de faire une étape
de recettage si le planning l’avait permit.
5. PROGRAMMES REALISES
Dans cette partie, je vais exposer quelques captures d’écrans qui vont permettre de comprendre
le « look and feel » de l’application.
Voici l’écran de connexion. Le contrôle habituel des champs et fait. Si les identifiants sont
correct, l’utilisateur est redirigé vers la page d’accueil de l’application. Dans le cas contraire, un message
d’erreur est affiché et il faut saisir les identifiants de nouveau.
Cette page est affichée en cas de succès de connexion. Cet écran respecte la charte Sopra Group. Le
menu sur la gauche change selon les droits de l’utilisateur. Dans notre cas, l’utilisateur connecté est un
simple collaborateur. Il a accès uniquement à l’option de déconnexion, à l’affichage de l’accueil, et à
l’accès à son profil.
L’utilisateur peut également changer son mot de passe via le lien en haut à droite.
Voici par exemple les menus pour les rôles de directeur d’agence, d’administrateur de l’application et
de responsable d’offre.
Nous allons découvrir à quoi mènent ces différents menus et comment sont attribués les droits par la suite.
« Mon Profil »
Ce module permet à un collaborateur d’éditer son profil. Ce profil permettra de générer directement le
C.V. du collaborateur sous différents formats, comme le .doc ou le .pdf (développement prévu en 2008).
L’utilisateur doit renseigner différents informations comme son nom, prénom, adresse
électronique, téléphone, les différentes écoles qu’il a fréquenté, son agence de rattachement, son site de
rattachement, les années d’expérience avant Sopra Group, sa date d’embauche, son manager et son relai
agence.
On remarque qu’il y’a d’autres onglets qui permettent d’ajouter des compétences métier, fonctionnelles,
techniques, de choisir sa filière souhaitée, de renseigner ses filières précédentes, de consulter ses rôles
au sein de l’application, ses formations et ses missions.
« Filières »
« Missions »
Bien entendu, toutes les technologies, rôles, filières, en gros tous les référentiels doivent être modifiable
via l’application et donc via les menus « Mes référentiels » et « Gestion des référentiels ».
Par exemple, pour le référentiel technologique :
Un utilisateur qui est soit manager, soit relai, soit directeur d’agence à accès aux profils des
collaborateurs qu’il gère via le menu « Mes collaborateurs » :
« Mes Collaborateurs »
« Mon Collaborateur »
Un peu à la manière du profil, l’utilisateur peut modifier les données du collaborateur pour que son
profil soit le plus conforme possible.
Il possède quelques actions de plus comme par exemple définir ses missions :
« Mission »
Et enfin, quelques captures d’écrans du module de gestion de planning et d’attribution des missions :
En colonne : les mois, en ligne : les sites. Le numéro est la date de disponibilité dans le mois, le nom de
la personne est un lien qui dirige vers la fiche du collaborateur (écran suivant) et la case de couleur signifie
:
DF : Dispo. Ferme. Collaborateur à placer d’urgence.
MAC : Manager à consulter. A placer rapidement.
FPP : Forte Probabilité de Prolongation. Pas de grand risque.
Fiche collaborateur
Apres un clic sur un nom dans le tableau, on atterri sur cette fiche, qui récapitule les informations sur le
collaborateur et qui permet de modifier son statut et de suivre les propositions commerciale le concernant.
6. B I L A N
6.1. B ilan Te c h n iq u e
Tout d’abord, ce stage m’a entièrement formé sur les technologies J2EE. A l’université ne sont
enseignées que les bases de Java. La formation a été autodidacte du fait que les différents
acteurs techniques n’avaient pas de temps à me consacrer, mais répondaient à mes courriels.
J’ai également pu acquérir des notions importantes comme la persistance des données par exemple, et
eu l’occasion, pour la première fois, d’utiliser un Framework et toutes les fonctionnalités qu’il propose.
De plus, la nécessité d’un serveur pour le développement d’une application était également nouveau pour
moi.
De part mes conversations avec les collaborateurs de Sopra Group, j’ai pu remarquer que les profils
J2EE sont énormément appréciés de nos jours, et force est de constater que ce domaine me
plait, la programmation objet était intéressante et agréable, la puissance de java et le mélange des
technologies donne un vrai sens à la conception et à la réalisation. Il est clair que l’enseignement des
technologies seules à l’université limite énormément la programmation. Par exemple, nous n’avions
jamais utilisé de librairie dans aucun projet, lors de mon stage, j’en utilise pas moins d’une quinzaine pour
le projet !
En bref, n’étant pas un mordu de programmation, la thématique d’ « objet » et les notions qu’elle sous-
entend me motivent cependant.
Je trouve dommage que lors de notre formation ne nous soient pas enseignés les technologies
.NET/J2EE de façon professionnelle (il est certain qu’il faut débuter par de la théorie, mais ce que j’ai
fait lors de mon parcours scolaire est loin du professionnel).
Un point positif de notre formation est l’orientation « Base de données ». Je n’ai eu aucun souci avec la
base de données, et je me suis même senti limité par MySQL et son « phpmyadmin ». Nous avions
également abordé l’Ajax de la façon basique. L’utiliser pour mon projet, avec la facilité apportée par
JSF a été un jeu d’enfant.
Un manque ressenti se situe au niveau de la modélisation. UML n’est enseigné qu’en Master 1, j’ai du
me servir de mes bases de DUT. De plus, la démarche intégratrice étant inconnue de Sopra Group, j’ai
du me tourner vers une modélisation Merise plus classique (MCD & MPD).
6.2. Bilan h u m a i n
Il est clair qu’avant mon stage, je ne connaissais absolument pas le monde des SSII. Les sociétés
de service étant la principale source de recrutement des jeunes ingénieurs en informatique, je trouve
dommage que ca ne soit pas plus abordé lors de notre formation. Expliquer comment fonctionne
une SSII en quelques heures nous préparerais bien mieux à mon humble avis.
J’ai donc du me plonger dans le fonctionnement d’une SSII, le sujet de mon stage faisant parti du cœur
de métier des sociétés de service. J’ai également eu la chance de discuter avec d’autre collaborateurs, soit
en les côtoyant à l’agence lors de leurs inter-contrats, soit lors de la pause déjeuné (pour les
collaborateurs en mission chez Cora Informatique qui mangeaient à la cafétéria du Cora-Technopole, et
qui m’accueillaient gentiment à leur table).
J’ai pu suivre la vie d’une SSII de l’intérieur, assisté au rythme des réunions, au travail de fond
des commerciaux pour proposer des missions aux collaborateurs, au travail de recrutement.
Mes connaissances se sont également élargies sur les droits du forfait cadres (droit qui devrait être
enseigné en plus du droit d’un employé par rapport à employeur, et en plus du droit de
l’informatique), sur le fonctionnement d’une équipe projet, sur les possibilités d’évolution au sein d’une
SSII tel Sopra Group.
Un point positif est que la formation MIAGE possède une bonne réputation de ce que j’ai pu en
discuter, qu’elle appuie fortement sur la communication et que cela m’a énormément aidé car je pense et
j’espère que personne n’a à se plaindre de la communication dont j’ai fait preuve lors de mon stage.
Pour finir, n’étant qu’en licence, j’espère trouver une formation plus orientée vers le monde
professionnel lors de mes deux années de master.
Web sites :
Sopra Group,
http://www.sopragroup.com/
JBoss Seam Framework demo,
http://demo.flamingo.ex adel.com/booking/home.seam
API JSF,
http://java.sun.com/javaee/javaserverfaces/1.2 /docs/api/index.html
Hibernate EntityManager,
http://www.hibernate.org/hib_docs/entitymanager/reference/en/html/index.html
API RichFaces & Ajax4JSF,
http://www .jboss.org/file-
access/default/members/jbossrichfa ces/freezone/docs/tlddoc/index.html
Demo RichFaces Components (éléments graphiques) ,
http://livedemo.exadel.com/richfaces-demo/richfaces/dropDownMenu.jsf
Developpez.net, Forum & Cours,
http://www.deve loppez.net/
JExcel librairie pour l’export Excel sous SEAM,
http://www.seamframework.org/Community/ExcelForSeamPreview
RichFaces developer guide,
http://www .jboss.org/file-
access/default/members/jbossrichfaces/f reezone/docs/devguide/en/html/index.html
Jean-Michel DOUDOUX, Cours complet FR JSF,
http://www.jmdoudoux.f r/java/dej/chap053.htm
<body>
<ui:include src="menu.xhtml">
<ui:param name="projectName" value="Agence"/>
</ui:include>
<div class="panelMenu">
<h:graphicImage styleClass="icone" alt="Sopra Group"
url="/img/imgCroisillon.gif"></h:graphicImage>
<ui:include src="panelMenu.xhtml"/>
</div>
<div class="body">
<a4j:outputPanel id="body">
<ui:insert name="body"/>
</a4j:outputPanel>
</div>
<div class="footer">
<h:outputText value="© Sopra Group, 2001-2008" styleClass="footer-left"/>
<h:graphicImage styleClass="icone, footer-right" alt="Sopra Group"
url="/img/imgLogoSopraGroup.gif"></h:graphicImage>
</div>
</body>
</html>
<ui:define name="body">
<rich:panel>
<f:facet name="header">Référentiel Metier - Ajouter</f:facet>
<div class="subbody">
<rich:spacer height="10px" />
<h:form id="add_metier">
<div class="bandeau"><h:outputText value="Ajout d'une
compétence métier : " /></div>
<h:panelGrid id="panelAddRMetier" columns="4" columnClasses="name,
value, value, value">
<h:outputLabel for="libelle_metier" value="Libellé"
/><h:outputLabel value=":" />
<h:inputText id="libelle_metier" value="#{rMetierAA.lib}"
required="true" size="40" >
<f:validateLength maximum="30"/>
</h:inputText>
<h:message for="libelle_metier" styleClass="message" />
</h:panelGrid>
<div class="bandeau"><h:outputText value=" " /></div>
<h:panelGrid id="panelButtonRNiveau" columns="3">
<h:commandButton value="Ajouter"
action="#{rMetierAA.rMetierAdd}" />
<h:outputLabel value=" " />
<h:commandButton value="Annuler"
action="#{menunavig.goSearchRMetier}" immediate="true"/>
</h:panelGrid>
</h:form>
</div>
</rich:panel>
</ui:define>
</ui:composition>
Code de la vue
package com.mydomain.agence.referentiels;
import java.io.Serializable;
import java.sql.Timestamp;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.validator.NotNull;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import com.mydomain.agence.Constants;
@Entity
@Name("rmetier")
@Scope(ScopeType.EVENT)
@Table(name="r_metier")
public class Metier implements Serializable{
private static final long serialVersionUID = 1961639726393704338L;
private int cd_metier;
private String lib_metier;
private String actif;
private String userMaj;
private Timestamp dateMaj;
@NotNull
@Column(name="lib_metier")
public String getLib_metier() {
return lib_metier;
}
public void setLib_metier(String lib_metier) {
this.lib_metier = lib_metier;
}
@NotNull
@Column(name="actif")
public boolean isActif()
{
return this.actif.equals(Constants.STATUT_ACTIF);
}
public void setActif(boolean actif) {
if (actif)
{
this.actif = Constants.STATUT_ACTIF;
}
else
{
this.actif = Constants.STATUT_INACTIF;
}
}
@NotNull
@Column(name="user_maj")
public String getUserMaj() {
return userMaj;
}
public void setUserMaj(String userMaj) {
this.userMaj = userMaj;
}
@NotNull
@Column(name="date_maj")
public Timestamp getDateMaj() {
return dateMaj;
}
public void setDateMaj(Timestamp dateMaj) {
this.dateMaj = dateMaj;
}
}
package com.mydomain.agence.referentielsAction.Metier;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.GregorianCalendar;
import javax.ejb.Remove;
import javax.persistence.EntityManager;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.security.Restrict;
import com.mydomain.agence.individus.Connection;
import com.mydomain.agence.interfaces.RMetierAdding;
import com.mydomain.agence.referentiels.Metier;
import com.sun.xml.internal.ws.developer.Stateful;
@Restrict("#{identity.loggedIn}")
@Stateful
@Name("rMetierAA")
@Scope(ScopeType.SESSION)
public class RMetierAddingAction implements RMetierAdding, Serializable {
private static final long serialVersionUID = 8231940036588997725L;
@In("entityManager") private EntityManager em;
@In(value="#{connect}") private Connection user;
@In(value="#{rMetierSA}") private RMetierSearchingAction rmsa;
private Metier addedMetier;
private String lib;
@Remove @Destroy
public void destroy() {
}
import java.io.IOException;
import java.io.Serializable;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletResponse;
import jxl.*;
import jxl.format.Alignment;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.format.Orientation;
import jxl.format.VerticalAlignment;
import jxl.write.*;
import jxl.write.Number;
import jxl.write.biff.RowsExceededException;
import com.mydomain.agence.individus.Personne;
import com.mydomain.agence.rows.Tab_DispoRow;
@Name("EETD")
@Scope(ScopeType.SESSION)
public class ExtractExcelTD implements Serializable {
private static final long serialVersionUID = 8395966513132871975L;
private WritableWorkbook w;
private WritableSheet s;
private FacesContext context;
this.writeTableau();
this.writeEnTete();
this.close();
} catch (IOException e) {
e.printStackTrace();
} catch (WriteException e) {
e.printStackTrace();
}
}
context = FacesContext.getCurrentInstance();
HttpServletResponse response = (HttpServletResponse)
context.getExternalContext().getResponse();
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=tabDispo-
"+date+".xls");
w = Workbook.createWorkbook(response.getOutputStream());
s = w.createSheet("Tableau des disponibilites", 0);
}
public void writeTableau() throws RowsExceededException, WriteException{
//apparence de la colonne site
WritableFont fontAgence=new WritableFont(WritableFont.ARIAL, 12,
WritableFont.BOLD);
fontAgence.setColour(jxl.format.Colour.AUTOMATIC);
WritableCellFormat fontAgenceFormat = new WritableCellFormat (fontAgence);
fontAgenceFormat.setAlignment(Alignment.CENTRE);
fontAgenceFormat.setOrientation(Orientation.PLUS_90);
fontAgenceFormat.setVerticalAlignment(VerticalAlignment.CENTRE);
fontAgenceFormat.setBackground(jxl.format.Colour.WHITE);
fontAgenceFormat.setBorder(Border.TOP, BorderLineStyle.MEDIUM,
jxl.format.Colour.AUTOMATIC);
fontAgenceFormat.setBorder(Border.RIGHT, BorderLineStyle.THIN,
jxl.format.Colour.AUTOMATIC);
s.setColumnView(1, 5);
//Type de dispo
WritableFont typeDispoCol=new WritableFont(WritableFont.ARIAL, 12,
WritableFont.BOLD);
typeDispoCol.setColour(jxl.format.Colour.WHITE);
WritableCellFormat typeDispoFormat = new WritableCellFormat
(typeDispoCol);
typeDispoFormat.setAlignment(Alignment.CENTRE);
typeDispoFormat.setOrientation(Orientation.PLUS_90);
typeDispoFormat.setVerticalAlignment(VerticalAlignment.CENTRE);
typeDispoFormat.setBackground(jxl.format.Colour.AUTOMATIC);
s.setColumnView(0, 5);
//ligne de transition
WritableCellFormat ligneTransitionFormat = new WritableCellFormat ();
ligneTransitionFormat.setBackground(jxl.format.Colour.BLACK);
ligneTransitionFormat.setBorder(Border.RIGHT, BorderLineStyle.THICK,
jxl.format.Colour.BLACK);
colNoJourFormat2.setBackground(jxl.format.Colour.PALE_BLUE);
CellView colNoJour2=new CellView();
colNoJour2.setSize(256*3);
colNoJour2.setFormat(colNoJourFormat);
//remplissage du tableau
this.row=2;
this.rowD=2;
this.rowMax=2;
this.col=1;
this.colD=1;
/**
* Methode qui comble le tableau avec des cases vide
* @param colNoJourFormat WritableCellFormat : style associé à la colonne
NoJour
* @param colPersonneFormat WritableCellFormat : style associé à la colonne
Personne
* @throws RowsExceededException
* @throws WriteException
*/
public void comblerTableau(WritableCellFormat colNoJourFormat,
WritableCellFormat colPersonneFormat) throws RowsExceededException,
WriteException{
if(this.row-this.rowD != this.max){
for(int x=(this.row-this.rowD); x<this.max; x++){
Label l1=new Label(col, this.rowD+x, "", colNoJourFormat);
s.addCell(l1);
this.col++;
Label l2=new Label(this.col, this.rowD+x, "", colPersonneFormat);
s.addCell(l2);
this.col--;
}
}
}
/**
* Methode qui affiche une colonne pour un mois, et pour un site donné
* @param lp List<Personne> : liste de personne
this.rowMax=this.row;
this.row=this.rowD;
this.col+=2;
Iterator<Personne> i= lp.listIterator();
Personne p;
while(i.hasNext()){
p=(Personne) i.next();
Calendar cal=Calendar.getInstance();
cal.setTime(p.getDate_dispo());
if(firstColumn){
Calendar nowCal=Calendar.getInstance();
if(nowCal.get(Calendar.MONTH)==0 && cal.get(Calendar.MONTH) > 0 &&
cal.get(Calendar.MONTH)<12 && cal.get(Calendar.YEAR)<nowCal.get(Calendar.YEAR)){
Label jour_dispo=new Label(this.col, this.row,
cal.get(Calendar.DATE)+"/"+(cal.get(Calendar.MONTH)+1), colNoJourFormat);
s.addCell(jour_dispo);
} else if(cal.get(Calendar.MONTH)<nowCal.get(Calendar.MONTH)){
Label jour_dispo=new Label(this.col, this.row,
cal.get(Calendar.DATE)+"/"+(cal.get(Calendar.MONTH)+1), colNoJourFormat);
s.addCell(jour_dispo);
} else {
Number jour_dispo=new Number(this.col, this.row,
cal.get(Calendar.DATE), colNoJourFormat);
s.addCell(jour_dispo);
}
} else {
Number jour_dispo=new Number(this.col, this.row,
cal.get(Calendar.DATE), colNoJourFormat);
s.addCell(jour_dispo);
}
this.col++;
String taux="";
if(p.getTaux_affectation()<100){
taux=p.getTaux_affectation()+"% - ";
}
if(p.getCommentaires()==null || p.getCommentaires().compareTo("")==0){
collaborateur=new Label(this.col, this.row, p.getPrenom()+"
"+p.getNom(), colPersonneFormat);
} else collaborateur=new Label(this.col, this.row, p.getPrenom()+"
"+p.getNom() +"\n("+taux+p.getCommentaires()+")", colPersonneFormat);
s.addCell(collaborateur);
col--;
this.row++;
if(this.row>this.rowMax) this.rowMax=this.row;
}
this.comblerTableau(colNoJourFormat, colPersonneFormat);
}
/**
* Methode qui renvoie une sous liste contenant juste les personne d'un type
de dispo.
* @param lp List<Personne> : liste de personne dans laquelle il faut chercher
* @param typeDispo String : Type de dispo à chercher dans la liste
* @return List<Personne> : sous liste contenant juste les personne d'un type
de dispo.
*/
public List<Personne> isolerPersonneTypeDispo(List<Personne> lp, String
typeDispo){
List<Personne> lret=new ArrayList<Personne>();
Iterator<Personne> i=lp.listIterator();
Personne p;
while(i.hasNext()){
p=(Personne) i.next();
if(p.getType_dispo().compareTo(typeDispo)==0) lret.add(p);
}
return lret;
}
/**
* Methode qui affiche chacune des sous table correspondant a un type de dispo
* @param type String : type de la dispo tel qu'il apparait dans l'objet
("DF", "MAC", "FPP")
* @param labelType String : Label de la premiere colonne
* @param ligneTransitionFormat
* @param fontAgenceFormat
* @param colNoJourFormat
* @param colPersonneFormat
* @param typeDispoFormat
* @param ligneTransitionFormat2
* @throws RowsExceededException
* @throws WriteException
*/
public void afficherSousTable(String type, String labelType,
WritableCellFormat ligneTransitionFormat,
WritableCellFormat fontAgenceFormat,
WritableCellFormat colNoJourFormat,
WritableCellFormat colPersonneFormat,
WritableCellFormat fontAgenceFormat2,
WritableCellFormat colNoJourFormat2,
WritableCellFormat colPersonneFormat2,
WritableCellFormat typeDispoFormat,
WritableCellFormat ligneTransitionFormat2) throws
RowsExceededException, WriteException{
Label site;
Label ligneTransition;
Label typedispo;
Iterator<Tab_DispoRow> i;
Tab_DispoRow tdr;
this.rowDTypeDispo=this.rowMax;
i=ltdr.listIterator();
int j=0;
while(i.hasNext()){
this.rowD=this.rowMax;
this.colD=this.col;
this.row=this.rowMax;
ligneTransition=new Label(1, (this.rowMax-1), "",
ligneTransitionFormat);
s.addCell(ligneTransition);
s.mergeCells(1, (this.rowMax-1), 13, (this.rowMax-1));
s.setRowView(this.rowMax-1, 100);
tdr=(Tab_DispoRow) i.next();
if(j%2==0){
site=new Label(this.col, this.row, tdr.getSite().getLib_site(),
fontAgenceFormat);
} else {
site=new Label(this.col, this.row, tdr.getSite().getLib_site(),
fontAgenceFormat2);
}
s.addCell(site);
this.col++;
List<Personne>
lp1=this.isolerPersonneTypeDispo(tdr.getListePersonne1(), type);
List<Personne>
lp2=this.isolerPersonneTypeDispo(tdr.getListePersonne2(), type);
List<Personne>
lp3=this.isolerPersonneTypeDispo(tdr.getListePersonne3(), type);
List<Personne>
lp4=this.isolerPersonneTypeDispo(tdr.getListePersonne4(), type);
List<Personne>
lp5=this.isolerPersonneTypeDispo(tdr.getListePersonne5(), type);
List<Personne>
lp6=this.isolerPersonneTypeDispo(tdr.getListePersonne6(), type);
if(j%2==0){
//premiere colonne
this.col=0;
this.afficherColonne(lp1, colNoJourFormat, colPersonneFormat,
true);
//deuxieme colonne
this.afficherColonne(lp2, colNoJourFormat, colPersonneFormat,
false);
//troisieme colonne
this.afficherColonne(lp3, colNoJourFormat, colPersonneFormat,
false);
//quatrieme colonne
this.afficherColonne(lp4, colNoJourFormat, colPersonneFormat,
false);
//cinquieme colonne
this.afficherColonne(lp5, colNoJourFormat, colPersonneFormat,
false);
//sixieme colonne
this.afficherColonne(lp6, colNoJourFormat, colPersonneFormat,
false);
} else {
//premiere colonne
this.col=0;
this.afficherColonne(lp1, colNoJourFormat2, colPersonneFormat2,
true);
//deuxieme colonne
this.afficherColonne(lp2, colNoJourFormat2, colPersonneFormat2,
false);
//troisieme colonne
this.afficherColonne(lp3, colNoJourFormat2, colPersonneFormat2,
false);
//quatrieme colonne
this.afficherColonne(lp4, colNoJourFormat2, colPersonneFormat2,
false);
//cinquieme colonne
this.afficherColonne(lp5, colNoJourFormat2, colPersonneFormat2,
false);
//sixieme colonne
this.afficherColonne(lp6, colNoJourFormat2, colPersonneFormat2,
false);
}
this.col=this.colD;
this.rowMax=this.rowD+this.max;
s.mergeCells(site.getColumn(), site.getRow(), this.col, (this.rowMax-
1));
this.rowMax++;
this.row++; j+
+;
}
typedispo=new Label(0, this.rowDTypeDispo-1, labelType, typeDispoFormat);
s.addCell(typedispo);
s.mergeCells(0, this.rowDTypeDispo-1, 0, this.rowMax-1);
this.rowMax++;
}
}