/** * @param int $rateId * @param string $dateFrom * @param string $dateTo * @return array */ public function getRateDataByRateIdDates($rateId, $dateFrom, $dateTo) { $inventoryDao = new Inventory($this->getServiceLocator(), '\\ArrayObject'); $rates = $inventoryDao->getRateDataByRateIdDates($rateId, $dateFrom, $dateTo); $ratesData = []; foreach ($rates as $rate) { $ratesData[$rate['date']] = ['apartment_id' => $rate['apartment_id'], 'room_id' => $rate['room_id'], 'rate_name' => $rate['rate_name'], 'price' => $rate['price'], 'date' => $rate['date'], 'capacity' => $rate['capacity'], 'rate_id' => $rate['rate_id']]; } return $ratesData; }
/** * @param int $apartment_id * @param float $sale * @param date $startDate * @param date $endDate * @var ginosiColl ginosiCollectTransactionsSummaryInApartmentCurrency * @var partnerColl partnerCollectTransactionsSummaryInApartmentCurrency * @return Array */ private function _getSaleArray($apartment_id, $sale, $startDate, $endDate, $passYear = false) { $sale['all_bookings'] = $sale['all_cancelations'] = $sale['all_cancelations'] = $sale['highest_sold_price'] = $sale['long_stay'] = $sale['stay_period']['long'] = 0; $sale['stay_period'] = []; $notUsedStatus = [ForBookingStatus::BOOKING_STATUS_CANCELLED_INVALID, ForBookingStatus::BOOKING_STATUS_CANCELLED_EXCEPTION, ForBookingStatus::BOOKING_STATUS_CANCELLED_TEST_BOOKING, ForBookingStatus::BOOKING_STATUS_CANCELLED_MOVED]; /** * @var $bankTransactionService \DDD\Service\Booking\BankTransaction * @var \DDD\Dao\Booking\ReservationNightly $reservationNightlyDao */ $bookingDao = new Booking($this->getServiceLocator(), 'DDD\\Domain\\Apartment\\Statistics\\ForBasicDataBooking'); $userManagerDao = $this->getServiceLocator()->get('dao_user_user_manager'); $reservationNightlyDao = $this->getServiceLocator()->get('dao_booking_reservation_nightly'); $inventoryDao = new Inventory($this->getServiceLocator(), '\\ArrayObject'); $bankTransactionService = $this->getServiceLocator()->get('service_booking_bank_transaction'); $expenseDao = new ExpenseStatistics($this->getServiceLocator()); $bookings = $bookingDao->getBookingsForYear($apartment_id, $startDate, $endDate, $notUsedStatus); $monthlyConst = $expenseDao->getMonthlyCost($apartment_id, $startDate, $endDate); // calculate with nightly data $fistDate = $startDate; $i = 0; while ($i <= 12) { $nextDate = date('Y-m-01', strtotime('+1 month', strtotime($fistDate))); $monthDays = cal_days_in_month(CAL_GREGORIAN, date('m', strtotime($fistDate)), date('Y', strtotime($fistDate))); // reservation day count $monthlyData = $reservationNightlyDao->getBookedMonthlyData($apartment_id, $fistDate, $nextDate); $bookedDayCount = $monthlyData['count']; $monthlySum = $monthlyData['sum']; // closed days $totalClosed = $inventoryDao->getClosedAv($apartment_id, $fistDate, $nextDate); $selectedMonth = date("M_Y", strtotime($fistDate)); $sale['close_out'][$selectedMonth] = $totalClosed - $bookedDayCount; $sale['unsold_days'][$selectedMonth] = $monthDays - $bookedDayCount; $sale['monthly_av_price'][$selectedMonth] = number_format($bookedDayCount ? $monthlySum / $bookedDayCount : 0, 2, '.', ''); // get highest and lowest sold prices if ($passYear) { // get highest price if ($sale['highest_sold_price'] < $monthlyData['max']) { $sale['highest_sold_price'] = $monthlyData['max']; } // get lowest price if (!array_key_exists('lowest_sold_price', $sale) && $monthlyData['min']) { $sale['lowest_sold_price'] = $monthlyData['min']; } elseif (isset($sale['lowest_sold_price']) && $sale['lowest_sold_price'] > $monthlyData['min'] && $monthlyData['min']) { $sale['lowest_sold_price'] = $monthlyData['min']; } } $fistDate = $nextDate; $i++; } // Monthly Booking And Cancelations And Margin foreach ($bookings as $book) { $month = date("M_Y", strtotime($book->getDate_to())); /* @var $ginosiColl $ginosiCollectTransactionsSummaryDomain \DDD\Domain\Booking\TransactionSummary */ $ginosiColl = $bankTransactionService->getTransactionsSummary($book->getId(), BankTransaction::TRANSACTION_MONEY_DIRECTION_GINOSI_COLLECT, [BankTransaction::BANK_TRANSACTION_TYPE_PAY]); $ginosiCollCurrency = $ginosiColl->getSummaryInApartmentCurrency(); /* @var $partnerCollectTransactionsSummaryDomain \DDD\Domain\Booking\TransactionSummary */ $partnerColl = $bankTransactionService->getTransactionsSummary($book->getId(), BankTransaction::TRANSACTION_MONEY_DIRECTION_PARTNER_COLLECT, [BankTransaction::BANK_TRANSACTION_TYPE_PAY]); $partnerCollCurrency = $partnerColl->getSummaryInApartmentCurrency(); $transactionsSummary = $ginosiCollCurrency + $partnerCollCurrency; if (ForBookingStatus::BOOKING_STATUS_BOOKED == $book->getStatus()) { $sale['all_bookings'] += 1; $sale['monthly_bookings'][$month] += 1; $ginosiksRes = $userManagerDao->getGinosiksReservation($book->getGuestEmail()); if ($ginosiksRes) { $sale['free_sold'][$month] += 1; } $date_diff = Helper::getDaysFromTwoDate($book->getDate_to(), $book->getDate_from()); if ($sale['long_stay'] < $date_diff) { $sale['long_stay'] = $date_diff; } } elseif (ForBookingStatus::BOOKING_STATUS_CANCELLED_BY_CUSTOMER == $book->getStatus()) { $sale['all_cancelations'] += 1; $month = date("M_Y", strtotime($book->getDate_to())); $sale['monthly_cancalations'][$month] += 1; } $sale = $this->_setMonthlyCost($book, $month, $sale, $transactionsSummary); } //Calculate final monthly cost foreach ($monthlyConst as $month => $cost) { if (isset($sale['monthly_cost'][$month])) { $sale['monthly_cost'][$month] += $cost; $sale['monthly_cost_total'] += $cost; $sale['profit'][$month] = $sale['monthly_revenue'][$month] - $sale['monthly_cost'][$month]; } } // Cancellation score $total_reservations = ($sale['all_cancelations'] + $sale['all_bookings']) * 100; if (0 != $total_reservations) { $sale['cancelation_score'] = $sale['all_cancelations'] / ($sale['all_cancelations'] + $sale['all_bookings']) * 100; $sale['cancelation_score'] = number_format($sale['cancelation_score'], 1); } else { $sale['cancelation_score'] = 0; } // Monthly Occupancy $bookingReservationData = $bookingDao->getReservationForAccOnDate($apartment_id, $startDate, $endDate); $reservationDates = []; foreach ($bookingReservationData as $reservation) { $reservationDates = array_merge($reservationDates, Helper::getDateListInRange($reservation->getDate_from(), date('Y-m-d', strtotime('-1 day', strtotime($reservation->getDate_to()))))); } //Get Extremes $inventoryDao = new Inventory($this->getServiceLocator(), 'DDD\\Domain\\Apartment\\Statistics\\ForBasicDataInventory'); $extremums = $inventoryDao->getExtremums($apartment_id, $startDate, $endDate); $sale['max_avilability'] = $extremums->getMax_availability(); $sale['max_price'] = $extremums->getMax_price(); $sale['min_price'] = $extremums->getMin_price(); //Get Review $apartmentReview = $this->getServiceLocator()->get('service_apartment_review'); $apartmentGeneralDao = $this->getServiceLocator()->get('dao_apartment_general'); $reviewScore = $apartmentGeneralDao->getReviewScore($apartment_id)['score']; $sale['review'] = $reviewScore; return $sale; //Set All Times Statistics }
private function getRateAvailabilityByDate($masterRateId, $dateFrom, $dateTo) { $inventoryDao = new \DDD\Dao\Apartment\Inventory($this->getServiceLocator()); $inventoryDomainList = $inventoryDao->getAvailabilityByRateIdAndDateRange($masterRateId, $dateFrom, $dateTo); $output = []; if ($inventoryDomainList->count()) { foreach ($inventoryDomainList as $inventoryDomain) { $output[$inventoryDomain->getDate()] = ['availability' => $inventoryDomain->getAvailability(), 'isChanged' => $inventoryDomain->getIsChanged(), 'isLockPrice' => $inventoryDomain->getIsLockPrice()]; } } return $output; }
/** * @param $itemId * @param null $dateFrom * @param null $dateTo * @param string $type * @return CivilResponder */ public function syncAll($itemId, $dateFrom = null, $dateTo = null, $type = self::SYNC_WITH_PRODUCT) { $response = new \stdClass(); try { /** * @var \DDD\Dao\Apartel\Inventory $apartelInventoryDao */ if ($this->getProductType() == self::PRODUCT_APARTEL) { $apartelInventoryDao = $this->getServiceLocator()->get('dao_apartel_inventory'); $inventoryDomain = $apartelInventoryDao->getRateAvailabilityByApartelId($itemId, $dateFrom, $dateTo, $type); } else { $inventoryDao = new Inventory($this->getServiceLocator(), 'DDD\\Domain\\Apartment\\Inventory\\RateAvailabilityComplete'); $inventoryDomain = $inventoryDao->getRateAvailabilityByApartmentId($itemId, $dateFrom, $dateTo, $type); } if ($inventoryDomain) { $reqRates = $chunkedReqRates = $resultStatuses = []; $apartmentId = 0; foreach ($inventoryDomain as $rate) { if (!$apartmentId) { $apartmentId = $rate->getProductId(); } $reqRates[] = ['rate_id' => $rate->getCubilisRateId(), 'room_id' => $rate->getCubilisRoomId(), 'avail' => $rate->getAvailability(), 'capacity' => $rate->getCapacity(), 'price' => $rate->getPrice(), 'min_stay' => $rate->getMinStay(), 'max_stay' => $rate->getMaxStay(), 'date' => $rate->getDate()]; } if (count($reqRates) > 50) { $chunkedReqRates = array_chunk($reqRates, 50); } else { $chunkedReqRates[] = $reqRates; } foreach ($chunkedReqRates as $ratesCollection) { $result = $this->syncCollection($apartmentId, $ratesCollection); if ($result->getStatus() == CivilResponder::STATUS_ERROR) { break; } $resultStatuses[] = $result; } if (count($chunkedReqRates) == count($resultStatuses)) { $response->code = 0; $response->status = CivilResponder::STATUS_SUCCESS; $response->message = 'Successfully synced.'; } else { $response->code = 1; $response->status = CivilResponder::STATUS_ERROR; $response->message = count($resultStatuses) . ' out of ' . count($chunkedReqRates) . ' fail. Last error message: ' . $result->getMessage() . '.'; $response->data = $resultStatuses; } $response = ['Cubilis' => $response]; } else { throw new \Exception('Nothing found to sync.'); } } catch (\Exception $ex) { $this->gr2logException($ex, 'Channel Manager: Synchronization All Failed', ['item_id' => $itemId, 'date_from' => $dateFrom, 'date_to' => $dateTo, 'type' => $type]); $response->status = CivilResponder::STATUS_ERROR; $response->code = $ex->getCode(); $response->message = $ex->getMessage(); $response = ['ChannelManager' => $response]; } return $this->civilResponseForCivilPeople($response); }
public function ajaxToggleAvailabilityAction() { /** * @var Request $request * @var Response $response * @var \DDD\Service\Apartment\Inventory $inventoryService */ $request = $this->getRequest(); $output = ['bo' => ['status' => 'error']]; try { $date = $request->getPost('date', null); $action = $request->getPost('action', null); $reasonMessage = $request->getPost('message', null); if ($request->isPost() && $request->isXmlHttpRequest()) { $inventoryService = $this->getServiceLocator()->get('service_apartment_inventory'); if (strtotime($date) !== false && in_array($action, ['open', 'close'])) { $apartmentId = $this->apartmentId; $inventoryDao = new InventoryDao($this->getServiceLocator()); $availability = $action == 'open' ? 1 : 0; $preInvData = $inventoryDao->getApartmentAvailabilityByDate($apartmentId, date('Y-m-d', strtotime($date))); $preAvailability = null; if ($preInvData) { $preAvailability = $preInvData->getAvailability(); } if (!$availability && !$reasonMessage) { throw new \Exception(TextConstants::AVAILABILITY_CLOSE_MSG); } $responseUpdate = $inventoryService->updateAvailabilityFromCalendar($apartmentId, $date, $availability); $auth = $this->getServiceLocator()->get('library_backoffice_auth'); if ($responseUpdate['status'] == 'success') { if (!$availability) { $reasonMessage = !empty($reasonMessage) ? '<br><i>Reason:</i> "' . $reasonMessage . '"' : ''; /* @var $actionLogger \Library\ActionLogger\Logger */ $actionLogger = $this->getServiceLocator()->get('ActionLogger'); $actionLogger->save(ActionLogger::MODULE_APARTMENT_CALENDAR, $apartmentId, ActionLogger::ACTION_APARTMENT_CALENDAR_AVAILABILITY, 'Availability <b>closed</b> for ' . $date . $reasonMessage); } $output['bo']['status'] = 'success'; $output['bo']['msg'] = $responseUpdate['msg']; } else { throw new \Exception($responseUpdate['msg']); //'Cannot update price.' } $dateExploded = explode(' ', $date); /* @var $apartmentInventoryService \DDD\Service\Apartment\Inventory */ $apartmentInventoryService = $this->getServiceLocator()->get('service_apartment_inventory'); $accommodationsDao = $this->getServiceLocator()->get('dao_accommodation_accommodations'); $bookingOnDate = $apartmentInventoryService->checkApartmentAvailabilityByDate($apartmentId, $dateExploded[0], Booking::BOOKING_STATUS_BOOKED); $userId = $auth->getIdentity()->id; $accInfo = $accommodationsDao->fetchOne(["id" => $apartmentId]); $sellingStatus = [ApartmentService::APARTMENT_STATUS_LIVE_AND_SELLING, ApartmentService::APARTMENT_STATUS_SELLING_NOT_SEARCHABLE]; if (in_array($accInfo->getStatus(), $sellingStatus) && $preAvailability != $availability && $availability == 0 && !$bookingOnDate) { $notifService = $this->getServiceLocator()->get('service_notifications'); $userManagerDao = $this->getServiceLocator()->get('dao_user_user_manager'); $userGroupDao = $this->getServiceLocator()->get('dao_user_user_groups'); $accName = $accInfo->getName(); $userInfo = $userManagerDao->getUserById($userId); $roledUsers = $userGroupDao->getUsersByGroupId(Roles::ROLE_APARTMENT_AVAILABILITY_MONITOR); $recipient = []; foreach ($roledUsers as $roledUser) { $recipient[] = $roledUser->getUserId(); } $now = date('Y-m-d'); $sender = NotificationService::$availabilityMonitoring; $calendarDate = date('Y/m', strtotime($date)); $closeDate = date('Y-m-d', strtotime($date)); if ($availability) { $notifMsg = TextConstants::OPEN_APARTMENT_CALENDAR; } else { $notifMsg = TextConstants::CLOSE_APARTMENT_CALENDAR . ' ' . $reasonMessage; } // notification if (!$auth->hasRole(Roles::ROLE_NO_TRACK_AVAILABILITY_CHANGES)) { $message = sprintf($notifMsg, $userId, $userInfo->getFirstname() . ' ' . $userInfo->getLastname(), $apartmentId, $calendarDate, $accName, $closeDate); $url = '/apartment/' . $apartmentId . '/calendar/' . $calendarDate; $notificationData = ['recipient' => $recipient, 'sender' => $sender, 'sender_id' => $userId, 'message' => $message, 'url' => $url, 'show_date' => $now]; $notifService->createNotification($notificationData); } } } else { $output['bo']['msg'] = 'Bad parameters.'; } } else { $output['bo']['msg'] = 'Bad request.'; } } catch (\Exception $ex) { $output['bo']['msg'] = $ex->getMessage(); } return new JsonModel($output); }