View Javadoc
1   /*
2    * Copyright (c) 2002-2018, Mairie de 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.stock.modules.billetterie.web;
35  
36  import au.com.bytecode.opencsv.CSVWriter;
37  
38  import com.keypoint.PngEncoder;
39  
40  import fr.paris.lutece.plugins.stock.commons.exception.BusinessException;
41  import fr.paris.lutece.plugins.stock.modules.billetterie.utils.constants.BilletterieConstants;
42  import fr.paris.lutece.plugins.stock.modules.tickets.business.ResultStatistic;
43  import fr.paris.lutece.plugins.stock.modules.tickets.service.IStatisticService;
44  import fr.paris.lutece.plugins.stock.modules.tickets.service.StatisticService;
45  import fr.paris.lutece.plugins.stock.modules.tickets.utils.constants.TicketsConstants;
46  import fr.paris.lutece.plugins.stock.modules.tickets.utils.export.TicketsExportUtils;
47  import fr.paris.lutece.plugins.stock.utils.DateUtils;
48  import fr.paris.lutece.plugins.stock.utils.constants.StockConstants;
49  import fr.paris.lutece.portal.service.admin.AdminUserService;
50  import fr.paris.lutece.portal.service.i18n.I18nService;
51  import fr.paris.lutece.portal.service.spring.SpringContextService;
52  import fr.paris.lutece.portal.service.template.AppTemplateService;
53  import fr.paris.lutece.portal.service.util.AppLogService;
54  import fr.paris.lutece.portal.service.util.AppPropertiesService;
55  import fr.paris.lutece.util.date.DateUtil;
56  import fr.paris.lutece.util.html.HtmlTemplate;
57  import fr.paris.lutece.util.url.UrlItem;
58  
59  import org.apache.commons.lang.StringUtils;
60  
61  import org.jfree.chart.ChartRenderingInfo;
62  import org.jfree.chart.JFreeChart;
63  import org.jfree.chart.entity.StandardEntityCollection;
64  
65  import java.awt.image.BufferedImage;
66  
67  import java.io.IOException;
68  import java.io.OutputStream;
69  import java.io.StringWriter;
70  import java.io.UnsupportedEncodingException;
71  
72  import java.sql.Timestamp;
73  
74  import java.util.ArrayList;
75  import java.util.Date;
76  import java.util.HashMap;
77  import java.util.List;
78  import java.util.Locale;
79  import java.util.Map;
80  
81  import javax.servlet.http.HttpServletRequest;
82  import javax.servlet.http.HttpServletResponse;
83  
84  /**
85   * The Class StatisticJspBean.
86   */
87  public class StatisticJspBean extends AbstractJspBean
88  {
89      /** The constant String CONSTANT_PRODUCT_TYPE */
90      public static final String CONSTANT_PRODUCT_TYPE = "1";
91  
92      /** The constant String CONSTANT_GROUP_BY_DAY */
93      public static final String CONSTANT_GROUP_BY_DAY = "0";
94  
95      /** The constant String CONSTANT_GROUP_BY_WEEK */
96      public static final String CONSTANT_GROUP_BY_WEEK = "1";
97  
98      /** The constant String CONSTANT_GROUP_BY_MONTH */
99      public static final String CONSTANT_GROUP_BY_MONTH = "2";
100 
101     /** The constant String CONSTANT_PURCHASE_TYPE */
102     public static final String CONSTANT_PURCHASE_TYPE = "2";
103 
104     // RIGHT
105     /** The constant String RIGHT_MANAGE_STATISTICS */
106     public static final String RIGHT_MANAGE_STATISTICS = "STATISTICS_MANAGEMENT";
107     private static final long serialVersionUID = -2502151554115352120L;
108 
109     // PAGES TITLES
110     private static final String PAGE_TITLE_MANAGE_PRODUCTS = "module.stock.billetterie.manage_products_statistics.pageTitle";
111     private static final String PAGE_TITLE_MANAGE_PURCHASE = "module.stock.billetterie.manage_purchase_statistics.pageTitle";
112 
113     // TEMPLATES
114     private static final String TEMPLATE_MANAGE_STATISTICS = "admin/plugins/stock/modules/billetterie/manage_statistics.html";
115     private static final String TEMPLATE_MANAGE_PRODUCTS_STATISTICS = "admin/plugins/stock/modules/billetterie/manage_products_statistics.html";
116     private static final String TEMPLATE_MANAGE_PURCHASE_STATISTICS = "admin/plugins/stock/modules/billetterie/manage_purchases_statistics.html";
117 
118     // MARKS
119     private static final String MARK_NUMBER_RESPONSE = "number_response";
120     private static final String MARK_FIRST_RESPONSE_DATE_FILTER = "fist_response_date_filter";
121     private static final String MARK_LAST_RESPONSE_DATE_FILTER = "last_response_date_filter";
122     private static final String PARAMETER_FIRST_RESPONSE_DATE_FILTER = "fist_response_date_filter";
123     private static final String PARAMETER_LAST_RESPONSE_DATE_FILTER = "last_response_date_filter";
124     private static final String MARK_TIMES_UNIT = "times_unit";
125     private static final String PARAMETER_TIMES_UNIT = "times_unit";
126     private static final String MARK_LOCALE = "locale";
127     private static final String PARAMETER_TYPE_DATA = "type_data";
128 
129     // MESSAGES
130     private static final String MESSAGE_ERROR_INVALID_DATE = "module.stock.billetterie.message.error.dateBeginBeforeDateEnd";
131 
132     // PROPERTIES
133     private static final String PROPERTY_PRODUCT_STAT_EXPORT_FILE_NAME = "stock-billetterie.csv.product.file.name";
134     private static final String PROPERTY_PURCHASE_STAT_EXPORT_FILE_NAME = "stock-billetterie.csv.purchase.file.name";
135     private static final String PROPERTY_ENCODING = "stock-billetterie.csv.encoding";
136     private static final String PROPERTY_NUMBER_RESPONSE_AXIS_X = "graph.numberResponseAxisX";
137     private static final String PROPERTY_LABEL_AXIS_X = "module.stock.billetterie.manage_statistics.labelAxisX";
138     private static final String PROPERTY_LABEL_AXIS_Y_PRODUCT = "module.stock.billetterie.manage_products_statistics.labelAxisY";
139     private static final String PROPERTY_LABEL_AXIS_Y_PURCHASE = "module.stock.billetterie.manage_purchases_statistics.labelAxisY";
140     private static final String CONTENT_TYPE_IMAGE_PNG = "image/PNG";
141 
142     /** The _service statistic. */
143     // @Inject
144     private IStatisticService _serviceStatistic;
145 
146     /**
147      * Instantiates a new statistic jsp bean.
148      */
149     public StatisticJspBean( )
150     {
151         super( );
152         _serviceStatistic = SpringContextService.getContext( ).getBean( IStatisticService.class );
153     }
154 
155     /**
156      * Generates a HTML form that displays the link to manage the visitors statistics and polls.
157      *
158      * @param request
159      *            the Http request
160      * @return HTML
161      */
162     public String getManageStatistics( HttpServletRequest request )
163     {
164         setPageTitleProperty( StockConstants.EMPTY_STRING );
165 
166         Map<String, Object> model = new HashMap<String, Object>( );
167         HtmlTemplate t = AppTemplateService.getTemplate( TEMPLATE_MANAGE_STATISTICS, getLocale( ), model );
168 
169         return getAdminPage( t.getHtml( ) );
170     }
171 
172     /**
173      * Gets the form result page.
174      *
175      * @param request
176      *            the http request
177      * @return the form test page
178      */
179     public String getManageProducts( HttpServletRequest request )
180     {
181         Locale locale = getLocale( );
182         HtmlTemplate template;
183         int nNumberResponse = 0;
184         Map<String, Object> model = new HashMap<String, Object>( );
185 
186         String strFistResponseDateFilter = request.getParameter( PARAMETER_FIRST_RESPONSE_DATE_FILTER );
187         String strLastResponseDateFilter = request.getParameter( PARAMETER_LAST_RESPONSE_DATE_FILTER );
188         String strTimesUnit = request.getParameter( PARAMETER_TIMES_UNIT );
189 
190         if ( ( strFistResponseDateFilter != null ) && ( strLastResponseDateFilter != null ) && !strFistResponseDateFilter.equals( StringUtils.EMPTY )
191                 && !strLastResponseDateFilter.equals( StringUtils.EMPTY ) )
192         {
193             if ( DateUtil.formatDate( strFistResponseDateFilter, locale ).after( DateUtil.formatDate( strLastResponseDateFilter, locale ) ) )
194             {
195                 BusinessException fe = new BusinessException( null, MESSAGE_ERROR_INVALID_DATE );
196                 model.put( BilletterieConstants.ERROR, getHtmlError( fe ) );
197             }
198         }
199 
200         Timestamp tFistResponseDateFilter = null;
201         Timestamp tLastResponseDateFilter = null;
202 
203         if ( strFistResponseDateFilter != null )
204         {
205             tFistResponseDateFilter = DateUtils.getDateFirstMinute( DateUtil.formatDate( strFistResponseDateFilter, locale ) );
206         }
207 
208         if ( strLastResponseDateFilter != null )
209         {
210             tLastResponseDateFilter = DateUtils.getDateLastMinute( DateUtil.formatDate( strLastResponseDateFilter, locale ) );
211         }
212 
213         nNumberResponse = _serviceStatistic.getCountProductsByDates( strFistResponseDateFilter, strLastResponseDateFilter );
214 
215         if ( strTimesUnit == null )
216         {
217             strTimesUnit = CONSTANT_GROUP_BY_DAY;
218         }
219 
220         model.put( MARK_LOCALE, AdminUserService.getLocale( request ).getLanguage( ) );
221         model.put( MARK_NUMBER_RESPONSE, nNumberResponse );
222         model.put( MARK_FIRST_RESPONSE_DATE_FILTER, ( tFistResponseDateFilter == null ) ? null : new Date( tFistResponseDateFilter.getTime( ) ) );
223         model.put( MARK_LAST_RESPONSE_DATE_FILTER, ( tLastResponseDateFilter == null ) ? null : new Date( tLastResponseDateFilter.getTime( ) ) );
224         model.put( MARK_TIMES_UNIT, strTimesUnit );
225         // model.put( MARK_EXPORT_FORMAT_REF_LIST, ExportFormatHome.getListExport( plugin ) );
226         model.put( "beanName", "product" );
227         setPageTitleProperty( PAGE_TITLE_MANAGE_PRODUCTS );
228         template = AppTemplateService.getTemplate( TEMPLATE_MANAGE_PRODUCTS_STATISTICS, locale, model );
229 
230         return getAdminPage( template.getHtml( ) );
231     }
232 
233     /**
234      * Gets the form result page.
235      *
236      * @param request
237      *            the http request
238      * @return the form test page
239      */
240     public String getManagePurchases( HttpServletRequest request )
241     {
242         Locale locale = getLocale( );
243         HtmlTemplate template;
244         int nNumberResponse = 0;
245         Map<String, Object> model = new HashMap<String, Object>( );
246 
247         String strFistResponseDateFilter = request.getParameter( PARAMETER_FIRST_RESPONSE_DATE_FILTER );
248         String strLastResponseDateFilter = request.getParameter( PARAMETER_LAST_RESPONSE_DATE_FILTER );
249         String strTimesUnit = request.getParameter( PARAMETER_TIMES_UNIT );
250 
251         if ( ( strFistResponseDateFilter != null ) && ( strLastResponseDateFilter != null ) && !strFistResponseDateFilter.equals( StringUtils.EMPTY )
252                 && !strLastResponseDateFilter.equals( StringUtils.EMPTY ) )
253         {
254             if ( DateUtil.formatDate( strFistResponseDateFilter, locale ).after( DateUtil.formatDate( strLastResponseDateFilter, locale ) ) )
255             {
256                 BusinessException fe = new BusinessException( null, MESSAGE_ERROR_INVALID_DATE );
257                 model.put( BilletterieConstants.ERROR, getHtmlError( fe ) );
258             }
259         }
260 
261         Timestamp tFistResponseDateFilter = null;
262         Timestamp tLastResponseDateFilter = null;
263 
264         if ( strFistResponseDateFilter != null )
265         {
266             tFistResponseDateFilter = DateUtils.getDateFirstMinute( DateUtil.formatDate( strFistResponseDateFilter, locale ) );
267         }
268 
269         if ( strLastResponseDateFilter != null )
270         {
271             tLastResponseDateFilter = DateUtils.getDateLastMinute( DateUtil.formatDate( strLastResponseDateFilter, locale ) );
272         }
273 
274         nNumberResponse = _serviceStatistic.getCountPurchasesByDates( strFistResponseDateFilter, strLastResponseDateFilter );
275 
276         if ( strTimesUnit == null )
277         {
278             strTimesUnit = CONSTANT_GROUP_BY_DAY;
279         }
280 
281         model.put( MARK_LOCALE, AdminUserService.getLocale( request ).getLanguage( ) );
282         model.put( MARK_NUMBER_RESPONSE, nNumberResponse );
283         model.put( MARK_FIRST_RESPONSE_DATE_FILTER, ( tFistResponseDateFilter == null ) ? null : new Date( tFistResponseDateFilter.getTime( ) ) );
284         model.put( MARK_LAST_RESPONSE_DATE_FILTER, ( tLastResponseDateFilter == null ) ? null : new Date( tLastResponseDateFilter.getTime( ) ) );
285         model.put( MARK_TIMES_UNIT, strTimesUnit );
286         // model.put( MARK_EXPORT_FORMAT_REF_LIST, ExportFormatHome.getListExport( plugin ) );
287         setPageTitleProperty( PAGE_TITLE_MANAGE_PURCHASE );
288         template = AppTemplateService.getTemplate( TEMPLATE_MANAGE_PURCHASE_STATISTICS, locale, model );
289 
290         return getAdminPage( template.getHtml( ) );
291     }
292 
293     /**
294      * write in the http response the statistic graph of all response submit who verify the date filter.
295      *
296      * @param request
297      *            the http request
298      * @param response
299      *            The http response
300      */
301     public void doGenerateGraph( HttpServletRequest request, HttpServletResponse response )
302     {
303         Locale locale = getLocale( );
304         String strFistResponseDateFilter = request.getParameter( PARAMETER_FIRST_RESPONSE_DATE_FILTER );
305         String strLastResponseDateFilter = request.getParameter( PARAMETER_LAST_RESPONSE_DATE_FILTER );
306         String strTimesUnit = request.getParameter( PARAMETER_TIMES_UNIT );
307         String strTypeData = request.getParameter( PARAMETER_TYPE_DATA );
308 
309         List<ResultStatistic> listeResultStatistic = null;
310 
311         if ( strTypeData.equals( CONSTANT_PRODUCT_TYPE ) )
312         {
313             listeResultStatistic = _serviceStatistic.getProductStatistic( strTimesUnit, strFistResponseDateFilter, strLastResponseDateFilter );
314         }
315         else
316         {
317             listeResultStatistic = _serviceStatistic.getPurchaseStatistic( strTimesUnit, strFistResponseDateFilter, strLastResponseDateFilter );
318         }
319 
320         String strNumberOfResponseAxisX = AppPropertiesService.getProperty( PROPERTY_NUMBER_RESPONSE_AXIS_X );
321         int nNumberOfResponseAxisX = 10;
322 
323         try
324         {
325             nNumberOfResponseAxisX = Integer.parseInt( strNumberOfResponseAxisX );
326         }
327         catch( NumberFormatException ne )
328         {
329             AppLogService.error( ne );
330         }
331 
332         List<ResultStatistic> listStatisticGraph = new ArrayList<ResultStatistic>( );
333         ResultStatistic statisticFormSubmit;
334 
335         if ( listeResultStatistic.size( ) != 0 )
336         {
337             for ( int cpt = 0; cpt < nNumberOfResponseAxisX; cpt++ )
338             {
339                 statisticFormSubmit = new ResultStatistic( );
340                 statisticFormSubmit.setNumberResponse( 0 );
341                 statisticFormSubmit.setStatisticDate( StatisticService.addStatisticInterval( listeResultStatistic.get( 0 ).getStatisticDate( ), strTimesUnit,
342                         cpt ) );
343                 listStatisticGraph.add( statisticFormSubmit );
344             }
345         }
346 
347         for ( ResultStatistic statisticFormSubmitGraph : listStatisticGraph )
348         {
349             for ( ResultStatistic resultStatistic : listeResultStatistic )
350             {
351                 if ( StatisticService.sameDate( statisticFormSubmitGraph.getStatisticDate( ), resultStatistic.getStatisticDate( ), strTimesUnit ) )
352                 {
353                     statisticFormSubmitGraph.setNumberResponse( resultStatistic.getNumberResponse( ) );
354                 }
355             }
356         }
357 
358         String strLabelAxisX = I18nService.getLocalizedString( PROPERTY_LABEL_AXIS_X, locale );
359         String strLabelAxisY;
360 
361         if ( strTypeData.equals( CONSTANT_PRODUCT_TYPE ) )
362         {
363             strLabelAxisY = I18nService.getLocalizedString( PROPERTY_LABEL_AXIS_Y_PRODUCT, locale );
364         }
365         else
366         {
367             strLabelAxisY = I18nService.getLocalizedString( PROPERTY_LABEL_AXIS_Y_PURCHASE, locale );
368         }
369 
370         try
371         {
372             JFreeChart chart = StatisticService.createXYGraph( listStatisticGraph, strLabelAxisX, strLabelAxisY, strTimesUnit );
373 
374             ChartRenderingInfo info = new ChartRenderingInfo( new StandardEntityCollection( ) );
375             BufferedImage chartImage = chart.createBufferedImage( 600, 200, info );
376             response.setContentType( CONTENT_TYPE_IMAGE_PNG );
377 
378             PngEncoder encoder = new PngEncoder( chartImage, false, 0, 9 );
379             response.getOutputStream( ).write( encoder.pngEncode( ) );
380             response.getOutputStream( ).flush( );
381             response.getOutputStream( ).close( );
382         }
383         catch( Exception e )
384         {
385             AppLogService.error( e );
386         }
387     }
388 
389     /**
390      * Exports all the statistics visitors filtered.
391      *
392      * @param request
393      *            The Http request
394      * @param response
395      *            The Http response
396      * @return The Url after the export
397      */
398     public String doExportStatistics( HttpServletRequest request, HttpServletResponse response )
399     {
400         String strFistResponseDateFilter = request.getParameter( PARAMETER_FIRST_RESPONSE_DATE_FILTER );
401         String strLastResponseDateFilter = request.getParameter( PARAMETER_LAST_RESPONSE_DATE_FILTER );
402         String strTimesUnit = request.getParameter( PARAMETER_TIMES_UNIT );
403         String strTypeData = request.getParameter( PARAMETER_TYPE_DATA );
404         List<ResultStatistic> listeResultStatistic = null;
405         String strExportFileName;
406 
407         if ( strTypeData.equals( CONSTANT_PRODUCT_TYPE ) )
408         {
409             listeResultStatistic = _serviceStatistic.getProductStatistic( strTimesUnit, strFistResponseDateFilter, strLastResponseDateFilter );
410             strExportFileName = PROPERTY_PRODUCT_STAT_EXPORT_FILE_NAME;
411         }
412         else
413         {
414             listeResultStatistic = _serviceStatistic.getPurchaseStatistic( strTimesUnit, strFistResponseDateFilter, strLastResponseDateFilter );
415             strExportFileName = PROPERTY_PURCHASE_STAT_EXPORT_FILE_NAME;
416         }
417 
418         List<String [ ]> listToCSVWriter = StatisticService.buildListToCSVWriter( listeResultStatistic, strTimesUnit, getLocale( ) );
419 
420         // if ( listToCSVWriter == null )
421         // {
422         // if ( strTypeData.equals( CONSTANT_PRODUCT_TYPE ) )
423         // {
424         // return getManageProducts( request );
425         // }
426         // else
427         // {
428         // return getManagePurchases( request );
429         // }
430         // }
431         String strCsvSeparator = AppPropertiesService.getProperty( TicketsConstants.PROPERTY_CSV_SEPARATOR );
432         StringWriter strWriter = new StringWriter( );
433         CSVWriter csvWriter = new CSVWriter( strWriter, strCsvSeparator.toCharArray( ) [0] );
434 
435         csvWriter.writeAll( listToCSVWriter );
436 
437         String strEncoding = AppPropertiesService.getProperty( PROPERTY_ENCODING );
438         byte [ ] byteFileOutPut;
439 
440         try
441         {
442             byteFileOutPut = strWriter.toString( ).getBytes( strEncoding );
443         }
444         catch( UnsupportedEncodingException e )
445         {
446             byteFileOutPut = strWriter.toString( ).getBytes( );
447         }
448 
449         try
450         {
451             String strFormatExtension = AppPropertiesService.getProperty( TicketsConstants.PROPERTY_CSV_EXTENSION );
452             String strFileName = AppPropertiesService.getProperty( strExportFileName ) + "." + strFormatExtension;
453             TicketsExportUtils.addHeaderResponse( request, response, strFileName, strFormatExtension );
454             response.setContentLength( byteFileOutPut.length );
455 
456             OutputStream os = response.getOutputStream( );
457             os.write( byteFileOutPut );
458             os.flush( );
459             os.close( );
460 
461             // We do not close the output stream to allow HTTP keep alive
462         }
463         catch( IOException e )
464         {
465             AppLogService.error( e.getMessage( ), e );
466         }
467         finally
468         {
469             try
470             {
471                 csvWriter.close( );
472             }
473             catch( IOException e )
474             {
475                 AppLogService.error( e.getMessage( ), e );
476             }
477 
478             try
479             {
480                 strWriter.close( );
481             }
482             catch( IOException e )
483             {
484                 AppLogService.error( e.getMessage( ), e );
485             }
486         }
487 
488         UrlItem url = new UrlItem( getManageProducts( request ) );
489 
490         return url.getUrl( );
491     }
492 }