1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package fr.paris.lutece.plugins.participatoryideation.service;
35
36 import java.sql.Timestamp;
37 import java.text.Normalizer;
38 import java.util.Collection;
39 import java.util.Date;
40 import java.util.HashMap;
41 import java.util.List;
42 import java.util.Locale;
43 import java.util.Map;
44
45 import javax.servlet.http.HttpServletRequest;
46
47 import org.apache.commons.lang.StringUtils;
48
49 import fr.paris.lutece.plugins.extend.business.extender.history.ResourceExtenderHistory;
50 import fr.paris.lutece.plugins.extend.modules.comment.business.Comment;
51 import fr.paris.lutece.plugins.extend.modules.comment.service.CommentService;
52 import fr.paris.lutece.plugins.extend.modules.comment.service.ICommentService;
53 import fr.paris.lutece.plugins.extend.modules.comment.service.extender.CommentResourceExtender;
54 import fr.paris.lutece.plugins.extend.service.extender.history.IResourceExtenderHistoryService;
55 import fr.paris.lutece.plugins.extend.service.extender.history.ResourceExtenderHistoryService;
56 import fr.paris.lutece.plugins.participatoryideation.business.proposal.Proposal;
57 import fr.paris.lutece.plugins.participatoryideation.business.proposal.ProposalHome;
58 import fr.paris.lutece.plugins.participatoryideation.business.proposal.ProposalSearcher;
59 import fr.paris.lutece.plugins.participatoryideation.util.ParticipatoryIdeationConstants;
60 import fr.paris.lutece.plugins.workflowcore.business.action.Action;
61 import fr.paris.lutece.plugins.workflowcore.service.workflow.IWorkflowService;
62 import fr.paris.lutece.portal.service.datastore.DatastoreService;
63 import fr.paris.lutece.portal.service.i18n.I18nService;
64 import fr.paris.lutece.portal.service.spring.SpringContextService;
65 import fr.paris.lutece.portal.service.template.AppTemplateService;
66 import fr.paris.lutece.portal.service.util.AppLogService;
67 import fr.paris.lutece.portal.service.util.AppPropertiesService;
68 import fr.paris.lutece.portal.service.workflow.WorkflowService;
69 import fr.paris.lutece.util.html.HtmlTemplate;
70
71 public class ProposalWSService implements IProposalWSService
72 {
73
74 private static final String BEAN_PROPOSAL_WEB_SERVICE_SERVICE = "participatoryideation.proposalWSService";
75 private static IProposalWSService _singleton;
76 private static SolrProposalIndexer _solrProposalIndexer;
77 private static final String BEAN_SOLR_PROPOSAL_INDEXER = "participatoryideation.solrProposalIndexer";
78 private static ICommentService _commentService;
79 private static IResourceExtenderHistoryService _resourceHistoryService;
80
81
82 private static final String PROPERTY_POLITENESS_COMMENTS_PROJECTS_NOT_SELECTED = "eudonetbp.site_property.mail.politeness_comments_projects_not_selected.htmlblock";
83
84 private static final String MARK_COMMENT = "comment";
85
86
87
88
89
90
91 public static IProposalWSService getInstance( )
92 {
93 if ( _singleton == null )
94 {
95 _solrProposalIndexer = SpringContextService.getBean( BEAN_SOLR_PROPOSAL_INDEXER );
96 _singleton = SpringContextService.getBean( BEAN_PROPOSAL_WEB_SERVICE_SERVICE );
97 _commentService = SpringContextService.getBean( CommentService.BEAN_SERVICE );
98 _resourceHistoryService = SpringContextService.getBean( ResourceExtenderHistoryService.BEAN_SERVICE );
99
100 }
101 return _singleton;
102
103 }
104
105 @Override
106 public Collection<Proposal> getProposalsList( )
107 {
108
109 return ProposalHome.getProposalsList( );
110
111 }
112
113 @Override
114 public Proposal getProposalByIdentifiant( int nKey )
115 {
116
117 return ProposalHome.findByPrimaryKey( nKey );
118
119 }
120
121 @Override
122 public Proposal getProposalByIdentifiantAndCampaign( int nKey, String strCampaign )
123 {
124
125 return ProposalHome.findByCodes( strCampaign, nKey );
126
127 }
128
129 @Override
130 public Collection<Proposal> getProposalsListSearch( ProposalSearcher proposalSearcher )
131 {
132
133 return ProposalHome.getProposalsListSearch( proposalSearcher );
134 }
135
136 @Override
137 public void updateProposal( Proposal/../../../fr/paris/lutece/plugins/participatoryideation/business/proposal/Proposal.html#Proposal">Proposal proposalLutece, Proposal proposalEudonet, HttpServletRequest request )
138 {
139 updateProposal( proposalLutece, proposalEudonet, true, request );
140 }
141
142 @Override
143 public void updateProposal( Proposal/../../../fr/paris/lutece/plugins/participatoryideation/business/proposal/Proposal.html#Proposal">Proposal proposalLutece, Proposal proposalEudonet, boolean notify, HttpServletRequest request )
144 {
145
146 String valStatusLutece = proposalLutece.getStatusPublic( ).getValeur( );
147 String valStatusEudonet = proposalEudonet.getStatusEudonet( ).getValeur( );
148
149 String valStatusEudonetLutece = valStatusLutece;
150
151 if ( proposalLutece.getStatusEudonet( ) != null )
152 {
153 valStatusEudonetLutece = proposalLutece.getStatusEudonet( ).getValeur( );
154 }
155
156 if ( valStatusLutece.equals( valStatusEudonet )
157 || ( !valStatusLutece.equals( valStatusEudonet ) && !valStatusLutece.equals( valStatusEudonetLutece )
158 && !valStatusEudonet.equals( valStatusEudonetLutece ) )
159 || ( valStatusLutece.equals( Proposal.Status.STATUS_SUPPRIME_PAR_USAGER.getValeur( ) ) )
160 || ( valStatusEudonet.equals( Proposal.Status.STATUS_SUPPRIME_PAR_USAGER.getValeur( ) ) ) )
161 {
162
163 }
164 else
165 {
166 ProposalHome.updateBO( proposalEudonet );
167 if ( proposalEudonet.getMotifRecev( ) != null && StringUtils.isNotEmpty( proposalEudonet.getMotifRecev( ) )
168 && StringUtils.isNotBlank( proposalEudonet.getMotifRecev( ) ) && !( proposalLutece.getMotifRecev( ) != null
169 && proposalEudonet.getMotifRecev( ) != null && proposalEudonet.getMotifRecev( ).equals( proposalLutece.getMotifRecev( ) ) ) )
170 {
171 createComment( proposalEudonet );
172 }
173 if ( proposalEudonet.getStatusPublic( ).equals( Proposal.Status.STATUS_SUPPRIME_PAR_MDP )
174 || proposalEudonet.getStatusPublic( ).equals( Proposal.Status.STATUS_SUPPRIME_PAR_USAGER ) )
175 {
176 _solrProposalIndexer.removeProposal( proposalEudonet );
177 }
178 if ( WorkflowService.getInstance( ).isAvailable( ) )
179 {
180 processAction( valStatusEudonet, proposalLutece, notify, request );
181 }
182 }
183 }
184
185 @Override
186 public Proposal/../../../fr/paris/lutece/plugins/participatoryideation/business/proposal/Proposal.html#Proposal">Proposal updateProposal( Proposal proposal )
187 {
188
189 proposal = ProposalHome.updateBO( proposal );
190 return proposal;
191 }
192
193 @Override
194 public void createComment( Proposal proposal )
195 {
196 String strCommentPNS = DatastoreService.getDataValue( PROPERTY_POLITENESS_COMMENTS_PROJECTS_NOT_SELECTED, "" );
197 String strContentCommentPNS = proposal.getMotifRecev( );
198 Map<String, String> model = new HashMap<String, String>( );
199 model.put( MARK_COMMENT, proposal.getMotifRecev( ) );
200 try
201 {
202 HtmlTemplate t = AppTemplateService.getTemplateFromStringFtl( strCommentPNS, new Locale( "fr", "FR" ), model );
203 strContentCommentPNS = t.getHtml( );
204 }
205 catch( Exception e )
206 {
207
208 AppLogService.error( "Erreur avec le template freemarker dans les proprietes du site: ", e );
209 }
210
211 Comment comment = new Comment( );
212 comment.setIdExtendableResource( "" + proposal.getId( ) );
213 comment.setExtendableResourceType( Proposal.PROPERTY_RESOURCE_TYPE );
214 comment.setIdParentComment( 0 );
215 comment.setComment( strContentCommentPNS );
216 Timestamp currentDate = new Timestamp( new Date( ).getTime( ) );
217 comment.setDateComment( currentDate );
218 comment.setDateLastModif( currentDate );
219 comment.setName( "Mairie de Paris" );
220 comment.setEmail( "lutece@lutece.com" );
221 comment.setPublished( true );
222 comment.setIpAddress( "" );
223 comment.setIsAdminComment( true );
224 comment.setIsImportant( true );
225
226 comment.setPinned( true );
227 _commentService.create( comment );
228
229 ResourceExtenderHistory history = new ResourceExtenderHistory( );
230 history.setExtenderType( CommentResourceExtender.EXTENDER_TYPE_COMMENT );
231
232 history.setIdExtendableResource( "" + proposal.getId( ) );
233 history.setExtendableResourceType( Proposal.PROPERTY_RESOURCE_TYPE );
234 history.setIpAddress( StringUtils.EMPTY );
235 history.setUserGuid( AppPropertiesService.getProperty( ParticipatoryIdeationConstants.PROPERTY_GENERATE_PROPOSAL_LUTECE_USER_NAME ) );
236
237
238
239 _resourceHistoryService.create( history );
240 }
241
242 private void processAction( String proposalStatut, Proposal proposal, boolean notify, HttpServletRequest request )
243 {
244
245 boolean foundAction = false;
246 int nIdWorkflow = AppPropertiesService.getPropertyInt( ParticipatoryIdeationConstants.PROPERTY_WORKFLOW_ID, -1 );
247 String proposalStatutLibelle = removeAccent(
248 I18nService.getLocalizedString( ( Proposal.Status.getByValue( proposalStatut ).getLibelle( ) ), new Locale( "fr", "FR" ) ) )
249 + ( notify ? " (avec notification)" : " (sans notification)" );
250
251 if ( nIdWorkflow != -1 )
252 {
253 List<Action> actionsList = WorkflowService.getInstance( ).getMassActions( nIdWorkflow );
254 for ( Action action : actionsList )
255 {
256 String actionLibelle = removeAccent( action.getName( ) );
257 if ( actionLibelle.equals( proposalStatutLibelle ) )
258 {
259 foundAction = true;
260 IWorkflowService _service = SpringContextService
261 .getBean( fr.paris.lutece.plugins.workflowcore.service.workflow.WorkflowService.BEAN_SERVICE );
262 _service.doProcessAction( proposal.getId( ), Proposal.WORKFLOW_RESOURCE_TYPE, action.getId( ), -1, request, new Locale( "fr", "FR" ), false,
263 null );
264
265
266
267 }
268 }
269
270 if ( !foundAction )
271 {
272 AppLogService.error( "No such action on workflow #" + nIdWorkflow + " : '" + proposalStatutLibelle + "'" );
273 }
274
275
276
277
278
279
280 }
281 }
282
283 @Override
284 public void processActionByName( String strWorkflowProposalActionName, int nIdProposal, HttpServletRequest request )
285 {
286
287 int nIdWorkflow = AppPropertiesService.getPropertyInt( ParticipatoryIdeationConstants.PROPERTY_WORKFLOW_ID, -1 );
288
289 if ( nIdWorkflow != -1 && WorkflowService.getInstance( ).isAvailable( ) && !StringUtils.isEmpty( strWorkflowProposalActionName ) )
290 {
291
292 List<Action> actionsList = WorkflowService.getInstance( ).getMassActions( nIdWorkflow );
293
294 for ( Action action : actionsList )
295 {
296
297 if ( action.getName( ).equals( strWorkflowProposalActionName ) )
298 {
299
300 WorkflowService.getInstance( ).doProcessAction( nIdProposal, Proposal.WORKFLOW_RESOURCE_TYPE, action.getId( ), -1, request,
301 new Locale( "fr", "FR" ), true );
302
303 }
304 }
305 }
306
307 }
308
309 @Override
310 public void processActionByName( String strWorkflowProposalActionName, int nIdProposal )
311 {
312
313 int nIdWorkflow = AppPropertiesService.getPropertyInt( ParticipatoryIdeationConstants.PROPERTY_WORKFLOW_ID, -1 );
314
315 if ( nIdWorkflow != -1 && WorkflowService.getInstance( ).isAvailable( ) && !StringUtils.isEmpty( strWorkflowProposalActionName ) )
316 {
317
318 List<Action> actionsList = WorkflowService.getInstance( ).getMassActions( nIdWorkflow );
319
320 for ( Action action : actionsList )
321 {
322
323 if ( action.getName( ).equals( strWorkflowProposalActionName ) )
324 {
325
326 WorkflowService.getInstance( ).doProcessAction( nIdProposal, Proposal.WORKFLOW_RESOURCE_TYPE, action.getId( ), -1, null,
327 new Locale( "fr", "FR" ), true );
328
329 }
330 }
331 }
332
333 }
334
335 public static String removeAccent( String source )
336 {
337 return Normalizer.normalize( source, Normalizer.Form.NFD ).replaceAll( "[^\\p{ASCII}]", "" );
338 }
339
340 }