-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathReservationService.php
More file actions
151 lines (140 loc) · 5.01 KB
/
ReservationService.php
File metadata and controls
151 lines (140 loc) · 5.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<?php
/**
* ReservationService.php
*
* @author Ryuji AMANO <ryuji@ryus.co.jp>
* @link http://www.netcommons.org NetCommons Project
* @license http://www.netcommons.org/license.txt NetCommons License
*/
App::uses('ReservationRepeatService', 'Reservations.Service');
/**
* Class ReservationService
*/
class ReservationService {
/**
* 施設に対する予約が重複している日付を返す。
* 重複がなければ空配列
*
* @param string $locationKey 施設キー
* @param string $startDateTime 開始日時
* @param string $endDateTime 終了日時
* @param string $timezone タイムゾーン
* @param array $rrule rrule
* @param array $ignoreConditions 無視するEventのConditions日付のリスト
* @return array 予約が重複している日付のリスト
*/
public function getOverlapReservationDate(
$locationKey,
$startDateTime,
$endDateTime,
$timezone,
$rrule,
$ignoreConditions
) {
$overlapDates = [];
//繰り返しの日付リストを生成
$repeatService = new ReservationRepeatService();
$startDate = date('Y-m-d', strtotime($startDateTime));
$timeLength = strtotime($endDateTime) - strtotime($startDateTime); // 予約の時間幅
$repeatDateSet = $repeatService->getRepeatDateSet($rrule, $startDate);
// 日付、開始時刻、終了時刻にわける
$startTime = date('H:i:s', strtotime($startDateTime));
// 繰り返しの数だけ重複をチェックする
foreach ($repeatDateSet as $checkDate) {
// 繰り返し生成日付+時刻でチェックする開始日時、終了日時を生成
$checkStartDateTime = $checkDate . ' ' . $startTime;
$checkEndDateTime = date('Y-m-d H:i:s', strtotime($checkStartDateTime) + $timeLength);
if ($this->_existOverlapReservation(
$locationKey,
$checkStartDateTime,
$checkEndDateTime,
$timezone,
$ignoreConditions
)
) {
// 重複予約があれば重複日リストに追加
$overlapDates[] = $checkDate;
}
}
return $overlapDates;
}
/**
* 重複する予約があるかチェック
*
* @param string $locationKey 施設キー
* @param string $startDateTime 開始日時
* @param string $endDateTime 終了日時
* @param string $inputTimeZone 入力日時のタイムゾーン
* @param array $ignoreConditions 無視するEventのConditions日付のリスト
* @return bool true 重複有り false 重複無し
*/
protected function _existOverlapReservation(
$locationKey,
$startDateTime,
$endDateTime,
$inputTimeZone,
$ignoreConditions
) {
// この時点ではユーザタイム
// サーバタイムに変換
// $locationKeyで指定された施設に対して予約があるかをis_active=1 or (is_latest =1 AND 承認待ち)の中からさがす
// └is_latestも入れてるのは、未承認の仮予約でも重複させないため。
// サーバタイムに変換
$netCommonsTime = new NetCommonsTime();
$startDateTime = $netCommonsTime->toServerDatetime($startDateTime, $inputTimeZone);
$endDateTime = $netCommonsTime->toServerDatetime($endDateTime, $inputTimeZone);
$startDateTime = date('YmdHis', strtotime($startDateTime));
$endDateTime = date('YmdHis', strtotime($endDateTime));
// 存在チェック
//$this->loadModels(['ReservationEvent' => 'Reservations.ReservationEvent']);
$this->ReservationEvent = ClassRegistry::init('Reservations.ReservationEvent');
$conditions = [
'ReservationEvent.location_key' => $locationKey,
// 同じ繰り返しIDの予約は重複チェック対象外
// ignoreConditions の差し込み
$ignoreConditions,
//'ReservationEvent.reservation_rrule_id !=' => $rruleId,
// workflow
[
// isActive
// isLatestは承認申請中だけ(差し戻しと一時保存はチェックしない)
'OR' => [
'ReservationEvent.is_active' => 1,
[
'ReservationEvent.is_latest' => 1,
'ReservationEvent.status' => WorkflowComponent::STATUS_APPROVAL_WAITING,
]
]
],
[
'ReservationEvent.dtstart <' => $endDateTime,
'ReservationEvent.dtend >' => $startDateTime,
]
// 'OR' => [
// // 重複している予約は開始が$endDateTimeより前 AND 終了が$startDateTiemより後
// [
// 'ReservationEvent.dtstart <' => $endDateTime,
// 'ReservationEvent.dtend >' => $startDateTime,
//
// // 始点が指定した範囲にあったら時間枠重複
// //'ReservationEvent.dtstart >=' => $startDateTime,
// //'ReservationEvent.dtstart <' => $endDateTime,
// ],
// [
// // 終点が指定した範囲にあったら時間枠重複
// //'ReservationEvent.dtend >' => $startDateTime,
// //'ReservationEvent.dtend <=' => $endDateTime,
//
// ],
// [
// // 始点、終点ともそれぞれ指定範囲の前と後だったら時間枠重複
// 'ReservationEvent.dtstart <' => $startDateTime,
// 'ReservationEvent.dtend >' => $endDateTime,
// ],
// ]
//],
];
$exist = $this->ReservationEvent->find('count', ['conditions' => $conditions]);
return ($exist) ? true : false;
}
}