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.appointment.service;
35  
36  import static java.lang.Math.toIntExact;
37  
38  import java.time.DayOfWeek;
39  import java.time.LocalTime;
40  import java.time.temporal.ChronoUnit;
41  import java.util.ArrayList;
42  import java.util.HashSet;
43  import java.util.List;
44  
45  import fr.paris.lutece.plugins.appointment.business.planning.TimeSlot;
46  import fr.paris.lutece.plugins.appointment.business.planning.WorkingDay;
47  import fr.paris.lutece.plugins.appointment.business.planning.WorkingDayHome;
48  import fr.paris.lutece.plugins.appointment.web.dto.AppointmentFormDTO;
49  
50  /**
51   * Service class of a working day
52   * 
53   * @author Laurent Payen
54   *
55   */
56  public final class WorkingDayService
57  {
58  
59      /**
60       * Private constructor - this class does not need to be instantiated
61       */
62      private WorkingDayService( )
63      {
64      }
65  
66      /**
67       * Create in database a working day object with the given parameters
68       * 
69       * @param nIdWeekDefinition
70       *            the week definition Id
71       * @param dayOfWeek
72       *            the day of week
73       * @return the working day object built
74       */
75      public static WorkingDay generateWorkingDay( int nIdWeekDefinition, DayOfWeek dayOfWeek )
76      {
77          WorkingDay workingDay = new WorkingDay( );
78          workingDay.setIdWeekDefinition( nIdWeekDefinition );
79          workingDay.setDayOfWeek( dayOfWeek.getValue( ) );
80          WorkingDayHome.create( workingDay );
81          return workingDay;
82      }
83  
84      /**
85       * Save a working day
86       * 
87       * @param workingDay
88       *            the working day to save
89       * @return the working day saved
90       */
91      public static WorkingDay saveWorkingDay( WorkingDay workingDay )
92      {
93          return WorkingDayHome.create( workingDay );
94      }
95  
96      /**
97       * Create in database a working day and its time slots
98       * 
99       * @param nIdWeekDefinition
100      *            the week definition Id
101      * @param dayOfWeek
102      *            the day of week of the woking day
103      * @param startingTime
104      *            the starting time of the working day
105      * @param endingTime
106      *            the ending time of the working day
107      * @param nDuration
108      *            the duration of the time slot of the working day
109      * @param nMaxCapacity
110      *            the max capacity for the slots of the working day
111      */
112     public static void generateWorkingDayAndListTimeSlot( int nIdWeekDefinition, DayOfWeek dayOfWeek, LocalTime startingTime, LocalTime endingTime,
113             int nDuration, int nMaxCapacity )
114     {
115         WorkingDay workingDay = generateWorkingDay( nIdWeekDefinition, dayOfWeek );
116         TimeSlotService.createListTimeSlot( TimeSlotService.generateListTimeSlot( workingDay.getIdWorkingDay( ), startingTime, endingTime, nDuration,
117                 nMaxCapacity, Boolean.FALSE ) );
118     }
119 
120     /**
121      * Get the open days of an appointmentForm DTO
122      * 
123      * @param appointmentForm
124      *            the appointmentForm DTO
125      * @return the list of day of week opened
126      */
127     public static List<DayOfWeek> getOpenDays( AppointmentFormDTO appointmentForm )
128     {
129         List<DayOfWeek> openDays = new ArrayList<>( );
130         if ( appointmentForm.getIsOpenMonday( ) )
131         {
132             openDays.add( DayOfWeek.MONDAY );
133         }
134         if ( appointmentForm.getIsOpenTuesday( ) )
135         {
136             openDays.add( DayOfWeek.TUESDAY );
137         }
138         if ( appointmentForm.getIsOpenWednesday( ) )
139         {
140             openDays.add( DayOfWeek.WEDNESDAY );
141         }
142         if ( appointmentForm.getIsOpenThursday( ) )
143         {
144             openDays.add( DayOfWeek.THURSDAY );
145         }
146         if ( appointmentForm.getIsOpenFriday( ) )
147         {
148             openDays.add( DayOfWeek.FRIDAY );
149         }
150         if ( appointmentForm.getIsOpenSaturday( ) )
151         {
152             openDays.add( DayOfWeek.SATURDAY );
153         }
154         if ( appointmentForm.getIsOpenSunday( ) )
155         {
156             openDays.add( DayOfWeek.SUNDAY );
157         }
158         return openDays;
159     }
160 
161     /**
162      * Find the working days of a week definition
163      * 
164      * @param nIdWeekDefinition
165      *            the week definition Id
166      * @return a list of the working days of the week definition
167      */
168     public static List<WorkingDay> findListWorkingDayByWeekDefinition( int nIdWeekDefinition )
169     {
170         List<WorkingDay> listWorkingDay = WorkingDayHome.findByIdWeekDefinition( nIdWeekDefinition );
171         for ( WorkingDay workingDay : listWorkingDay )
172         {
173             workingDay.setListTimeSlot( TimeSlotService.findListTimeSlotByWorkingDay( workingDay.getIdWorkingDay( ) ) );
174         }
175         return listWorkingDay;
176     }
177 
178     /**
179      * Delete a list of working days
180      * 
181      * @param listWorkingDay
182      *            the list of working days to delete
183      */
184     public static void deleteListWorkingDay( List<WorkingDay> listWorkingDay )
185     {
186         for ( WorkingDay workingDay : listWorkingDay )
187         {
188             WorkingDayHome.delete( workingDay.getIdWorkingDay( ) );
189         }
190     }
191 
192     /**
193      * Find a working day with its primary key
194      * 
195      * @param nIdWorkingDay
196      *            the working day Id
197      * @return the working day found
198      */
199     public static WorkingDay findWorkingDayLightById( int nIdWorkingDay )
200     {
201         WorkingDay workingDay = WorkingDayHome.findByPrimaryKey( nIdWorkingDay );
202         return workingDay;
203     }
204 
205     /**
206      * Find a working day and set its time slots
207      * 
208      * @param nIdWorkingDay
209      *            the working day Id
210      * @return the working day found with its time slots
211      */
212     public static WorkingDay findWorkingDayById( int nIdWorkingDay )
213     {
214         WorkingDay workingDay = WorkingDayHome.findByPrimaryKey( nIdWorkingDay );
215         workingDay.setListTimeSlot( TimeSlotService.findListTimeSlotByWorkingDay( nIdWorkingDay ) );
216         return workingDay;
217     }
218 
219     /**
220      * Get the max ending time of a working day
221      * 
222      * @param workingDay
223      *            the working day
224      * @return the max ending time of the working day
225      */
226     public static LocalTime getMaxEndingTimeOfAWorkingDay( WorkingDay workingDay )
227     {
228         return workingDay.getListTimeSlot( ).stream( ).map( TimeSlot::getEndingTime ).max( LocalTime::compareTo ).get( );
229     }
230 
231     /**
232      * Get the max ending time of a list of working days
233      * 
234      * @param listWorkingDay
235      *            the list of working days
236      * @return the max ending time of the working days
237      */
238     public static LocalTime getMaxEndingTimeOfAListOfWorkingDay( List<WorkingDay> listWorkingDay )
239     {
240         LocalTime maxEndingTime = null;
241         LocalTime endingTimeTemp;
242         for ( WorkingDay workingDay : listWorkingDay )
243         {
244             endingTimeTemp = getMaxEndingTimeOfAWorkingDay( workingDay );
245             if ( maxEndingTime == null || endingTimeTemp.isAfter( maxEndingTime ) )
246             {
247                 maxEndingTime = endingTimeTemp;
248             }
249         }
250         return maxEndingTime;
251     }
252 
253     /**
254      * Get the min starting time of a working day
255      * 
256      * @param workingDay
257      *            the working day
258      * @return the min starting time of the working day
259      */
260     public static LocalTime getMinStartingTimeOfAWorkingDay( WorkingDay workingDay )
261     {
262         return workingDay.getListTimeSlot( ).stream( ).map( TimeSlot::getStartingTime ).min( LocalTime::compareTo ).get( );
263     }
264 
265     /**
266      * Get the min starting time of a list of working days
267      * 
268      * @param listWorkingDay
269      *            the list of working days
270      * @return the min starting time of the working days
271      */
272     public static LocalTime getMinStartingTimeOfAListOfWorkingDay( List<WorkingDay> listWorkingDay )
273     {
274         LocalTime minStartingTime = null;
275         LocalTime startingTimeTemp;
276         for ( WorkingDay workingDay : listWorkingDay )
277         {
278             startingTimeTemp = getMinStartingTimeOfAWorkingDay( workingDay );
279             if ( minStartingTime == null || startingTimeTemp.isBefore( minStartingTime ) )
280             {
281                 minStartingTime = startingTimeTemp;
282             }
283         }
284         return minStartingTime;
285     }
286 
287     /**
288      * Get the min duration slot of a working day
289      * 
290      * @param workingDay
291      *            the working day
292      * @return the min duration slot of a working day
293      */
294     public static int getMinDurationTimeSlotOfAWorkingDay( WorkingDay workingDay )
295     {
296         long lMinDuration = 0;
297         LocalTime startingTimeTemp;
298         LocalTime endingTimeTemp;
299         long lDurationTemp;
300         for ( TimeSlot timeSlot : workingDay.getListTimeSlot( ) )
301         {
302             startingTimeTemp = timeSlot.getStartingTime( );
303             endingTimeTemp = timeSlot.getEndingTime( );
304             lDurationTemp = startingTimeTemp.until( endingTimeTemp, ChronoUnit.MINUTES );
305             if ( lMinDuration == 0 || lMinDuration > lDurationTemp )
306             {
307                 lMinDuration = lDurationTemp;
308             }
309         }
310         return toIntExact( lMinDuration );
311     }
312 
313     /**
314      * Get the min duration slot of a list of working days
315      * 
316      * @param listWorkingDay
317      *            the list of working days
318      * @return the min duration slot of the working days
319      */
320     public static int getMinDurationTimeSlotOfAListOfWorkingDay( List<WorkingDay> listWorkingDay )
321     {
322         long lMinDuration = 0;
323         long lDurationTemp;
324         for ( WorkingDay workingDay : listWorkingDay )
325         {
326             lDurationTemp = getMinDurationTimeSlotOfAWorkingDay( workingDay );
327             if ( lMinDuration == 0 || lMinDuration > lDurationTemp )
328             {
329                 lMinDuration = lDurationTemp;
330             }
331         }
332         return toIntExact( lMinDuration );
333     }
334 
335     /**
336      * Get all the day of week of working days
337      * 
338      * @param listWorkingDay
339      *            the list of working days
340      * @return a set of day of week
341      */
342     public static HashSet<String> getSetDaysOfWeekOfAListOfWorkingDayForFullCalendar( List<WorkingDay> listWorkingDay )
343     {
344         HashSet<String> setDayOfWeek = new HashSet<>( );
345         for ( WorkingDay workingDay : listWorkingDay )
346         {
347             int dow = workingDay.getDayOfWeek( );
348             if ( dow == DayOfWeek.SUNDAY.getValue( ) )
349             {
350                 // The fullCalendar library is zero-base (Sunday=0)
351                 dow = 0;
352             }
353             setDayOfWeek.add( Integer.toString( dow ) );
354         }
355         return setDayOfWeek;
356     }
357 
358     /**
359      * Find the working day in a list of working day which matches the day of week given
360      * 
361      * @param listWorkingDay
362      *            the list of working days
363      * @param dayOfWeek
364      *            the day of week to search
365      * @return the working day that matches
366      */
367     public static WorkingDay getWorkingDayOfDayOfWeek( List<WorkingDay> listWorkingDay, DayOfWeek dayOfWeek )
368     {
369         return listWorkingDay.stream( ).filter( x -> x.getDayOfWeek( ) == dayOfWeek.getValue( ) ).findFirst( ).orElse( null );
370     }
371 
372 }