Version: current

      1 <?php
      2 // Заказ конкретного номера - со списком услуг, ФИО и т.д.
      3 class RoomOrder extends DataObject {
      4     static $db = array(
      5         'AdditionalPlacesCount' => 'Int',
      6         'Sort' => 'Int', // Сортировка заказов по полю Sort объекта Room
      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)) { //($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)) { //($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         //debug::show($fields);
    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. -