ProposalService.java
/*
* Copyright (c) 2002-2020, 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.participatoryideation.service;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import org.springframework.transaction.annotation.Transactional;
import fr.paris.lutece.plugins.extend.business.extender.history.ResourceExtenderHistory;
import fr.paris.lutece.plugins.extend.business.extender.history.ResourceExtenderHistoryFilter;
import fr.paris.lutece.plugins.extend.modules.follow.service.extender.FollowResourceExtender;
import fr.paris.lutece.plugins.extend.service.extender.history.IResourceExtenderHistoryService;
import fr.paris.lutece.plugins.participatoryideation.business.proposal.Proposal;
import fr.paris.lutece.plugins.participatoryideation.business.proposal.ProposalHome;
import fr.paris.lutece.plugins.participatoryideation.business.proposal.ProposalSearcher;
import fr.paris.lutece.plugins.participatoryideation.util.ParticipatoryIdeationConstants;
import fr.paris.lutece.plugins.participatoryideation.web.IdeationApp;
import fr.paris.lutece.portal.business.file.File;
import fr.paris.lutece.portal.business.file.FileHome;
import fr.paris.lutece.portal.service.i18n.I18nService;
import fr.paris.lutece.portal.service.spring.SpringContextService;
import fr.paris.lutece.portal.service.util.AppLogService;
import fr.paris.lutece.portal.service.util.AppPropertiesService;
import fr.paris.lutece.util.ReferenceList;
public class ProposalService implements IProposalService
{
private static final String PROPERTY_LABEL_NQPV = "participatoryideation.qpvqva.nqpv.label";
private static final String PROPERTY_LABEL_QVA = "participatoryideation.qpvqva.qva.label";
private static final String PROPERTY_LABEL_GPRU = "participatoryideation.qpvqva.gpru.label";
private static final String PROPERTY_LABEL_QBP = "participatoryideation.qpvqva.qbp.label";
private static final String PROPERTY_LABEL_ERR = "participatoryideation.qpvqva.err.label";
private static final String PROPERTY_LABEL_NON = "participatoryideation.qpvqva.non.label";
private static final String PROPERTY_LABEL_UNK = "participatoryideation.qpvqva.unk.label";
private static final String PROPERTY_LABEL_ARDT = "participatoryideation.location_type.ardt.label";
private static final String PROPERTY_LABEL_PARIS = "participatoryideation.location_type.paris.label";
private static final String PROPERTY_FIELD4_LABEL_YES = "participatoryideation.field4.yes.label";
private static final String PROPERTY_FIELD4_LABEL_NO = "participatoryideation.field4.no.label";
private static volatile ReferenceList _listQpvQvaCodes;
private static volatile Map<String, String> _mapQpvQvaCodes;
private static volatile ReferenceList _listField4Codes;
private static volatile Map<String, String> _mapField4Codes;
private static volatile ReferenceList _listTypeLocation;
private static volatile Map<String, String> _mapTypeLocation;
private static IProposalService _singleton;
private static SolrProposalIndexer _solrProposalIndexer;
private static final String BEAN_PROPOSAL_SERVICE = "participatoryideation.proposalService";
private static final String BEAN_TRANSACTION_MANAGER = "participatoryideation.proposalServiceTransactionManager";
private static final String BEAN_SOLR_PROPOSAL_INDEXER = "participatoryideation.solrProposalIndexer";
@Inject
private IResourceExtenderHistoryService _resourceExtenderHistoryService;
public static IProposalService getInstance( )
{
if ( _singleton == null )
{
_singleton = SpringContextService.getBean( BEAN_PROPOSAL_SERVICE );
_solrProposalIndexer = SpringContextService.getBean( BEAN_SOLR_PROPOSAL_INDEXER );
_listQpvQvaCodes = new ReferenceList( );
_listQpvQvaCodes.addItem( IdeationApp.QPV_QVA_NO, I18nService.getLocalizedString( PROPERTY_LABEL_NON, Locale.FRENCH ) );
_listQpvQvaCodes.addItem( IdeationApp.QPV_QVA_QPV, I18nService.getLocalizedString( PROPERTY_LABEL_NQPV, Locale.FRENCH ) );
_listQpvQvaCodes.addItem( IdeationApp.QPV_QVA_QVA, I18nService.getLocalizedString( PROPERTY_LABEL_QVA, Locale.FRENCH ) );
_listQpvQvaCodes.addItem( IdeationApp.QPV_QVA_GPRU, I18nService.getLocalizedString( PROPERTY_LABEL_GPRU, Locale.FRENCH ) );
_listQpvQvaCodes.addItem( IdeationApp.QPV_QVA_QBP, I18nService.getLocalizedString( PROPERTY_LABEL_QBP, Locale.FRENCH ) );
_listQpvQvaCodes.addItem( IdeationApp.QPV_QVA_ERR, I18nService.getLocalizedString( PROPERTY_LABEL_ERR, Locale.FRENCH ) );
_listQpvQvaCodes.addItem( ProposalSearcher.QPVQVA_UNKNOWN, I18nService.getLocalizedString( PROPERTY_LABEL_UNK, Locale.FRENCH ) );
_mapQpvQvaCodes = _listQpvQvaCodes.toMap( );
_listField4Codes = new ReferenceList( );
_listField4Codes.addItem( IdeationApp.FIELD4_LABEL_YES, I18nService.getLocalizedString( PROPERTY_FIELD4_LABEL_YES, Locale.FRENCH ) );
_listField4Codes.addItem( IdeationApp.FIELD4_LABEL_NO, I18nService.getLocalizedString( PROPERTY_FIELD4_LABEL_NO, Locale.FRENCH ) );
_mapField4Codes = _listField4Codes.toMap( );
_listTypeLocation = new ReferenceList( );
_listTypeLocation.addItem( Proposal.LOCATION_AREA_TYPE_LOCALIZED, I18nService.getLocalizedString( PROPERTY_LABEL_ARDT, Locale.FRENCH ) );
_listTypeLocation.addItem( Proposal.LOCATION_AREA_TYPE_WHOLE, I18nService.getLocalizedString( PROPERTY_LABEL_PARIS, Locale.FRENCH ) );
_mapTypeLocation = _listTypeLocation.toMap( );
}
return _singleton;
}
private void createFiles( Proposal proposal, String type, List<File> attachedFiles )
{
for ( File file : attachedFiles )
{
FileHome.create( file );
}
}
// Don't forget to use InnoDB tables for the following tables!
// core_file, core_physical_file, participatoryideation_proposals, participatoryideation_proposals_files
// Check with:
// sql> show table status ;
@Transactional( BEAN_TRANSACTION_MANAGER )
public synchronized void createProposalDB( Proposal proposal ) throws IdeationErrorException
{
createFiles( proposal, Proposal.ATTACHED_FILE_TYPE_DOC, proposal.getDocs( ) );
createFiles( proposal, Proposal.ATTACHED_FILE_TYPE_IMG, proposal.getImgs( ) );
ProposalHome.create( proposal );
}
public void createProposal( Proposal proposal ) throws IdeationErrorException
{
_singleton.createProposalDB( proposal );
_solrProposalIndexer.writeProposal( proposal );
}
public void removeProposalCommon( Proposal proposal )
{
proposal.setExportedTag( 2 );
ProposalHome.updateBO( proposal );
ProposalHome.removeLinkByChild( proposal.getId( ) );
ProposalHome.removeLinkByParent( proposal.getId( ) );
}
public void removeProposal( Proposal proposal )
{
removeProposalCommon( proposal );
String strWorkflowActionNameDeleteProposal = AppPropertiesService
.getProperty( ParticipatoryIdeationConstants.PROPERTY_WORKFLOW_ACTION_NAME_DELETE_PROPOSAL );
ProposalWSService.getInstance( ).processActionByName( strWorkflowActionNameDeleteProposal, proposal.getId( ) );
}
public void removeProposalByMdp( Proposal proposal )
{
removeProposalCommon( proposal );
String strWorkflowActionNameDeleteProposalByMdp = AppPropertiesService
.getProperty( ParticipatoryIdeationConstants.PROPERTY_WORKFLOW_ACTION_NAME_DELETE_PROPOSAL_BY_MDP );
ProposalWSService.getInstance( ).processActionByName( strWorkflowActionNameDeleteProposalByMdp, proposal.getId( ) );
}
/**
* {@inheritDoc}
*/
@Override
public boolean isPublished( Proposal proposal )
{
return proposal.getStatusPublic( ) != null && proposal.getStatusPublic( ).isPublished( );
}
/**
* @return the QpvQvaCodes
*/
public ReferenceList getQpvQvaCodesList( )
{
return _listQpvQvaCodes;
}
/**
* @return the QpvQvaCodes
*/
public Map<String, String> getQpvQvaCodesMap( )
{
return _mapQpvQvaCodes;
}
/**
* @return the field4Codes as a list
*/
public ReferenceList getField4CodesList( )
{
return _listField4Codes;
}
/**
* @return the Field4Codes as a map
*/
public Map<String, String> getField4CodesMap( )
{
return _mapField4Codes;
}
/**
* @return the TypeLocation
*/
public ReferenceList getTypeLocationList( )
{
return _listTypeLocation;
}
/**
* @return the TypeLocation
*/
public Map<String, String> getTypeLocationMap( )
{
return _mapTypeLocation;
}
// *********************************************************************************************
// * SUBMITTER SUBMITTER SUBMITTER SUBMITTER SUBMITTER SUBMITTER SUBMITTER SUBMITTER SUBMITTER *
// * SUBMITTER SUBMITTER SUBMITTER SUBMITTER SUBMITTER SUBMITTER SUBMITTER SUBMITTER SUBMITTER *
// *********************************************************************************************
/**
* {@inheritDoc}
*/
@Override
public Set<String> getUniqueUserGuidsProposalsSubmitters( List<Integer> propIds )
{
Set<String> userGuids = new HashSet<String>( );
for ( Integer propId : propIds )
{
Proposal proposal = ProposalHome.findByPrimaryKey( propId );
if ( proposal == null )
{
AppLogService.error( "ERROR : Unable to find proposal #'" + propId + "' !" );
}
else
{
userGuids.add( proposal.getLuteceUserName( ) );
}
}
return userGuids;
}
// *********************************************************************************************
// * FOLLOW FOLLOW FOLLOW FOLLOW FOLLOW FOLLOW FOLLOW FOLLOW FOLLOW FOLLOW FOLLOW FOLLOW FOLLO *
// * FOLLOW FOLLOW FOLLOW FOLLOW FOLLOW FOLLOW FOLLOW FOLLOW FOLLOW FOLLOW FOLLOW FOLLOW FOLLO *
// *********************************************************************************************
/**
* {@inheritDoc}
*/
@Override
public Set<String> getUniqueUserGuidsProposalsFollowers( List<Integer> propIds )
{
Set<String> userGuids = new HashSet<String>( );
for ( Integer propId : propIds )
{
ResourceExtenderHistoryFilter filter = new ResourceExtenderHistoryFilter( );
filter.setExtenderType( FollowResourceExtender.RESOURCE_EXTENDER );
filter.setExtendableResourceType( Proposal.PROPERTY_RESOURCE_TYPE );
filter.setIdExtendableResource( propId.toString( ) );
List<ResourceExtenderHistory> listHistories = _resourceExtenderHistoryService.findByFilter( filter );
for ( ResourceExtenderHistory followerHistory : listHistories )
{
userGuids.add( followerHistory.getUserGuid( ) );
}
}
return userGuids;
}
}