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.stock.modules.billetterie.web;
35
36 import fr.paris.lutece.plugins.stock.business.attribute.AbstractAttributeNum;
37 import fr.paris.lutece.plugins.stock.business.attribute.product.ProductAttributeNum;
38 import fr.paris.lutece.plugins.stock.business.attribute.purchase.PurchaseAttribute;
39 import fr.paris.lutece.plugins.stock.business.offer.Offer;
40 import fr.paris.lutece.plugins.stock.business.product.Product;
41 import fr.paris.lutece.plugins.stock.business.product.ProductFilter;
42 import fr.paris.lutece.plugins.stock.business.provider.Provider;
43 import fr.paris.lutece.plugins.stock.business.provider.ProviderFilter;
44 import fr.paris.lutece.plugins.stock.business.purchase.Purchase;
45 import fr.paris.lutece.plugins.stock.business.purchase.PurchaseFilter;
46 import fr.paris.lutece.plugins.stock.commons.ResultList;
47 import fr.paris.lutece.plugins.stock.commons.exception.FunctionnalException;
48 import fr.paris.lutece.plugins.stock.modules.billetterie.utils.constants.BilletterieConstants;
49 import fr.paris.lutece.plugins.stock.modules.tickets.business.*;
50 import fr.paris.lutece.plugins.stock.modules.tickets.service.*;
51 import fr.paris.lutece.plugins.stock.modules.tickets.utils.constants.TicketsConstants;
52
53 import fr.paris.lutece.plugins.stock.service.IProductService;
54 import fr.paris.lutece.plugins.stock.utils.constants.StockConstants;
55 import fr.paris.lutece.portal.service.i18n.I18nService;
56 import fr.paris.lutece.portal.service.spring.SpringContextService;
57 import fr.paris.lutece.portal.service.template.AppTemplateService;
58 import fr.paris.lutece.portal.service.util.AppPathService;
59 import fr.paris.lutece.portal.service.util.AppPropertiesService;
60 import fr.paris.lutece.util.html.HtmlTemplate;
61
62 import org.apache.commons.lang.StringUtils;
63
64 import org.apache.log4j.Logger;
65
66 import java.util.*;
67 import java.util.stream.Collectors;
68
69 import javax.inject.Inject;
70 import javax.inject.Named;
71 import javax.servlet.http.HttpServletRequest;
72
73 import static java.util.Optional.ofNullable;
74 import static java.util.stream.Collectors.groupingBy;
75 import static java.util.stream.Collectors.mapping;
76
77
78
79
80 public class NotificationJspBean extends AbstractJspBean
81 {
82 public static final Logger LOGGER = Logger.getLogger( NotificationJspBean.class );
83 public static final String RESOURCE_TYPE = "STOCK";
84 public static final String RIGHT_MANAGE_NOTIFICATIONS = "OFFERS_MANAGEMENT";
85
86
87 public static final String MARK_NOTIFICATION = "notification";
88 public static final String MARK_TITLE = "title";
89 public static final String MARK_OFFER_ID = "offer_id";
90 public static final String MARK_CANCEL = "cancel";
91 public static final String MARK_NOTIFY = "notify";
92 public static final String MARK_LOCK = "lock";
93 public static final String MARK_NOTIFICATION_ACTION = "notificationAction";
94 public static final String MARK_AVERTISSEMENT = "avertissement";
95 public static final String MARK_SEANCE = "seance";
96 public static final String MARK_LIST_RESERVATION = "liste_reservations";
97 public static final String MARK_TARIF_REDUIT_ID = "idTarifReduit";
98 public static final String MARK_BASE_URL = "base_url";
99 public static final String MARK_PARTNER_CONTACT_MAIL = "partner_contact_mail";
100
101
102 private static final String BEAN_STOCK_TICKETS_SEANCE_SERVICE = "stock-tickets.seanceService";
103 private static final String BEAN_STOCK_TICKETS_RESERVATION_DAO = "stock-tickets.reservationDAO";
104
105
106 private static final String JSP_MANAGE_OFFERS = "jsp/admin/plugins/stock/modules/billetterie/ManageOffers.jsp";
107 private static final String JSP_SEND_NOTIFICATION = "SendNotification.jsp";
108
109
110 private static final String TEMPLATE_SEND_NOTIFICATION = "admin/plugins/stock/modules/billetterie/send_notification.html";
111 private static final String TEMPLATE_MAIL_LOCK = "admin/plugins/stock/modules/billetterie/mail_lock.html";
112 private static final String TEMPLATE_MAIL_CANCEL = "admin/plugins/stock/modules/billetterie/mail_cancel.html";
113
114
115 private static final String PROPERTY_PAGE_TITLE_SEND_NOTIFICATION = "module.stock.billetterie.send_notification.title";
116 private static final String PROPERTY_MAIL_SEPARATOR = "mail.list.separator";
117
118
119 private static final String MESSAGE_AVERTISSEMENT_CANCEL_OFFER = "module.stock.billetterie.message.cancelOffer.avertissement";
120 private static final String MESSAGE_AVERTISSEMENT_SEND_OFFER = "module.stock.billetterie.message.sendOffer.avertissement";
121 private static final String MESSAGE_NOTIFICATION_CANCEL_SUBJECT = "module.stock.billetterie.notification.cancel.subject";
122 private static final String MESSAGE_NOTIFICATION_BOOKING_LIST_SUBJECT = "module.stock.billetterie.notification.bookingList.subject";
123
124
125 private static final String ORDER_FILTER_USER_NAME = "userName";
126 private ISeanceService _serviceOffer;
127 private IPurchaseService _servicePurchase;
128 private INotificationService _serviceNotification;
129 private IProviderService _serviceProvider;
130 private IShowService _serviceShow;
131
132
133 private IReservationDAO _daoPurchase;
134
135
136
137
138 public NotificationJspBean( )
139 {
140 super( );
141 _serviceOffer = (ISeanceService) SpringContextService.getBean( BEAN_STOCK_TICKETS_SEANCE_SERVICE );
142 _servicePurchase = SpringContextService.getContext( ).getBean( IPurchaseService.class );
143 _serviceNotification = SpringContextService.getContext( ).getBean( INotificationService.class );
144 _serviceProvider = SpringContextService.getContext( ).getBean( IProviderService.class );
145 _serviceShow = SpringContextService.getContext( ).getBean( IShowService.class );
146 _daoPurchase = (IReservationDAO) SpringContextService.getContext( ).getBean( BEAN_STOCK_TICKETS_RESERVATION_DAO );
147 }
148
149
150
151
152
153
154
155
156 public String getSendNotification( HttpServletRequest request )
157 {
158 NotificationDTO notification;
159 Map<String, Object> model = new HashMap<String, Object>( );
160
161
162 FunctionnalException ve = getErrorOnce( request );
163
164 if ( ve != null )
165 {
166 notification = (NotificationDTO) ve.getBean( );
167 model.put( BilletterieConstants.ERROR, getHtmlError( ve ) );
168 }
169 else
170 {
171 setPageTitleProperty( PROPERTY_PAGE_TITLE_SEND_NOTIFICATION );
172
173 notification = new NotificationDTO( );
174 }
175
176 String strIdOffer = request.getParameter( MARK_OFFER_ID );
177 String strCancel = request.getParameter( MARK_CANCEL );
178 String strNotify = request.getParameter( MARK_NOTIFY );
179 String strLock = request.getParameter( MARK_LOCK );
180 Integer idOffer = Integer.parseInt( strIdOffer );
181
182 SeanceDTO seanceDto = new SeanceDTO( );
183 seanceDto = ofNullable( idOffer ).map( e -> _serviceOffer.findSeanceById( e ) ).orElse( null );
184 ShowDTO showDto = ofNullable( seanceDto ).map( e -> e.getProduct( ) ).orElse( null );
185 Product productById = ofNullable(showDto).map( e ->_serviceShow.getProductById(e.getId()) ).orElse(null);
186 PurchaseFilter filter = new PurchaseFilter( );
187
188 List<ReservationDTO> listReservations = new ArrayList<>( );
189 Set<ReservationDTO> listReservationsPurchaseByUsername = new HashSet<>();
190 Set<ReservationDTO> listReservationsPurchase = new HashSet<>();
191
192 List<String> listContact = new ArrayList<>( );
193
194 if ( StringUtils.isNotEmpty( strIdOffer ) )
195 {
196 SeanceDTO seance = this._serviceOffer.findSeanceById( idOffer );
197 notification.setIdOffer( idOffer );
198
199 List<String> orderList = new ArrayList<String>( );
200 orderList.add( ORDER_FILTER_USER_NAME );
201 filter.setOrders( orderList );
202 filter.setOrderAsc( true );
203 filter.setIdOffer( idOffer );
204
205 listReservations = this._servicePurchase.findByFilter( filter, null );
206
207 Map<String, Integer> reservationDtoByUsername = listReservations.stream()
208 .collect(groupingBy(ReservationDTO::getUserName, Collectors.summingInt(ReservationDTO::getQuantity)
209 ));
210
211 listReservationsPurchaseByUsername = listReservations.stream()
212 .collect(Collectors.toCollection(() ->
213 new TreeSet<>(Comparator.comparing(ReservationDTO::getUserName))));
214
215 if (reservationDtoByUsername != null) {
216 for (ReservationDTO reservationDTO:listReservationsPurchaseByUsername) {
217 reservationDTO.setQuantity(reservationDtoByUsername.get(reservationDTO.getUserName()));
218 listReservationsPurchase.add(reservationDTO);
219 }
220 }
221
222
223 if ( StringUtils.isNotEmpty( strCancel )
224 || ( ( notification.getNotificationAction( ) != null ) && notification.getNotificationAction( ).equals(
225 TicketsConstants.OFFER_STATUT_CANCEL ) ) )
226 {
227
228 notification.setNotificationAction( TicketsConstants.OFFER_STATUT_CANCEL );
229
230
231 StringBuilder recipientsTo = new StringBuilder( 100 );
232
233 for ( ReservationDTO reservationDTO : listReservationsPurchase )
234 {
235 recipientsTo.append( reservationDTO.getEmailAgent( ) ).append( AppPropertiesService.getProperty( PROPERTY_MAIL_SEPARATOR ) );
236
237 }
238
239 notification.setRecipientsTo( recipientsTo.toString( ) );
240
241 notification
242 .setSubject( getMessage( MESSAGE_NOTIFICATION_CANCEL_SUBJECT, seance.getProduct( ).getName( ), seance.getDate( ), seance.getHour( ) ) );
243
244
245 Map<String, Object> modelMail = new HashMap<String, Object>( );
246 modelMail.put( MARK_BASE_URL, AppPathService.getBaseUrl( request ) );
247 modelMail.put( MARK_SEANCE, seance );
248
249 HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_MAIL_CANCEL, request.getLocale( ), modelMail );
250 notification.setMessage( template.getHtml( ) );
251 }
252
253
254 else
255 if ( StringUtils.isNotEmpty( strLock )
256 || ( ( notification.getNotificationAction( ) != null ) && notification.getNotificationAction( ).equals(
257 TicketsConstants.OFFER_STATUT_LOCK ) ) )
258 {
259 ShowDTO product = seance.getProduct( );
260
261 if ( product != null )
262 {
263 Integer idSalle = product.getIdProvider( );
264
265 if ( idSalle != null )
266 {
267 Integer [ ] arrayIdContact = seance.getIdContact( );
268
269 if ( ( arrayIdContact != null ) && ( arrayIdContact.length > 0 ) )
270 {
271 PartnerDTO partner = _serviceProvider.findById( idSalle );
272 StringBuilder contactMail = null;
273
274 for ( Integer idContact : arrayIdContact )
275 {
276
277 if ( idContact >= 0 )
278 {
279 if ( contactMail == null )
280 {
281 contactMail = new StringBuilder( );
282 }
283 else
284 {
285 contactMail.append( ";" );
286 }
287
288 contactMail.append( partner.getContactMail( idContact ) );
289 }
290 }
291
292 if ( contactMail != null )
293 {
294 if ( contactMail.toString( ) != null )
295 {
296 notification.setRecipientsTo( contactMail.toString( ) );
297 }
298 else
299 {
300 notification.setRecipientsTo( "" );
301 }
302 }
303 }
304 }
305 }
306
307 notification.setNotificationAction( TicketsConstants.OFFER_STATUT_LOCK );
308
309
310 notification.setSubject( getMessage( MESSAGE_NOTIFICATION_BOOKING_LIST_SUBJECT, seance.getProduct( ).getName( ) + " " + seance.getDate( )
311 + " - " + seance.getHour( ) ) );
312
313
314 Map<String, Object> modelMail = new HashMap<String, Object>( );
315 modelMail.put( MARK_BASE_URL, AppPathService.getBaseUrl( request ) );
316 modelMail.put( MARK_SEANCE, seance );
317 modelMail.put( MARK_TARIF_REDUIT_ID, TicketsConstants.OFFER_TYPE_REDUCT_ID );
318 modelMail.put( MARK_LIST_RESERVATION, listReservationsPurchase );
319
320 HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_MAIL_LOCK, request.getLocale( ), modelMail );
321 notification.setMessage( template.getHtml( ) );
322 }
323
324
325 else
326 {
327
328 StringBuilder recipientsTo = new StringBuilder( );
329
330 for ( ReservationDTO purchase : listReservationsPurchase )
331 {
332 recipientsTo.append( purchase.getEmailAgent( ) ).append( AppPropertiesService.getProperty( PROPERTY_MAIL_SEPARATOR ) );
333 }
334
335 notification.setRecipientsTo( recipientsTo.toString( ) );
336 }
337 }
338
339
340 if ( StringUtils.isNotEmpty( strCancel )
341 || ( ( notification.getNotificationAction( ) != null ) && notification.getNotificationAction( ).equals( TicketsConstants.OFFER_STATUT_CANCEL ) ) )
342 {
343 model.put( MARK_AVERTISSEMENT, I18nService.getLocalizedString( MESSAGE_AVERTISSEMENT_CANCEL_OFFER, request.getLocale( ) ) );
344 }
345
346
347 else
348 if ( StringUtils.isNotEmpty( strLock )
349 || ( ( notification.getNotificationAction( ) != null ) && notification.getNotificationAction( ).equals( TicketsConstants.OFFER_STATUT_LOCK ) ) )
350 {
351 model.put( MARK_AVERTISSEMENT, I18nService.getLocalizedString( MESSAGE_AVERTISSEMENT_SEND_OFFER, request.getLocale( ) ) );
352 }
353
354
355 model.put( StockConstants.MARK_JSP_BACK, request.getParameter( StockConstants.MARK_JSP_BACK ) );
356 model.put( MARK_NOTIFICATION, notification );
357
358 model.put( MARK_TITLE, I18nService.getLocalizedString( PROPERTY_PAGE_TITLE_SEND_NOTIFICATION, Locale.getDefault( ) ) );
359
360 if ( StringUtils.isNotEmpty( strCancel ) || StringUtils.isNotEmpty( strNotify ) )
361 {
362 if (listReservationsPurchase !=null){
363 for ( ReservationDTO reservationDTO : listReservationsPurchase )
364 {
365 listContact.add( reservationDTO.getEmailAgent( ) );
366 }
367 }
368 }
369 else
370 {
371 List<Contact> lstContact = ofNullable( showDto ).map( e -> _serviceProvider.findById( e.getIdProvider( ) ).getContactList( ) ).orElse( null );
372
373 if ( lstContact != null && productById != null )
374 {
375 for ( Contact c : lstContact )
376 {
377 for ( AbstractAttributeNum sh : productById.getAttributeNumList( ) )
378 {
379 if ( sh.getValue( ).intValueExact( ) == c.getId( ) && sh.getKey( ).contains( "idContact" ) )
380 {
381 listContact.add( c.getMail( ) );
382 }
383 }
384 }
385 }
386 }
387
388 model.put( MARK_PARTNER_CONTACT_MAIL, listContact );
389
390 HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_SEND_NOTIFICATION, getLocale( ), model );
391
392 return getAdminPage( template.getHtml( ) );
393 }
394
395
396
397
398
399
400
401
402 public String doSendNotification( HttpServletRequest request )
403 {
404 if ( null != request.getParameter( StockConstants.PARAMETER_BUTTON_CANCEL ) )
405 {
406 return doGoBack( request );
407 }
408
409 NotificationDTO notification = new NotificationDTO( );
410 populate( notification, request );
411
412 try
413 {
414
415 validateBilletterie( notification );
416
417 if ( ( notification.getIdOffer( ) != null ) && ( notification.getIdOffer( ) > 0 ) )
418 {
419 SeanceDTO seance = this._serviceOffer.findSeanceById( notification.getIdOffer( ) );
420
421 if ( notification.getNotificationAction( ).equals( TicketsConstants.OFFER_STATUT_LOCK ) )
422 {
423 seance.setStatut( TicketsConstants.OFFER_STATUT_LOCK );
424 this._serviceOffer.update( seance );
425 }
426 else
427 if ( notification.getNotificationAction( ).equals( TicketsConstants.OFFER_STATUT_CANCEL ) )
428 {
429 seance.setStatut( TicketsConstants.OFFER_STATUT_CANCEL );
430 this._serviceOffer.update( seance );
431 }
432 }
433
434 _serviceNotification.send( notification );
435 }
436 catch( FunctionnalException e )
437 {
438 return manageFunctionnalException( request, e, JSP_SEND_NOTIFICATION );
439 }
440
441 return doGoBack( request );
442 }
443
444
445
446
447
448
449
450
451 private String doGoBack( HttpServletRequest request )
452 {
453 String strJspBack = request.getParameter( StockConstants.MARK_JSP_BACK );
454
455 return StringUtils.isNotBlank( strJspBack ) ? ( AppPathService.getBaseUrl( request ) + strJspBack )
456 : ( AppPathService.getBaseUrl( request ) + JSP_MANAGE_OFFERS );
457 }
458 }