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 java.time.DayOfWeek;
37  import java.time.LocalDate;
38  import java.time.LocalTime;
39  import java.util.ArrayList;
40  import java.util.Collection;
41  import java.util.HashMap;
42  import java.util.List;
43  import java.util.Map;
44  
45  import org.apache.commons.collections.CollectionUtils;
46  
47  import fr.paris.lutece.plugins.appointment.business.planning.TimeSlot;
48  import fr.paris.lutece.plugins.appointment.business.planning.TimeSlotHome;
49  import fr.paris.lutece.plugins.appointment.business.planning.WeekDefinition;
50  import fr.paris.lutece.plugins.appointment.business.planning.WorkingDay;
51  import fr.paris.lutece.plugins.appointment.business.planning.WorkingDayHome;
52  import fr.paris.lutece.plugins.appointment.business.rule.ReservationRule;
53  import fr.paris.lutece.plugins.appointment.business.rule.ReservationRuleHome;
54  import fr.paris.lutece.plugins.appointment.service.listeners.WeekDefinitionManagerListener;
55  import fr.paris.lutece.plugins.appointment.web.dto.AppointmentFormDTO;
56  import fr.paris.lutece.portal.service.util.AppLogService;
57  import fr.paris.lutece.util.ReferenceList;
58  import fr.paris.lutece.util.sql.TransactionManager;
59  
60  /**
61   * Service class for the reservation rule
62   * 
63   * @author Laurent Payen
64   *
65   */
66  public final class ReservationRuleService
67  {
68      private static final String CONST_COPY_OF_WEEK = "Copy ";
69  
70      /**
71       * Private constructor - this class does not need to be instantiated
72       */
73      private ReservationRuleService( )
74      {
75      }
76  
77      /**
78       * Create in database a reservation rule object from an appointmentForm DTO
79       * 
80       * @param appointmentForm
81       *            the appointmentForm DTO
82       * @param nIdForm
83       *            the form Id
84       * @param dateOfApply
85       *            the date of the reservation rule
86       * @return the Reservation Rule object created
87       */
88      public static ReservationRule createReservationRule( AppointmentFormDTO appointmentForm, int nIdForm )
89      {
90          ReservationRuleness/rule/ReservationRule.html#ReservationRule">ReservationRule reservationRule = new ReservationRule( );
91          fillInReservationRule( reservationRule, appointmentForm, nIdForm );
92          ReservationRuleHome.create( reservationRule );
93          return reservationRule;
94      }
95  
96      /**
97       * Create in database a reservation rule object from an appointmentForm DTO
98       * 
99       * @param appointmentForm
100      *            the appointmentForm DTO
101      * 
102      * @return the Reservation Rule id
103      */
104     public static int createTypicalWeek( AppointmentFormDTO appointmentForm )
105     {
106 
107         int nIdForm = appointmentForm.getIdForm( );
108         ReservationRule reservationRule = createReservationRule( appointmentForm, nIdForm );
109         int nMaxCapacity = reservationRule.getMaxCapacityPerSlot( );
110         LocalTime startingTime = LocalTime.parse( appointmentForm.getTimeStart( ) );
111         LocalTime endingTime = LocalTime.parse( appointmentForm.getTimeEnd( ) );
112         int nDuration = appointmentForm.getDurationAppointments( );
113         for ( DayOfWeek dayOfWeek : WorkingDayService.getOpenDays( appointmentForm ) )
114         {
115             WorkingDayService.generateWorkingDayAndListTimeSlot( reservationRule.getIdReservationRule( ), dayOfWeek, startingTime, endingTime, nDuration,
116                     nMaxCapacity );
117         }
118         return reservationRule.getIdReservationRule( );
119     }
120 
121     /**
122      * Make a copy of typical week, with all its values
123      * 
124      * @param nIdReservationRule
125      *            the reservationRule Id to copy
126      * @return the id of the reservation rule created
127      */
128 
129     public static int copyReservationRule( int nIdReservationRule )
130     {
131         ReservationRule reservationRule = findReservationRuleById( nIdReservationRule );
132         if ( reservationRule != null )
133         {
134 
135             reservationRule.setName( CONST_COPY_OF_WEEK + reservationRule.getName( ) );
136             TransactionManager.beginTransaction( AppointmentPlugin.getPlugin( ) );
137             try
138             {
139                 ReservationRuleHome.create( reservationRule );
140                 for ( WorkingDay workingDay : reservationRule.getListWorkingDay( ) )
141                 {
142                     workingDay.setIdReservationRule( reservationRule.getIdReservationRule( ) );
143                     WorkingDayHome.create( workingDay );
144                     for ( TimeSlot timeSlotTemp : workingDay.getListTimeSlot( ) )
145                     {
146 
147                         timeSlotTemp.setIdWorkingDay( workingDay.getIdWorkingDay( ) );
148                         TimeSlotHome.create( timeSlotTemp );
149                     }
150                 }
151                 TransactionManager.commitTransaction( AppointmentPlugin.getPlugin( ) );
152                 return reservationRule.getIdReservationRule( );
153             }
154             catch( RuntimeException e )
155             {
156                 TransactionManager.rollBack( AppointmentPlugin.getPlugin( ) );
157                 AppLogService.error( "Error copy typical week" + e.getMessage( ), e );
158                 return 0;
159             }
160         }
161 
162         return 0;
163     }
164 
165     /**
166      * Update a form with the new values of an appointmentForm DTO Advanced Parameters (with a date of application) --> new Typical Week
167      * 
168      * @param appointmentForm
169      *            the appointmentForm DTO
170      */
171     public static void updateAdvancedParameters( AppointmentFormDTO appointmentForm )
172     {
173         int nIdForm = appointmentForm.getIdForm( );
174         ReservationRule reservationRule = updateReservationRule( appointmentForm, nIdForm );
175         int nMaxCapacity = reservationRule.getMaxCapacityPerSlot( );
176         List<WorkingDay> listWorkingDay = WorkingDayService.findListWorkingDayByWeekDefinitionRule( reservationRule.getIdReservationRule( ) );
177 
178         if ( CollectionUtils.isNotEmpty( listWorkingDay ) )
179         {
180             for ( WorkingDay workingDay : listWorkingDay )
181             {
182                 TimeSlotHome.deleteByIdWorkingDay( workingDay.getIdWorkingDay( ) );
183             }
184             WorkingDayHome.deleteByIdReservationRule( reservationRule.getIdReservationRule( ) );
185         }
186         LocalTime startingHour = LocalTime.parse( appointmentForm.getTimeStart( ) );
187         LocalTime endingHour = LocalTime.parse( appointmentForm.getTimeEnd( ) );
188         int nDuration = appointmentForm.getDurationAppointments( );
189         for ( DayOfWeek dayOfWeek : WorkingDayService.getOpenDays( appointmentForm ) )
190         {
191             WorkingDayService.generateWorkingDayAndListTimeSlot( reservationRule.getIdReservationRule( ), dayOfWeek, startingHour, endingHour, nDuration,
192                     nMaxCapacity );
193         }
194         List<WeekDefinition> listWeek = WeekDefinitionService.findByReservationRule( appointmentForm.getIdReservationRule( ) );
195         if ( CollectionUtils.isNotEmpty( listWeek ) )
196         {
197 
198             WeekDefinitionManagerListener.notifyListenersListWeekDefinitionChanged( appointmentForm.getIdForm( ), listWeek );
199         }
200     }
201 
202     /**
203      * Delete a reservation rule by its id
204      * 
205      * @param reservationRule
206      *            the reservation rule to delete
207      */
208     public static void removeReservationRule( int nIdReservationRule )
209     {
210         ReservationRule rule = findReservationRuleById( nIdReservationRule );
211         if ( rule != null )
212         {
213             for ( WorkingDay day : rule.getListWorkingDay( ) )
214             {
215 
216                 TimeSlotHome.deleteByIdWorkingDay( day.getIdWorkingDay( ) );
217                 WorkingDayHome.delete( day.getIdWorkingDay( ) );
218 
219             }
220             ReservationRuleHome.delete( rule.getIdReservationRule( ) );
221         }
222     }
223 
224     /**
225      * save a reservation rule
226      * 
227      * @param reservationRule
228      *            the reservation rule to save
229      */
230     public static void saveReservationRule( ReservationRule reservationRule )
231     {
232         ReservationRuleHome.create( reservationRule );
233     }
234 
235     /**
236      * Update in database a reservation rule with the values of an appointmentForm DTO
237      * 
238      * @param appointmentForm
239      *            the appointmentForm DTO
240      * @param nIdForm
241      *            the form Id
242      * @return the reservation rule object updated
243      */
244     public static ReservationRule updateReservationRule( AppointmentFormDTO appointmentForm, int nIdForm )
245     {
246         ReservationRule reservationRule = ReservationRuleService.findReservationRuleById( appointmentForm.getIdReservationRule( ) );
247         if ( reservationRule == null )
248         {
249             reservationRule = createReservationRule( appointmentForm, nIdForm );
250         }
251         else
252         {
253             fillInReservationRule( reservationRule, appointmentForm, nIdForm );
254             ReservationRuleHome.update( reservationRule );
255         }
256         return reservationRule;
257     }
258 
259     /**
260      * Fill the reservation rule object with the corresponding values of an appointmentForm DTO
261      * 
262      * @param reservationRule
263      *            the reservation rule object to fill in
264      * @param appointmentForm
265      *            the appointmentForm DTO
266      * @param nIdForm
267      *            the form Id
268      */
269     public static void fillInReservationRule( ReservationRule reservationRule, AppointmentFormDTO appointmentForm, int nIdForm )
270     {
271         reservationRule.setMaxCapacityPerSlot( appointmentForm.getMaxCapacityPerSlot( ) );
272         reservationRule.setMaxPeoplePerAppointment( appointmentForm.getMaxPeoplePerAppointment( ) );
273         reservationRule.setName( appointmentForm.getName( ) );
274         reservationRule.setDescriptionRule( appointmentForm.getDescriptionRule( ) );
275         reservationRule.setDurationAppointments( appointmentForm.getDurationAppointments( ) );
276         reservationRule.setColor( appointmentForm.getColor( ) );
277         reservationRule.setIdForm( nIdForm );
278     }
279 
280     /**
281      * Find in database a reservation rule of a form closest to a date
282      * 
283      * @param nIdForm
284      *            the form Id
285      * @param dateOfApply
286      *            the date
287      * @return the reservation rule to apply at this date
288      */
289     public static ReservationRule findReservationRuleByIdFormAndClosestToDateOfApply( int nIdForm, LocalDate dateOfApply )
290     {
291         ReservationRule reservationRule = ReservationRuleHome.findReservationRuleByIdFormAndClosestToDateOfApply( nIdForm, dateOfApply );
292         if ( reservationRule != null )
293         {
294 
295             reservationRule.setListWorkingDay( WorkingDayService.findListWorkingDayByWeekDefinitionRule( reservationRule.getIdReservationRule( ) ) );
296         }
297         return reservationRule;
298     }
299 
300     /**
301      * Find the reservation rule of a form on a specific date
302      * 
303      * @param nIdForm
304      *            the form Id
305      * @param dateOfApply
306      *            the date of the reservation rule
307      * @return the reservation rule object
308      */
309     public static ReservationRule findReservationRuleByIdFormAndDateOfApply( int nIdForm, LocalDate dateOfApply )
310     {
311 
312         ReservationRule reservationRule = ReservationRuleHome.findByIdFormAndDateOfApply( nIdForm, dateOfApply );
313         if ( reservationRule != null )
314         {
315 
316             reservationRule.setListWorkingDay( WorkingDayService.findListWorkingDayByWeekDefinitionRule( reservationRule.getIdReservationRule( ) ) );
317         }
318         return reservationRule;
319     }
320 
321     /**
322      * Find a reservation rule with its primary key
323      * 
324      * @param nIdReservationRule
325      *            the reservation rule Id
326      * @return the Reservation Rule Object
327      */
328     public static ReservationRule findReservationRuleById( int nIdReservationRule )
329     {
330         ReservationRule reservationRule = ReservationRuleHome.findByPrimaryKey( nIdReservationRule );
331         if ( reservationRule != null )
332         {
333 
334             reservationRule.setListWorkingDay( WorkingDayService.findListWorkingDayByWeekDefinitionRule( reservationRule.getIdReservationRule( ) ) );
335         }
336         return reservationRule;
337     }
338 
339     /**
340      * Build a reference list of all reservation rules of a form
341      * 
342      * @param nIdForm
343      *            the form Id
344      * @return the reference list (id reservation rule / date of apply of the reservation rule)
345      */
346     public static ReferenceList findAllReservationRule( int nIdForm )
347     {
348         ReferenceList listRule = new ReferenceList( );
349         List<ReservationRule> listReservationRule = ReservationRuleHome.findByIdForm( nIdForm );
350         for ( ReservationRule reservationRule : listReservationRule )
351         {
352             listRule.addItem( reservationRule.getIdReservationRule( ), reservationRule.getName( ) );
353         }
354         return listRule;
355     }
356 
357     /**
358      * Find all the reservation rule of a form
359      * 
360      * @param nIdForm
361      *            the form Id
362      * @return an HashMap with the date of apply in key and the reservation rule in value
363      */
364     public static Map<WeekDefinition, ReservationRule> findAllReservationRule( int nIdForm, Collection<WeekDefinition> listWeekDefinition )
365     {
366 
367         Map<WeekDefinition, ReservationRule> mapReservationRule = new HashMap<>( );
368         List<ReservationRule> listReservationRule = ReservationRuleHome.findByIdForm( nIdForm );
369         for ( WeekDefinition weekDefinition : listWeekDefinition )
370         {
371             ReservationRule reservationRule = listReservationRule.stream( ).filter( p -> p.getIdReservationRule( ) == weekDefinition.getIdReservationRule( ) )
372                     .findAny( ).orElse( null );
373             if ( reservationRule != null )
374             {
375                 reservationRule.setListWorkingDay( WorkingDayService.findListWorkingDayByWeekDefinitionRule( reservationRule.getIdReservationRule( ) ) );
376                 mapReservationRule.put( weekDefinition, reservationRule );
377             }
378 
379         }
380         return mapReservationRule;
381     }
382 
383     /**
384      * Returns a list of the reservation rules of a form
385      * 
386      * @param nIdForm
387      *            the form id
388      * @return a list of reservation rules of the form
389      */
390     public static List<ReservationRule> findListReservationRule( int nIdForm )
391     {
392 
393         List<ReservationRule> listReservationRule = ReservationRuleHome.findByIdForm( nIdForm );
394         for ( ReservationRule reservationRule : listReservationRule )
395         {
396             reservationRule.setListWorkingDay( WorkingDayService.findListWorkingDayByWeekDefinitionRule( reservationRule.getIdReservationRule( ) ) );
397         }
398         return listReservationRule;
399     }
400 
401     /**
402      * Returns a list of the reservation rules of a form
403      * 
404      * @param nIdForm
405      *            the form id
406      * @param listWeekDefinition
407      *            the week definition list
408      * @return a list of reservation rules of the form
409      */
410     public static List<ReservationRule> findListReservationRule( int nIdForm, Collection<WeekDefinition> listWeekDefinition )
411     {
412 
413         List<ReservationRule> listReservationRule = new ArrayList<>( );
414         for ( ReservationRule reservationRule : ReservationRuleHome.findByIdForm( nIdForm ) )
415         {
416             if ( listWeekDefinition.stream( ).anyMatch( p -> p.getIdReservationRule( ) == reservationRule.getIdReservationRule( ) ) )
417             {
418 
419                 reservationRule.setListWorkingDay( WorkingDayService.findListWorkingDayByWeekDefinitionRule( reservationRule.getIdReservationRule( ) ) );
420                 listReservationRule.add( reservationRule );
421             }
422         }
423         return listReservationRule;
424     }
425 
426 }