1 <?php
2
3 class RoomOrder extends DataObject {
4 static $db = array(
5 'AdditionalPlacesCount' => 'Int',
6 'Sort' => 'Int',
7 'RoomCost' => 'Decimal(10, 2)',
8 'AdditionalPlacesCost' => 'Decimal(10, 2)',
9 'RoomOrderCost' => 'Decimal(10, 2)',
10 );
11
12 static $has_one = array(
13 'Room' => 'Room',
14 'Rate' => 'RoomRate',
15 'Order' => 'BookingOrder',
16 'MainPerson' => 'RoomOrderPerson',
17 );
18
19 static $has_many = array(
20 'AdditionalPersons' => 'RoomOrderPerson',
21 'RoomServices' => 'RoomServiceOrder'
22 );
23
24 static $summary_fields = array('Room.Title', 'Rate.Title', 'Rate.PersonCount', 'MainPerson.FirstName', 'MainPerson.LastName', 'AdditionalPlacesCount', 'RoomOrderCost', 'RoomOrderServicesCost');
25
26
27 static function get_date_room_orders($roomID, $startDate, $endDate) {
28 if (($startDate > $endDate)) {
29 return false;
30 }
31
32 $room = DataObject::get_by_id('Room', $roomID);
33 if (!$room) {
34 return false;
35 }
36
37 $start = date('Y-m-d 12:00', strtotime($startDate));
38 $end = date('Y-m-d 23:59', strtotime($endDate));
39 $ordersList = array();
40 while($start < $end) {
41 $where = array();
42 $where[] = "RoomID = {$roomID}";
43 $where[] = "BookingOrder.StartDate <= '" . date('Y-m-d', strtotime($start)) . "' AND BookingOrder.EndDate >= '" . date('Y-m-d', strtotime($start)) . "'";
44 $where[] = "BookingOrder.Status IN('". implode("', '", BookingOrder::$accounted_statuses)."')";
45
46 $orders = DataObject::get('RoomOrder', implode(' AND ', $where), '', "JOIN BookingOrder ON BookingOrder.ID = RoomOrder.OrderID");
47 $ordersList[date('Y_m_d', strtotime($startDate))] = $orders;
48 $start = date('Y-m-d 12:00', strtotime("+1 day", strtotime($start)));
49 }
50 return $ordersList;
51 }
52
53
54 static function available_rooms_count($roomID, $startDate, $endDate) {
55 if (($startDate > $endDate)) {
56 return false;
57 }
58
59 $room = DataObject::get_by_id('Room', $roomID);
60 if (!$room) {
61 return false;
62 }
63
64 $maxUseCount = 0;
65 $ordersList = self::get_date_room_orders($roomID, $startDate, $endDate);
66 if ($ordersList) {
67 foreach($ordersList as $date=>$dayOrders) {
68 if ($dayOrders && ($dayOrders->Count() > $maxUseCount)) {
69 $maxUseCount = $dayOrders->Count();
70 }
71 }
72 }
73 if ($room->OrderingRoomsCount > $maxUseCount) {
74 return $room->OrderingRoomsCount - $maxUseCount;
75 }
76 return false;
77 }
78
79 function canView($member = null) {
80 return Permission::check('CMS_ACCESS_BookingOrderAdmin', 'any', $member);
81 }
82
83 function canEdit($member = null) {
84 return Permission::check('CMS_ACCESS_BookingOrderAdmin', 'any', $member);
85 }
86
87 function canDelete($member = null) {
88 return Permission::check('CMS_ACCESS_BookingOrderAdmin', 'any', $member);
89 }
90
91 function canCreate($member = null) {
92 return Permission::check('CMS_ACCESS_BookingOrderAdmin', 'any', $member);
93 }
94
95 function fieldLabels($includerelations = true) {
96 $labels = parent::fieldLabels($includerelations);
97 $labels['Room.Title'] = _t('RoomOrder.RoomTitle', 'Room Title');
98 $labels['Rate.Title'] = _t('RoomOrder.RateTitle', 'Rate Title');
99 $labels['Rate.PersonCount'] = _t('RoomOrder.PersonCount', 'Person Count');
100 $labels['MainPerson.FirstName'] = _t('RoomOrder.FirstName', 'First Name');
101 $labels['MainPerson.LastName'] = _t('RoomOrder.LastName', 'Last Name');
102 $labels['RoomOrderServicesCost'] = _t('RoomOrder.RoomOrderServicesCost', 'Services Cost');
103 return $labels;
104 }
105
106 function getTitle() {
107 return _t('RoomOrder.has_one_Room') . " {$this->Sort}, {$this->Room()->Title}, " . _t('RoomOrder.has_one_Rate') . " {$this->Rate()->Title} (" . $this->Rate()->TotalPersonString() . " чел.)";
108 }
109
110
111
112 function calcRoomOrderCost() {
113 $this->RoomCost = $this->RatePrice();
114 $this->AdditionalPlacesCost = $this->AdditionalPlacesPrice();
115 $this->RoomOrderCost = $this->RoomCost + $this->AdditionalPlacesCost;
116
117 }
118
119 function onBeforeWrite() {
120 parent::onBeforeWrite();
121
122 if ($this->isChanged('RateID')) {
123 $rate = DataObject::get_by_id('RoomRate', $this->RateID);
124 if ($rate) {
125 $this->RoomID = $rate->RoomID;
126 }
127
128 $this->calcRoomOrderCost();
129 }
130 if ($this->MainPersonLastName && $this->MainPersonFirstName && $this->MainPersonSureName && $this->MainPersonCitizenship) {
131 if ($this->MainPersonID && $this->MainPerson()) {
132 $this->MainPerson()->LastName = $this->MainPersonLastName;
133 $this->MainPerson()->FirstName = $this->MainPersonFirstName;
134 $this->MainPerson()->SureName = $this->MainPersonSureName;
135 $this->MainPerson()->Citizenship = $this->MainPersonCitizenship;
136 $this->MainPerson()->write();
137 } else {
138 $newMainPerson = new RoomOrderPerson();
139 $newMainPerson->LastName = $this->MainPersonLastName;
140 $newMainPerson->FirstName = $this->MainPersonFirstName;
141 $newMainPerson->SureName = $this->MainPersonSureName;
142 $newMainPerson->Citizenship = $this->MainPersonCitizenship;
143 $newMainPerson->write();
144 $this->MainPersonID = $newMainPerson->ID;
145 }
146 }
147 }
148
149
150 function onAfterWrite() {
151 parent::onAfterWrite();
152 if ($this->isChanged('RateID')) {
153 $order = $this->Order();
154 $order->calculateOrderCost();
155 $order->write();
156 }
157 }
158
159 function onAfterDelete() {
160 $order = $this->Order();
161 $order->calculateOrderCost();
162 $order->write();
163 parent::onAfterDelete();
164 }
165
166 function getCMSFields() {
167 $fields = parent::getCMSFields();
168
169 $fields->removeByName('MainPersonID');
170
171 $fields->addFieldToTab('Root.Main', new TextField('MainPersonLastName', $this->MainPerson()->fieldLabel('LastName'), $this->MainPerson()->LastName));
172 $fields->addFieldToTab('Root.Main', new TextField('MainPersonFirstName', $this->MainPerson()->fieldLabel('FirstName'), $this->MainPerson()->FirstName));
173 $fields->addFieldToTab('Root.Main', new TextField('MainPersonSureName', $this->MainPerson()->fieldLabel('SureName'), $this->MainPerson()->SureName));
174 $fields->addFieldToTab('Root.Main', new TextField('MainPersonCitizenship', $this->MainPerson()->fieldLabel('Citizenship'), $this->MainPerson()->Citizenship));
175
176 $fields->removeByName('Sort');
177 $fields->removeByName('RoomID');
178
179 $fieldList = array();
180 $fieldList['LastName'] = _t('RoomOrderPerson.db_LastName');
181 $fieldList['FirstName'] = _t('RoomOrderPerson.db_FirstName');
182 $fieldList['SureName'] = _t('RoomOrderPerson.db_SureName');
183 $fieldList['Citizenship'] = _t('RoomOrderPerson.db_Citizenship');
184
185 $fieldTypes = array(
186 'LastName' => 'TextField',
187 'FirstName' => 'TextField',
188 'SureName' => 'TextField',
189 'Citizenship' => 'TextField',
190 );
191 $tf = new TableField(
192 'AdditionalPersons',
193 'RoomOrderPerson',
194 $fieldList,
195 $fieldTypes
196
197 );
198 $tf->setCustomSourceItems($this->AdditionalPersons());
199 $fields->replaceField('AdditionalPersons', $tf);
200
201 $rs = array();
202 $rooms = Room::get_available_rooms();
203 if ($rooms) {
204 foreach($rooms as $room) {
205 if ($room->ActiveRates() && $room->ActiveRates()->Count()) {
206 $rs[$room->Title] = $room->ActiveRates()->map();
207 }
208 }
209 }
210 $fields->replaceField('RateID', new GroupedDropdownField('RateID', $this->fieldLabel('Rate'), $rs));
211
212 $fieldList = array(
213 'RoomServiceID' => 'Название',
214 'Count' => 'Количество',
215 );
216
217 $fieldList = array();
218 $fieldList['RoomServiceID'] = _t('RoomServiceOrder.Title');
219 $fieldList['Count'] = _t('RoomServiceOrder.db_Count');
220
221 $fieldTypes = array(
222 'RoomServiceID' => 'RoomServiceDropdownField',
223 'Count' => 'TextField',
224 );
225 $tf = new TableField(
226 'RoomServices',
227 'RoomServiceOrder',
228 $fieldList,
229 $fieldTypes
230
231 );
232 $tf->setCustomSourceItems($this->RoomServices());
233 $fields->replaceField('RoomServices', $tf);
234
235 return $fields;
236 }
237
238 function RatePrice() {
239 return $this->Rate()->PeriodPrice(strtotime($this->Order()->StartDate), strtotime($this->Order()->EndDate));
240 }
241
242 function TotalPersonsCount() {
243 return $this->AdditionalPersons()->Count() + 1;
244 }
245
246 function AdditionalPlacesPrice() {
247 return $this->AdditionalPlacesCount * $this->Room()->AdditionalPlaceCost * $this->Order()->OrderLength();
248 }
249
250 function RoomOrderPrice() {
251 $servicesSum = 0;
252 foreach($this->RoomServices() as $roomService) {
253 $servicesSum += $roomService->RoomServicePrice();
254 }
255 return $this->RatePrice() + $this->AdditionalPlacesPrice() + $servicesSum;
256 }
257
258 function RoomOrderServicesCost() {
259 $servicesSum = 0;
260 foreach($this->RoomServices() as $roomService) {
261 $servicesSum += $roomService->RoomServicePrice();
262 }
263 return $servicesSum;
264 }
265 }
266
267
268 class RoomServiceDropdownField extends DropdownField{
269
270 function __construct($name, $title = null, $source = null, $value = "", $form = null) {
271 if (RoomService::get_active()) {
272 $source = RoomService::get_active()->map();
273 }
274 parent::__construct($name, $title, $source, $value, $form);
275 $this->setHasEmptyDefault(true);
276 $this->setEmptyString(_t('RoomServiceDropdownField.SelectRoomService'));
277 }
278
279 }
280
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the
Silverstripe Forums to ask development related questions.
-