function datepickerAction() { ob_clean(); $unitID = $this->_getParam('unit_id', null); $unitModel = new RM_Units(); $unit = $unitModel->get($unitID); $reservationModel = new RM_Reservations(); $reservations = $reservationModel->fetchAllForUnitCalendar($unit); $config = new RM_Config(); $RMdate = new RM_Date(); $jsonDisabledPeriods = new stdClass(); $jsonDisabledPeriods->start = array(); $jsonDisabledPeriods->end = array(); foreach ($reservations as $period) { $jsonPeriod = new stdClass(); $jsonPeriod->start = $config->convertDates($period->start_datetime, RM_Config::JS_DATEFORMAT, RM_Config::PHP_DATEFORMAT); $jsonPeriod->end = $config->convertDates($period->end_datetime, RM_Config::JS_DATEFORMAT, RM_Config::PHP_DATEFORMAT); // store the start date picker blocked periods $jsonDisabledPeriods->start[] = clone $jsonPeriod; $jsonPeriod->start = $RMdate->dateAdd($config->convertDates($period->start_datetime, RM_Config::JS_DATEFORMAT, RM_Config::PHP_DATEFORMAT), 1); $jsonPeriod->end = $RMdate->dateAdd($config->convertDates($period->end_datetime, RM_Config::JS_DATEFORMAT, RM_Config::PHP_DATEFORMAT), 1); $jsonDisabledPeriods->end[] = clone $jsonPeriod; } $json = Zend_Json::encode($jsonDisabledPeriods); $this->view->calendardata = $json; $this->view->unit_id = $unitID; echo $this->view->render('DailyPrices/datepicker.phtml'); die; }
function getEndDatetime($format = null) { if ($format == null) { return $this->end_datetime; } $date = new RM_Date($this->end_datetime, self::$_dateFormat); return $date->toString($format); }
/** * Returns unit that are not that have a min stay on this period more than this period * or don't have a prices at all for this period * * @param RM_Date $day * @param int $persons * @param int $length - period length in days * @return array - array with */ private function _getByMinPeriod($day, $persons, $length) { $datetime = $day->toString('Y-m-d'); $sql = "\n \t\tSELECT\n \t\t\t{$this->_name}.unit_id as unit_id\n \t\tFROM\n \t\t\t{$this->_name}\n \t\tWHERE\n \t\t\tnumber_persons='" . $persons->getAdults() . "'\n AND min_stay > {$length}\n \t\t\tAND UNIX_TIMESTAMP(start_datetime) <= UNIX_TIMESTAMP('{$datetime}')\n \t\t\tAND UNIX_TIMESTAMP(end_datetime) >= UNIX_TIMESTAMP('{$datetime}')"; $rowsTemp = $this->_getBySQL($sql); $notUnitIDs = array(); foreach ($rowsTemp as $row) { $notUnitIDs[] = $row->unit_id; } return $notUnitIDs; }
/** * Gets the calendar Data * * @return JSON */ private function _getdata($startRange = false, $endRange = false) { if (!$startRange || !$endRange) { $startRange = date("Y-m-d"); $endRange = date("Y-m-d"); } $unitModel = new RM_Units(); $units = $unitModel->getAll(new RM_Unit_Search_Criteria()); $unitModel = new RM_Units(); $reservationModel = new RM_Reservations(); $config = new RM_Config(); $evtsArray = array(); // add 6 months to either side of the reservation $RMDate = new RM_Date(); $start = $RMDate->dateSub($startRange, 180); $end = $RMDate->dateAdd($endRange, 180); $filter = array(); $filter['data']['type'] = 'date'; $filter['field'] = 'start_datetime'; $filter['data']['comparison'] = 'gt'; $filter['data']['value'] = $start; $filterArray[] = $filter; $filter = array(); $filter['data']['type'] = 'date'; $filter['field'] = 'end_datetime'; $filter['data']['comparison'] = 'lt'; $filter['data']['value'] = $end; $filterArray[] = $filter; $filter = array(); $filter['data']['type'] = 'numeric'; $filter['field'] = 'in_progress'; $filter['data']['comparison'] = 'eq'; $filter['data']['value'] = 0; $filterArray[] = $filter; foreach ($units as $unit) { $unit = $unitModel->get($unit->id); $reservations = $reservationModel->fetchAllByUnit($unit, $filterArray); foreach ($reservations as $period) { $idArray = explode("-", $period->id); $id = (int) $idArray[1]; // check time $ad = true; // all day $starttime = explode(" ", $period->start_datetime); if ($starttime[1] !== "00:00:00") { $ad = false; } $endtime = explode(" ", $period->end_datetime); if ($endtime[1] !== "23:30:00") { $ad = false; } $evtsArray[] = array("id" => $id, "cid" => $unit->id, "uid" => (int) $period->user_id, "title" => "<span style='text-align:center;width:70%;'>" . $period->id . " " . $unit->name . "(" . $unit->id . ")</span>", "start" => $period->start_datetime, "end" => $period->end_datetime, "ad" => $ad); } } return array("success" => true, "message" => RM_Environment::getInstance()->getTranslation(RM_Environment::TRANSLATE_MAIN)->_('Admin.Reservation.Edit', "LoadedData"), "data" => $evtsArray); }
private function _getDatetimes() { $dateFunc = new RM_Date(); $datetimes = $dateFunc->getDatesArray(date("Y-m-d"), -($this->_stepsOffset * $this->_step), $this->_step); return $datetimes; }
function setdatecriteriaJsonAction() { $this->_withoutView(); $unitID = $this->_getParam('unit_id', null); $unitModel = new RM_Units(); $unit = $unitModel->get($unitID, RM_Environment::getInstance()->getLocale(), array("summary", "description")); if ($unit == null) { return array('data' => array('success' => false, 'error' => $this->_translate->_('User.DatePicker', 'SelectedUnitDoesNotExists'))); } //TODO: we need to check dates for null $startdate = $this->_getParam('startdate', null); $enddate = $this->_getParam('enddate', null); $quantity = (int) $this->_getParam('qty', 1); //TODO: we need to check dates for rigth format to parse them into objects //check if start date is after end date $startDateObject = new RM_Date(strtotime($startdate)); $endDateObject = new RM_Date(strtotime($enddate)); if ($endDateObject->isEarlier($startDateObject)) { return array('data' => array('success' => false, 'error' => $this->_translate->_('User.DatePicker', 'StartAfterEnd'))); } // check if the dates are available... $period = new RM_Reservation_Period($startDateObject, $endDateObject); $adults = $this->_getParam("adults", 1); $children = $this->_getParam("children", 0); $infants = $this->_getParam("infants", 0); $persons = new RM_Reservation_Persons(array("adults" => $adults, "children" => $children, "infants" => $infants)); // get otherinfo - this is non-standard price system information. $otherinfo = Zend_Json::decode($this->_getParam("otherinfo", "{}")); // while we don't need the price here, getTotalUnitPrice will also check the // period selected is valid. $information = new RM_Prices_Information($unit, $period, $persons, $otherinfo); $priceSystem = RM_Environment::getInstance()->getPriceSystem(); try { $calculatedTotalPrice = $priceSystem->getTotalUnitPrice($information); } catch (RM_Exception $e) { return array('data' => array('success' => false, 'error' => $e->getMessage())); } // get the default start/end times... $startArray = explode(" ", $startdate); $endArray = explode(" ", $enddate); $realPriceSystem = $priceSystem->getRealPriceSystem($unit); $configObjectName = "RM_Unit" . $realPriceSystem->name . "Config"; // ie: RM_UnitDailyPricesConfig $priceConfigObject = new $configObjectName(); $recreatePeriod = false; // if the start time is null or 00:00:00 load the default price system times if (!isset($startArray[1]) || $startArray[1] === "" || $startArray[1] === "00:00:00") { try { // placed in a try so that if the price module returns an exception for default_end_time it does not crash this $defaultStartTime = $priceConfigObject->fetchValueByUnit($unitID, 'default_start_time'); $startdate = $startArray[0] . " " . $defaultStartTime; $startDateObject = new RM_Date(strtotime($startdate)); $recreatePeriod = true; } catch (Exception $e) { } } // if the end time is null or 00:00:00 load the default price system times if (!isset($endArray[1]) || $endArray[1] === "" || $endArray[1] === "23:30:00") { try { // placed in a try so that if the price module returns an exception for default_end_time it does not crash this $defaultEndTime = $priceConfigObject->fetchValueByUnit($unitID, 'default_end_time'); $enddate = $endArray[0] . " " . $defaultEndTime; $endDateObject = new RM_Date(strtotime($enddate)); $recreatePeriod = true; } catch (Exception $e) { } } // if the times have been added re-create the period object with the times... if ($recreatePeriod) { $period = new RM_Reservation_Period($startDateObject, $endDateObject); } // get the unit setting for the setting availablity_check // this could fail if the price system doesn't have this setting so it is wrapped in a try try { $availabilityCheck = $priceConfigObject->fetchValueByUnit($unitID, 'availablity_check'); } catch (Exception $e) { $availabilityCheck = "1"; } // check availability if ($availabilityCheck == "1") { $isAvailable = $unitModel->isAvailableUnitbyDate($unit, $period); if (!$isAvailable) { return array('data' => array('success' => false, 'error' => $this->_translate->_('User.DatePicker', 'ReselectDates'))); } } $data = array(); $data['start_datetime'] = $startdate; $data['end_datetime'] = $enddate; $data['adults'] = $adults; $data['children'] = $children; $data['infants'] = $infants; $data['otherinfo'] = $otherinfo; $data['quantity'] = $quantity; $criteria = new RM_Unit_Search_Criteria($data); $criteria->publishedOnly = true; RM_Reservation_Manager::getInstance()->resetCriteria()->setCriteria($criteria); // handle groups $isGroup = $unit->isGroup(); $groupID = $unit->getGroupId(); // if this is a group we need to get an available unit from the 'pool' if ($isGroup) { // get available sub units $AllavailableSubUnits = $unit->getAllSubUnits($criteria, $unit); foreach ($AllavailableSubUnits as $subunit) { if ($subunit->getGroupId() === $unit->getGroupId()) { $availableSubUnits[] = $subunit; } } // set a temporary session variable this is used in the groups row class $_SESSION["returnAllUnits"] = true; $units = array(); $subunits = array(); $selectedCount = 0; // if there is a unit available take the first one from the returned units... foreach ($availableSubUnits as $potentialUnit) { if ($selectedCount >= $quantity) { break; } $details = new RM_Reservation_Details($potentialUnit, $period, $persons, $otherinfo); RM_Reservation_Manager::getInstance()->addDetails($details); $selectedCount += 1; } // if the number of units saved to the reservation are not equal to the quantity also add the master unit if ($selectedCount < $quantity) { // add the master unit also $details = new RM_Reservation_Details($unit, $period, $persons, $otherinfo); RM_Reservation_Manager::getInstance()->addDetails($details); } } else { $details = new RM_Reservation_Details($unit, $period, $persons); RM_Reservation_Manager::getInstance()->addDetails($details); } // remove the temporary session variable unset($_SESSION["returnAllUnits"]); return array('data' => array('success' => true)); }
/** * Return price for one day. Based on weekday rate or weekend rate or week price (substracting by 7) * * @param RM_Date $day * @param int $daysNumber Total number of days for reservation * @param Zend_Db_Table_Row_Abstract $unit Unit that belong to reservation * @param int $persons Number of persons that will live in unit * @param date $startdatetime the startdate of the reservation (date object) * @return float */ public function getDayPrice($day, $daysNumber, $unit, $persons, $startdatetime = null) { $model = $this->_unitPricesModel; $priceRow = $model->getByDay($unit, $day, $persons); if ($priceRow == null) { return 0; } // min stay == max stay if ((int) $priceRow->min_stay !== 0 && (int) $priceRow->max_stay !== 0 && (int) $priceRow->min_stay === (int) $priceRow->max_stay) { if ($daysNumber > (int) $priceRow->max_stay || $daysNumber < (int) $priceRow->min_stay) { $msg = str_replace("[XX]", $priceRow->max_stay, $this->_translate->_('RM.Module.DailyPrices', 'DaysRetrictedTo')); throw new RM_Exception($msg); } } // min stay check if ($daysNumber < (int) $priceRow->min_stay) { $msg = str_replace("[XX]", $priceRow->min_stay, $this->_translate->_('RM.Module.DailyPrices', 'DaysNumberIsSmallerThanMin')); throw new RM_Exception($msg); } // max stay check if ((int) $priceRow->max_stay !== 0 && ((int) $priceRow->max_stay >= (int) $priceRow->min_stay && $daysNumber > (int) $priceRow->max_stay)) { $msg = str_replace("[XX]", $priceRow->max_stay, $this->_translate->_('RM.Module.DailyPrices', 'DaysNumberIsGreaterThanMax')); throw new RM_Exception($msg); } // period restrictions if ((int) $priceRow->period_restriction !== 0 && !is_int($daysNumber / (int) $priceRow->period_restriction)) { $msg = str_replace("[XX]", $priceRow->period_restriction, $this->_translate->_('RM.Module.DailyPrices', 'PeriodRestrictionMsg')); throw new RM_Exception($msg); } // handle if an object or string is passed for the date. if (is_object($startdatetime)) { $selectedStartDay = date("w", $startdatetime->toString("U")); } else { $selectedStartDay = date("w", strtotime($startdatetime)); } // $priceRow->week_startday = -1 means that weekday restriction is disabled if ($priceRow->week_startday != -1) { // get the day names into an array $translate = RM_Environment::getInstance()->getTranslation(RM_Environment::TRANSLATE_MAIN); $dayJson = $translate->_('Common.JSON', 'WeekDaysLongNumbered'); $dayJson = str_replace(chr(39), chr(34), $dayJson); //Zend_Json::decode does not support single quotes so replace these with doubles $daysArray = Zend_Json::decode($dayJson); if ($priceRow->week_startday1 != -1) { if ($priceRow->week_startday == $selectedStartDay || $priceRow->week_startday1 == $selectedStartDay) { // no code here } else { $msg = str_replace("[DAY]", $daysArray[$priceRow->week_startday][1] . '/' . $daysArray[$priceRow->week_startday1][1], $this->_translate->_('RM.Module.DailyPrices', 'StartDayNotAllowed')); throw new RM_Exception($msg); } } else { if ($priceRow->week_startday != $selectedStartDay) { $msg = str_replace("[DAY]", $daysArray[$priceRow->week_startday][1], $this->_translate->_('RM.Module.DailyPrices', 'StartDayNotAllowed')); throw new RM_Exception($msg); } } } // end day restriction... // $priceRow->week_startday = -1 means that weekday restriction is disabled if ($priceRow->week_endday != -1) { $rmDate = new RM_Date(); $enddatetime = $rmDate->dateAdd(date("Y-m-d", $startdatetime->toString("U")), $daysNumber); $selectedEndDay = date("w", strtotime($enddatetime)); // get the day names into an array $translate = RM_Environment::getInstance()->getTranslation(RM_Environment::TRANSLATE_MAIN); $dayJson = $translate->_('Common.JSON', 'WeekDaysLongNumbered'); $dayJson = str_replace(chr(39), chr(34), $dayJson); //Zend_Json::decode does not support single quotes so replace these with doubles $daysArray = Zend_Json::decode($dayJson); if ($priceRow->week_endday1 != -1) { if ($priceRow->week_endday == $selectedEndDay || $priceRow->week_endday1 == $selectedEndDay) { // no code here } else { $msg = str_replace("[DAY]", $daysArray[$priceRow->week_endday][1] . '/' . $daysArray[$priceRow->week_endday1][1], $this->_translate->_('RM.Module.DailyPrices', 'EndDayNotAllowed')); throw new RM_Exception($msg); } } else { if ($priceRow->week_endday != $selectedEndDay) { $msg = str_replace("[DAY]", $daysArray[$priceRow->week_endday][1], $this->_translate->_('RM.Module.DailyPrices', 'EndDayNotAllowed')); throw new RM_Exception($msg); } } } // get config values $priceConfigModel = $this->_unitPricesConfigModel; $weekendPriceEnabled = (int) $priceConfigModel->fetchValueByUnit($unit->id, 'weekend_price_enabled'); $dailyPriceEnabled = (int) $priceConfigModel->fetchValueByUnit($unit->id, 'daily_price_enabled'); $monthlyPriceEnabled = (int) $priceConfigModel->fetchValueByUnit($unit->id, 'monthly_price_enabled'); $midweekDays = explode(",", $priceConfigModel->fetchValueByUnit($unit->id, 'midweek_days')); $weekendDays = explode(",", $priceConfigModel->fetchValueByUnit($unit->id, 'weekend_days')); // perform the calculation rules... // the rules are cascaded starting from weekly price to daily... // if month or above... if ($monthlyPriceEnabled === 1 && $daysNumber >= 30) { $dayrate = $priceRow->monthly_rate / 30; return $dayrate; } // if weekly or over if ($daysNumber >= 7) { $dayrate = $priceRow->weekly_rate / 7; return $dayrate; } // if weekend if ($weekendPriceEnabled === 1 && RM_DailyPrices_Weekend::isWeekend($weekendDays, $day->toString('w'))) { return $priceRow->weekend_price; } // if midweek days if ($midweekDays !== 0 && RM_DailyPrices_Midweek::isMidWeek($midweekDays, $day->toString('w'))) { return $priceRow->midweek_price; } // if daily if ($dailyPriceEnabled) { return $priceRow->weekday_price; } // fallback to weekly price if no other rule have caught this return $priceRow->weekly_rate / 7; }
/** * Check is input day is weekend. * * @param Zend_Db_Table_Row * @param RM_Date $day * @return bool */ public function isWeekend($unit, $day) { $dayNumber = $day->getWeekday(); $weekend = $this->fetchValueByUnit($unit->id, 'weekend_days'); return RM_DailyPricesConfig::isWeekend($weekend, $dayNumber); }