/** * @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 }