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