View Javadoc
1   /*
2    * Copyright (c) 2002-2016, Mairie de Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.plugins.atelieraba.web;
35  
36  import java.sql.Date;
37  import java.sql.Timestamp;
38  import java.text.Normalizer;
39  import java.text.ParseException;
40  import java.text.SimpleDateFormat;
41  import java.util.ArrayList;
42  import java.util.Collection;
43  import java.util.HashMap;
44  import java.util.List;
45  import java.util.Locale;
46  import java.util.Map;
47  import java.util.regex.Pattern;
48  import java.util.stream.Collectors;
49  
50  import javax.servlet.http.HttpServletRequest;
51  
52  import org.apache.commons.lang.StringUtils;
53  
54  import fr.paris.lutece.plugins.atelieraba.business.Atelier;
55  import fr.paris.lutece.plugins.atelieraba.business.AtelierHome;
56  import fr.paris.lutece.plugins.atelieraba.business.Cours;
57  import fr.paris.lutece.plugins.atelieraba.business.CoursHome;
58  import fr.paris.lutece.plugins.atelieraba.business.EleveArpegeHome;
59  import fr.paris.lutece.plugins.atelieraba.business.Inscrit;
60  import fr.paris.lutece.plugins.atelieraba.business.InscritHome;
61  import fr.paris.lutece.plugins.atelieraba.business.UserInfo;
62  import fr.paris.lutece.plugins.atelieraba.utils.constants.AtelierabaConstants;
63  import fr.paris.lutece.portal.service.datastore.DatastoreService;
64  import fr.paris.lutece.portal.service.i18n.I18nService;
65  import fr.paris.lutece.portal.service.message.SiteMessageException;
66  import fr.paris.lutece.portal.service.plugin.Plugin;
67  import fr.paris.lutece.portal.service.security.LuteceUser;
68  import fr.paris.lutece.portal.service.security.SecurityService;
69  import fr.paris.lutece.portal.service.security.UserNotSignedException;
70  import fr.paris.lutece.portal.service.util.AppException;
71  import fr.paris.lutece.portal.service.util.AppPropertiesService;
72  import fr.paris.lutece.portal.service.workflow.WorkflowService;
73  import fr.paris.lutece.portal.util.mvc.commons.annotations.Action;
74  import fr.paris.lutece.portal.util.mvc.commons.annotations.View;
75  import fr.paris.lutece.portal.util.mvc.utils.MVCMessage;
76  import fr.paris.lutece.portal.util.mvc.utils.MVCUtils;
77  import fr.paris.lutece.portal.util.mvc.xpage.MVCApplication;
78  import fr.paris.lutece.portal.util.mvc.xpage.annotations.Controller;
79  import fr.paris.lutece.portal.web.xpages.XPage;
80  import fr.paris.lutece.util.ErrorMessage;
81  
82  /**
83   * Cette classe permet de s'inscrire aux cours
84   */
85  @Controller( xpageName = "formulaire", pageTitleI18nKey = "atelieraba.xpage.atelieraba.pageTitle", pagePathI18nKey = "atelieraba.xpage.atelieraba.pagePathLabel" )
86  public class FormulaireXPage extends MVCApplication
87  {
88      private static final long    serialVersionUID                    = 593672657000475604L;
89  
90      // Templates
91      private static final String  TEMPLATE_START                      = "/skin/plugins/atelieraba/start.html";
92      private static final String  TEMPLATE_ETAPES                     = "/skin/plugins/atelieraba/etapes.html";
93      private static final String  TEMPLATE_CONSULTATION               = "/skin/plugins/atelieraba/consultation.html";
94  
95      // the following have no path information because they are included by TEMPLATE_ETAPES
96      private static final String  TEMPLATE_ATELIER                    = "atelier.html";
97      private static final String  TEMPLATE_INFORMATIONS               = "informations.html";
98      private static final String  TEMPLATE_CONTACT                    = "contact.html";
99      private static final String  TEMPLATE_QUESTIONNAIRE              = "questionnaire.html";
100     private static final String  TEMPLATE_RECAP                      = "recap.html";
101     private static final String  TEMPLATE_CONFIRM                    = "confirm.html";
102 
103     // Views
104     private static final String  VIEW_START                          = "start";
105     private static final String  VIEW_ATELIER                        = "atelier";
106     private static final String  VIEW_INFORMATIONS                   = "informations";
107     private static final String  VIEW_CONTACT                        = "contact";
108     private static final String  VIEW_QUESTIONNAIRE                  = "questionnaire";
109     private static final String  VIEW_RECAP                          = "recap";
110     private static final String  VIEW_CONFIRM                        = "confirm";
111     private static final String  VIEW_CONSULTATION                   = "consultation";
112 
113     // Actions
114     private static final String  ACTION_START                        = "start";
115     private static final String  ACTION_ATELIER                      = "atelier";
116     private static final String  ACTION_INFORMATIONS                 = "informations";
117     private static final String  ACTION_CONTACT                      = "contact";
118     private static final String  ACTION_QUESTIONNAIRE                = "questionnaire";
119     private static final String  ACTION_RECAP                        = "recap";
120 
121     // Markers
122     private static final String  MARK_MONCOMPTE_ACTIVE               = "moncompte_active";
123     private static final String  MARK_MONCOMPTE                      = "moncompte";
124     private static final String  MARK_MONCOMPTE_EMAIL                = "moncompte_email";
125     private static final String  MARK_ERROR_FIELDS                   = "field_errors";
126     private static final String  MARK_3975                           = "is3975";
127     private static final String  MARK_STEPS_INDEX                    = "cur_etape_index";
128     private static final String  MARK_STEPS_CONTENT                  = "cur_etape_content";
129     private static final String  MARK_ATELIER_NUMBER                 = "numero_atelier";
130     private static final String  MARK_ATELIER_PRECEDENT              = "atelier_precedent";
131     private static final String  MARK_SKIP_CHOICE                    = "skip_choice";
132     private static final String  MARK_COURS_TREE                     = "cours_tree";
133     private static final String  MARK_ATELIER_LIST                   = "atelier_list";
134     private static final String  MARK_RATIO_DISPONIBILITE_LIST       = "ratio";
135     private static final String  MARK_CHOIX_DISCIPLINE               = "discipline";
136     private static final String  MARK_CHOIX_ATELIER                  = "atelier";
137     private static final String  MARK_CHOIX_CRENEAU                  = "creneau";
138     private static final String  MARK_ID_COURS                       = "id_cours";
139     private static final String  MARK_CANDIDAT_NOM                   = "nom";
140     private static final String  MARK_CANDIDAT_PRENOM                = "prenom";
141     private static final String  MARK_CANDIDAT_NAISSANCE             = "naissance";
142     private static final String  MARK_CANDIDAT_ADRESSE               = "adresse";
143     private static final String  MARK_CANDIDAT_DOUBLON               = "candidat_doublon";
144     private static final String  MARK_CONTACT_NOM                    = "contact_nom";
145     private static final String  MARK_CONTACT_PRENOM                 = "contact_prenom";
146     private static final String  MARK_CONTACT_EMAIL                  = "contact_email";
147     private static final String  MARK_CONTACT_TELEPHONE              = "contact_telephone";
148     private static final String  MARK_DECOUVERTE_LIST                = "decouverte_list";
149     private static final String  MARK_MOTIVATION_LIST                = "motivation_list";
150     private static final String  MARK_DEMARCHE_LIST                  = "demarche_list";
151     private static final String  MARK_DECOUVERTE                     = "decouverte";
152     private static final String  MARK_MOTIVATION                     = "motivation";
153     private static final String  MARK_DEMARCHE                       = "demarche";
154     private static final String  MARK_CANDIDATURE_LIST               = "candidature_list";
155 
156     // Parameters
157     private static final String  PARAMETER_ACCEPT_TOS                = "accept_tos";
158     private static final String  PARAMETER_3975                      = "is3975";
159     private static final String  PARAMETER_ID_INSCRIT                = "id_inscrit";
160     private static final String  PARAMETER_ATELIER_NUMBER            = "numero_atelier";
161     private static final String  PARAMETER_SKIP_CHOICE               = "sauter_choix";
162     private static final int     NUMBER_OF_CHOICES                   = 2;
163     private static final String  PARAMETER_CHOIX_DISCIPLINE          = "discipline";
164     private static final String  PARAMETER_CHOIX_ATELIER             = "atelier";
165     private static final String  PARAMETER_CHOIX_CRENEAU             = "creneau";
166     private static final String  PARAMETER_ID_COURS                  = "id_cours";
167     private static final String  PARAMETER_CANDIDAT_NOM              = "nom";
168     private static final String  PARAMETER_CANDIDAT_PRENOM           = "prenom";
169     private static final String  PARAMETER_CANDIDAT_NAISSANCE        = "naissance";
170     private static final String  PARAMETER_CANDIDAT_ADRESSE          = "adresse";
171     private static final String  PARAMETER_CONTACT_NOM               = "contact_nom";
172     private static final String  PARAMETER_CONTACT_PRENOM            = "contact_prenom";
173     private static final String  PARAMETER_CONTACT_EMAIL             = "contact_email";
174     private static final String  PARAMETER_CONTACT_TELEPHONE         = "contact_telephone";
175     private static final String  PARAMETER_DECOUVERTE_LIST           = "sitelabels.site_property.formulaire.inscription.section5.questionnaire.liste1";
176     private static final String  PARAMETER_MOTIVATION_LIST           = "sitelabels.site_property.formulaire.inscription.section5.questionnaire.liste2";
177     private static final String  PARAMETER_DEMARCHE_LIST             = "sitelabels.site_property.formulaire.inscription.section5.questionnaire.liste3";
178     private static final String  PARAMETER_DECOUVERTE                = "decouverte";
179     private static final String  PARAMETER_MOTIVATION                = "motivation";
180     private static final String  PARAMETER_DEMARCHE                  = "demarche";
181     private static final String  PARAMETER_ERREUR_QUESTIONNAIRE      = "erreur_questionnaire";
182 
183     // Workflow Properties
184     private static final int     PROPERTY_ID_WORKFLOW_1              = AppPropertiesService.getPropertyInt( AtelierabaConstants.PROPERTY_WORKFLOW_ID,
185             AtelierabaConstants.PROPERTY_ID_WORKFLOW_ATELIER_1 );
186     private static final int     PROPERTY_ID_WORKFLOW_2              = AppPropertiesService.getPropertyInt( AtelierabaConstants.PROPERTY_WORKFLOW_ID,
187             AtelierabaConstants.PROPERTY_ID_WORKFLOW_ATELIER_2 );
188 
189     // Pattern
190     private static final Pattern whitespace_sanitize_pattern         = Pattern.compile( " +" );
191     private static final Pattern phonenumber_sanitize_pattern        = Pattern.compile( "[^0-9|\\+]" );
192     private static final Pattern phonenumber_plus_sanitize_pattern   = Pattern.compile( "^(00)" );
193     private static final Pattern phonenumber_french_sanitize_pattern = Pattern.compile( "^(\\+33)" );
194 
195     // Form steps
196     private enum STEPS
197     {
198         ATELIER1_INDEX, ATELIER2_INDEX, INFORMATIONS_INDEX, CONTACT_INDEX, QUESTIONNAIRE_INDEX, RECAP_INDEX, CONFIRM_INDEX;
199     }
200 
201     // Session variables
202     private Inscrit                         _inscrit;
203     private List<Atelier>                   _atelier;
204 
205     // The following are not persisted in the beans but need to be stored in session
206     private List<Boolean>                   _skipChoices;
207     private boolean                         _bAcceptedTOS;
208     private boolean                         _is3975;
209     private UserInfo                        _userInfo;
210     private Map<String, List<ErrorMessage>> _mapErrorFields                   = new HashMap<>( );
211 
212     // Error message
213     private static final String             MESSAGE_ERROR_COMPTE_INACTIVE     = "sitelabels.site_property.message_erreur_compte_inactive.textblock";
214     private static final String             ERROR_COMPTE_INACTIVE             = "atelieraba.error.compteInactive";
215     private static final String             INFO_SESSION_EXPIRED              = "atelieraba.info.sessionExpired";
216     private static final String             KEY_ERROR_TOS                     = "tos";
217     private static final String             INFO_TOS_REQUIRED                 = "atelieraba.error.TOSRequired";
218     private static final String             MESSAGE_CONTROLE_CANDIDAT_DOUBLON = "sitelabels.site_property.formulaire.inscription.section3.erreur.doublon";
219     private static final String             ERROR_CHAMP_NOM                   = "atelieraba.error.champNom";
220     private static final String             ERROR_CHAMP_PRENOM                = "atelieraba.error.champPrenom";
221     private static final String             ERROR_CHAMP_ADRESSE               = "atelieraba.error.champAdresse";
222     private static final String             ERROR_DATE_FORMAT                 = "atelieraba.error.dateFormat";
223     private static final String             ERROR_CHAMP_CONTACT_NOM           = "atelieraba.error.champContactNom";
224     private static final String             ERROR_CHAMP_CONTACT_PRENOM        = "atelieraba.error.champContactPrenom";
225     private static final String             ERROR_CHAMP_CONTACT_EMAIL         = "atelieraba.error.champContactEmail";
226     private static final String             ERROR_CHAMP_CONTACT_TELEPHONE     = "atelieraba.error.champContactTelephone";
227     private static final String             ERROR_DECOUVERTE_NON_COCHE        = "atelieraba.error.decouverteNonCoche";
228     private static final String             ERROR_MOTIVATION_NON_COCHE        = "atelieraba.error.motivationNonCoche";
229     private static final String             ERROR_DEMARCHE_NON_COCHE          = "atelieraba.error.demarcheNonCoche";
230     private static final String             ERROR_UNKNOWN                     = "atelieraba.error.unknown";
231     private static final String             ERROR_MISSING_ATELIER             = "atelieraba.error.missingFirstAtelier";
232     private static final String             ERROR_RESTRICTED                  = "atelieraba.error.restricted";
233 
234     protected UserInfo getUser( HttpServletRequest request, boolean requestAuthent ) throws UserNotSignedException
235     {
236         LuteceUser luteceUser = null;
237 
238         if ( SecurityService.isAuthenticationEnable( ) )
239         {
240             luteceUser = SecurityService.getInstance( ).getRemoteUser( request );
241             String strView = MVCUtils.getView( request );
242 
243             if ( requestAuthent && ( luteceUser == null ) && !_is3975 && ( strView != null ) )
244             {
245                 throw new UserNotSignedException( );
246             }
247         }
248         return new UserInfo( luteceUser );
249     }
250 
251     /**
252      * Before doing the regular view/actions, check that the visitor has a session and has accepted the terms of use
253      *
254      * @param request
255      *            the http request
256      * @param nMode
257      *            the mode
258      * @param plugin
259      *            the plugin
260      * @return the html code of the page depending on the view/action
261      * @throws SiteMessageException
262      *             SiteMessageException
263      * @throws UserNotSignedException
264      *             UserNotSignedException
265      */
266     @Override
267     public XPage getPage( HttpServletRequest request, int nMode, Plugin plugin ) throws SiteMessageException, UserNotSignedException
268     {
269         Locale locale = getLocale( request );
270         _userInfo = getUser( request, true );
271 
272         if ( !_bAcceptedTOS )
273         {
274             String strAction = MVCUtils.getAction( request );
275             String strView = MVCUtils.getView( request );
276 
277             if ( !ACTION_START.equals( strAction ) && !VIEW_START.equals( strView ) && !VIEW_CONFIRM.equals( strView ) && ( _userInfo.getMonCompte( ) == null ) )
278             {
279                 if ( ( strAction != null ) || ( strView != null ) )
280                 {
281                     addInfo( INFO_SESSION_EXPIRED, locale );
282                     return redirectView( request, VIEW_START );
283                 }
284                 return getTOS( request );
285             }
286         }
287 
288         try
289         {
290             return super.getPage( request, nMode, plugin );
291         } catch ( AppException e )
292         {
293             if ( _inscrit == null )
294             {
295                 addInfo( INFO_SESSION_EXPIRED, locale );
296             }
297             SecurityService.getInstance( ).logoutUser( request );
298             request.getSession( );
299             _userInfo = null;
300             return redirectView( request, VIEW_START );
301         }
302     }
303 
304     /**
305      * The TOS acceptance
306      *
307      * @param request
308      *            The Http Request
309      * @return The html code of the plugin
310      */
311     @View( value = VIEW_START, defaultView = true )
312     public XPage getTOS( HttpServletRequest request )
313     {
314         _is3975 = false;
315         String str3975 = request.getParameter( PARAMETER_3975 );
316 
317         if ( ( str3975 != null ) && PARAMETER_3975.equals( str3975 ) )
318         {
319             _is3975 = true;
320         }
321 
322         if ( ( _userInfo != null ) && ( _userInfo.getMonCompte( ) != null ) && !_userInfo.isUserActivate( ) )
323         {
324             addError( DatastoreService.getDataValue( MESSAGE_ERROR_COMPTE_INACTIVE, I18nService.getLocalizedString( ERROR_COMPTE_INACTIVE, request.getLocale( ) ) ) );
325         }
326 
327         Map<String, Object> model = getModel( );
328         model.put( MARK_3975, _is3975 );
329         model.put( MARK_MONCOMPTE, _userInfo );
330         if ( ( _userInfo != null ) && ( _userInfo.getMonCompte( ) != null ) )
331         {
332             if ( _userInfo.isUserActivate( ) )
333             {
334                 model.put( MARK_MONCOMPTE_ACTIVE, "true" );
335                 List<Inscrit> candidatures = InscritHome.findByGuid( _userInfo.getGuid( ) );
336                 List<Map<String, Object>> apercuCandidatures = new ArrayList<>( );
337                 for ( Inscrit candidature : candidatures )
338                 {
339                     Map<String, Object> apercuCandidature = new HashMap<>( );
340                     apercuCandidature.put( "inscrit", candidature );
341                     Atelier premierAtelier = AtelierHome.findByInscrit( candidature.getId( ) ).get( 0 );
342                     apercuCandidature.put( "premier_atelier", CoursHome.findByPrimaryKey( premierAtelier.getFkIdCours( ) ) );
343                     apercuCandidatures.add( apercuCandidature );
344                 }
345                 model.put( MARK_CANDIDATURE_LIST, apercuCandidatures );
346             }
347             model.put( MARK_MONCOMPTE_EMAIL, _userInfo.getEmail( ) );
348         }
349 
350         return getXPage( TEMPLATE_START, request.getLocale( ), model );
351     }
352 
353     /**
354      * Process the TOS of Use acceptance
355      *
356      * @param request
357      *            The Http Request
358      * @return The Jsp URL of the process result
359      */
360     @Action( ACTION_START )
361     public XPage doCreateInscrit( HttpServletRequest request )
362     {
363         String str3975 = request.getParameter( PARAMETER_3975 );
364         if ( ( str3975 != null ) && PARAMETER_3975.equals( str3975 ) )
365         {
366             _is3975 = true;
367         }
368 
369         if ( !"y".equals( request.getParameter( PARAMETER_ACCEPT_TOS ) ) )
370         {
371             addCustomError( KEY_ERROR_TOS, INFO_TOS_REQUIRED, getLocale( request ) );
372             if ( _is3975 )
373             {
374                 Map<String, String> mapParameter = new HashMap<>( );
375                 mapParameter.put( PARAMETER_3975, PARAMETER_3975 );
376                 return redirect( request, VIEW_START, mapParameter );
377             }
378             return redirectView( request, VIEW_START );
379         }
380 
381         _inscrit = new Inscrit( );
382         _atelier = new ArrayList<>( );
383         _bAcceptedTOS = true;
384         _skipChoices = new ArrayList<>( );
385         // First choice can't be skipped
386         _skipChoices.add( false );
387 
388         return redirectView( request, VIEW_ATELIER );
389     }
390 
391     /**
392      * The Atelier form
393      *
394      * @param request
395      *            The Http Request
396      * @return The html code of the plugin
397      */
398     @View( value = VIEW_ATELIER )
399     public XPage getAtelier( HttpServletRequest request )
400     {
401         int atelierNumber = validateAtelierNumber( request.getParameter( PARAMETER_ATELIER_NUMBER ) );
402         String choixDiscipline = "";
403         String choixAtelier = "";
404         String choixCreneau = "";
405         String choixIdCours = "";
406 
407         String skipChoice = "n";
408         if ( atelierNumber < _skipChoices.size( ) )
409         {
410             skipChoice = _skipChoices.get( atelierNumber ) ? "y" : "n";
411         }
412 
413         Atelier atelier = null;
414         if ( atelierNumber < _atelier.size( ) )
415         {
416             atelier = _atelier.get( atelierNumber );
417             Cours cours = CoursHome.findByPrimaryKey( atelier.getFkIdCours( ) );
418             choixDiscipline = cours.getDiscipline( );
419             choixAtelier = cours.getTitreAtelier( );
420             choixCreneau = cours.getCreneau( );
421             choixIdCours = Integer.toString( cours.getId( ) );
422         }
423 
424         Cours previousChoiceCours = null;
425         if ( ( atelierNumber > 0 ) && ( ( atelierNumber - 1 ) < _atelier.size( ) ) )
426         {
427             previousChoiceCours = CoursHome.findByPrimaryKey( _atelier.get( atelierNumber - 1 ).getFkIdCours( ) );
428         }
429 
430         Collection<Cours> coursList = CoursHome.getCourssList( );
431         Map<String, Map<String, List<Cours>>> coursMap = coursList.stream( ).collect( Collectors.groupingBy( c -> c.getDiscipline( ), Collectors.groupingBy( c -> c.getTitreAtelier( ) ) ) );
432         Map<Integer, Integer> placesVivantesMap = CoursHome.getPlacesVivantesList( );
433         Map<String, String> disponibiliteList = new HashMap<>( );
434         for ( Cours cours : coursList )
435         {
436             int idCours = cours.getId( );
437             String id = Integer.toString( idCours );
438             int placesVivantes = placesVivantesMap.get( idCours );
439             int placesDisponibles = cours.getPlacesDisponibles( );
440             int placesListeAttente = cours.getPlacesListeAttente( );
441 
442             String ratio = "close";
443             if ( placesVivantes < placesDisponibles )
444             {
445                 ratio = "open";
446             } else if ( placesVivantes < ( placesDisponibles + placesListeAttente ) )
447             {
448                 ratio = "wait";
449             }
450             disponibiliteList.put( id, ratio );
451         }
452 
453         Map<String, Object> model = getModel( );
454         model.put( MARK_ATELIER_NUMBER, atelierNumber );
455         model.put( MARK_COURS_TREE, coursMap );
456         model.put( MARK_RATIO_DISPONIBILITE_LIST, disponibiliteList );
457         model.put( MARK_CHOIX_DISCIPLINE, choixDiscipline );
458         model.put( MARK_CHOIX_ATELIER, choixAtelier );
459         model.put( MARK_CHOIX_CRENEAU, choixCreneau );
460         model.put( MARK_ID_COURS, choixIdCours );
461         if ( previousChoiceCours != null )
462         {
463             model.put( MARK_ATELIER_PRECEDENT, previousChoiceCours.getId( ) );
464         }
465         model.put( MARK_3975, _is3975 );
466         model.put( MARK_SKIP_CHOICE, skipChoice );
467         model.put( MARK_STEPS_INDEX, STEPS.ATELIER1_INDEX.ordinal( ) + atelierNumber );
468         model.put( MARK_STEPS_CONTENT, TEMPLATE_ATELIER );
469 
470         return getXPage( TEMPLATE_ETAPES, request.getLocale( ), model );
471     }
472 
473     /**
474      * Process the Atelier Form
475      *
476      * @param request
477      *            The Http Request
478      * @return The Jsp URL of the process result
479      */
480     @Action( ACTION_ATELIER )
481     public XPage doAtelier( HttpServletRequest request )
482     {
483         String choixDiscipline = request.getParameter( PARAMETER_CHOIX_DISCIPLINE );
484         String choixAtelier = request.getParameter( PARAMETER_CHOIX_ATELIER );
485         String choixCreneau = request.getParameter( PARAMETER_CHOIX_CRENEAU );
486         String choixIdCours = request.getParameter( PARAMETER_ID_COURS );
487         int atelierNumber = validateAtelierNumber( request.getParameter( PARAMETER_ATELIER_NUMBER ) );
488         boolean bSkipChoix = ( atelierNumber > 0 ) && "y".equals( request.getParameter( PARAMETER_SKIP_CHOICE ) );
489 
490         if ( atelierNumber < _skipChoices.size( ) )
491         {
492             _skipChoices.set( atelierNumber, bSkipChoix );
493         } else
494         {
495             _skipChoices.add( bSkipChoix );
496         }
497 
498         int total = _atelier.size( );
499 
500         for ( int i = atelierNumber; i < total; i++ )
501         {
502             _atelier.remove( _atelier.size( ) - 1 );
503         }
504 
505         if ( !bSkipChoix )
506         {
507             if ( ( choixIdCours == null ) || ( choixDiscipline == null ) || ( choixAtelier == null ) || ( choixCreneau == null ) )
508             {
509                 return redirect( request, VIEW_ATELIER, PARAMETER_ATELIER_NUMBER, atelierNumber );
510             }
511 
512             Cours cours = CoursHome.findByCode( choixDiscipline, choixAtelier, choixCreneau );
513 
514             if ( ( cours == null ) || !( Integer.toString( cours.getId( ) ).equals( choixIdCours ) ) )
515             {
516                 return redirect( request, VIEW_ATELIER, PARAMETER_ATELIER_NUMBER, atelierNumber );
517             }
518 
519             Cours previousChoiceCours = null;
520 
521             if ( ( atelierNumber > 0 ) && ( ( atelierNumber - 1 ) < _atelier.size( ) ) )
522             {
523                 previousChoiceCours = CoursHome.findByPrimaryKey( _atelier.get( atelierNumber - 1 ).getFkIdCours( ) );
524             }
525 
526             if ( ( previousChoiceCours != null ) && ( previousChoiceCours.getId( ) == cours.getId( ) ) )
527             {
528                 return redirect( request, VIEW_ATELIER, PARAMETER_ATELIER_NUMBER, atelierNumber );
529             }
530 
531             Atelier atelier = new Atelier( );
532             atelier.setNumeroAtelier( atelierNumber + 1 );
533             atelier.setFkIdCours( cours.getId( ) );
534             _atelier.add( atelier );
535         }
536 
537         if ( atelierNumber < ( NUMBER_OF_CHOICES - 1 ) )
538         {
539             return redirect( request, VIEW_ATELIER, PARAMETER_ATELIER_NUMBER, atelierNumber + 1 );
540         }
541         return redirectView( request, VIEW_INFORMATIONS );
542     }
543 
544     /**
545      * The Informations form
546      *
547      * @param request
548      *            The Http Request
549      * @return The html code of the plugin
550      */
551     @View( value = VIEW_INFORMATIONS )
552     public XPage getInformations( HttpServletRequest request )
553     {
554         if ( !_is3975 )
555         {
556             if ( ( _inscrit.getNom( ) == null ) || _inscrit.getNom( ).isEmpty( ) )
557             {
558                 _inscrit.setNom( formatMonCompteInfo( _userInfo.getFamilyName( ) ) );
559             }
560             if ( ( _inscrit.getPrenom( ) == null ) || _inscrit.getPrenom( ).isEmpty( ) )
561             {
562                 _inscrit.setPrenom( formatMonCompteInfo( _userInfo.getGivenName( ) ) );
563             }
564             if ( ( _inscrit.getNaissance( ) == null ) )
565             {
566                 _inscrit.setNaissance( formatDateMonCompteInfo( _userInfo.getBirthdate( ) ) );
567             }
568         }
569 
570         Map<String, Object> model = getModel( );
571         model.put( MARK_3975, _is3975 );
572         model.put( MARK_STEPS_INDEX, STEPS.INFORMATIONS_INDEX.ordinal( ) );
573         model.put( MARK_STEPS_CONTENT, TEMPLATE_INFORMATIONS );
574 
575         return getXPage( TEMPLATE_ETAPES, request.getLocale( ), model );
576     }
577 
578     /**
579      * Process the Informations
580      *
581      * @param request
582      *            The Http Request
583      * @return The Jsp URL of the process result
584      * @throws ParseException
585      */
586     @Action( ACTION_INFORMATIONS )
587     public XPage doInformations( HttpServletRequest request ) throws ParseException
588     {
589         Locale locale = getLocale( request );
590         boolean validation = true;
591         String strNom = request.getParameter( PARAMETER_CANDIDAT_NOM );
592         String strPrenom = request.getParameter( PARAMETER_CANDIDAT_PRENOM );
593         String strNaissance = request.getParameter( PARAMETER_CANDIDAT_NAISSANCE );
594         String strAdresse = request.getParameter( PARAMETER_CANDIDAT_ADRESSE );
595 
596         if ( ( strNom != null ) && !strNom.isEmpty( ) )
597         {
598             _inscrit.setNom( sanitizeName( strNom ) );
599         } else
600         {
601             addCustomError( MARK_CANDIDAT_NOM, ERROR_CHAMP_NOM, locale );
602             validation = false;
603         }
604 
605         if ( ( strPrenom != null ) && !strPrenom.isEmpty( ) )
606         {
607             _inscrit.setPrenom( sanitizeName( strPrenom ) );
608         } else
609         {
610             addCustomError( MARK_CANDIDAT_PRENOM, ERROR_CHAMP_PRENOM, locale );
611             validation = false;
612         }
613 
614         if ( ( strAdresse != null ) && !strAdresse.isEmpty( ) )
615         {
616             _inscrit.setAdresseDomicile( sanitizeName( strAdresse ) );
617         } else
618         {
619             addCustomError( MARK_CANDIDAT_ADRESSE, ERROR_CHAMP_ADRESSE, locale );
620             validation = false;
621         }
622 
623         if ( ( ( strNaissance != null ) && !strNaissance.isEmpty( ) ) && Pattern.matches( Inscrit.PATTERN_NAISSANCE, strNaissance ) )
624         {
625             java.util.Date dateNaissance = new SimpleDateFormat( Inscrit.CONVERTER_PATTERN_NAISSANCE ).parse( strNaissance );
626             Date sqlDateNaissance = new Date( dateNaissance.getTime( ) );
627             _inscrit.setNaissance( sqlDateNaissance );
628         } else
629         {
630             addCustomError( MARK_CANDIDAT_NAISSANCE, ERROR_DATE_FORMAT, locale );
631             validation = false;
632         }
633 
634         if ( validation )
635         {
636             int idInscritDoublon = InscritHome.getInscritDoublon( _inscrit );
637             if ( ( idInscritDoublon != 0 ) && ( idInscritDoublon != _inscrit.getId( ) ) )
638             {
639                 addError( MARK_CANDIDAT_DOUBLON, DatastoreService.getDataValue( MESSAGE_CONTROLE_CANDIDAT_DOUBLON, StringUtils.EMPTY ) );
640                 validation = false;
641             }
642         }
643 
644         if ( !validation )
645         {
646             return redirectView( request, VIEW_INFORMATIONS );
647         }
648 
649         return redirectView( request, VIEW_CONTACT );
650     }
651 
652     /**
653      * The Contact form
654      *
655      * @param request
656      *            The Http Request
657      * @return The html code of the plugin
658      */
659     @View( value = VIEW_CONTACT )
660     public XPage getContact( HttpServletRequest request )
661     {
662         if ( !_is3975 )
663         {
664             if ( ( _inscrit.getContactNom( ) == null ) || _inscrit.getContactNom( ).isEmpty( ) )
665             {
666                 _inscrit.setContactNom( formatMonCompteInfo( _userInfo.getFamilyName( ) ) );
667             }
668             if ( ( _inscrit.getContactPrenom( ) == null ) || _inscrit.getContactPrenom( ).isEmpty( ) )
669             {
670                 _inscrit.setContactPrenom( formatMonCompteInfo( _userInfo.getGivenName( ) ) );
671             }
672             if ( ( _inscrit.getContactTelephone( ) == null ) || _inscrit.getContactTelephone( ).isEmpty( ) )
673             {
674                 _inscrit.setContactTelephone( _userInfo.getPhoneNumber( ) );
675             }
676             _inscrit.setContactEmail( _userInfo.getEmail( ) );
677             _inscrit.setGuid( _userInfo.getGuid( ) );
678         }
679 
680         Map<String, Object> model = getModel( );
681         model.put( MARK_3975, _is3975 );
682         model.put( MARK_STEPS_INDEX, STEPS.CONTACT_INDEX.ordinal( ) );
683         model.put( MARK_STEPS_CONTENT, TEMPLATE_CONTACT );
684 
685         return getXPage( TEMPLATE_ETAPES, request.getLocale( ), model );
686     }
687 
688     /**
689      * Process the Contact
690      *
691      * @param request
692      *            The Http Request
693      * @return The Jsp URL of the process result
694      * @throws ParseException
695      */
696     @Action( ACTION_CONTACT )
697     public XPage doContact( HttpServletRequest request )
698     {
699         Locale locale = getLocale( request );
700         boolean validation = true;
701         String strContactNom = request.getParameter( PARAMETER_CONTACT_NOM );
702         String strContactPrenom = request.getParameter( PARAMETER_CONTACT_PRENOM );
703         String strContactEmail = request.getParameter( PARAMETER_CONTACT_EMAIL );
704         String strContactTelephone = request.getParameter( PARAMETER_CONTACT_TELEPHONE );
705 
706         if ( ( strContactNom != null ) && !strContactNom.isEmpty( ) )
707         {
708             _inscrit.setContactNom( sanitizeName( strContactNom ) );
709         } else
710         {
711             addCustomError( MARK_CONTACT_NOM, ERROR_CHAMP_CONTACT_NOM, locale );
712             validation = false;
713         }
714 
715         if ( ( strContactPrenom != null ) && !strContactPrenom.isEmpty( ) )
716         {
717             _inscrit.setContactPrenom( sanitizeName( strContactPrenom ) );
718         } else
719         {
720             addCustomError( MARK_CONTACT_PRENOM, ERROR_CHAMP_CONTACT_PRENOM, locale );
721             validation = false;
722         }
723 
724         if ( ( ( strContactEmail != null ) && !strContactEmail.isEmpty( ) ) && Pattern.matches( Inscrit.PATTERN_EMAIL, strContactEmail ) )
725         {
726             _inscrit.setContactEmail( strContactEmail );
727         } else
728         {
729             addCustomError( MARK_CONTACT_EMAIL, ERROR_CHAMP_CONTACT_EMAIL, locale );
730             validation = false;
731         }
732 
733         if ( ( ( strContactTelephone != null ) && !strContactTelephone.isEmpty( ) ) )
734         {
735             String strSanitizedContactTelephone = sanitizePhoneNumber( strContactTelephone );
736             if ( Pattern.matches( Inscrit.PATTERN_TELEPHONE, strSanitizedContactTelephone ) )
737             {
738                 _inscrit.setContactTelephone( strSanitizedContactTelephone );
739             } else
740             {
741                 addCustomError( MARK_CONTACT_TELEPHONE, ERROR_CHAMP_CONTACT_TELEPHONE, locale );
742                 validation = false;
743             }
744         } else
745         {
746             addCustomError( MARK_CONTACT_TELEPHONE, ERROR_CHAMP_CONTACT_TELEPHONE, locale );
747             validation = false;
748         }
749 
750         if ( !validation )
751         {
752             return redirectView( request, VIEW_CONTACT );
753         }
754 
755         return redirectView( request, VIEW_QUESTIONNAIRE );
756     }
757 
758     /**
759      * The Questionnaire form
760      *
761      * @param request
762      *            The Http Request
763      * @return The html code of the plugin
764      */
765     @View( value = VIEW_QUESTIONNAIRE )
766     public XPage getQuestionnaire( HttpServletRequest request )
767     {
768         Map<String, Object> model = getModel( );
769         String separator = "\\s*;\\s*";
770         List<String> decouverteList = new ArrayList<>( );
771         List<String> motivationList = new ArrayList<>( );
772         List<String> demarcheList = new ArrayList<>( );
773 
774         for ( String decouverte : DatastoreService.getDataValue( PARAMETER_DECOUVERTE_LIST, StringUtils.EMPTY ).split( separator ) )
775         {
776             decouverteList.add( decouverte );
777         }
778         for ( String motivation : DatastoreService.getDataValue( PARAMETER_MOTIVATION_LIST, StringUtils.EMPTY ).split( separator ) )
779         {
780             motivationList.add( motivation );
781         }
782         for ( String demarche : DatastoreService.getDataValue( PARAMETER_DEMARCHE_LIST, StringUtils.EMPTY ).split( separator ) )
783         {
784             demarcheList.add( demarche );
785         }
786 
787         model.put( MARK_DECOUVERTE_LIST, decouverteList );
788         model.put( MARK_MOTIVATION_LIST, motivationList );
789         model.put( MARK_DEMARCHE_LIST, demarcheList );
790         model.put( MARK_3975, _is3975 );
791         model.put( MARK_STEPS_INDEX, STEPS.QUESTIONNAIRE_INDEX.ordinal( ) );
792         model.put( MARK_STEPS_CONTENT, TEMPLATE_QUESTIONNAIRE );
793 
794         return getXPage( TEMPLATE_ETAPES, request.getLocale( ), model );
795     }
796 
797     /**
798      * Process the Questionnaire
799      *
800      * @param request
801      *            The Http Request
802      * @return The Jsp URL of the process result
803      */
804     @Action( ACTION_QUESTIONNAIRE )
805     public XPage doQuestionnaire( HttpServletRequest request )
806     {
807         Locale locale = getLocale( request );
808         boolean validation = true;
809         String strDecouverte = request.getParameter( PARAMETER_DECOUVERTE );
810         String strMotivation = request.getParameter( PARAMETER_MOTIVATION );
811         String strDemarche = request.getParameter( PARAMETER_DEMARCHE );
812 
813         if ( request.getParameter( PARAMETER_ERREUR_QUESTIONNAIRE ) == null )
814         {
815             if ( ( strDecouverte != null ) && !strDecouverte.isEmpty( ) )
816             {
817                 _inscrit.setDecouverte( strDecouverte );
818             } else
819             {
820                 addCustomError( MARK_DECOUVERTE, ERROR_DECOUVERTE_NON_COCHE, locale );
821                 validation = false;
822             }
823 
824             if ( ( strMotivation != null ) && !strMotivation.isEmpty( ) )
825             {
826                 _inscrit.setMotivation( strMotivation );
827             } else
828             {
829                 addCustomError( MARK_MOTIVATION, ERROR_MOTIVATION_NON_COCHE, locale );
830                 validation = false;
831             }
832 
833             if ( ( strDemarche != null ) && !strDemarche.isEmpty( ) )
834             {
835                 _inscrit.setDemarche( strDemarche );
836             } else
837             {
838                 addCustomError( MARK_DEMARCHE, ERROR_DEMARCHE_NON_COCHE, locale );
839                 validation = false;
840             }
841 
842             if ( !validation )
843             {
844                 return redirectView( request, VIEW_QUESTIONNAIRE );
845             }
846         }
847 
848         return redirectView( request, VIEW_RECAP );
849     }
850 
851     /**
852      * The Recap
853      *
854      * @param request
855      *            The Http Request
856      * @return The html code of the plugin
857      */
858     @View( value = VIEW_RECAP )
859     public XPage getRecap( HttpServletRequest request )
860     {
861         Locale locale = getLocale( request );
862         Map<String, Object> model = getModel( );
863 
864         if ( _atelier.isEmpty( ) )
865         {
866             addError( ERROR_MISSING_ATELIER, locale );
867             return redirect( request, VIEW_ATELIER, PARAMETER_ATELIER_NUMBER, 0 );
868         }
869 
870         if ( !fullInscriptionValid( ) )
871         {
872             _bAcceptedTOS = false;
873             addError( ERROR_UNKNOWN, locale );
874             return redirectView( request, VIEW_START );
875         }
876 
877         model.put( MARK_STEPS_INDEX, STEPS.RECAP_INDEX.ordinal( ) );
878         model.put( MARK_STEPS_CONTENT, TEMPLATE_RECAP );
879         model.put( MARK_3975, _is3975 );
880 
881         return getXPage( TEMPLATE_ETAPES, locale, model );
882     }
883 
884     /**
885      * Process the Recap
886      *
887      * @param request
888      *            The Http Request
889      * @return The Jsp URL of the process result
890      */
891     @Action( ACTION_RECAP )
892     public XPage doRecap( HttpServletRequest request )
893     {
894         Locale locale = getLocale( request );
895         try
896         {
897             _userInfo = getUser( request, false );
898         } catch ( UserNotSignedException e )
899         {
900         }
901 
902         if ( !fullInscriptionValid( ) )
903         {
904             _bAcceptedTOS = false;
905             addError( ERROR_UNKNOWN, locale );
906             return redirectView( request, VIEW_START );
907         }
908 
909         String source = _is3975 ? AtelierabaConstants.PROPERTY_SOURCE_3975 : AtelierabaConstants.PROPERTY_SOURCE_WEB;
910         _inscrit.setSource( source );
911 
912         if ( _userInfo != null )
913         {
914             if ( !_is3975 )
915             {
916                 _inscrit.setGuid( _userInfo.getGuid( ) );
917             } else
918             {
919                 _inscrit.setGuid( "-1" );
920             }
921         }
922 
923         if ( _inscrit.getId( ) == 0 )
924         {
925             _inscrit.setDateInscription( new Timestamp( System.currentTimeMillis( ) ) );
926             _inscrit.setProbableArpege( EleveArpegeHome.isEleveArpegeProbable( _inscrit.getContactEmail( ), _inscrit.getContactTelephone( ) ) );
927             _inscrit = InscritHome.create( _inscrit );
928             int idtelier1 = 0;
929 
930             for ( Atelier atelier : _atelier )
931             {
932                 Atelier completeAtelier = new Atelier( );
933                 completeAtelier.setFkIdInscrit( _inscrit.getId( ) );
934                 completeAtelier.setNumeroAtelier( atelier.getNumeroAtelier( ) );
935                 completeAtelier.setFkIdCours( atelier.getFkIdCours( ) );
936                 completeAtelier = AtelierHome.create( completeAtelier );
937 
938                 if ( completeAtelier.getNumeroAtelier( ) == 1 )
939                 {
940                     idtelier1 = completeAtelier.getId( );
941                     WorkflowService.getInstance( ).getState( completeAtelier.getId( ), AtelierabaConstants.WORKFLOW_RESOURCE_TYPE, PROPERTY_ID_WORKFLOW_1, -1 );
942                 } else if ( completeAtelier.getNumeroAtelier( ) == 2 )
943                 {
944                     WorkflowService.getInstance( ).getState( completeAtelier.getId( ), AtelierabaConstants.WORKFLOW_RESOURCE_TYPE, PROPERTY_ID_WORKFLOW_2, -1 );
945                 }
946             }
947 
948             WorkflowService.getInstance( ).doProcessAction( idtelier1, AtelierabaConstants.WORKFLOW_RESOURCE_TYPE, AtelierabaConstants.PROPERTY_ACTION_RENVOYER_AR, -1, request, locale, false );
949             WorkflowService.getInstance( ).executeActionAutomatic( idtelier1, AtelierabaConstants.WORKFLOW_RESOURCE_TYPE, PROPERTY_ID_WORKFLOW_1, -1 );
950 
951         }
952 
953         // Force to restart the form; redirects views and actions to VIEW_START, but still allows to view the confirmation
954         _bAcceptedTOS = false;
955 
956         return redirectView( request, VIEW_CONFIRM );
957     }
958 
959     /**
960      * The final confirmation
961      *
962      * @param request
963      *            The Http Request
964      * @return The html code of the plugin
965      */
966     @View( value = VIEW_CONFIRM )
967     public XPage getConfirm( HttpServletRequest request )
968     {
969         Locale locale = getLocale( request );
970         Map<String, Object> model = getModel( );
971 
972         // We must protect against expired sessions because this view is special cased in getPage
973         if ( !fullInscriptionValid( ) )
974         {
975             addInfo( INFO_SESSION_EXPIRED, locale );
976             return redirectView( request, VIEW_START );
977         }
978 
979         model.put( MARK_3975, _is3975 );
980         model.put( MARK_CONTACT_EMAIL, _inscrit.getContactEmail( ) );
981         model.put( MARK_STEPS_INDEX, STEPS.CONFIRM_INDEX.ordinal( ) );
982         model.put( MARK_STEPS_CONTENT, TEMPLATE_CONFIRM );
983 
984         return getXPage( TEMPLATE_ETAPES, locale, model );
985     }
986 
987     /**
988      * The Consultation Mode
989      *
990      * @param request
991      *            The Http Request
992      * @return The html code of the plugin
993      */
994     @View( value = VIEW_CONSULTATION )
995     public XPage getConsultation( HttpServletRequest request )
996     {
997         int idInscrit = Integer.parseInt( request.getParameter( PARAMETER_ID_INSCRIT ) );
998         boolean rightsToConsult = false;
999 
1000         List<Inscrit> inscrits = InscritHome.findByGuid( _userInfo.getGuid( ) );
1001         for ( Inscrit inscrit : inscrits )
1002         {
1003             if ( inscrit.getId( ) == idInscrit )
1004             {
1005                 _inscrit = inscrit;
1006                 rightsToConsult = true;
1007             }
1008         }
1009 
1010         if ( !rightsToConsult )
1011         {
1012             addError( ERROR_RESTRICTED, getLocale( request ) );
1013             return redirectView( request, VIEW_START );
1014         }
1015 
1016         _atelier = AtelierHome.findByInscrit( idInscrit );
1017 
1018         if ( !fullInscriptionValid( ) )
1019         {
1020             addError( ERROR_UNKNOWN, getLocale( request ) );
1021             return redirectView( request, VIEW_START );
1022         }
1023 
1024         Map<String, Object> model = getModel( );
1025         model.put( MARK_3975, _is3975 );
1026 
1027         return getXPage( TEMPLATE_CONSULTATION, getLocale( request ), model );
1028     }
1029 
1030     /**
1031      * parse/validate atelier number
1032      *
1033      * @param strAtelierNumber
1034      *            the atelierNumber as a string
1035      * @return the atelierNumber as an int
1036      */
1037     private int validateAtelierNumber( String strAtelierNumber )
1038     {
1039         int atelierNumber;
1040         if ( strAtelierNumber == null )
1041         {
1042             atelierNumber = _atelier.size( );
1043         } else
1044         {
1045             try
1046             {
1047                 atelierNumber = Integer.parseInt( strAtelierNumber );
1048             } catch ( NumberFormatException ex )
1049             {
1050                 atelierNumber = _atelier.size( );
1051             }
1052         }
1053         return Math.min( atelierNumber, NUMBER_OF_CHOICES - 1 );
1054     }
1055 
1056     /**
1057      * Sanitize the name
1058      *
1059      * @param name
1060      *            the name
1061      * @return the sanitized name
1062      */
1063     public static String sanitizeName( String name )
1064     {
1065         return whitespace_sanitize_pattern.matcher( name.toUpperCase( ).trim( ) ).replaceAll( " " );
1066     }
1067 
1068     /**
1069      * Sanitize the phone number
1070      *
1071      * @param phoneNumber
1072      *            the phone number
1073      * @return the sanitized phone number
1074      */
1075     public static String sanitizePhoneNumber( String phoneNumber )
1076     {
1077         String cleanNumber = phonenumber_sanitize_pattern.matcher( phoneNumber ).replaceAll( "" );
1078         String cleanerNumber = phonenumber_plus_sanitize_pattern.matcher( cleanNumber ).replaceAll( "+" );
1079         return phonenumber_french_sanitize_pattern.matcher( cleanerNumber ).replaceAll( "0" );
1080     }
1081 
1082     /**
1083      * Supprime accent et tiret
1084      *
1085      * @param stringToFormat
1086      * @return chaine format
1087      */
1088     private String formatMonCompteInfo( String stringToFormat )
1089     {
1090         if ( stringToFormat == null )
1091         {
1092             return null;
1093         }
1094         String stringResult = Normalizer.normalize( stringToFormat, Normalizer.Form.NFD );
1095         stringResult = stringResult.replaceAll( "[^\\p{ASCII}]", "" );
1096         stringResult = stringResult.replaceAll( "-", " " );
1097         return sanitizeName( stringResult );
1098     }
1099 
1100     /**
1101      * Formatte la date
1102      *
1103      * @param stringToDate
1104      * @return sql date format
1105      */
1106     private Date formatDateMonCompteInfo( String stringToDate )
1107     {
1108         if ( stringToDate == null )
1109         {
1110             return null;
1111         }
1112 
1113         try
1114         {
1115             java.util.Date date = new SimpleDateFormat( Inscrit.CONVERTER_PATTERN_NAISSANCE ).parse( stringToDate );
1116             return new Date( date.getTime( ) );
1117         } catch ( ParseException e )
1118         {
1119         }
1120         return null;
1121     }
1122 
1123     /**
1124      * Final check that all user input looks good
1125      *
1126      * @return true if good, else false
1127      */
1128     private boolean fullInscriptionValid( )
1129     {
1130         return ( ( ( _atelier != null ) && !_atelier.isEmpty( ) ) && ( _inscrit != null ) && ( ( _inscrit.getNom( ) != null ) && !_inscrit.getNom( ).isEmpty( ) )
1131                 && ( ( _inscrit.getPrenom( ) != null ) && !_inscrit.getPrenom( ).isEmpty( ) ) && ( _inscrit.getNaissance( ) != null )
1132                 && ( ( _inscrit.getAdresseDomicile( ) != null ) && !_inscrit.getAdresseDomicile( ).isEmpty( ) ) && ( ( _inscrit.getContactNom( ) != null ) && !_inscrit.getContactNom( ).isEmpty( ) )
1133                 && ( ( _inscrit.getContactPrenom( ) != null ) && !_inscrit.getContactPrenom( ).isEmpty( ) ) && ( ( _inscrit.getContactEmail( ) != null ) && !_inscrit.getContactEmail( ).isEmpty( ) )
1134                 && ( ( _inscrit.getContactTelephone( ) != null ) && !_inscrit.getContactTelephone( ).isEmpty( ) ) );
1135     }
1136 
1137     /**
1138      * Add an error message. The error message must NOT be an I18n key.
1139      *
1140      * @param strField
1141      *            The field for which there is an error
1142      * @param strMessage
1143      *            The message
1144      */
1145     protected void addError( String strField, String strMessage )
1146     {
1147         MVCMessage m = new MVCMessage( strMessage );
1148         List<ErrorMessage> l;
1149 
1150         if ( _mapErrorFields.containsKey( strField ) )
1151         {
1152             l = _mapErrorFields.get( strField );
1153         } else
1154         {
1155             l = new ArrayList<>( );
1156             _mapErrorFields.put( strField, l );
1157         }
1158 
1159         l.add( m );
1160         // Backward compatibility
1161         super.addError( strMessage );
1162     }
1163 
1164     /**
1165      * Add an error message. The error message must be an I18n key.
1166      *
1167      * @param strField
1168      *            The field for which there is an error
1169      * @param strMessageKey
1170      *            The message
1171      * @param locale
1172      *            The locale to display the message in
1173      */
1174     protected void addCustomError( String strField, String strMessageKey, Locale locale )
1175     {
1176         addError( strField, I18nService.getLocalizedString( strMessageKey, locale ) );
1177     }
1178 
1179     /**
1180      * Get a model Object filled with default values
1181      *
1182      * @return The model
1183      */
1184     @Override
1185     protected Map<String, Object> getModel( )
1186     {
1187         Map<String, Object> model = super.getModel( );
1188         fillRecap( model );
1189 
1190         HashMap<String, List<ErrorMessage>> mapErrorFieldsCopy = new HashMap<>( );
1191         mapErrorFieldsCopy.putAll( _mapErrorFields );
1192         model.put( MARK_ERROR_FIELDS, mapErrorFieldsCopy );
1193         _mapErrorFields.clear( );
1194 
1195         return model;
1196     }
1197 
1198     /**
1199      * Fill the model with commons objects used in templates
1200      *
1201      * @param model
1202      *            The model
1203      */
1204     protected void fillRecap( Map<String, Object> model )
1205     {
1206         if ( _inscrit == null )
1207         {
1208             return;
1209         }
1210 
1211         Collection<Map<String, Object>> atelierModels = new ArrayList<>( _atelier.size( ) );
1212         for ( int i = 0; i < _atelier.size( ); i++ )
1213         {
1214             Cours cours = CoursHome.findByPrimaryKey( _atelier.get( i ).getFkIdCours( ) );
1215             Map<String, Object> atelierModel = new HashMap<>( );
1216             atelierModel.put( MARK_CHOIX_DISCIPLINE, cours.getDiscipline( ) );
1217             atelierModel.put( MARK_CHOIX_ATELIER, cours.getTitreAtelier( ) );
1218             atelierModel.put( MARK_CHOIX_CRENEAU, cours.getCreneau( ) );
1219             atelierModel.put( MARK_ID_COURS, cours.getId( ) );
1220             atelierModels.add( atelierModel );
1221         }
1222 
1223         model.put( MARK_ATELIER_LIST, atelierModels );
1224         model.put( MARK_CANDIDAT_NOM, _inscrit.getNom( ) );
1225         model.put( MARK_CANDIDAT_PRENOM, _inscrit.getPrenom( ) );
1226         model.put( MARK_CANDIDAT_NAISSANCE, _inscrit.getNaissance( ) );
1227         model.put( MARK_CANDIDAT_ADRESSE, _inscrit.getAdresseDomicile( ) );
1228         model.put( MARK_CONTACT_NOM, _inscrit.getContactNom( ) );
1229         model.put( MARK_CONTACT_PRENOM, _inscrit.getContactPrenom( ) );
1230         model.put( MARK_CONTACT_EMAIL, _inscrit.getContactEmail( ) );
1231         model.put( MARK_CONTACT_TELEPHONE, _inscrit.getContactTelephone( ) );
1232         model.put( MARK_DECOUVERTE, _inscrit.getDecouverte( ) );
1233         model.put( MARK_MOTIVATION, _inscrit.getMotivation( ) );
1234         model.put( MARK_DEMARCHE, _inscrit.getDemarche( ) );
1235     }
1236 }