View Javadoc
1   /*
2    * Copyright (c) 2002-2022, City of 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.appointment.modules.management.web;
35  
36  import java.util.ArrayList;
37  import java.util.Arrays;
38  import java.util.List;
39  import java.util.Locale;
40  import java.util.Map;
41  import java.util.stream.Collectors;
42  
43  import javax.servlet.http.HttpServletRequest;
44  
45  import org.apache.commons.lang3.ArrayUtils;
46  import org.apache.commons.lang3.StringUtils;
47  
48  import fr.paris.lutece.api.user.User;
49  import fr.paris.lutece.plugins.appointment.business.category.Category;
50  import fr.paris.lutece.plugins.appointment.business.category.CategoryHome;
51  import fr.paris.lutece.plugins.appointment.business.form.Form;
52  import fr.paris.lutece.plugins.appointment.business.form.FormHome;
53  import fr.paris.lutece.plugins.appointment.modules.management.business.search.AppointmentSearchItem;
54  import fr.paris.lutece.plugins.appointment.modules.management.business.search.MultiviewFilter;
55  import fr.paris.lutece.plugins.appointment.modules.management.service.AppointmentSearchService;
56  import fr.paris.lutece.plugins.appointment.modules.management.service.IAppointmentSearchService;
57  import fr.paris.lutece.plugins.appointment.modules.management.service.search.AppointmentSortConfig;
58  import fr.paris.lutece.plugins.appointment.service.AppointmentResourceIdService;
59  import fr.paris.lutece.plugins.appointment.service.AppointmentService;
60  import fr.paris.lutece.plugins.appointment.service.export.AppointmentExportService;
61  import fr.paris.lutece.plugins.appointment.service.export.ExcelAppointmentGenerator;
62  import fr.paris.lutece.plugins.appointment.web.dto.AppointmentDTO;
63  import fr.paris.lutece.plugins.filegenerator.service.TemporaryFileGeneratorService;
64  import fr.paris.lutece.portal.service.admin.AccessDeniedException;
65  import fr.paris.lutece.portal.service.i18n.I18nService;
66  import fr.paris.lutece.portal.service.rbac.RBACService;
67  import fr.paris.lutece.portal.service.spring.SpringContextService;
68  import fr.paris.lutece.portal.service.util.AppPropertiesService;
69  import fr.paris.lutece.portal.service.workgroup.AdminWorkgroupService;
70  import fr.paris.lutece.portal.util.mvc.admin.MVCAdminJspBean;
71  import fr.paris.lutece.portal.util.mvc.admin.annotations.Controller;
72  import fr.paris.lutece.portal.util.mvc.commons.annotations.Action;
73  import fr.paris.lutece.portal.util.mvc.commons.annotations.View;
74  import fr.paris.lutece.portal.web.util.LocalizedDelegatePaginator;
75  import fr.paris.lutece.util.ReferenceItem;
76  import fr.paris.lutece.util.ReferenceList;
77  import fr.paris.lutece.util.html.AbstractPaginator;
78  
79  @Controller( controllerJsp = "MultiviewAppointment.jsp", controllerPath = "jsp/admin/plugins/appointment/modules/management", right = "MULTIVIEW_APPOINTMENT" )
80  public class MultiviewAppointmentJspBean extends MVCAdminJspBean
81  {
82      private static final long serialVersionUID = 2621411978305115179L;
83  
84      private static final String PROPERTY_DEFAULT_LIST_ITEM_PER_PAGE = "appointment-management.itemsPerPage";
85      private static final String JSP_MANAGE_APPOINTMENT = "jsp/admin/plugins/appointment/modules/management/MultiviewAppointment.jsp";
86  
87      // Parameters
88      private static final String PARAMETER_PAGE_INDEX = "page_index";
89      private static final String PARAMETER_ORDER_BY = "orderBy";
90      private static final String PARAMETER_ORDER_ASC = "orderAsc";
91      private static final String PARAMETER_SEARCH = "Search";
92      private static final String PARAMETER_RESET = "reset";
93      private static final String PARAMETER_SELECTED_DEFAULT_FIELD = "selectedDefaultFieldList";
94  
95      // Views
96      private static final String MULTIVIEW_APPOINTMENTS = "multiview_appointments";
97  
98      // Actions
99      private static final String ACTION_EXPORT_APPOINTMENTS = "doExportAppointments";
100 
101     // Templates
102     private static final String TEMPLATE_MULTIVIEW_APPOINTMENT = "admin/plugins/appointment/modules/management/multiview_appointments.html";
103 
104     // Properties for page titles
105     private static final String PROPERTY_PAGE_TITLE_MULTIVIEW_APPOINTMENTS = "module.appointment.management.multiview.appointment.pageTitle";
106     private static final String UNRESERVED = "appointment.message.labelStatusUnreserved";
107     private static final String RESERVED = "appointment.message.labelStatusReserved";
108 
109     // Marks
110     private static final String MARK_APPOINTMENT_LIST = "appointment_list";
111     private static final String MARK_PAGINATOR = "paginator";
112     private static final String MARK_NB_ITEMS_PER_PAGE = "nb_items_per_page";
113     private static final String MARK_LIST_STATUS = "listStatus";
114     private static final String MARK_LIST_FORMS = "listForms";
115     private static final String MARK_LIST_CATEGORIES = "listCategories";
116     private static final String MARK_FILTER = "filter";
117     private static final String MARK_LANGUAGE = "language";
118     private static final String MARK_DEFAULT_FIELD_LIST = "defaultFieldList";
119 
120     private static final String START_DATE = "start_date";
121 
122     // Variables
123     private IAppointmentSearchService _appointmentSearchService = SpringContextService.getBean( AppointmentSearchService.BEAN_NAME );
124     private String _strCurrentPageIndex;
125     private int _nItemsPerPage;
126     private AppointmentSortConfig _sortConfig;
127     private MultiviewFilter _filter;
128 
129     /**
130      * Return the view with the responses of all the appointments
131      * 
132      * @param request
133      *            The request on which to retrieve informations
134      * @return the view associated to the responses value of all forms
135      */
136     @View( value = MULTIVIEW_APPOINTMENTS, defaultView = true )
137     public String getMultiviewAppointments( HttpServletRequest request )
138     {
139         initiatePaginatorProperties( request );
140 
141         // If it is a new search
142         if ( request.getParameter( PARAMETER_SEARCH ) != null )
143         {
144             // Populate the filter
145             populate( _filter, request );
146             _strCurrentPageIndex = "1";
147         }
148         else
149             if ( request.getParameter( PARAMETER_RESET ) != null || _filter == null )
150             {
151                 _filter = new MultiviewFilter( );
152             }
153 
154         ReferenceList formList = getListForms( getUser( ) );
155         _filter.setIdFormList( formList.stream( ).map( ReferenceItem::getCode ).map( Integer::parseInt ).collect( Collectors.toList( ) ) );
156 
157         List<AppointmentSearchItem> appointmentList = new ArrayList<>( );
158         int nbResults = _appointmentSearchService.search( appointmentList, _filter, getIndexStart( ), _nItemsPerPage, _sortConfig );
159         LocalizedDelegatePaginator<AppointmentSearchItem> paginator = new LocalizedDelegatePaginator<>( appointmentList, _nItemsPerPage, JSP_MANAGE_APPOINTMENT,
160                 PARAMETER_PAGE_INDEX, _strCurrentPageIndex, nbResults, getLocale( ) );
161 
162         Map<String, Object> model = getModel( );
163         model.put( MARK_NB_ITEMS_PER_PAGE, String.valueOf( _nItemsPerPage ) );
164         model.put( MARK_PAGINATOR, paginator );
165         model.put( MARK_APPOINTMENT_LIST, paginator.getPageItems( ) );
166         model.put( MARK_LIST_STATUS, getListStatus( ) );
167         model.put( MARK_FILTER, _filter );
168         model.put( MARK_LANGUAGE, getLocale( ) );
169         model.put( MARK_LIST_FORMS, formList );
170         model.put( MARK_LIST_CATEGORIES, getListCategories( ) );
171         model.put( MARK_DEFAULT_FIELD_LIST, AppointmentExportService.getDefaultColumnList( getLocale( ) ) );
172 
173         return getPage( PROPERTY_PAGE_TITLE_MULTIVIEW_APPOINTMENTS, TEMPLATE_MULTIVIEW_APPOINTMENT, model );
174     }
175 
176     /**
177      * Do download a file from an appointment response
178      * 
179      * @param request
180      *            The request
181      * @param response
182      *            The response
183      * @return nothing.
184      * @throws AccessDeniedException
185      *             If the user is not authorized to access this feature
186      */
187     @Action( ACTION_EXPORT_APPOINTMENTS )
188     public String doExportAppointments( HttpServletRequest request ) throws AccessDeniedException
189     {
190         Locale locale = getLocale( );
191         List<AppointmentDTO> listAppointmentsDTO = new ArrayList<>( );
192         if ( _filter != null )
193         {
194             List<AppointmentSearchItem> appointmentList = new ArrayList<>( );
195             _appointmentSearchService.search( appointmentList, _filter, 0, 0, _sortConfig );
196 
197             for ( AppointmentSearchItem item : appointmentList )
198             {
199                 listAppointmentsDTO.add( AppointmentService.buildAppointmentDTOFromIdAppointment( item.getIdAppointment( ) ) );
200             }
201         }
202 
203         List<String> defaultColumnList = new ArrayList<>( );
204         if ( ArrayUtils.isNotEmpty( request.getParameterValues( PARAMETER_SELECTED_DEFAULT_FIELD ) ) )
205         {
206             defaultColumnList = Arrays.asList( request.getParameterValues( PARAMETER_SELECTED_DEFAULT_FIELD ) );
207         }
208 
209         ExcelAppointmentGenerator generator = new ExcelAppointmentGenerator( defaultColumnList, locale, listAppointmentsDTO, new ArrayList<>( ) );
210 
211         TemporaryFileGeneratorService.getInstance( ).generateFile( generator, getUser( ) );
212         addInfo( "appointment.export.async.message", locale );
213 
214         return getMultiviewAppointments( request );
215     }
216 
217     private void initiatePaginatorProperties( HttpServletRequest request )
218     {
219         _sortConfig = null;
220         _strCurrentPageIndex = AbstractPaginator.getPageIndex( request, AbstractPaginator.PARAMETER_PAGE_INDEX, _strCurrentPageIndex );
221         int nDefaultItemsPerPage = AppPropertiesService.getPropertyInt( PROPERTY_DEFAULT_LIST_ITEM_PER_PAGE, 50 );
222         _nItemsPerPage = AbstractPaginator.getItemsPerPage( request, AbstractPaginator.PARAMETER_ITEMS_PER_PAGE, _nItemsPerPage, nDefaultItemsPerPage );
223 
224 
225         String sortName = request.getParameter( PARAMETER_ORDER_BY );
226         String sortOrderAsc = request.getParameter( PARAMETER_ORDER_ASC );
227 
228         if ( StringUtils.isEmpty( sortName ) )
229         {
230             sortName = START_DATE;
231         }
232 
233         boolean bDesc = Boolean.TRUE; //DEFAULT DESC ORDER
234         if ( StringUtils.isNotEmpty( sortOrderAsc ) )
235         {
236             bDesc = !Boolean.parseBoolean( sortOrderAsc );
237         }
238 
239         _sortConfig = new AppointmentSortConfig( sortName, bDesc );
240 
241     }
242 
243     /**
244      * Return the current page index as int
245      * 
246      * @return the current page index
247      */
248     private int getCurrentPageIndex( )
249     {
250         if ( _strCurrentPageIndex != null )
251         {
252             return Integer.parseInt( _strCurrentPageIndex );
253         }
254         return 1;
255     }
256 
257     /**
258      * Get the index start
259      * 
260      * @return the started index
261      */
262     private int getIndexStart( )
263     {
264         return ( getCurrentPageIndex( ) - 1 ) * _nItemsPerPage;
265     }
266 
267     private ReferenceList getListForms( User user )
268     {
269         ReferenceList refListForms = new ReferenceList( );
270         refListForms.addItem( -1, StringUtils.EMPTY );
271 
272         List<Form> formList = FormHome.findAllForms( );
273         formList = (List<Form>) AdminWorkgroupService.getAuthorizedCollection( formList, user );
274         formList = (List<Form>) RBACService.getAuthorizedCollection( formList, AppointmentResourceIdService.PERMISSION_VIEW_FORM, user );
275 
276         for ( Form form : formList )
277         {
278             refListForms.addItem( form.getIdForm( ), form.getTitle( ) );
279         }
280         return refListForms;
281     }
282 
283     private ReferenceList getListCategories( )
284     {
285         ReferenceList refListForms = new ReferenceList( );
286         refListForms.addItem( -1, StringUtils.EMPTY );
287 
288         List<Category> categoryList = CategoryHome.findAllCategories( );
289         for ( Category category : categoryList )
290         {
291             refListForms.addItem( category.getIdCategory( ), category.getLabel( ) );
292         }
293         return refListForms;
294     }
295 
296     /**
297      * List of all the available status of an appointment
298      * 
299      * @return the list of the status
300      */
301     private ReferenceList getListStatus( )
302     {
303         ReferenceList refListStatus = new ReferenceList( );
304         refListStatus.addItem( -1, StringUtils.EMPTY );
305         refListStatus.addItem( 0, I18nService.getLocalizedString( RESERVED, getLocale( ) ) );
306         refListStatus.addItem( 1, I18nService.getLocalizedString( UNRESERVED, getLocale( ) ) );
307         return refListStatus;
308     }
309 }