FormUtil.java
/*
* Copyright (c) 2002-2022, 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.appointment.modules.solr.service;
import fr.paris.lutece.plugins.appointment.business.category.Category;
import fr.paris.lutece.plugins.appointment.business.category.CategoryHome;
import fr.paris.lutece.plugins.appointment.business.slot.Slot;
import fr.paris.lutece.plugins.appointment.service.FormService;
import fr.paris.lutece.plugins.appointment.web.dto.AppointmentFormDTO;
import fr.paris.lutece.plugins.search.solr.indexer.SolrIndexerService;
import fr.paris.lutece.plugins.search.solr.indexer.SolrItem;
import fr.paris.lutece.portal.service.image.ImageResourceManager;
import fr.paris.lutece.portal.web.l10n.LocaleService;
import fr.paris.lutece.util.url.UrlItem;
import org.apache.commons.lang3.StringUtils;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.WeekFields;
import java.util.Arrays;
import java.util.List;
/**
* Utils for the Appointment Form (Item, Url, Uid ...)
*
* @author Laurent Payen
*
*/
public final class FormUtil
{
private static final String MIN_HOURS_BEFORE_APPOINTMENT = "min_hours_before_appointment";
private static final String FORM_ID_CATEGORY = "form_id_category";
private static final String APPOINTMENT_ACTIVE = "appointment_active";
private static final String URL_BASE = "url_base";
private static final String FORM_ID_TITLE = "form_id_title";
private static final String APPOINTMENT_MULTISLOTS = "appointment_multislots";
private static final String APPOINTMENT_MAX_CONSECUTIVES_SLOTS = "appointment_max_consecutives_slots";
private static final String APPOINTMENT_NB_FREE_PLACES = "appointment_nb_free_places";
private static final String APPOINTMENT_NB_PLACES = "appointment_nb_places";
private static final String VIEW_APPOINTMENT = "getViewAppointmentCalendar";
private static final String FORM_ID_TITLE_SEPARATOR = "|";
private static final String DASH = "-";
private static final String SLASH = "/";
public static final String PARAMETER_ID_FORM = "id_form";
private static final String IMAGE_RESOURCE_TYPE_ID = "appointmentForm_icon";
private static final String ICON_URL = "appointment_form_icon_url";
/**
* Private constructor - this class does not need to be instantiated
*/
private FormUtil( )
{
}
/**
* Get the form Uid
*
* @param nIdForm
* the form id
* @return the form Uid
*/
public static String getFormUid( int nIdForm )
{
return SolrIndexerService.getWebAppName( ) + Utilities.UNDERSCORE
+ Utilities.buildResourceUid( Integer.toString( nIdForm ), Utilities.RESOURCE_TYPE_APPOINTMENT );
}
/**
* Get the form url
*
* @param nIdForm
* the form id
* @return the form url
*/
public static String getFormUrl( int nIdForm )
{
UrlItem url = new UrlItem( SolrIndexerService.getBaseUrl( ) );
url.addParameter( Utilities.PARAMETER_XPAGE, Utilities.XPAGE_APPOINTMENT );
url.addParameter( Utilities.PARAMETER_VIEW, VIEW_APPOINTMENT );
url.addParameter( PARAMETER_ID_FORM, nIdForm );
return url.getUrl( );
}
/**
* Build and return the default form item for Solr
*
* @param appointmentForm
* the appointment form
* @return the form item
*/
public static SolrItem getDefaultFormItem( AppointmentFormDTO appointmentForm )
{
SolrItem item = new SolrItem( );
item.setSummary( appointmentForm.getDescription( ) );
item.setTitle( appointmentForm.getTitle( ) );
item.setSite( SolrIndexerService.getWebAppName( ) );
item.setRole( appointmentForm.getRole( ) );
item.setXmlContent( StringUtils.EMPTY );
Category category = CategoryHome.findByPrimaryKey( appointmentForm.getIdCategory( ) );
if ( category != null )
{
item.setCategorie( Arrays.asList( category.getLabel( ) ) );
item.addDynamicField( FORM_ID_CATEGORY, (long) category.getIdCategory( ) );
}
StringBuilder stringBuilder = new StringBuilder( );
item.setContent( stringBuilder.toString( ) );
item.addDynamicField( MIN_HOURS_BEFORE_APPOINTMENT, (long) appointmentForm.getMinTimeBeforeAppointment( ) );
item.addDynamicFieldNotAnalysed( APPOINTMENT_ACTIVE, Boolean.toString( appointmentForm.getIsActive( ) ) );
item.addDynamicFieldNotAnalysed( URL_BASE, SolrIndexerService.getRootUrl( ) );
item.addDynamicFieldNotAnalysed( FORM_ID_TITLE, getFormUid( appointmentForm.getIdForm( ) ) + FORM_ID_TITLE_SEPARATOR + appointmentForm.getTitle( ) );
item.addDynamicFieldNotAnalysed( ICON_URL, SolrIndexerService.getRootUrl( ) + ImageResourceManager.getImageUrl( IMAGE_RESOURCE_TYPE_ID, appointmentForm.getIdForm() ));
return item;
}
/**
* Build and return the Form Item for Solr
*
* @param appointmentForm
* the Appointment Form
* @param listSlots
* the list of the slots of the form
* @return the Form Item
*/
public static SolrItem getFormItem( AppointmentFormDTO appointmentForm, List<Slot> listSlots )
{
SolrItem item = getDefaultFormItem( appointmentForm );
item.setUrl( getFormUrl( appointmentForm.getIdForm( ) ) );
item.setUid( Utilities.buildResourceUid( Integer.toString( appointmentForm.getIdForm( ) ), Utilities.RESOURCE_TYPE_APPOINTMENT ) );
item.setDate( appointmentForm.getDateStartValidity( ) );
item.setType( Utilities.SHORT_NAME_APPOINTMENT );
int freePlaces = 0;
int places = 0;
for ( Slot slot : listSlots )
{
freePlaces += Math.max( 0, slot.getNbPotentialRemainingPlaces( ) );
places += slot.getMaxCapacity( );
}
if ( StringUtils.isNotEmpty( appointmentForm.getAddress( ) ) && appointmentForm.getLongitude( ) != null && appointmentForm.getLatitude( ) != null )
{
item.addDynamicFieldGeoloc( Utilities.SHORT_NAME_APPOINTMENT, appointmentForm.getAddress( ), appointmentForm.getLongitude( ),
appointmentForm.getLatitude( ), Utilities.SHORT_NAME_APPOINTMENT + DASH + freePlaces + SLASH + places );
}
item.addDynamicField( APPOINTMENT_MULTISLOTS, Boolean.toString( appointmentForm.getIsMultislotAppointment( ) ) );
if( appointmentForm.getIsMultislotAppointment( ) ) {
item.addDynamicField(APPOINTMENT_MAX_CONSECUTIVES_SLOTS, Long.valueOf(appointmentForm.getNbConsecutiveSlots()));
}
else {
item.addDynamicField(APPOINTMENT_MAX_CONSECUTIVES_SLOTS, 1L);
}
item.addDynamicField( APPOINTMENT_NB_FREE_PLACES, Long.valueOf( freePlaces ) );
item.addDynamicField( APPOINTMENT_NB_PLACES, Long.valueOf( places ) );
// Date Hierarchy
if ( appointmentForm.getDateStartValidity( ) != null )
{
item.setHieDate( appointmentForm.getDateStartValidity( ).toLocalDate( ).format( Utilities.HIE_DATE_FORMATTER ) );
}
return item;
}
/**
* check if the period between the startingDate and endingDate is displayed on the calendar FO
*
* @param nIdForm
* the form
* @param stratingDate
* the starting period
* @param endingDate
* the ending period
* @return true if the period between the startingDate and endingDate is displayed on the calendar FO
*/
public static boolean isPeriodValidToIndex( int nIdForm, LocalDate stratingDate, LocalDate endingDate )
{
AppointmentFormDTO form = FormService.buildAppointmentFormWithoutReservationRule( nIdForm );
int nNbWeeksToDisplay = form.getNbWeeksToDisplay( );
LocalDate startingDateOfDisplay = LocalDateTime.now( ).plusHours( form.getMinTimeBeforeAppointment( ) ).toLocalDate( );
if ( form.getDateStartValidity( ) != null && startingDateOfDisplay.isBefore( form.getDateStartValidity( ).toLocalDate( ) ) )
{
startingDateOfDisplay = form.getDateStartValidity( ).toLocalDate( );
}
// Calculate the ending date of display with the nb weeks to display since today
// We calculate the number of weeks including the current week, so it and will end to the (n) next sunday
LocalDate endingDateOfDisplay = startingDateOfDisplay.with( WeekFields.of( LocaleService.getDefault( ) ).dayOfWeek( ), DayOfWeek.SUNDAY.getValue( ) )
.plusWeeks( nNbWeeksToDisplay - 1L );
if ( form.getDateEndValidity( ) != null && endingDateOfDisplay.isAfter( form.getDateEndValidity( ).toLocalDate( ) ) )
{
endingDateOfDisplay = form.getDateEndValidity( ).toLocalDate( );
}
return !( stratingDate.isAfter( endingDateOfDisplay ) || endingDate.isBefore( startingDateOfDisplay ) );
}
}