1 <?php
2 3 4 5 6
7 class RoomRate extends DataObject {
8 static $db = array(
9 'Title' => 'Varchar(150)',
10 'PersonCount' => 'Int',
11 'Active' => 'Boolean',
12 'Base' => 'Boolean',
13 'NoReturn' => 'Boolean',
14 'AdditionalPlaceCount' => 'Int',
15 );
16
17 static $has_one = array(
18 'Icon' => 'Image',
19 'Room' => 'Room',
20 );
21
22 static $many_many = array(
23 'StandartServices' => 'RoomService',
24 'Prices' => 'RatePeriod',
25 );
26
27 static = array(
28 'Prices' => array('Price' => 'Decimal(10, 2)'),
29 );
30
31 static $default_sort = 'Active, Base desc, PersonCount, AdditionalPlaceCount';
32
33 static $searchable_fields = array('Title', 'PersonCount', 'Base', 'NoReturn');
34 static $summary_fields = array('Title', 'PersonCount', 'ActiveTitle', 'BaseTitle', 'NoReturnTitle');
35
36 37 38 39 40 41 42 43
44 static function period_length($startDate, $endDate) {
45 $startDate = date_create($startDate);
46 $endDate = date_create($endDate);
47 $interval = date_diff($startDate, $endDate);
48 return (int)$interval->format('%a');
49 }
50
51 function fieldLabels($relations = true) {
52
53 $labels = parent::fieldLabels($relations);
54 $labels['ActiveTitle'] = $labels['Active'];
55 $labels['BaseTitle'] = $labels['Base'];
56 $labels['NoReturnTitle'] = $labels['NoReturn'];
57 return $labels;
58 }
59
60 function TitleWithPrice() {
61 return $this->Title . " (" . $this->PeriodPrice() . " руб.)";
62 }
63
64 function TitleAdditionalPlaces() {
65 return $this->Title . " (+ {$this->AdditionalPlaceCount} чел.)";
66 }
67
68 function ActiveTitle() {
69 return ($this->Active) ? _t('Boolean.YES') : _t('Boolean.NO');
70 }
71
72 function BaseTitle() {
73 return ($this->Base) ? _t('Boolean.YES') : _t('Boolean.NO');
74 }
75
76 function NoReturnTitle() {
77 return ($this->NoReturn) ? _t('Boolean.YES') : _t('Boolean.NO');
78 }
79
80 function getCMSFields() {
81 $fields = parent::getCMSFields();
82 $fields->removeFieldFromTab('Root.Prices','Prices');
83 $fields->removeByName('Prices');
84 if ($this->isInDB()) {
85 $tab = $fields->findOrMakeTab('Root.RatePrices', _t('Room.PRICES'));
86 if ($this->allPrices()) {
87 foreach ($this->allPrices() as $p) {
88 $tab->push(new RoomRate_PriceField('Prices', $p));
89 }
90 }
91 }
92 $opt = $this->Room()->Services();
93 $fields->replaceField('StandartServices', new CheckboxSetField('StandartServices', $this->fieldLabel('StandartServices'), $opt->map()));
94
95 return $fields;
96 }
97
98 99 100 101 102
103 function allPrices() {
104
105 $all = DataObject::get('RatePeriod');
106 foreach ($this->Prices() as $p) {
107 if ($rec = $all->find('ID', $p->ID)) {
108 $all->replace($rec, $p);
109 }
110 }
111 return $all;
112 }
113
114 115 116 117 118 119 120
121 function ActivePrices($all = false) {
122 if ($all) $this->Prices();
123
124 $dt = $this->Prices("Date < now()", 'Date DESC', '', 1)->First();
125 return $this->Prices("Date >= '$dt->Date'", 'Date ASC');
126 }
127
128 function onBeforeWrite() {
129 parent::onBeforeWrite();
130
131 if ($this->isChanged('Base') && ($this->Base == 1)) {
132 foreach($this->Room()->Rates() as $rate) {
133 if ($rate->ID != $this->ID) {
134 $rate->Base = 0;
135 $rate->write();
136 }
137 }
138 }
139 }
140
141 142 143 144 145 146 147
148 function getOneDayRoomPrice($date=false) {
149 if (!$date) {
150 $date = time();
151 }
152 $price = 0;
153 foreach($this->Prices() as $ratePrice) {
154 if (strtotime($ratePrice->Date) <= $date) {
155 $price = $ratePrice->Price;
156 }
157 else break;
158 }
159 return (float)$price;
160 }
161
162 163 164 165 166 167 168 169 170 171
172 function PeriodPrice($startDate=false, $endDate=false) {
173 $totalPrice = 0;
174 if ((!$startDate || !$endDate) && ($filterData = BookingPage::getFilterDates())) {
175 $startDate = strtotime($filterData['FilterStartDate']);
176 $endDate = strtotime($filterData['FilterEndDate']);
177 }
178 if ($startDate && $endDate) {
179 while($startDate <= strtotime("-1 day", $endDate)) {
180 $totalPrice += $this->getOneDayRoomPrice($startDate);
181 $startDate = strtotime("+1 day", $startDate);
182 }
183 }
184 return $totalPrice;
185 }
186
187 function getPrice() {
188 return $this->PeriodPrice();
189 }
190
191
192 193 194 195 196
197 198 199 200 201 202 203 204
205
206 207 208 209 210 211 212
213 function PersonWord($person = false) {
214 if ($person === false) $person = $this->PersonCount;
215
216 return Convert::number2name(
217 $person,
218 _t('BookingPage.Person1'),
219 _t('BookingPage.Person4'),
220 _t('BookingPage.Person5')
221 );
222 }
223
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
240
241 function getTotalPersonCount() {
242 return $this->PersonCount + $this->AdditionalPlaceCount;
243 }
244
245 function TotalPersonString() {
246 return $this->PersonCount . (($this->AdditionalPlaceCount > 0) ? "+" . $this->AdditionalPlaceCount : '');
247 }
248
249 250 251 252 253 254
255 function RoomCountSelector() {
256 $nums = array();
257 $nums[0] = _t('RoomRate.SelectRoomCount', 'select');
258
259 $dates = BookingPage::getFilterDates();
260 $availableCount = RoomOrder::available_rooms_count($this->RoomID, $dates['FilterStartDate'], $dates['FilterEndDate']);
261 if (!$availableCount) {
262 return false;
263 }
264
265 for($i = 1; $i <= $availableCount; $i++) {
266 $nums[$i] = $i;
267 }
268 $count = 0;
269 if ($order = BookingOrder::get_current_order()) {
270 $count = $order->getOrderRoomsCount($this->ID);
271 }
272 $f = new DropdownField("RoomCount[$this->RoomID][$this->ID]", '', $nums, $count);
273 $f->addExtraClass('RoomCountSelector');
274 $f->addExtraAttribute('autocomplete', 'off');
275 $f->addExtraAttribute('data-rateid', $this->ID);
276 $f->addExtraAttribute('data-roomid', $this->RoomID);
277 $f->addExtraAttribute('data-personcount', $this->TotalPersonCount);
278 return $f->FieldHolder();
279 }
280
281
282
283
284 285 286 287 288 289
290 function AdditionalPlacesSelector() {
291 if ($this->AdditionalPlaceCount) {
292 $nums = array();
293 $nums[0] = _t('RoomRate.SelectAdditionalPlaces', 'select');
294 for($i = 1; $i <= $this->AdditionalPlaceCount; $i++) {
295 $nums[$i] = $i;
296 }
297 $f = new DropdownField("AdditionalPlacesCount[$this->RoomID][$this->ID]", '', $nums);
298 $f->addExtraClass('AdditionalPlacesSelector');
299 $f->addExtraAttribute('data-rateid', $this->ID);
300 $f->addExtraAttribute('data-roomid', $this->RoomID);
301 $f->addExtraAttribute('data-additionalplacescost', $this->Room()->AdditionalPlaceCost * BookingPage::getFilterDatesPeriodLength());
302 return $f;
303 }
304 return false;
305 }
306 }
307
308 309 310 311 312
313 class RoomRate_PriceField extends NumericField {
314
315 function __construct($name, $param) {
316 $name .= '[' . $param->ID . ']';
317 parent::__construct($name, $param->Title, $param->Price);
318 }
319
320 function saveInto(DataObject $record) {
321 if (!preg_match('/(\w+)\[(\d+)\]/', $this->name, $matches))
322 user_error("RoomRate_PriceField::saveInto() $this->name has invalid format");
323
324 $fieldName = $matches[1];
325 $id = $matches[2];
326
327 $saveDest = $record->$fieldName();
328
329 if (!$saveDest)
330 user_error("RoomRate_PriceField::saveInto() Field '$fieldName' not found on $record->class.$record->ID", E_USER_ERROR);
331
332 if ($this->value > 0) {
333 $saveDest->add($id, array('Price' => $this->value));
334 }
335 else {
336 $saveDest->remove($id);
337 }
338 }
339 }
340
[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.
-