FormsTaskService.java
/*
* Copyright (c) 2002-2022, City of Paris
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright notice
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice
* and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* License 1.0
*/
package fr.paris.lutece.plugins.workflow.modules.forms.service.task;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import fr.paris.lutece.plugins.forms.business.FormQuestionResponse;
import fr.paris.lutece.plugins.forms.business.FormQuestionResponseHome;
import fr.paris.lutece.plugins.forms.business.FormResponse;
import fr.paris.lutece.plugins.forms.business.FormResponseHome;
import fr.paris.lutece.plugins.forms.business.FormResponseStep;
import fr.paris.lutece.plugins.forms.business.Question;
import fr.paris.lutece.plugins.forms.business.Step;
import fr.paris.lutece.plugins.forms.service.EntryServiceManager;
import fr.paris.lutece.plugins.forms.service.entrytype.EntryTypeDate;
import fr.paris.lutece.plugins.forms.web.StepDisplayTree;
import fr.paris.lutece.plugins.forms.web.entrytype.DisplayType;
import fr.paris.lutece.plugins.forms.web.entrytype.IEntryDataService;
import fr.paris.lutece.plugins.genericattributes.business.Response;
import fr.paris.lutece.plugins.genericattributes.service.entrytype.AbstractEntryTypeUpload;
import fr.paris.lutece.plugins.genericattributes.service.entrytype.EntryTypeServiceManager;
import fr.paris.lutece.plugins.genericattributes.service.entrytype.IEntryTypeService;
import fr.paris.lutece.plugins.workflow.modules.forms.utils.EditableResponse;
import fr.paris.lutece.plugins.workflowcore.business.action.Action;
import fr.paris.lutece.plugins.workflowcore.business.resource.ResourceHistory;
import fr.paris.lutece.plugins.workflowcore.business.state.State;
import fr.paris.lutece.plugins.workflowcore.business.state.StateFilter;
import fr.paris.lutece.plugins.workflowcore.service.action.IActionService;
import fr.paris.lutece.plugins.workflowcore.service.resource.IResourceHistoryService;
import fr.paris.lutece.plugins.workflowcore.service.state.IStateService;
import fr.paris.lutece.portal.business.file.FileHome;
import fr.paris.lutece.portal.service.message.SiteMessageException;
import fr.paris.lutece.portal.service.message.SiteMessageService;
import fr.paris.lutece.portal.service.util.AppException;
import fr.paris.lutece.util.ReferenceList;
/**
* This class is a service for the tasks of the plugin-forms
*
*/
public class FormsTaskService implements IFormsTaskService
{
private static final String NULL = "null";
private static final String SEPARATOR = ", ";
@Inject
private IResourceHistoryService _resourceHistoryService;
@Inject
private IActionService _actionService;
@Inject
private IStateService _stateService;
/**
* {@inheritDoc}
*/
@Override
public ResourceHistory findResourceHistory( int nIdResourceHistory )
{
return _resourceHistoryService.findByPrimaryKey( nIdResourceHistory );
}
/**
* {@inheritDoc}
*/
@Override
public FormResponse findFormResponseFrom( int nIdResource, String strResourceType )
{
return loadFormResponse( nIdResource, strResourceType, true );
}
@Override
public FormResponse findFormResponseWithoutSteps( int nIdResource, String strResourceType )
{
return loadFormResponse( nIdResource, strResourceType, false );
}
private FormResponse loadFormResponse( int nIdResource, String strResourceType, boolean loadSteps )
{
FormResponse formResponse = null;
if ( FormResponse.RESOURCE_TYPE.equals( strResourceType ) )
{
if ( loadSteps )
{
formResponse = FormResponseHome.findByPrimaryKey( nIdResource );
}
else
{
formResponse = FormResponseHome.loadById( nIdResource );
}
}
else
{
throw new AppException( "This task must be used with a form" );
}
return formResponse;
}
@Override
public List<String> buildFormStepDisplayTreeList( HttpServletRequest request, List<Step> listStep, List<Question> listQuestionToDisplay,
FormResponse formResponse, DisplayType displayType )
{
List<String> listFormDisplayTrees = new ArrayList<>( );
List<FormQuestionResponse> listFormQuestionResponse = FormQuestionResponseHome.getFormQuestionResponseListByFormResponse( formResponse.getId( ) );
List<Integer> listQuestionToDisplayId = listQuestionToDisplay.stream( ).map( Question::getId ).collect( Collectors.toList( ) );
listFormQuestionResponse = listFormQuestionResponse.stream( )
.filter( formQuestionResponse -> listQuestionToDisplayId.contains( formQuestionResponse.getQuestion( ).getId( ) ) )
.collect( Collectors.toList( ) );
for ( FormQuestionResponse formQuestionResponse : listFormQuestionResponse )
{
IEntryTypeService entryTypeService = EntryTypeServiceManager.getEntryTypeService( formQuestionResponse.getQuestion( ).getEntry( ) );
if ( entryTypeService instanceof EntryTypeDate )
{
for ( Response response : formQuestionResponse.getEntryResponse( ) )
{
response.setToStringValueResponse( entryTypeService.getResponseValueForRecap( formQuestionResponse.getQuestion( ).getEntry( ), request,
response, request.getLocale( ) ) );
}
}
}
if ( !CollectionUtils.isEmpty( listStep ) )
{
for ( Step step : listStep )
{
int nIdStep = step.getId( );
StepDisplayTree stepDisplayTree = new StepDisplayTree( nIdStep, formResponse, listQuestionToDisplayId );
listFormDisplayTrees.add( stepDisplayTree.getCompositeHtml( request, listFormQuestionResponse, request.getLocale( ), displayType ) );
}
}
return listFormDisplayTrees;
}
@Override
public List<EditableResponse> findChangedResponses( List<EditableResponse> listEditableResponse )
{
List<EditableResponse> listChangedResponse = new ArrayList<>( );
for ( EditableResponse editableResponse : listEditableResponse )
{
IEntryDataService dataService = EntryServiceManager.getInstance( )
.getEntryDataService( editableResponse.getQuestion( ).getEntry( ).getEntryType( ) );
if ( dataService.isResponseChanged( editableResponse.getResponseSaved( ), editableResponse.getResponseFromForm( ) ) )
{
listChangedResponse.add( editableResponse );
}
}
return listChangedResponse;
}
@Override
public List<EditableResponse> createEditableResponses( FormResponse formResponse, List<Question> listQuestion, HttpServletRequest request )
{
List<EditableResponse> listEditableResponse = new ArrayList<>( );
for ( Question question : listQuestion )
{
IEntryDataService entryDataService = EntryServiceManager.getInstance( ).getEntryDataService( question.getEntry( ).getEntryType( ) );
FormQuestionResponse responseFromForm = entryDataService.createResponseFromRequest( question, request, false );
responseFromForm.setIdFormResponse( formResponse.getId( ) );
FormQuestionResponse responseSaved = findSavedResponse( formResponse, question );
if ( responseSaved == null )
{
EditableResponse editableResponse = new EditableResponse( responseSaved, responseFromForm );
listEditableResponse.add( editableResponse );
continue;
}
IEntryTypeService entryTypeService = EntryTypeServiceManager.getEntryTypeService( question.getEntry( ) );
if ( entryTypeService instanceof EntryTypeDate )
{
for ( Response response : responseSaved.getEntryResponse( ) )
{
response.setToStringValueResponse(
entryTypeService.getResponseValueForRecap( question.getEntry( ), request, response, request.getLocale( ) ) );
}
}
if ( entryTypeService instanceof AbstractEntryTypeUpload )
{
for ( Response response : responseSaved.getEntryResponse( ) )
{
if ( response.getFile( ) != null )
{
response.setFile( FileHome.findByPrimaryKey( response.getFile( ).getIdFile( ) ) );
}
}
}
EditableResponse editableResponse = new EditableResponse( responseSaved, responseFromForm );
listEditableResponse.add( editableResponse );
}
return listEditableResponse;
}
private FormQuestionResponse findSavedResponse( FormResponse formResponse, Question question )
{
FormQuestionResponse formQuestionResponse = null;
List<FormQuestionResponse> listResponseSaved = findResponses( formResponse, question );
for ( FormQuestionResponse responseSaved : listResponseSaved )
{
if ( responseSaved.getQuestion( ).getIterationNumber( ) == question.getIterationNumber( ) )
{
formQuestionResponse = responseSaved;
break;
}
}
return formQuestionResponse;
}
@Override
public List<FormQuestionResponse> findResponses( FormResponse formResponse, Question question )
{
List<FormQuestionResponse> listFormQuestionResponse = new ArrayList<>( );
for ( FormResponseStep formResponseStep : formResponse.getSteps( ) )
{
if ( formResponseStep.getStep( ).getId( ) == question.getIdStep( ) )
{
for ( FormQuestionResponse formQuestionResponse : formResponseStep.getQuestions( ) )
{
if ( formQuestionResponse.getQuestion( ).getId( ) == question.getId( ) )
{
listFormQuestionResponse.add( formQuestionResponse );
}
}
}
}
return listFormQuestionResponse;
}
@Override
public ReferenceList getListStates( int nIdAction )
{
ReferenceList referenceListStates = new ReferenceList( );
Action action = _actionService.findByPrimaryKey( nIdAction );
if ( ( action != null ) && ( action.getWorkflow( ) != null ) )
{
StateFilter stateFilter = new StateFilter( );
stateFilter.setIdWorkflow( action.getWorkflow( ).getId( ) );
List<State> listStates = _stateService.getListStateByFilter( stateFilter );
referenceListStates.addItem( -1, StringUtils.EMPTY );
referenceListStates.addAll( ReferenceList.convert( listStates, "id", "name", true ) );
}
return referenceListStates;
}
@Override
public void setSiteMessage( HttpServletRequest request, String strMessage, int nTypeMessage, String strUrlReturn ) throws SiteMessageException
{
if ( StringUtils.isNotBlank( strUrlReturn ) )
{
SiteMessageService.setMessage( request, strMessage, nTypeMessage, strUrlReturn );
}
else
{
SiteMessageService.setMessage( request, strMessage, nTypeMessage );
}
}
@Override
public FormResponse getFormResponseFromIdHistory( int nIdHistory )
{
FormResponse response = null;
ResourceHistory resourceHistory = _resourceHistoryService.findByPrimaryKey( nIdHistory );
if ( resourceHistory != null && FormResponse.RESOURCE_TYPE.equals( resourceHistory.getResourceType( ) ) )
{
response = FormResponseHome.findByPrimaryKey( resourceHistory.getIdResource( ) );
}
return response;
}
@Override
public String createPreviousNewValue( FormQuestionResponse responseForm )
{
String value = StringUtils.EMPTY;
if ( responseForm == null )
{
return value;
}
for ( int i = 0; i < responseForm.getEntryResponse( ).size( ); i++ )
{
Response response = responseForm.getEntryResponse( ).get( i );
if ( response.getFile( ) != null )
{
value = response.getFile( ).getTitle( );
}
else
{
if ( response.getToStringValueResponse( ) == null || response.getToStringValueResponse( ).equalsIgnoreCase( NULL ) )
{
value = StringUtils.EMPTY;
}
else
{
value += response.getToStringValueResponse( );
}
}
if ( i + 1 != responseForm.getEntryResponse( ).size( ) )
{
value += SEPARATOR;
}
}
return value;
}
}