View Javadoc
1   /*
2    * Copyright (c) 2002-2022, City of 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.workflow.modules.forms.service;
35  
36  import java.util.Comparator;
37  import java.util.HashMap;
38  import java.util.List;
39  import java.util.Locale;
40  import java.util.Map;
41  import java.util.stream.Collectors;
42  
43  import javax.servlet.http.HttpServletRequest;
44  
45  import org.apache.commons.collections.CollectionUtils;
46  import org.apache.commons.lang3.StringUtils;
47  import org.apache.commons.lang3.math.NumberUtils;
48  
49  import fr.paris.lutece.plugins.forms.business.FormHome;
50  import fr.paris.lutece.plugins.forms.business.FormQuestionResponse;
51  import fr.paris.lutece.plugins.forms.business.FormQuestionResponseHome;
52  import fr.paris.lutece.plugins.forms.business.FormResponse;
53  import fr.paris.lutece.plugins.forms.business.FormResponseHome;
54  import fr.paris.lutece.plugins.forms.business.Question;
55  import fr.paris.lutece.plugins.forms.business.QuestionHome;
56  import fr.paris.lutece.plugins.forms.business.Step;
57  import fr.paris.lutece.plugins.forms.business.StepHome;
58  import fr.paris.lutece.plugins.genericattributes.business.Response;
59  import fr.paris.lutece.plugins.workflow.modules.forms.business.FormResponseValueStateControllerConfig;
60  import fr.paris.lutece.plugins.workflow.modules.forms.business.FormResponseValueStateControllerConfigHome;
61  import fr.paris.lutece.plugins.workflow.modules.state.service.IChooseStateController;
62  import fr.paris.lutece.plugins.workflowcore.business.config.ITaskConfig;
63  import fr.paris.lutece.plugins.workflowcore.service.task.ITask;
64  import fr.paris.lutece.util.ReferenceList;
65  
66  public abstract class AbstractFormResponseStateController implements IChooseStateController
67  {
68      // Mark
69      private static final String MARK_FORM_LIST = "form_list";
70      private static final String MARK_ID_FORM = "id_form";
71      private static final String MARK_STEP_LIST = "list_step";
72      private static final String MARK_ID_STEP = "id_step";
73      private static final String MARK_QUESTION_LIST = "question_list";
74      private static final String MARK_ID_QUESTION = "id_question";
75      private static final String MARK_VALUE_LIST = "value_list";
76      private static final String MARK_RESPONSE_VALUE = "response_value";
77      private static final String MARK_MULTIFORM = "multiform";
78      private static final String MARK_CODE_LIST = "code_list";
79      private static final String MARK_CODE = "code";
80  
81      // Parameters
82      private static final String PARAMETER_ACTION = "apply";
83      private static final String PARAMETER_FORM = "form_select";
84      private static final String PARAMETER_STEP = "step_select";
85      private static final String PARAMETER_QUESTION = "question_select";
86      private static final String PARAMETER_VALUE = "response_value";
87      private static final String PARAMETER_MULTIFORM = "multiform";
88      private static final String PARAMETER_CODE = "code_select";
89  
90      // Actions
91      private static final String ACTION_SELECT_FORM = "select_form_config";
92      private static final String ACTION_SELECT_STEP = "select_step_config";
93      private static final String ACTION_SELECT_QUESTION = "select_question_config";
94      private static final String ACTION_SELECT_MULTIFORM = "select_multiform";
95  
96      @Override
97      public boolean hasConfig( )
98      {
99          return true;
100     }
101 
102     @Override
103     public void doRemoveConfig( ITask task )
104     {
105         FormResponseValueStateControllerConfigHome.removeByTask( task.getId( ) );
106     }
107 
108     protected Map<String, Object> createModelConfig( ITaskConfig config )
109     {
110         FormResponseValueStateControllerConfig controllerConfig = loadConfig( config.getIdTask( ) );
111 
112         Map<String, Object> model = new HashMap<>( );
113         model.put( MARK_FORM_LIST, FormHome.getFormsReferenceList( ) );
114         model.put( MARK_MULTIFORM, controllerConfig.isMultiform( ) );
115         model.put( MARK_CODE_LIST, getCodeReferenceList( ) );
116         model.put( MARK_CODE, controllerConfig.getCode( ) );
117 
118         if ( controllerConfig.getForm( ) != null )
119         {
120             model.put( MARK_ID_FORM, controllerConfig.getForm( ).getId( ) );
121             model.put( MARK_STEP_LIST, StepHome.getStepReferenceListByForm( controllerConfig.getForm( ).getId( ) ) );
122         }
123         if ( controllerConfig.getStep( ) != null )
124         {
125             model.put( MARK_ID_STEP, controllerConfig.getStep( ).getId( ) );
126             model.put( MARK_QUESTION_LIST, getQuestionReferenceList( controllerConfig.getStep( ).getId( ) ) );
127         }
128         if ( controllerConfig.getQuestion( ) != null )
129         {
130             model.put( MARK_ID_QUESTION, controllerConfig.getQuestion( ).getId( ) );
131             model.put( MARK_VALUE_LIST, getResponseReferenceList( controllerConfig.getQuestion( ).getId( ) ) );
132         }
133         if ( StringUtils.isNotEmpty( controllerConfig.getValue( ) ) )
134         {
135             model.put( MARK_RESPONSE_VALUE, controllerConfig.getValue( ) );
136         }
137 
138         return model;
139     }
140 
141     @Override
142     public void doSaveConfig( HttpServletRequest request, Locale locale, ITask task )
143     {
144         FormResponseValueStateControllerConfig controllerConfig = loadConfig( task.getId( ) );
145         String action = request.getParameter( PARAMETER_ACTION );
146         if ( action != null )
147         {
148             switch( action )
149             {
150                 case ACTION_SELECT_MULTIFORM:
151                     controllerConfig.setMultiform( request.getParameter( PARAMETER_MULTIFORM ) != null );
152                     controllerConfig.setForm( null );
153                     controllerConfig.setStep( null );
154                     controllerConfig.setQuestion( null );
155                     controllerConfig.setValue( null );
156                     controllerConfig.setCode( null );
157                     break;
158                 case ACTION_SELECT_FORM:
159                     controllerConfig.setForm( FormHome.findByPrimaryKey( Integer.valueOf( request.getParameter( PARAMETER_FORM ) ) ) );
160                     controllerConfig.setStep( null );
161                     controllerConfig.setQuestion( null );
162                     break;
163                 case ACTION_SELECT_STEP:
164                     controllerConfig.setStep( StepHome.findByPrimaryKey( Integer.parseInt( request.getParameter( PARAMETER_STEP ) ) ) );
165                     controllerConfig.setQuestion( null );
166                     break;
167                 case ACTION_SELECT_QUESTION:
168                     controllerConfig.setQuestion( QuestionHome.findByPrimaryKey( Integer.parseInt( request.getParameter( PARAMETER_QUESTION ) ) ) );
169                     break;
170                 default:
171                     break;
172             }
173         }
174         if ( controllerConfig.isMultiform( ) )
175         {
176             controllerConfig.setCode( request.getParameter( PARAMETER_CODE ) );
177         }
178         else
179         {
180             if ( NumberUtils.isCreatable( request.getParameter( PARAMETER_QUESTION ) ) )
181             {
182                 controllerConfig.setQuestion( QuestionHome.findByPrimaryKey( Integer.parseInt( request.getParameter( PARAMETER_QUESTION ) ) ) );
183             }
184             controllerConfig.setCode( null );
185         }
186         controllerConfig.setValue( request.getParameter( PARAMETER_VALUE ) );
187         FormResponseValueStateControllerConfigHome.update( controllerConfig );
188     }
189 
190     protected abstract ReferenceList getResponseReferenceList( int idQuestion );
191 
192     protected FormResponseValueStateControllerConfig loadConfig( int idTask )
193     {
194         FormResponseValueStateControllerConfig controllerConfig = FormResponseValueStateControllerConfigHome.findByTask( idTask );
195         if ( controllerConfig == null )
196         {
197             controllerConfig = new FormResponseValueStateControllerConfig( );
198             controllerConfig.setIdTask( idTask );
199             FormResponseValueStateControllerConfigHome.create( controllerConfig );
200         }
201         return controllerConfig;
202     }
203 
204     protected ReferenceList getQuestionReferenceList( int idStep )
205     {
206         ReferenceList refList = new ReferenceList( );
207         refList.addItem( -1, "" );
208         if ( idStep != -1 )
209         {
210             List<Question> questionList = QuestionHome.getQuestionsListByStep( idStep );
211             for ( Question question : questionList )
212             {
213                 if ( canQuestionBeCondition( question ) )
214                 {
215                     refList.addItem( question.getId( ), question.getTitle( ) );
216                 }
217             }
218         }
219 
220         return refList;
221     }
222 
223     protected ReferenceList getCodeReferenceList( )
224     {
225         ReferenceList refList = new ReferenceList( );
226         List<Question> questionList = QuestionHome.getQuestionsList( ).stream( ).filter( this::canQuestionBeCondition ).collect( Collectors.toList( ) );
227         List<String> codeList = questionList.stream( ).map( Question::getCode ).distinct( ).collect( Collectors.toList( ) );
228         codeList.sort( Comparator.naturalOrder( ) );
229         for ( String code : codeList )
230         {
231             refList.addItem( code, code );
232         }
233         return refList;
234     }
235 
236     protected abstract boolean canQuestionBeCondition( Question question );
237 
238     protected Response getResponseFromConfigAndFormResponse( FormResponseValueStateControllerConfig config, int idResponse )
239     {
240         Question question = null;
241         if ( config.isMultiform( ) )
242         {
243             FormResponse formResponse = FormResponseHome.findByPrimaryKey( idResponse );
244             for ( Question q : QuestionHome.findByCode( config.getCode( ) ) )
245             {
246                 Step step = StepHome.findByPrimaryKey( q.getIdStep( ) );
247                 if ( step.getIdForm( ) == formResponse.getFormId( ) )
248                 {
249                     question = q;
250                     break;
251                 }
252             }
253         }
254         else
255         {
256             question = config.getQuestion( );
257         }
258 
259         if ( question == null )
260         {
261             return null;
262         }
263         List<FormQuestionResponse> responseList = FormQuestionResponseHome.findFormQuestionResponseByResponseQuestion( idResponse, question.getId( ) );
264 
265         if ( CollectionUtils.isEmpty( responseList ) )
266         {
267             return null;
268         }
269         List<Response> entryResponseList = responseList.get( 0 ).getEntryResponse( );
270         if ( CollectionUtils.isEmpty( entryResponseList ) )
271         {
272             return null;
273         }
274         return entryResponseList.get( 0 );
275     }
276 }