· 6 years ago · Feb 14, 2020, 08:14 AM
1/**
2 * getFreeTimeSlots this function will return free timeslots based on clubId and date, coach_id and court id
3 * This api is getting called only from Mobile App
4 */
5 public function getFreeTimeSlots(){
6 if ($this->request->is('post')) {
7 $this->loadModel('ClubBookingSession');
8 $this->loadModel('Setting');
9 $this->loadModel('User');
10 $this->loadModel('Club');
11 $this->loadModel('Court');
12
13 $club_slots = array();
14 $club_id = $this->request->data['club_id'];
15 $booking_date = $this->request->data['booking_date'];
16 $user_id = $this->request->data['user_id'];
17
18
19
20
21
22 if(isset($this->request->data['coach_id'])){
23 $coach_id = $this->request->data['coach_id'];
24 }
25 else{
26 $coach_id = "";
27 }
28
29 //$clubSetting = $this->Setting->findByClubId($club_id);
30 $clubSetting = $this->Setting->find('first', array (
31 'conditions' => array (
32 'Setting.club_id' => $club_id
33 ),
34 'fields' => array (
35 'Setting.time_slot_gap',
36 'Club.default_start_time',
37 'Club.default_end_time',
38 'Club.timezone_id'
39 )
40 ));
41 // $clubDetails = $this->User->Club->findById($club_id);
42 // $clubDetails = $this->User->Club->find('first', array (
43 // 'conditions' => array (
44 // 'Club.id' => $club_id
45 // ),
46 // 'fields' => array (
47 // 'Timezone.id',
48 // 'Club.default_start_time',
49 // 'Club.default_end_time',
50 // )
51 // ));
52 $clubTimezoneOffset = $this->Common->getClubTimezoneOffset($clubSetting['Club']['timezone_id']);
53 $courtCounter = 0;
54 $day = strtoupper(date('D',strtotime($booking_date)));
55
56 if(empty($clubSetting)){
57 $response['status'] = false;
58 $response['message'] = 'Club not found.';
59 echo json_encode($response);
60 die;
61 }
62
63 if(empty($clubSetting)){
64 $response['status'] = false;
65 $response['message'] = 'Club setting not found.';
66 echo json_encode($response);
67 die;
68 }
69
70 //$userBuysSlots = $this->checkPlayerAvailabilityFromFreeslots($user_id ,$booking_date, $clubTimezoneOffset, true);
71
72 $duration = $clubSetting['Setting']['time_slot_gap']; // in minutes
73 $book_start_datetime = $booking_date.' '.$clubSetting['Club']['default_start_time'];
74 $book_end_datetime = $booking_date.' '.$clubSetting['Club']['default_end_time'];
75
76 if(isset($this->request->data['court_surface_id'])){
77 $court_surface_id = $this->request->data['court_surface_id'];
78 }
79 else{
80 $court_surface_id = "";
81 }
82
83 $courtFreeSlots = $this->getCourtIdFromCourtSurfaceId($club_id, $book_start_datetime, $book_end_datetime, $booking_date, $day, $user_id, $duration, $court_surface_id, $clubTimezoneOffset);
84 $userFreeSlots = $this->getUserFreeSlots($user_id,$book_start_datetime,$book_end_datetime,$duration, $clubTimezoneOffset);
85 $courtFreeSlots = array_intersect($userFreeSlots,$courtFreeSlots);
86
87 if(isset($coach_id) && $coach_id!=""){
88 $this->loadModel('CoachAvailableHour');
89 if($booking_date == date('Y-m-d')){
90 $bookingTimestamp = (strtotime(date("Y-m-d H:i:s")) - ($clubTimezoneOffset*60));
91 }else{
92 $bookingTimestamp = (strtotime($booking_date) - ($clubTimezoneOffset*60));
93 }
94 $bookingDay = strtoupper(date('D', $bookingTimestamp + ($clubTimezoneOffset*60))); // DAY of the day should be on CLUB's timezone not on UTC
95 $coachHours = $this->CoachAvailableHour->find('all',array('conditions'=>array('CoachAvailableHour.club_id'=>$club_id,'CoachAvailableHour.coach_id'=>$coach_id,'CoachAvailableHour.sport_type_id'=>1,'CoachAvailableHour.day'=>$bookingDay,'CoachAvailableHour.available_in_app'=>1)));
96 if(count($coachHours)>1){
97 // 2 timestamps get the one with
98 }
99 elseif (count($coachHours)==1) {
100 $coachHours = $coachHours[0];
101 $coachCourtStartTime = $booking_date.' '.$coachHours['CoachAvailableHour']['start_time'];
102 $coachCourtEndTime = $booking_date.' '.$coachHours['CoachAvailableHour']['end_time'];
103
104 // $coachCourtStartTime = date('Y-m-d H:i:s',strtotime($booking_date." ".$coachHours['CoachAvailableHour']['start_time']) - ($clubTimezoneOffset*60));
105 // $coachCourtEndTime = date('Y-m-d H:i:s',strtotime($booking_date." ".$coachHours['CoachAvailableHour']['end_time']) - ($clubTimezoneOffset*60));
106
107
108
109 $CoachSlots = $this->ClubBookingSession->query("CALL coachSlot('$coachCourtStartTime','$coachCourtEndTime','$duration','$club_id','$coach_id');");
110
111 $coachFreeSlots=array();
112 foreach($CoachSlots as $CoachSlotsKey=>$CoachSlot){
113 $coachFreeSlots[$CoachSlot['CS']['start_date_time'].'_'.$CoachSlot['CS']['end_date_time']]=$CoachSlot['CS']['start_date_time'].'_'.$CoachSlot['CS']['end_date_time'];
114 }
115 $total_free_slots=array_intersect($courtFreeSlots, $coachFreeSlots);
116
117
118 foreach ($total_free_slots as $key => $total_free_slot) {
119 $ct = date("Y-m-d H:i:s");
120
121 $slot_type = explode("_", $total_free_slot);
122
123 $start_time_array = explode(" ", $slot_type[0]);
124 $start_time_slot = $start_time_array[1];
125
126 $end_time_array = explode(" ", $slot_type[1]);
127 $end_time_slot = $end_time_array[1];
128
129
130 $temp = array();
131 if(($booking_date." ".$start_time_slot > date("Y-m-d H:i:s",strtotime($ct) + ($clubTimezoneOffset*60)))){
132 // $temp['startTime'] = date("H:i", strtotime($start_time_slot));
133 // $temp['endTime'] = date("H:i", strtotime($end_time_slot));
134 $temp['startTime'] = date("H:i",strtotime($start_time_slot) + ($clubTimezoneOffset*60));
135 $temp['endTime'] = date("H:i",strtotime($end_time_slot) + ($clubTimezoneOffset*60));
136 }
137 $club_slots[]=$temp;
138 }
139
140 }else {
141 $response['status'] = true;
142 $response['data']['club_start_time'] = $clubSetting['Club']['default_start_time'];
143 $response['data']['club_end_time'] = $clubSetting['Club']['default_end_time'];
144 $response['data']['time_slot_gap'] = $clubSetting['Setting']['time_slot_gap'];
145 $response['data']['available_hours'] = [];
146 echo json_encode($response);
147 die;
148 }
149 }
150 else{
151 foreach ($courtFreeSlots as $key => $courtFreeSlot) {
152 $ct = date("Y-m-d H:i:s");
153 $slot_type = explode("_", $courtFreeSlot);
154 $start_time_array = explode(" ", $slot_type[0]);
155 $start_time_slot = $start_time_array[1];
156
157 $end_time_array = explode(" ", $slot_type[1]);
158 $end_time_slot = $end_time_array[1];
159
160 $temp = array();
161 if(($booking_date." ".$start_time_slot >= date("Y-m-d H:i:s",strtotime($ct) + ($clubTimezoneOffset*60)))){
162 // $temp['startTime'] = date("H:i", strtotime($start_time_slot));
163 // $temp['endTime'] = date("H:i", strtotime($end_time_slot));
164 $temp['startTime'] = date("H:i",strtotime($start_time_slot) + ($clubTimezoneOffset*60));
165 $temp['endTime'] = date("H:i",strtotime($end_time_slot) + ($clubTimezoneOffset*60));
166 }
167
168 $club_slots[]=$temp;
169 }
170 }
171
172 $response['status'] = true;
173 $response['data']['club_start_time'] = $clubSetting['Club']['default_start_time'];
174 $response['data']['club_end_time'] = $clubSetting['Club']['default_end_time'];
175 $response['data']['time_slot_gap'] = $clubSetting['Setting']['time_slot_gap'];
176 $response['data']['available_hours'] = $club_slots;
177 } else {
178 $response['status'] = false;
179 $response['message'] = 'Invalid request';
180 }
181 echo json_encode($response);
182 }
183
184 /**
185 * gets user free slots
186 * start date time and end date times are in UTC
187 * calls the stored procudres and find the unique free slots in the same duration interval as specified in club settings
188 */
189 private function getUserFreeSlots($userId,$startDateTime,$endDateTime,$duration, $clubTimezoneOffset){
190 //get player details
191 $player = $this->User->findById($userId);
192 $playerId = $player['Player']['id'];
193 // call the stored procedure
194 // the procedure accepts both userID and playerId in order to shortent the query and complexity of the StroedProd
195 $freeSlots = $this->ClubBookingSession->query("CALL getFreeSlotsForPlayer('$startDateTime','$endDateTime','$duration','$playerId','$userId');");
196 $freePlayerSlots = array();
197 foreach($freeSlots as $freeSlotsKey=>$freeSlot){
198 $user_start_datetime = date('Y-m-d H:i:s',strtotime($freeSlot['S']['start_date_time']));
199 $user_end_datetime = date('Y-m-d H:i:s',strtotime($freeSlot['S']['end_date_time']));
200
201
202 // $user_start_datetime = $freeSlot['S']['start_date_time'];
203 // $user_end_datetime = $freeSlot['S']['end_date_time'];
204 $freePlayerSlots[$user_start_datetime.'_'.$user_end_datetime]=$user_start_datetime.'_'.$user_end_datetime;
205 }
206 return $freePlayerSlots;
207 }
208
209
210 /**
211 * gets court free slots
212 * start date time and end date times are in UTC
213 * calls the stored procudres and find the unique free slots in the same duration interval as specified in club settings
214 */
215 private function getCourtIdFromCourtSurfaceId($club_id, $book_start_datetime, $book_end_datetime, $booking_date, $day, $user_id, $duration=30, $court_surface_id=0, $clubTimezoneOffset){
216 $return_array = array();
217 if($court_surface_id!=0){
218 //$allAvailableCourtsWithSpecifiedSurfaces = $this->Court->findAllByClubIdAndCourtSurfaceIdAndAvailableInAppAndStatus($club_id, $court_surface_id,1,1);
219 $allAvailableCourtsWithSpecifiedSurfaces = $this->Court->find('all', array(
220 'conditions' => array (
221 'Court.club_id' => $club_id,
222 'Court.court_surface_id' => $court_surface_id,
223 'Court.available_in_app' => 1,
224 'Court.status' => 1
225 ),
226 'fields' => array (
227 'Court.id'
228 )
229 ));
230 $courtFreeSlots=array();
231 if(!empty($allAvailableCourtsWithSpecifiedSurfaces)){
232 foreach( $allAvailableCourtsWithSpecifiedSurfaces as $freeKey => $allAvailableCourtsWithSpecifiedSurface){
233 $court_id = $allAvailableCourtsWithSpecifiedSurface['Court']['id'];
234
235 $this->loadModel('CourtAvailableHour');
236 $availableCourts = $this->CourtAvailableHour->find('first',
237 array(
238 'conditions' =>
239 array(
240 'CourtAvailableHour.court_id' => $court_id,
241 'CourtAvailableHour.club_id' => $club_id,
242 'CourtAvailableHour.day' => $day,
243 ),
244 'fields' =>
245 array(
246 'CourtAvailableHour.start_time',
247 'CourtAvailableHour.end_time'
248 )
249 )
250 );
251 if(!empty($availableCourts)){
252 $book_start_datetime = date('Y-m-d H:i:s',strtotime($booking_date." ".$availableCourts['CourtAvailableHour']['start_time']) - ($clubTimezoneOffset*60));
253 $book_end_datetime = date('Y-m-d H:i:s',strtotime($booking_date." ".$availableCourts['CourtAvailableHour']['end_time']) - ($clubTimezoneOffset*60));
254
255 $freeslots = $this->ClubBookingSession->query("CALL slots('$book_start_datetime','$book_end_datetime','$duration','$court_id');");
256 foreach($freeslots as $freeslotKey=>$freeslot){
257 $temp_start_time = date('Y-m-d H:i:s',strtotime($freeslot['S']['start_date_time'])+$clubTimezoneOffset*60);
258
259 $temp_end_time = date("Y-m-d H:i:s",strtotime($freeslot['S']['end_date_time']) +($clubTimezoneOffset*60));
260 $courtFreeSlots[$temp_start_time.'_'.$temp_end_time]=$temp_start_time.'_'.$temp_end_time;
261 }
262 }
263 }
264 }
265 $return_array = $courtFreeSlots;
266 }
267 else{
268 //$allAvailableCourtsWithSpecifiedSurfaces = $this->Court->findAllByClubIdAndAvailableInAppAndStatus($club_id, 1,1);
269 $allAvailableCourtsWithSpecifiedSurfaces = $this->Court->find('all', array(
270 'conditions' => array (
271 'Court.club_id' => $club_id,
272 'Court.available_in_app' => 1,
273 'Court.status' => 1
274 ),
275 'fields' => array (
276 'Court.id'
277 )
278 ));
279 $courtFreeSlots=array();
280 if(!empty($allAvailableCourtsWithSpecifiedSurfaces)){
281 foreach($allAvailableCourtsWithSpecifiedSurfaces as $freeKey => $allAvailableCourtsWithSpecifiedSurface){
282 $court_id = $allAvailableCourtsWithSpecifiedSurface['Court']['id'];
283
284 $this->loadModel('CourtAvailableHour');
285
286 // get free timeslot for each court
287 $availableCourts = $this->CourtAvailableHour->find('first',
288
289 array(
290 'conditions' =>
291 array(
292 'CourtAvailableHour.court_id' => $court_id,
293 'CourtAvailableHour.club_id' => $club_id,
294 'CourtAvailableHour.day' => $day,
295 ),
296 'fields' =>
297 array(
298 'CourtAvailableHour.start_time',
299 'CourtAvailableHour.end_time'
300 )
301
302 )
303 );
304 if(!empty($availableCourts)){
305 $book_start_datetime = $booking_date." ".$availableCourts['CourtAvailableHour']['start_time'];
306 $book_end_datetime = $booking_date." ".$availableCourts['CourtAvailableHour']['end_time'];
307
308 $book_start_datetime = date('Y-m-d H:i:s',strtotime($booking_date." ".$availableCourts['CourtAvailableHour']['start_time']) - ($clubTimezoneOffset*60));
309 $book_end_datetime = date('Y-m-d H:i:s',strtotime($booking_date." ".$availableCourts['CourtAvailableHour']['end_time']) - ($clubTimezoneOffset*60));
310
311 $freeslots = $this->ClubBookingSession->query("CALL slots('$book_start_datetime','$book_end_datetime','$duration','$court_id');");
312 foreach($freeslots as $freeslotKey=>$freeslot){
313 $temp_start_time = date('Y-m-d H:i:s',strtotime($freeslot['S']['start_date_time'])+$clubTimezoneOffset*60);
314 $temp_end_time = date("Y-m-d H:i:s",strtotime($freeslot['S']['end_date_time']) +($clubTimezoneOffset*60));
315 $courtFreeSlots[$temp_start_time.'_'.$temp_end_time]=$temp_start_time.'_'.$temp_end_time;
316 }
317 if($freeKey==0){
318 $return_array = $courtFreeSlots;
319 }
320 else{
321 $return_array=array_merge($return_array,$courtFreeSlots);
322 }
323
324 }
325 }
326 }
327
328 }
329 return $return_array;
330 }