Exemplo n.º 1
0
 /**
  * @return array|\Zend\Http\Response|ViewModel
  */
 public function indexAction()
 {
     /**
      * @var ReservationsDAO $reservationsDao
      */
     $reservationsDao = $this->getServiceLocator()->get('dao_booking_booking');
     $pageToken = $this->params()->fromQuery('token');
     if ($pageToken) {
         $reservationData = $reservationsDao->getReservationDataForChargeAuthorizationPage($pageToken);
         if ($reservationData) {
             $now3d = new \DateTime(null, new \DateTimeZone($reservationData->getTimezone()));
             $now3d = strtotime($now3d->modify('-3 day')->format('Y-m-d'));
             if ($now3d > strtotime($reservationData->getReservationDateTo()) && $now3d > strtotime($reservationData->getCccaCreationDate())) {
                 return $this->redirect()->toRoute('home')->setStatusCode('301');
             }
         } else {
             return $this->redirect()->toRoute('home')->setStatusCode('301');
         }
     } else {
         return $this->redirect()->toRoute('home')->setStatusCode('301');
     }
     /**
      * @var ChargeAuthorizationService $chargeAuthorizationService
      */
     $chargeAuthorizationService = $this->getServiceLocator()->get('service_reservation_charge_authorization');
     $info = $chargeAuthorizationService->getInfoForCCCAPage($pageToken);
     $amount = $info->getAmount();
     $chargeAuthorizationService->changeChargeAuthorizationPageStatus($reservationData->getReservationId(), $pageToken, ChargeAuthorization::CHARGE_AUTHORIZATION_PAGE_STATUS_VIEWED);
     $cccaForm = new ChargeAuthorizationForm();
     $cccaForm->prepare();
     /**
      * @var ChargeDAO $chargesDao
      */
     $chargesDao = $this->getServiceLocator()->get('dao_booking_charge');
     $chargesSummary = $chargesDao->calculateChargesSummary($reservationData->getReservationId(), \DDD\Service\Booking\Charge::CHARGE_MONEY_DIRECTION_GINOSI_COLLECT);
     $cancellationPolicyData = ['is_refundable' => $reservationData->getIsRefundable(), 'refundable_before_hours' => $reservationData->getRefundableBeforeHours(), 'penalty_type' => $reservationData->getPenaltyType(), 'penalty_percent' => $reservationData->getPenaltyValue(), 'penalty_fixed_amount' => $reservationData->getPenaltyValue(), 'penalty_nights' => $reservationData->getPenaltyValue(), 'night_count' => \Library\Utility\Helper::getDaysFromTwoDate($reservationData->getReservationDateFrom(), $reservationData->getReservationDateTo()), 'code' => $reservationData->getCustomerCurrency()];
     /**
      * @var WebsiteApartmentService $websiteApartmentService
      */
     $websiteApartmentService = $this->getServiceLocator()->get('service_website_apartment');
     $cancellationPolicyDescriptionArray = $websiteApartmentService->cancelationPolicy($cancellationPolicyData);
     $cancellationPolicyDescription = $cancellationPolicyDescriptionArray['description'];
     $reservationData->setCancellationPolicy($cancellationPolicyDescription);
     $creditCardData = $chargeAuthorizationService->getCreditCardDataForAuthorizationPage($reservationData->getCreditCardId());
     if (is_null($amount)) {
         //for backup compatibility
         $amount = $chargesSummary->getSummaryInApartmentCurrency();
     }
     $this->layout()->userTrackingInfo = ['res_number' => $reservationData->getReservationNumber(), 'partner_id' => $reservationData->getPartnerId()];
     return new ViewModel(['cccaForm' => $cccaForm, 'reservationData' => $reservationData, 'creditCardData' => $creditCardData, 'chargesSummary' => $chargesSummary, 'amount' => $amount]);
 }
Exemplo n.º 2
0
Arquivo: Main.php Projeto: arbi/MyCode
 /**
  * @param $cubilisRateIdDates
  * @param $roomTypeId
  * @param $dates
  * @param $bookingDomain
  * @param $fromCubilisRatesData
  * @param $productId
  * @param $channelResId
  * @param $partnerId
  * @param $isApartel
  * @param $building
  * @param $apartmentListUsed
  * @param $guestCount
  * @return array
  */
 public function getNightlyData($cubilisRateIdDates, $roomTypeId, $dates, $bookingDomain, $fromCubilisRatesData, $productId, $channelResId, $partnerId, $isApartel, $building, $apartmentListUsed, $guestCount)
 {
     /**
      * @var \DDD\Dao\Apartment\General $apartmentDao
      * @var \DDD\Dao\Apartel\Inventory $apartelInventoryDao
      * @var \DDD\Dao\Apartel\General $apartelDao
      * @var \DDD\Service\Reservation\RateSelector $rateSelector
      * @var \DDD\Service\Reservation\RateSelector $rateSelector
      * @var \DDD\Service\Reservation\PartnerSpecific $partnerSpecificService
      * @var \DDD\Dao\Partners\Partners $partnerDao
      * @var \DDD\Service\Apartel\Type $apartelTypeService
      * @var \DDD\Service\Partners $partnerService
      */
     $rateSelector = $this->getServiceLocator()->get('service_reservation_rate_selector');
     $partnerSpecificService = $this->getServiceLocator()->get('service_reservation_partner_specific');
     $apartmentInventoryDao = new Inventory($this->getServiceLocator(), '\\ArrayObject');
     $apartelTypeService = $this->getServiceLocator()->get('service_apartel_type');
     $partnerDao = $this->getServiceLocator()->get('dao_partners_partners');
     $partnerService = $this->getServiceLocator()->get('service_partners');
     $result = ['ratesData' => [], 'overbooking' => false, 'apartel' => false];
     // night count
     $nightCount = Helper::getDaysFromTwoDate($dates['date_from'], $dates['date_to']);
     // Apartel reservation
     if ($isApartel) {
         $apartelInventoryDao = $this->getServiceLocator()->get('dao_apartel_inventory');
         $apartelDao = $this->getServiceLocator()->get('dao_apartel_general');
         $apartelId = $productId;
         $rates = $apartelInventoryDao->getRateByCubilisRateIdDates($cubilisRateIdDates, $roomTypeId);
         // if empty get parent and create task
         if (!count($rates) || count($rates) != $nightCount) {
             $rates = $apartelInventoryDao->getRateByParentRateIdDates($dates, $roomTypeId);
             $result['rateMissingTask'] = true;
         }
         $rates = iterator_to_array($rates);
         $firstApartment = $apartelDao->getApartelCurrency($apartelId);
         $ginosiCurrency = $firstApartment['code'];
         // modification
         if ($bookingDomain) {
             $apartmentId = $bookingDomain->getApartmentIdAssigned();
         } else {
             // new reservation
             // get best apartment for apartel reservation
             $getApartmentForType = $apartelTypeService->getBestApartmentForType($roomTypeId, $dates, $guestCount, $apartmentListUsed, $building);
             if ($getApartmentForType['status'] == 'not-available') {
                 $result['overbooking'] = true;
             }
             $apartmentId = $getApartmentForType['apartment_id'];
         }
     } else {
         $rates = $apartmentInventoryDao->getRateByCubilisRateIdDates($cubilisRateIdDates, $roomTypeId);
         // if empty get parent and create task
         if (!count($rates) || count($rates) != $nightCount) {
             $rates = $apartmentInventoryDao->getRateByParentRateIdDates($dates, $roomTypeId);
             $result['rateMissingTask'] = true;
         }
         $apartmentId = $productId;
         $apartelId = 0;
         $apartmentDao = $this->getServiceLocator()->get('dao_apartment_general');
         $apartmentData = $apartmentDao->getCurrency($apartmentId);
         $ginosiCurrency = $apartmentData['code'];
     }
     $ratesData = [];
     $currencyNotMatch = $ratePriceNotMatch = $rateNameNot = false;
     //  Modification: check has availability this apartment after change date
     if ($bookingDomain && ($dates['date_from'] < $bookingDomain->getDateFrom() || $dates['date_to'] > $bookingDomain->getDateTo())) {
         $oldNightlyData = Helper::getDateListInRange($bookingDomain->getDateFrom(), date('Y-m-d', strtotime('-1 day', strtotime($bookingDomain->getDateTo()))));
         $newDateRange = Helper::getDateListInRange($dates['date_from'], date('Y-m-d', strtotime('-1 day', strtotime($dates['date_to']))));
         $diffDates = array_diff($newDateRange, $oldNightlyData);
         $apartmentAvailability = $apartmentInventoryDao->checkApartmentAvailabilityApartmentDateList($apartmentId, $diffDates);
         if (!$apartmentAvailability) {
             $result['overbooking'] = true;
         }
     }
     // init strategy to get Partner Id if one was not registered in our system
     $partner = ['id' => $partnerService::PARTNER_UNKNOWN, 'commission' => $partnerService::PARTNER_UNKNOWN_COMMISSION];
     if ($partnerId) {
         $changedPartnerId = $partnerSpecificService->changePartnerForSomeCases($partnerId, $apartmentId);
         $partnerId = $changedPartnerId ? $changedPartnerId : $partnerId;
         $isOurPartnerId = $changedPartnerId ? true : false;
         $partnerData = $partnerService->getPartnerDataForReservation($partnerId, $apartmentId, $isOurPartnerId);
         $partner = ['id' => $partnerData->getGid(), 'commission' => $partnerData->getCommission()];
     }
     // check apply fuzzy logic for this partner
     $applyFuzzyLogic = $partnerDao->checkFuzzyLogic($partner['id']);
     foreach ($rates as $rate) {
         $ourPrice = $rate['price'];
         // if modification check rate exist and active if not use fuzzy logic
         if ($bookingDomain && ($bookingDomain->getDateFrom() > $rate['date'] || $bookingDomain->getDateTo() <= $rate['date']) && (!$rate['rate_id'] || !$rate['active'])) {
             $rate = $rateSelector->getSelectorRate($bookingDomain->getId(), $rate['date'], false, $isApartel);
         }
         // check availability in Reservation
         if (!$bookingDomain && !$result['overbooking'] && $rate['availability'] == 0) {
             $result['overbooking'] = true;
         }
         // check rate price mismatch
         if ($applyFuzzyLogic && isset($fromCubilisRatesData[$rate['date']]['price']) && $ourPrice != $fromCubilisRatesData[$rate['date']]['price']) {
             // fuzzy logic for base price
             $priceFuzzyLogic = $partnerSpecificService->getBasePriceByFuzzyLogic($fromCubilisRatesData[$rate['date']]['price'], $partner, $apartmentId, $rate['capacity'], $nightCount);
             $price = $priceFuzzyLogic ? $priceFuzzyLogic : $ourPrice;
         } else {
             $price = $ourPrice;
         }
         $cubilisRateId = isset($fromCubilisRatesData[$rate['date']]['channel_rate_id']) ? $fromCubilisRatesData[$rate['date']]['channel_rate_id'] : 0;
         // check Rate Name
         if (isset($fromCubilisRatesData[$rate['date']]['rate_name']) && $fromCubilisRatesData[$rate['date']]['rate_name']) {
             $rateName = $fromCubilisRatesData[$rate['date']]['rate_name'];
         } else {
             $rateName = $rate['rate_name'];
             // send critical email if not send rate name
             if (!$rateNameNot) {
                 $this->gr2err('Cubilis Not Sending Rate Name', ['cron' => 'ChannelManager', 'apartment_id' => $apartmentId, 'apartel_id' => $apartelId, 'channel_rate_id' => $cubilisRateId, 'channel_res_id' => $channelResId, 'date' => $rate['date']]);
                 $rateNameNot = true;
             }
         }
         $ratesData[$rate['date']] = ['apartment_id' => $apartmentId, 'room_id' => $rate['room_type_id'], 'rate_name' => $rateName, 'price' => $price, 'date' => $rate['date'], 'capacity' => $rate['capacity'], 'rate_id' => $rate['rate_id'], 'availability' => $rate['availability']];
         // send critical email if has currency mismatch
         if (!$currencyNotMatch && (!isset($fromCubilisRatesData[$rate['date']]['currency']) || strtolower($ginosiCurrency) != strtolower($fromCubilisRatesData[$rate['date']]['currency']))) {
             $this->gr2err('Cubilis apartment currency mismatch with our apartment currency', ['cron' => 'ChannelManager', 'apartment_id' => $apartmentId, 'apartel_id' => $apartelId, 'channel_res_id' => $channelResId]);
             $currencyNotMatch = true;
         }
     }
     // extra check if rate not matched
     if (count($rates) != $nightCount) {
         $result['overbooking'] = true;
     }
     // apartel data
     if ($isApartel) {
         $result['apartel']['apartment_id'] = $apartmentId;
         $result['apartel']['apartel_id'] = $apartelId;
     }
     $result['ratesData'] = $ratesData;
     return $result;
 }
Exemplo n.º 3
0
 /**
  * @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
 }
Exemplo n.º 4
0
 /**
  * @param array $data
  * @return array
  */
 public function bookingDataByCCPassword($data)
 {
     /**
      * @var \DDD\Service\Website\Apartment $apartmentService
      * @var \DDD\Service\Booking\Charge $chargeService
      */
     $apartmentService = $this->getServiceLocator()->get('service_website_apartment');
     $chargeService = $this->getServiceLocator()->get('service_booking_charge');
     if (!isset($data['code']) || !ClassicValidator::checkCCPdateCode($data['code'])) {
         return false;
     }
     /**
      * @var \DDD\Dao\Booking\Booking $bookingDao
      */
     $bookingDao = $this->getServiceLocator()->get('dao_booking_booking');
     $bookingDao->setEntity(new \ArrayObject());
     $resData = $bookingDao->getResDataByCCUpdateCode($data['code']);
     if (!$resData) {
         return false;
     }
     $img = Helper::getImgByWith($resData['img1'], WebSite::IMG_WIDTH_SEARCH, true, true);
     if ($img) {
         $resData['image'] = $img;
     }
     $resData['user_currency'] = $resData['guest_currency_code'];
     $bookNightCount = Helper::getDaysFromTwoDate($resData['date_from'], $resData['date_to']);
     $resData['night_count'] = $bookNightCount;
     $resData['totalNigthCount'] = $bookNightCount;
     // Cancelation Policy
     $cancelationDate = $resData;
     $cancelationDate['penalty_percent'] = $cancelationDate['penalty_fixed_amount'] = $cancelationDate['penalty_nights'] = $resData['penalty_val'];
     $cancelationDate['night_count'] = $bookNightCount;
     $cancelationDate['code'] = $resData['apartment_currency_code'];
     $cancelationPolicy = $apartmentService->cancelationPolicy($cancelationDate);
     $resData['cancelation_type'] = $cancelationPolicy['type'];
     $resData['cancelation_policy'] = $cancelationPolicy['description'];
     $paymentDetails = $chargeService->getCharges($resData['id']);
     // When showing to customers we don't really want to show base and additional parts of taxes separately
     // This part of code runs through payment details and combines same type of taxes for same day into a single unit
     $floatPattern = '/-?(?:\\d+|\\d*\\.\\d+)/';
     $smarterPaymentDetails = [];
     if ($paymentDetails) {
         foreach ($paymentDetails as $payment) {
             if ($payment['type'] != 'tax') {
                 array_push($smarterPaymentDetails, $payment);
             } else {
                 $paymentKey = $payment['type_id'] . '-' . $payment['date'];
                 if (!isset($smarterPaymentDetails[$paymentKey])) {
                     $smarterPaymentDetails[$paymentKey] = $payment;
                 } else {
                     preg_match($floatPattern, $smarterPaymentDetails[$paymentKey]['label'], $match);
                     $currValue = $match[0];
                     $currPrice = $smarterPaymentDetails[$paymentKey]['price'];
                     preg_match($floatPattern, $payment['label'], $match);
                     $additionalValue = $match[0];
                     $additionalPrice = $payment['price'];
                     $smarterPaymentDetails[$paymentKey]['label'] = str_replace($currValue, $currValue + $additionalValue, $smarterPaymentDetails[$paymentKey]['label']);
                     $smarterPaymentDetails[$paymentKey]['price'] = str_replace($currPrice, $currPrice + $additionalPrice, $smarterPaymentDetails[$paymentKey]['price']);
                     $smarterPaymentDetails[$paymentKey]['price_view'] = str_replace($currPrice, $currPrice + $additionalPrice, $smarterPaymentDetails[$paymentKey]['price_view']);
                 }
             }
         }
     }
     $resData['paymentDetails']['payments'] = $smarterPaymentDetails;
     return $resData;
 }
Exemplo n.º 5
0
 /**
  * @param \DDD\Domain\Booking\ChargeProcess $reservation
  * @param bool|false $isBookerPrice
  * @return array
  *
  */
 public function getToBeChargedItems($reservation, $isBookerPrice = false)
 {
     /**
      * @var $bookingTicketService \DDD\Service\Booking\BookingTicket
      * @var ApartmentMainService $apartmentMainService
      * @var \DDD\Service\Textline $textlineService
      */
     $bookingTicketService = $this->getServiceLocator()->get('service_booking_booking_ticket');
     $textlineService = $this->getServiceLocator()->get('service_textline');
     $discountParams = [];
     if ($reservation->getPartnerId()) {
         $discountParams = ['aff_id' => $reservation->getPartnerId(), 'email' => $reservation->getGuestEmail()];
     }
     if ($isBookerPrice) {
         $totalPrice = $reservation->getBookerPrice();
         $price = $reservation->getBookerPrice();
     } else {
         $totalPrice = $reservation->getPrice();
         $price = $reservation->getPrice();
     }
     $nightCount = Helper::getDaysFromTwoDate($reservation->getDateTo(), $reservation->getDateFrom());
     $currencySymbol = $reservation->getCurrencySymbol();
     // Night Charges
     $chargesList = [['label' => Helper::evaluateTextline($textlineService->getUniversalTextline(1580), ['{{NIGHT_COUNT}}' => $nightCount]), 'price_view' => $currencySymbol . number_format($totalPrice, 2, '.', ' '), 'price' => $totalPrice, 'percent' => 0, 'type' => 'night', 'class' => '', 'description' => '', 'tax_included' => '']];
     // Discount Charges
     $discountValidator = $bookingTicketService->validateAndCheckDiscountData($discountParams, false);
     $discounted = false;
     if (isset($discountValidator['discount_value']) && $discountValidator['valid'] && isset($discountValidator['discount_value']) && ceil($discountValidator['discount_value'])) {
         $discountValue = $totalPrice * $discountValidator['discount_value'] / 100;
         $price = $totalPrice - $discountValue;
         $discounted = true;
         $totalPrice = $totalPrice - $discountValue;
         array_push($chargesList, ['label' => (isset($discountValidator['partner_name']) ? $discountValidator['partner_name'] : '') . ' ' . $textlineService->getUniversalTextline(1503), 'price_view' => '- ' . $currencySymbol . number_format($discountValue, 2, '.', ' '), 'price' => $discountValue, 'percent' => 0, 'type' => 'discount', 'class' => 'text-danger', 'description' => '', 'tax_included' => '']);
     }
     // Taxes Charges
     /** @var \DDD\Service\Currency\Currency $currencyService */
     $currencyService = $this->getServiceLocator()->get('service_currency_currency');
     $currencyRate = 1;
     if ($reservation->getGuestCurrency() != $reservation->getApartmentCurrency()) {
         $currencyRate = $currencyService->getCurrencyConversionRate($reservation->getGuestCurrency(), $reservation->getApartmentCurrency());
     }
     if ($reservation->getCityTotType() > 0 && $reservation->getCityTot() > 0) {
         $taxDiscounted = false;
         $totDuration = $reservation->getTotMaxDuration() ? min($reservation->getTotMaxDuration(), $nightCount) : $nightCount;
         $totValue = $reservation->getCityTot() + $reservation->getTotAdditional();
         if ($reservation->getCityTotType() == Taxes::TAXES_TYPE_PERCENT) {
             $cityTot = $price / 100 * $totValue * $totDuration / $nightCount;
             $taxValue = $totValue . ' %';
             if ($discounted) {
                 $taxDiscounted = true;
             }
             $percent = $totValue;
         } else {
             $cityTot = $totDuration * $totValue * $currencyRate;
             $taxValue = $currencySymbol . ' ' . number_format($totValue * $currencyRate, 2, '.', ' ') . ' ' . $textlineService->getUniversalTextline(1473);
             $percent = 0;
         }
         array_push($chargesList, ['label' => $textlineService->getUniversalTextline(1259) . ' (' . $taxValue . ($reservation->getTotIncluded() == 1 ? ', ' . $textlineService->getUniversalTextline(1472) : '') . ') ' . ($taxDiscounted ? $textlineService->getUniversalTextline(1633) : ''), 'price_view' => $currencySymbol . number_format($cityTot, 2, '.', ' '), 'price' => $cityTot, 'percent' => $percent, 'duration' => $totDuration, 'type' => 'tax', 'class' => 'text-primary', 'description' => $textlineService->getUniversalTextline(1429), 'tax_included' => $reservation->getTotIncluded() == 1 ?: '', 'date' => $reservation->getDateFrom(), 'type_id' => BookingAddon::ADDON_TYPE_TAX_TOT]);
         if ($reservation->getTotIncluded() != 1) {
             $totalPrice += $cityTot;
         }
     }
     if ($reservation->getCityVatType() > 0 && $reservation->getCityVat() > 0) {
         $taxDiscounted = false;
         $vatDuration = $reservation->getVatMaxDuration() ? min($reservation->getVatMaxDuration(), $nightCount) : $nightCount;
         $vatValue = $reservation->getCityVat() + $reservation->getVatAdditional();
         if ($reservation->getCityVatType() == Taxes::TAXES_TYPE_PERCENT) {
             $cityVat = $price / 100 * $vatValue * $vatDuration / $nightCount;
             $taxValue = $vatValue . ' %';
             if ($discounted) {
                 $taxDiscounted = true;
             }
             $percent = $vatValue;
         } else {
             $cityVat = $vatDuration * $vatValue * $currencyRate;
             $taxValue = $currencySymbol . number_format($vatValue * $currencyRate, 2, '.', ' ') . ' ' . $textlineService->getUniversalTextline(1473);
             $percent = 0;
         }
         array_push($chargesList, ['label' => $textlineService->getUniversalTextline(1260) . ' (' . $taxValue . ($reservation->getVatIncluded() == 1 ? ', ' . $textlineService->getUniversalTextline(1472) : '') . ') ' . ($taxDiscounted ? $textlineService->getUniversalTextline(1633) : ''), 'price_view' => $currencySymbol . number_format($cityVat, 2, '.', ' '), 'price' => $cityVat, 'percent' => $percent, 'duration' => $vatDuration, 'type' => 'tax', 'class' => 'text-primary', 'description' => $textlineService->getUniversalTextline(1430), 'tax_included' => $reservation->getVatIncluded() == 1 ?: '', 'date' => $reservation->getDateFrom(), 'type_id' => BookingAddon::ADDON_TYPE_TAX_VAT]);
         if ($reservation->getVatIncluded() != 1) {
             $totalPrice += $cityVat;
         }
     }
     if ($reservation->getCitySalesTaxType() > 0 && $reservation->getCitySalesTax() > 0) {
         $taxDiscounted = false;
         $salesTaxDuration = $reservation->getSalesTaxMaxDuration() ? min($reservation->getSalesTaxMaxDuration(), $nightCount) : $nightCount;
         $salesTaxValue = $reservation->getCitySalesTax() + $reservation->getSalesTaxAdditional();
         if ($reservation->getCitySalesTaxType() == Taxes::TAXES_TYPE_PERCENT) {
             $citySalesTax = $price / 100 * $salesTaxValue * $salesTaxDuration / $nightCount;
             $taxValue = $salesTaxValue . ' %';
             if ($discounted) {
                 $taxDiscounted = true;
             }
             $percent = $salesTaxValue;
         } else {
             $citySalesTax = $salesTaxDuration * $salesTaxValue * $currencyRate;
             $taxValue = $currencySymbol . ' ' . number_format($salesTaxValue * $currencyRate, 2, '.', ' ') . ' ' . $textlineService->getUniversalTextline(1473);
             $percent = 0;
         }
         array_push($chargesList, ['label' => $textlineService->getUniversalTextline(1261) . ' (' . $taxValue . ($reservation->getSalesTaxIncluded() == 1 ? ', ' . $textlineService->getUniversalTextline(1472) : '') . ') ' . ($taxDiscounted ? $textlineService->getUniversalTextline(1633) : ''), 'price_view' => $currencySymbol . number_format($citySalesTax, 2, '.', ' '), 'price' => $citySalesTax, 'percent' => $percent, 'duration' => $salesTaxDuration, 'type' => 'tax', 'class' => 'text-primary', 'description' => $textlineService->getUniversalTextline(1431), 'tax_included' => $reservation->getSalesTaxIncluded() == 1 ?: '', 'date' => $reservation->getDateFrom(), 'type_id' => BookingAddon::ADDON_TYPE_SALES_TAX]);
         if ($reservation->getSalesTaxIncluded() != 1) {
             $totalPrice += $citySalesTax;
         }
     }
     if ($reservation->getCityTaxType() > 0 && $reservation->getCityTax() > 0) {
         $cityTaxDuration = $reservation->getCityTaxMaxDuration() ? min($reservation->getCityTaxMaxDuration(), $nightCount) : $nightCount;
         $cityTaxValue = $reservation->getCityTax() + $reservation->getCityTaxAdditional();
         $taxDiscounted = false;
         if ($reservation->getCityTaxType() == Taxes::TAXES_TYPE_PERCENT) {
             $cityTax = $price / 100 * $cityTaxValue * $cityTaxDuration / $nightCount;
             $taxValue = $cityTaxValue . ' %';
             if ($discounted) {
                 $taxDiscounted = true;
             }
             $percent = $cityTaxValue;
         } elseif ($reservation->getCityTaxType() == Taxes::TAXES_TYPE_PER_PERSON) {
             $cityTax = $cityTaxDuration * $cityTaxValue * $currencyRate * $reservation->getOccupancy();
             $taxValue = $currencySymbol . ' ' . number_format($cityTaxValue * $currencyRate, 2, '.', ' ') . ' ' . $textlineService->getUniversalTextline(1493);
             $percent = 0;
             // Per person per night
         } else {
             $cityTax = $cityTaxDuration * $cityTaxValue * $currencyRate;
             $taxValue = $currencySymbol . ' ' . number_format($cityTaxValue * $currencyRate, 2, '.', ' ') . ' ' . $textlineService->getUniversalTextline(1473);
             $percent = 0;
         }
         array_push($chargesList, ['label' => $textlineService->getUniversalTextline(1262) . ' (' . $taxValue . ($reservation->getCityTaxIncluded() == 1 ? ', ' . $textlineService->getUniversalTextline(1472) : '') . ') ' . ($taxDiscounted ? $textlineService->getUniversalTextline(1633) : ''), 'price_view' => $currencySymbol . number_format($cityTax, 2, '.', ' '), 'price' => $cityTax, 'percent' => $percent, 'duration' => $cityTaxDuration, 'type' => 'tax', 'class' => 'text-primary', 'description' => $textlineService->getUniversalTextline(1432), 'tax_included' => $reservation->getCityTaxIncluded() == 1 ?: '', 'date' => $reservation->getDateFrom(), 'type_id' => BookingAddon::ADDON_TYPE_CITY_TAX]);
         if ($reservation->getCityTaxIncluded() != 1) {
             $totalPrice += $cityTax;
         }
     }
     // parking taxes
     $parkingNights = $this->getParkingNightsFromRemarks($reservation->getRemarks());
     if ($parkingNights) {
         // get apartment dao`s
         $apartmentDao = $this->getServiceLocator()->get('dao_accommodation_accommodations');
         $apartmentSpotsDao = $this->getServiceLocator()->get('dao_apartment_spots');
         $reservationNightlyDao = $this->getServiceLocator()->get('dao_booking_reservation_nightly');
         $resStartDate = $reservation->getDateFrom();
         $resEndDate = $reservation->getDateTo();
         $date1 = date_create($resStartDate);
         $date2 = date_create($resEndDate);
         $dateDiff = date_diff($date2, $date1)->d + 1;
         $nightData = $reservationNightlyDao->fetchAll(['reservation_id' => $reservation->getId()], ['id', 'price', 'date', 'rate_name']);
         $nightlyArr = [];
         foreach ($nightData as $night) {
             array_push($nightlyArr, $night);
         }
         /**
          * @var \DDD\Dao\Parking\Spot\Inventory $parkingInventoryDao
          */
         $parkingStart = $reservation->getDateFrom();
         $parkingEnd = date('Y-m-j', strtotime($reservation->getDateFrom() . '+' . $parkingNights . ' days'));
         $newApartmentPreferedSpotId = $availableSpot = $selectedSpot = [];
         $apartmentPreferSpots = $apartmentSpotsDao->getApartmentSpots($reservation->getApartmentIdAssigned());
         if ($apartmentPreferSpots->count()) {
             foreach ($apartmentPreferSpots as $apartmentPreferSpot) {
                 array_push($newApartmentPreferedSpotId, $apartmentPreferSpot['spot_id']);
             }
             $reservationApartmentId = $reservation->getApartmentIdAssigned();
             $apartmentService = $this->getServiceLocator()->get('service_apartment_general');
             $apartmentTimezone = $apartmentService->getApartmentTimezoneById($reservationApartmentId)['timezone'];
             $datetime = new \DateTime('now');
             $datetime->setTimezone(new \DateTimeZone($apartmentTimezone));
             $dateToday = $datetime->format('Y-m-d');
             $availableSpot = $apartmentDao->getAvailableSpotsInLotForApartmentForDateRangeByPriority($reservationApartmentId, $parkingStart, $parkingEnd, [], false, [], $dateToday, true, $newApartmentPreferedSpotId);
             if (count($availableSpot)) {
                 foreach ($availableSpot as $row) {
                     $selectedSpot = $row;
                 }
             }
         }
         $parkingTotal = 0;
         if ($dateDiff >= $parkingNights && count($availableSpot) && count($selectedSpot)) {
             for ($iterator = 0; $iterator < $parkingNights; $iterator++) {
                 $parkingTotal += $selectedSpot['price'];
             }
         }
         if ($parkingTotal > 0) {
             $parkingTotal = $currencyRate * $parkingTotal;
             $totalPrice += $parkingTotal;
             array_push($chargesList, ['label' => 'Parking', 'price_view' => $currencySymbol . number_format($parkingTotal, 2, '.', ' '), 'price' => $parkingTotal, 'percent' => 0, 'type' => 'tax', 'class' => 'text-primary', 'description' => $textlineService->getUniversalTextline(1430), 'tax_included' => $reservation->getVatIncluded() == 1 ?: '']);
         }
     }
     // Cleaning Fee
     $apartmentMainService = $this->getServiceLocator()->get('service_apartment_main');
     $cleaningFee = $apartmentMainService->getApartmentCleaningFeeInGuestCurrency($reservation->getApartmentId(), $reservation->getApartmentCurrency(), $reservation->getGuestCurrency(), $reservation->getCheckCurrency());
     if ($cleaningFee) {
         $cleaningFee = $cleaningFee * $currencyRate;
         $totalPrice += $cleaningFee;
         array_push($chargesList, ['label' => $textlineService->getUniversalTextline(1497), 'price_view' => $currencySymbol . number_format($cleaningFee, 2, '.', ' '), 'price' => $cleaningFee, 'percent' => 0, 'type' => 'fee', 'class' => 'text-primary', 'description' => $textlineService->getUniversalTextline(1498), 'tax_included' => '']);
     }
     // Total
     array_push($chargesList, ['label' => $textlineService->getUniversalTextline(1305), 'price_view' => $currencySymbol . number_format($totalPrice, 2, '.', ' '), 'price' => $totalPrice, 'percent' => 0, 'type' => 'total', 'class' => '', 'description' => '', 'tax_included' => '']);
     return $chargesList;
 }
Exemplo n.º 6
0
 /**
  * @param $apartel
  * @param $arrival
  * @param $departure
  * @param $guest
  * @param $pageItemCount
  * @param $offset
  * @param $bedrooms
  * @return array
  */
 public function getApartmentsByApartelDate($apartel, $arrival, $departure, $guest, $pageItemCount, $offset, $bedrooms)
 {
     $bookNightCount = Helper::getDaysFromTwoDate($arrival, $departure);
     $checkNightCount = Helper::getDaysFromTwoDate($arrival, date('Y-m-d'));
     $bedroomsSqlPart = '';
     if (count($bedrooms) > 0 && count($bedrooms) < 12) {
         $bedroomsSqlPart = 'AND apartment.bedroom_count in (' . implode(',', $bedrooms) . ')';
     }
     $sql = "\n                SELECT SQL_CALC_FOUND_ROWS sub2.*, MIN(sub2.price_avg) as price_min, MAX(sub2.price_avg) as price_max FROM (\n                    SELECT sub1.*, avg(price_av) as price_avg, MIN(availability) as availability_min FROM  (\n                        SELECT\n                              apartment.id            AS prod_id,\n                              apartment.name          AS prod_name,\n                              apartment.url           AS url,\n                              apartment.score         AS score,\n                              apartment.max_capacity  AS capacity,\n                              apartment.city_id,\n                              apartment.country_id,\n                              media.img1              AS img1,\n                              apartment.bedroom_count AS bedroom_count,\n                              apartment.square_meters AS square_meters,\n                              apartment.address       AS address,\n                              (rate_av.availability)  AS availability,\n                              (rate_av.price)         AS price_av,\n                              rates.id                AS rate_id,\n                              apartment.currency_id,\n                              rates.name              AS rate_name,\n                              currency.code,\n                              currency.symbol,\n                              det1.slug as slug,\n                              apartel.apartment_group_id\n                            FROM " . DbTables::TBL_APARTEL_REL_TYPE_APARTMENT . " AS rel_apartel\n                              INNER JOIN " . DbTables::TBL_APARTEL_TYPE . " AS apartel_type ON rel_apartel.apartel_type_id = apartel_type.id\n                              INNER JOIN " . DbTables::TBL_APARTELS . " AS apartel ON apartel_type.apartel_id = apartel.id\n                              INNER JOIN " . DbTables::TBL_APARTMENTS . " AS apartment ON rel_apartel.apartment_id = apartment.id\n                              INNER JOIN " . DbTables::TBL_CITIES . " AS city ON apartment.city_id = city.id\n                              INNER JOIN " . DbTables::TBL_APARTMENT_IMAGES . " AS media ON apartment.id = media.apartment_id\n                              INNER JOIN " . DbTables::TBL_APARTMENT_RATES . " AS rates ON apartment.id = rates.apartment_id\n                                                                        AND rates.active = 1\n                                                                        AND rates.min_stay <= ?\n                                                                        AND rates.max_stay >= ?\n                                                                        AND rates.release_period_start <= ?\n                                                                        AND rates.release_period_end >= ?\n                              INNER JOIN ga_apartment_inventory AS rate_av ON rates.id = rate_av.rate_id\n                              INNER JOIN " . DbTables::TBL_CURRENCY . " as currency ON apartment.currency_id = currency.id\n                              INNER JOIN " . DbTables::TBL_LOCATION_DETAILS . " AS det1 ON city.detail_id = det1.id\n                            WHERE apartel.slug = ? AND apartment.status = " . Objects::PRODUCT_STATUS_LIVEANDSELLIG . "\n                                  AND rates.capacity >= ?\n                                  AND rate_av.date >= ?\n                                  AND rate_av.date < ?\n                                  {$bedroomsSqlPart}\n                            ORDER BY apartment.id ASC, rate_av.availability ASC\n                    ) as sub1 GROUP BY sub1.rate_id\n                )  as sub2  WHERE sub2.availability_min = 1\n                GROUP BY sub2.prod_id\n                ORDER BY sub2.score DESC, sub2.price_avg ASC, sub2.prod_name ASC\n                LIMIT {$pageItemCount} OFFSET {$offset}\n        ";
     $statement = $this->adapter->createStatement($sql, [$bookNightCount, $bookNightCount, $checkNightCount, $checkNightCount, $apartel, $guest, $arrival, $departure]);
     $result = $statement->execute();
     $statementCount = $this->adapter->query('SELECT FOUND_ROWS() as total');
     $resultCount = $statementCount->execute();
     $rowCount = $resultCount->current();
     $total = $rowCount['total'];
     return ['result' => $result, 'total' => $total];
 }
Exemplo n.º 7
0
 /**
  * @param int|bool $reservationId
  * @return array
  */
 public function getReceiptData($reservationId = false)
 {
     /**
      * @var \DDD\Dao\Booking\Charge $chargeDao
      * @var \DDD\Dao\Booking\ChargeTransaction $transactionDao
      * @var \DDD\Dao\Booking\Booking $bookingDao
      */
     $chargeDao = $this->getServiceLocator()->get('dao_booking_charge');
     $transactionDao = $this->getServiceLocator()->get('dao_booking_change_transaction');
     $bookingDao = $this->getServiceLocator()->get('dao_booking_booking');
     if (!$reservationId) {
         return ['status' => 'error', 'msg' => TextConstants::ERROR];
     }
     $reservationData = $bookingDao->getReceiptData($reservationId);
     if (!$reservationData) {
         return ['status' => 'error', 'msg' => TextConstants::ERROR];
     }
     $charges = $chargeDao->getChargesByReservationId($reservationId, 1, false, true);
     $transactions = $transactionDao->getReservationTransactionsAllCurrency($reservationId);
     // Generate smarter charges list
     // We don't want customers to see two Tax charges of same type for same day!
     // Besides, we don't really need all of the info getChargesByReservationId() provides
     $smarterCharges = [];
     if ($charges && $charges->count()) {
         foreach ($charges as $charge) {
             if (!isset($smarterCharges[$charge->getAddons_type() . '-' . $charge->getReservationNightlyDate()])) {
                 $smarterCharges[$charge->getAddons_type() . '-' . $charge->getReservationNightlyDate()] = ['id' => $charge->getId(), 'acc_amount' => $charge->getAcc_amount(), 'acc_currency' => $charge->getApartmentCurrency(), 'addon' => $charge->getAddon(), 'addons_value' => $charge->getAddons_value(), 'addons_type' => $charge->getAddons_type(), 'type' => $charge->getType(), 'location_join' => $charge->getLocation_join(), 'tax_type' => $charge->getTaxType(), 'reservation_nighly_date' => $charge->getReservationNightlyDate(), 'rate_name' => $charge->getRateName(), 'money_direction' => $charge->getMoneyDirection()];
             } else {
                 $smarterCharges[$charge->getAddons_type() . '-' . $charge->getReservationNightlyDate()]['acc_amount'] += $charge->getAcc_amount();
                 $smarterCharges[$charge->getAddons_type() . '-' . $charge->getReservationNightlyDate()]['addons_value'] += $charge->getAddons_value();
             }
         }
     }
     return ['status' => 'success', 'reservation' => $reservationData, 'charges' => $smarterCharges, 'transactions' => $transactions, 'today' => date('d M Y'), 'nightCount' => Helper::getDaysFromTwoDate($reservationData['date_from'], $reservationData['date_to'])];
 }
Exemplo n.º 8
0
 /**
  * @param $rates
  * @param $reservationPrice
  * @param $reservationId
  * @param bool $isNew
  * @param bool $isApartel
  * @return array
  */
 public function select($rates, $reservationPrice, $reservationId, $isNew = false, $isApartel = false)
 {
     /**
      * @var Booking $bookingDao
      * @var WorstCXLPolicySelector $policyService
      * @var Rate $rateDao
      * @var \DDD\Dao\Apartel\Rate $apartelRateDao
      */
     $worstPolicyData = ['is_refundable' => RateService::APARTMENT_RATE_NON_REFUNDABLE, 'penalty' => 0, 'penalty_fixed_amount' => $reservationPrice, 'refundable_before_hours' => 0, 'penalty_val' => 0];
     $bookingDao = $this->getServiceLocator()->get('dao_booking_booking');
     $ratesWithPolicy = [];
     // Reservation Data
     $reservationPolicyData = $bookingDao->getReservationPolicyData($reservationId);
     if (!$reservationPolicyData) {
         return $worstPolicyData;
     }
     // Existing policy
     if (!$isNew) {
         $ratesWithPolicy[] = ['is_refundable' => $reservationPolicyData['is_refundable'], 'penalty_type' => $reservationPolicyData['penalty'], 'refundable_before_hours' => $reservationPolicyData['refundable_before_hours'], 'penalty_val' => $reservationPolicyData['penalty_val']];
     }
     // Incoming Rates
     if (!empty($rates)) {
         if ($isApartel) {
             $apartelRateDao = $this->getServiceLocator()->get('dao_apartel_rate');
             $ratesData = $apartelRateDao->getRatesPolicyData($rates);
         } else {
             $rateDao = $this->getServiceLocator()->get('dao_apartment_rate');
             $ratesData = $rateDao->getRatesPolicyData($rates);
         }
         if ($ratesData->count()) {
             foreach ($ratesData as $row) {
                 $ratesWithPolicy[] = ['is_refundable' => $row['is_refundable'], 'penalty_type' => $row['penalty_type'], 'refundable_before_hours' => $row['refundable_before_hours'], 'penalty_val' => $row['penalty_type'] == RateService::PENALTY_TYPE_PERCENT ? $row['penalty_percent'] : ($row['penalty_type'] == RateService::PENALTY_TYPE_FIXED_AMOUNT ? $row['penalty_fixed_amount'] : $row['penalty_nights'])];
             }
         }
     }
     // Calculate best penalty policy
     $nights = Helper::getDaysFromTwoDate($reservationPolicyData['date_from'], $reservationPolicyData['date_to']);
     $penaltyVal = $penalty = $penaltyAmount = $refundableBeforeHours = 0;
     $isRefundablePenalty = false;
     foreach ($ratesWithPolicy as $policy) {
         if ($policy['is_refundable'] == RateService::APARTMENT_RATE_NON_REFUNDABLE) {
             //Non Refundable
             return $worstPolicyData;
         } elseif ($policy['is_refundable'] == RateService::APARTMENT_RATE_REFUNDABLE && $reservationPolicyData['penalty_hours'] <= $policy['refundable_before_hours']) {
             // Refundable penalty period
             $penaltyData = $this->penaltyCalculateData(['penalty_val' => $policy['penalty_val'], 'penalty_type' => $policy['penalty_type']], $nights, $reservationPrice, 1);
             $penaltyAmountNew = $penaltyData['penalty_amount'];
             if ($penaltyAmountNew > $penaltyAmount) {
                 $penalty = $policy['penalty_type'];
                 $penaltyAmount = $penaltyAmountNew;
                 $penaltyVal = $penaltyData['penalty_val'];
                 $refundableBeforeHours = $policy['refundable_before_hours'];
             }
             $isRefundablePenalty = true;
         } elseif ($policy['is_refundable'] == RateService::APARTMENT_RATE_REFUNDABLE && !$isRefundablePenalty) {
             // Refundable flexible period, Nothing change, apply what has
             $penaltyData = $this->penaltyCalculateData(['penalty_val' => $policy['penalty_val'], 'penalty_type' => $policy['penalty_type']], $nights, $reservationPrice, 1);
             $penaltyAmountNew = $penaltyData['penalty_amount'];
             if ($penaltyAmountNew > $penaltyAmount) {
                 $penalty = $policy['penalty_type'];
                 $penaltyAmount = $penaltyAmountNew;
                 $penaltyVal = $penaltyData['penalty_val'];
                 $refundableBeforeHours = $policy['refundable_before_hours'];
             }
         }
     }
     $worstPolicyData = ['is_refundable' => RateService::APARTMENT_RATE_REFUNDABLE, 'penalty' => $penalty, 'penalty_fixed_amount' => $penaltyAmount, 'refundable_before_hours' => $refundableBeforeHours, 'penalty_val' => $penaltyVal];
     return $worstPolicyData;
 }
Exemplo n.º 9
0
 /**
  * Use to generate and download reservations CSV file
  */
 public function downloadCsvAction()
 {
     /**
      * @var \DDD\Service\Booking\BookingManagement $bookingManagementService
      * @var \DDD\Service\Booking\BookingTicket $bookingTicketService
      * @var GeoliteCountry $geoliteCountryService
      * @var BookingExportRow[]|\ArrayObject $reservations
      */
     $bookingManagementService = $this->getServiceLocator()->get('service_booking_management');
     $bookingTicketService = $this->getServiceLocator()->get('service_booking_booking_ticket');
     $geoliteCountryService = $this->getServiceLocator()->get('service_geolite_country');
     // getting query parameters
     $queryParams = $this->params()->fromQuery();
     // get reservations data
     $reservations = $bookingManagementService->getReservationsToExport(null, null, $queryParams);
     $filteredArray = [];
     $currencyDao = $this->getServiceLocator()->get('dao_currency_currency');
     $currencyUtility = new Currency($currencyDao);
     foreach ($reservations as $reservation) {
         $isBlacklist = $reservation->isBlacklist();
         $isBlacklist = is_null($isBlacklist) ? 'No' : 'Yes';
         $sumAndBalanc = $bookingTicketService->getSumAndBalanc($reservation->getId());
         $filteredArray[] = ["Reservation" => $reservation->getReservationNumber(), "Affiliate ID" => $reservation->getAffiliateID(), "Affiliate Name" => $reservation->getPartnerName(), "Affiliate Reference" => $reservation->getPartnerRef(), "Status" => $reservation->getStatus(), "Blacklist" => $isBlacklist, "Apartel" => $reservation->getApartel(), "Booking Date" => date('Y-m-d', strtotime($reservation->getReservationDate())), "Booking Time" => date('H:i:s', strtotime($reservation->getReservationDate())), "Apartment Id" => $reservation->getApartmentIdAssigned(), "Apartment Name" => $reservation->getProductName(), "Apartment Building" => $reservation->getApartmentBuilding(), "Apartment City" => $reservation->getApartmentCity(), "Guest" => $reservation->getGuestFullName(), "Country" => $reservation->getCountry_name(), "City" => $reservation->getGuestCityName(), "IP" => $geoliteCountryService->composeIPAndCountryNameString($reservation->getIP()), "Arrival Date" => $reservation->getArrivalDate(), "Departure Date" => $reservation->getDepartureDate(), "Nights" => Helper::getDaysFromTwoDate($reservation->getArrivalDate(), $reservation->getDepartureDate()), "PAX" => $reservation->getPAX(), "Rate" => $reservation->getRateName(), "Base Price (EUR)" => $currencyUtility->convert(str_replace(',', '', $reservation->getPrice()), $reservation->getApartmentCurrencyCode(), 'EUR'), "Base Currency" => $reservation->getApartmentCurrencyCode(), "Base Price" => $reservation->getPrice(), "Charges(Ginosi)" => $sumAndBalanc['ginosiCollectChargesSummaryInApartmentCurrency'], "Transactions(Ginosi)" => $sumAndBalanc['ginosiCollectTransactionsSummaryInApartmentCurrency'], "Balance" => $reservation->getGuestBalance(), "Charges(Partner)" => $sumAndBalanc['partnerCollectChargesSummaryInApartmentCurrency'], "Transactions(Partner)" => $sumAndBalanc['partnerCollectTransactionsSummaryInApartmentCurrency'], "Partner Balance" => $reservation->getPartnerBalance(), "No Collection" => $reservation->getNo_collection(), "Review Score" => $reservation->getReviewScore(), "Like" => $reservation->getLike(), "Dislike" => $reservation->getDislike(), "Actual Arrival Date" => $reservation->getActualArrivalDate(), "Actual Departure Date" => $reservation->getActualDepartureDate()];
     }
     if (count($filteredArray)) {
         $response = $this->getResponse();
         $headers = $response->getHeaders();
         $utilityCsvGenerator = new CsvGenerator();
         $filename = 'reservations_' . str_replace(' ', '_', date('Y-m-d')) . '.csv';
         $utilityCsvGenerator->setDownloadHeaders($headers, $filename);
         $csv = $utilityCsvGenerator->generateCsv($filteredArray);
         $response->setContent($csv);
         return $response;
     } else {
         Helper::setFlashMessage(['notice' => 'The search results were empty, nothing to download.']);
         $url = $this->getRequest()->getHeader('Referer')->getUri();
         $this->redirect()->toUrl($url);
     }
 }
Exemplo n.º 10
0
 public function indexAction()
 {
     /** @var UserManager $managerDao */
     $managerDao = $this->getServiceLocator()->get('dao_user_user_manager');
     $teamService = $this->getServiceLocator()->get('service_team_team');
     $auth = $this->getServiceLocator()->get('library_backoffice_auth');
     /** @var \DDD\Service\User\Schedule $scheduleService */
     $scheduleService = $this->getServiceLocator()->get('service_user_schedule');
     $userId = $this->params()->fromRoute('id');
     $userSessionId = $auth->getIdentity()->id;
     $isLoggedInUserGlobalManager = false;
     $profileViewer = false;
     $isManager = false;
     $itsMe = false;
     if ($auth->hasRole(Roles::ROLE_PROFILE_VIEWER)) {
         $profileViewer = true;
     }
     if ($auth->hasRole(Roles::ROLE_PEOPLE_MANAGEMENT)) {
         $isLoggedInUserGlobalManager = true;
     }
     $hasHRole = $auth->hasRole(Roles::ROLE_PEOPLE_MANAGEMENT_HR);
     if ($userId === null || $userId == $userSessionId) {
         $userId = $userSessionId;
         $itsMe = true;
     }
     $rUserDao = $this->getServiceLocator()->get('dao_user_user_manager');
     $rUser = $rUserDao->findUserById((int) $userId);
     if (!$rUser) {
         return $this->redirect()->toUrl('/');
     }
     if ($rUser->getStartDate() && $rUser->getStartDate() != '0000-00-00') {
         //604800 is the number of seconds in one week
         //31536000 is the number of seconds in one year
         $weeksWorked = floor((time() - strtotime($rUser->getStartDate())) % 31536000 / 604800);
         $yearsWorked = floor((time() - strtotime($rUser->getStartDate())) / 31536000);
         if ($weeksWorked < 0 && $yearsWorked < 0) {
             $weeksWorked = 0;
             $yearsWorked = 0;
         }
     } else {
         $weeksWorked = 0;
         $yearsWorked = 0;
     }
     // get User Manager id
     $managerId = $rUser->getManager_id();
     if ($managerId === '0') {
         $managerId = 64;
     }
     // get Manager Profile
     $myManager = $managerDao->getUserById((int) $managerId);
     if ($auth->hasRole(Roles::ROLE_PEOPLE_DIRECTORY) && $userSessionId == $managerId) {
         $isManager = true;
     }
     /**
      * @var \DDD\Service\User $userService
      */
     $userService = $this->getServiceLocator()->get('service_user');
     /** @var \DDD\Service\Profile $profileService */
     $profileService = $this->getProfileService();
     $cityDao = $this->getServiceLocator()->get('dao_geolocation_city');
     $userDao = $userService->getUsersById((int) $userId, $isManager || $isLoggedInUserGlobalManager || $hasHRole);
     if (!$userDao) {
         $view = new ViewModel();
         $view->setTemplate('backoffice/profile/disabled.phtml');
         return $view;
     }
     $userProfile = $userDao->get('user_main');
     $userOptions = $userService->getUserOptions((int) $userId);
     $countryId = $userProfile->getCountry_id();
     $cities = $cityDao->getCityByCountryId((int) $countryId);
     // Get user schedule for 3 weeks
     $userSchedule = $scheduleService->getUserScheduleInRange($userId, date('Y-m-d'), date('Y-m-d', strtotime('+20 day')));
     $userSubordinates = $profileService->getUserSubordinates($userId);
     $vacationRequest = $userService->getUserVacationRequest((int) $userId);
     $detailsForm = new ProfileDetailsForm('changeDetails');
     $passwordForm = new ProfilePasswordForm('changePassword');
     // reservation ginosik
     $resevations = [];
     $stayedDays = 0;
     $bookingDao = new \DDD\Dao\Booking\Booking($this->getServiceLocator(), 'DDD\\Domain\\Booking\\BookingProfile');
     $resevationsResult = $bookingDao->getGinosikResevations($userProfile->getEmail(), $userProfile->getAlt_email());
     foreach ($resevationsResult as $row) {
         $days = Helper::getDaysFromTwoDate($row->getDate_from(), $row->getDate_to());
         $stayedDays += $days;
         array_push($resevations, sprintf(TextConstants::PROFILE_GINOSI_RESERVATION, '/booking/edit/' . $row->getReservationNumber(), $row->getReservationNumber(), $row->getApartmentName(), $row->getDate_from(), $row->getDate_to(), $days, $row->getGuestEmail()));
     }
     /**
      * @var UserMainService $userMainService
      */
     $userMainService = $this->getServiceLocator()->get('service_user_main');
     $userDepartmentId = $userMainService->getUserDepartmentId($userId);
     $isDepartment = 1;
     $departments = $teamService->getTeamList(null, $isDepartment);
     $coDepartments = [];
     $coDepartments[-1] = '-- Departments --';
     foreach ($departments as $department) {
         $coDepartments[$department->getId()] = $department->getName();
     }
     $userTeams = $teamService->getUserTeams($userId);
     $vacationDaysCountUsedInThisYear = $userService->getVacationDaysCountUsedInThisYear($userId);
     $cashingDays = $userService->calculateVacationCashableDaysCount($userDao->get('user_main')->getVacation_days_per_year(), $userDao->get('user_main')->getVacation_days(), true);
     $datetime = new \DateTime('now');
     $datetime->setTimezone(new \DateTimeZone($userProfile->getTimezone()));
     $dateTimeNow = $datetime->format(Constants::GLOBAL_DATE_TIME_FORMAT);
     $goodTimeToCall = $scheduleService->isUserWorking($userProfile->getId(), $datetime);
     $hasAccessToManage = $auth->hasRole(Roles::ROLE_PEOPLE_DIRECTORY) && ($auth->hasRole(Roles::ROLE_PEOPLE_MANAGEMENT) || $auth->hasRole(Roles::ROLE_PEOPLE_MANAGEMENT_HR) || $isManager);
     $userCurrencyId = $userDao->get('user_main')->getCurrencyId();
     $ginocoinSpentSoFar = false;
     if ($itsMe) {
         $ginocoinSpentSoFar = $this->calculateGinocoinSpentSoFar($auth->getIdentity()->id, $userCurrencyId);
     }
     return new ViewModel(['user' => $userDao, 'userOptions' => $userOptions, 'resevations' => $resevations, 'stayedDays' => $stayedDays, 'cities' => $cities, 'myManager' => $myManager, 'itsMe' => $itsMe, 'isManager' => $isManager, 'hasAccessToManage' => $hasAccessToManage, 'profileViewer' => $profileViewer, 'changeDetailsForm' => $detailsForm, 'changePasswordForm' => $passwordForm, 'schedule' => $userSchedule, 'local_datetime' => $dateTimeNow, 'good_time_to_call' => $goodTimeToCall, 'manager_subordinates' => $userSubordinates, 'vacationRequestOld' => $vacationRequest['old'], 'vacationRequestNew' => $vacationRequest['new'], 'vacationDaysUsedThisYesr' => $vacationDaysCountUsedInThisYear, 'cashingDays' => $cashingDays, 'weeksWorked' => $weeksWorked, 'yearsWorked' => $yearsWorked, 'userTeams' => $userTeams, 'userDepartment' => $userDepartmentId, 'departments' => $coDepartments, 'hasHRole' => $hasHRole, 'hasHRoleHrVacationEditor' => $auth->hasRole(Roles::ROLE_HR_VACATION_EDITOR), 'ginocoinSpentSoFar' => $ginocoinSpentSoFar]);
 }
Exemplo n.º 11
0
 /**
  * @param $bookingId
  * @param $itemId
  * @return array
  */
 public function getDataForFrontierCharge($bookingId, $itemId)
 {
     /**
      * @var \DDD\Service\Booking\BookingAddon $bookingAddonService
      * @var \DDD\Dao\Booking\Booking $bookingDao
      * @var \DDD\Service\Taxes $taxesService
      */
     $bookingTicketService = $this->getServiceLocator()->get('service_booking_booking_ticket');
     $bookingAddonService = $this->getServiceLocator()->get('service_booking_booking_addon');
     $taxesService = $this->getServiceLocator()->get('service_taxes');
     $apartmentGroupDao = $this->getServiceLocator()->get('dao_apartment_group_apartment_group');
     $chargeDao = $this->getServiceLocator()->get('dao_booking_charge');
     $bookingDao = $this->getServiceLocator()->get('dao_booking_booking');
     $accDetailsDao = new \DDD\Dao\Apartment\Details($this->getServiceLocator(), 'ArrayObject');
     $addonsArray = $bookingAddonService->getAddonsArray();
     $bookingData = $bookingDao->getBookingForFrontierCharge($bookingId);
     $detailsRow = $accDetailsDao->fetchOne(['apartment_id' => $bookingData['apartment_id_assigned']]);
     if ($detailsRow && (int) $detailsRow['cleaning_fee']) {
         foreach ($addonsArray as $key => $addon) {
             if ($addon['id'] == BookingAddon::ADDON_TYPE_CLEANING_FEE) {
                 $cleaningFee = $detailsRow['cleaning_fee'];
                 $addonsArray[$key]['cname'] = $bookingData['acc_currency_sign'];
                 $addonsArray[$key]['currency_rate'] = $bookingData['acc_currency_rate'];
                 $addonsArray[$key]['currency_id'] = $bookingData['acc_currency_id'];
                 $addonsArray[$key]['value'] = $cleaningFee;
             }
         }
     }
     $data = ['addons_array' => $addonsArray];
     $data['booking_data'] = $bookingData;
     $data['booking_data']['night_count'] = Helper::getDaysFromTwoDate($bookingData['date_to'], $bookingData['date_from']);
     // Taxes
     $nightCount = Helper::getDaysFromTwoDate($bookingData['date_to'], $bookingData['date_from']);
     $taxesParams = ['tot' => $bookingData['tot'], 'tot_type' => $bookingData['tot_type'], 'tot_included' => $bookingData['tot_included'], 'tot_max_duration' => $bookingData['tot_max_duration'], 'tot_additional' => $bookingData['tot_additional'], 'vat' => $bookingData['vat'], 'vat_type' => $bookingData['vat_type'], 'vat_included' => $bookingData['vat_included'], 'vat_additional' => $bookingData['vat_additional'], 'vat_max_duration' => $bookingData['vat_max_duration'], 'city_tax' => $bookingData['city_tax'], 'city_tax_type' => $bookingData['city_tax_type'], 'city_tax_included' => $bookingData['city_tax_included'], 'city_tax_additional' => $bookingData['city_tax_additional'], 'city_tax_max_duration' => $bookingData['city_tax_max_duration'], 'sales_tax' => $bookingData['sales_tax'], 'sales_tax_type' => $bookingData['sales_tax_type'], 'sales_tax_included' => $bookingData['sales_tax_included'], 'sales_tax_max_duration' => $bookingData['sales_tax_max_duration'], 'sales_tax_additional' => $bookingData['sales_tax_additional'], 'apartment_currency' => $bookingData['apartment_currency_code'], 'customer_currency' => $bookingData['guest_currency_code'], 'country_currency' => $bookingData['country_currency'], 'night_count' => $nightCount, 'rate_capacity' => $bookingData['rate_capacity'], 'occupancy' => $bookingData['occupancy']];
     $taxesData = $taxesService->getTaxesForCharge($taxesParams);
     $data += $taxesData;
     $apartmentGroup = $apartmentGroupDao->fetchOne(['id' => $itemId]);
     // Charges
     $charges = $chargeDao->getChargesByReservationId($bookingId, 1);
     $data['charges'] = $charges;
     $balances = $bookingTicketService->getSumAndBalanc($bookingId);
     $balance = number_format($balances['ginosiBalanceInApartmentCurrency'], 2, '.', '');
     $data['balance'] = $balance;
     $data['group_name'] = 'Group';
     if ($apartmentGroup) {
         $data['group_name'] = $apartmentGroup->getName();
     }
     return $data;
 }
Exemplo n.º 12
0
 /**
  * @param array $data
  * @return array
  */
 public function apartmentSearch($data)
 {
     $filter = $this->filterSearchData($data);
     $result = ['status' => '', 'result' => []];
     $rateList = [];
     $apartment = $data['apartment'];
     $city = $data['city'];
     $guest = $data['guest'] > 0 ? (int) $data['guest'] : 1;
     $arrival = date('Y-m-d', strtotime($data['arrival']));
     $departure = date('Y-m-d', strtotime($data['departure']));
     $nightCount = Helper::getDaysFromTwoDate($arrival, $departure);
     $no_av_status = 'no_av';
     $no_av_result = ['arrival' => Helper::dateForUrl($arrival), 'departure' => Helper::dateForUrl($departure), 'guest' => $guest, 'city' => $city];
     if ($filter) {
         $rateDao = $this->getInventoryDao();
         $response = $rateDao->getAvailableRates($apartment, Helper::urlForSearch($city), $guest, $arrival, $departure);
         $i = 1;
         if ($response->count() > 0) {
             $currencySymbol = WebSite::DEFAULT_CURRENCY;
             $userCurrency = $this->getCurrencySite();
             $currencyDao = $this->getServiceLocator()->get('dao_currency_currency');
             $currencyResult = $currencyDao->fetchOne(['code' => $userCurrency]);
             if ($currencyResult) {
                 $currencySymbol = $currencyResult->getSymbol();
             }
             $currencyUtility = new Currency($currencyDao);
             foreach ($response as $row) {
                 //check user currency and apartment currency
                 if ($userCurrency != $row['code']) {
                     $price = $currencyUtility->convert($row['price'], $row['code'], $userCurrency);
                 } else {
                     $price = $row['price'];
                 }
                 //cancelation policy
                 $cancelationData = $row;
                 $cancelationData['night_count'] = $nightCount;
                 $cancelation = $this->cancelationPolicy($cancelationData);
                 $discountPrice = 0;
                 $visitor = new Container('visitor');
                 if (!is_null($visitor->partnerId) && (int) $visitor->partnerId) {
                     $partnerDao = new \DDD\Dao\Partners\Partners($this->getServiceLocator());
                     $partnerInfo = $partnerDao->fetchOne(['gid' => (int) $visitor->partnerId]);
                     $discountPrice = 0;
                     if ($partnerInfo && ceil($partnerInfo->getDiscount())) {
                         $discountPrice = number_format($price * (100 - $partnerInfo->getDiscount()) * 0.01, 2, '.', '');
                     }
                 }
                 //rateList
                 $rateList[] = ['primary' => $i === 1 ? true : false, 'rate' => ['id' => $row['id'], 'name' => $row['name']], 'capacity' => $row['capacity'], 'price' => number_format($price, 2, '.', ''), 'total_price' => number_format($nightCount * $price, 2, '.', ''), 'currency' => ['name' => $userCurrency, 'sign' => $currencySymbol], 'policy' => ['name' => $cancelation['type'], 'description' => $cancelation['description']], 'discount' => ['price' => $discountPrice, 'total' => number_format($nightCount * $discountPrice, 2, '.', '')]];
                 $i++;
             }
             $result['status'] = 'success';
             $result['result'] = $rateList;
         } else {
             $result['status'] = $no_av_status;
             $result['result'] = $no_av_result;
         }
         return $result;
     }
     return ['status' => $no_av_status, 'result' => $no_av_result];
 }
Exemplo n.º 13
0
 public function getAvailableRates($apartmentUrl, $city, $guestCount, $arrivalDate, $departureDate)
 {
     $bookNightCount = Helper::getDaysFromTwoDate($arrivalDate, $departureDate);
     $checkNightCount = Helper::getDaysFromTwoDate($arrivalDate, date('Y-m-d'));
     $sql = "\n            select * from (\n                select\n                    product_rates.id               AS id,\n                    product_rates.name             AS name,\n                    product_rates.capacity         AS capacity,\n                    product_rates.type             AS type,\n                    product_rates.is_refundable    AS is_refundable,\n                    product_rates.refundable_before_hours AS refundable_before_hours,\n                    product_rates.penalty_percent  AS penalty_percent,\n                    product_rates.penalty_nights     AS penalty_nights,\n                    product_rates.penalty_fixed_amount   AS penalty_fixed_amount,\n                    product_rates.penalty_type     AS penalty_type,\n                    avg(rate_av.price)             AS price,\n                    min(rate_av.availability)     AS availability,\n                    apartments.currency_id         AS currency_id,\n                    geo_details.name            AS city_name,\n                    currency.code                  AS code,\n                    currency.symbol                AS symbol\n                from " . DbTables::TBL_APARTMENT_INVENTORY . " as rate_av\n                    left join " . DbTables::TBL_APARTMENT_RATES . "    as product_rates on product_rates.id = rate_av.rate_id\n                    left join " . DbTables::TBL_APARTMENTS . "       as apartments    on apartments.id = rate_av.apartment_id\n                    left join " . DbTables::TBL_CITIES . "           as cities        on cities.id = apartments.city_id\n                    left join " . DbTables::TBL_LOCATION_DETAILS . " as geo_details   on geo_details.id = cities.detail_id and lower(geo_details.name) = ?\n                    left join " . DbTables::TBL_CURRENCY . "         as currency      on currency.id = apartments.currency_id\n                where\n                    apartments.url         = ? and\n                    product_rates.active   = 1 and\n                    product_rates.capacity >= ? and\n                    product_rates.min_stay <= ? and\n                    product_rates.max_stay >= ? and\n                    product_rates.release_period_start <= ? and\n                    product_rates.release_period_end >= ? and\n                    rate_av.date           >= ? and\n                    rate_av.date           < ?\n                group by rate_av.rate_id\n                order by\n                  rate_av.price asc,\n                  product_rates.capacity asc\n            ) as result where result.availability > 0";
     if (!Helper::isBackofficeUser()) {
         $sql .= " limit 4";
     }
     $statement = $this->adapter->createStatement($sql, [$city, $apartmentUrl, $guestCount, $bookNightCount, $bookNightCount, $checkNightCount, $checkNightCount, $arrivalDate, $departureDate]);
     $result = $statement->execute();
     return $result;
 }
Exemplo n.º 14
0
 /**
  * Testing GetToBeChargedItems method
  */
 public function testGetToBeChargedItems()
 {
     // get any reservation
     $isBookerPrice = false;
     /**
      * @var \DDD\Dao\Booking\Booking $reservationDao
      */
     $reservationDao = $this->getApplicationServiceLocator()->get('dao_booking_booking');
     //        $reservation    = $reservationDao->fetchOne(function(Select $select) {
     //            $select->order('id DESC');
     //        });
     $getReservationWithChargesAndBookedStatusQuery = new Select();
     $getReservationWithChargesAndBookedStatusQuery->join([DbTables::TBL_CHARGE => 'charges'], 'charges.reservation_id = ' . DbTables::TBL_BOOKINGS . '.id', ['charge_id' => 'id'], Select::JOIN_INNER);
     $getReservationWithChargesAndBookedStatusQuery->where->isNotNull('charge_id');
     $getReservationWithChargesAndBookedStatusQuery->where->equalTo(DbTables::TBL_BOOKINGS . '.status', Booking::BOOKING_STATUS_BOOKED);
     $getReservationWithChargesAndBookedStatusQuery->order([DbTables::TBL_BOOKINGS . '.id' => 'DESC']);
     $reservation = $reservationDao->fetchOne($getReservationWithChargesAndBookedStatusQuery);
     $this->assertNotNull($reservation);
     // get textvine service
     /**
      * @var \DDD\Service\Textline $textlineService
      */
     $textlineService = $this->getApplicationServiceLocator()->get('service_textline');
     // check chargeProcess domain
     $reservation = $reservationDao->getDataForToBeCharged($reservation->getId());
     $this->assertInstanceOf('\\DDD\\Domain\\Booking\\ChargeProcess', $reservation);
     // check booking ticket
     $bookingTicketService = $this->getApplicationServiceLocator()->get('service_booking_booking_ticket');
     $this->assertInstanceOf('\\DDD\\Service\\Booking\\BookingTicket', $bookingTicketService);
     // check discount getters
     $this->assertTrue(method_exists($reservation, 'getPartnerId'), 'Class does not have method getPartnerId');
     $this->assertTrue(method_exists($reservation, 'getGuestEmail'), 'Class does not have method getGuestEmail');
     $discountParams = [];
     if ($reservation->getPartnerId()) {
         $discountParams = ['aff_id' => $reservation->getPartnerId(), 'email' => $reservation->getGuestEmail()];
     }
     // check price getters
     $this->assertTrue(method_exists($reservation, 'getBookerPrice'), 'Booking Object does not have method getBookerPrice');
     $this->assertTrue(method_exists($reservation, 'getPrice'), 'Booking Object does not have method getPrice');
     if ($isBookerPrice) {
         $totalPrice = $reservation->getBookerPrice();
         $price = $reservation->getBookerPrice();
     } else {
         $totalPrice = $reservation->getPrice();
         $price = $reservation->getPrice();
     }
     $nightCount = Helper::getDaysFromTwoDate($reservation->getDateTo(), $reservation->getDateFrom());
     $currencySymbol = $reservation->getCurrencySymbol();
     // check night count
     $this->assertLessThan($nightCount, 0);
     // Night Charges
     $chargesList = [['label' => Helper::evaluateTextline($textlineService->getUniversalTextline(1580), ['{{NIGHT_COUNT}}' => $nightCount]), 'price_view' => $currencySymbol . number_format($totalPrice, 2, '.', ' '), 'price' => $totalPrice, 'percent' => 0, 'type' => 'night', 'class' => '', 'description' => '', 'tax_included' => '']];
     /********************************************************************************************************/
     /********************************* Check discount charges ***********************************************/
     /********************************************************************************************************/
     $discountValidator = $bookingTicketService->validateAndCheckDiscountData($discountParams, false);
     $discounted = false;
     if (isset($discountValidator['discount_value']) && $discountValidator['valid'] && isset($discountValidator['discount_value']) && ceil($discountValidator['discount_value'])) {
         $discountValue = $totalPrice * $discountValidator['discount_value'] / 100;
         $price = $totalPrice - $discountValue;
         $discounted = true;
         $totalPrice = $totalPrice - $discountValue;
         array_push($chargesList, ['label' => (isset($discountValidator['partner_name']) ? $discountValidator['partner_name'] : '') . ' ' . $textlineService->getUniversalTextline(1503), 'price_view' => '- ' . $currencySymbol . number_format($discountValue, 2, '.', ' '), 'price' => $discountValue, 'percent' => 0, 'type' => 'discount', 'class' => 'text-danger', 'description' => '', 'tax_included' => '']);
     }
     /********************************************************************************************************/
     /************************************** Check Tax Charges ***********************************************/
     /********************************************************************************************************/
     $currencyService = $this->getApplicationServiceLocator()->get('service_currency_currency');
     $this->assertInstanceOf('\\DDD\\Service\\Currency\\Currency', $currencyService);
     $currencyRate = 1;
     $this->assertTrue(method_exists($reservation, 'getGuestCurrency'), 'Booking Object does not have method getGuestCurrency');
     $this->assertTrue(method_exists($reservation, 'getApartmentCurrency'), 'Booking Object does not have method getApartmentCurrency');
     $this->assertTrue(method_exists($currencyService, 'getCurrencyConversionRate'), 'Booking Object does not have method getCurrencyConversionRate');
     if ($reservation->getGuestCurrency() != $reservation->getApartmentCurrency() && $isBookerPrice) {
         $currencyRate = $currencyService->getCurrencyConversionRate($reservation->getGuestCurrency(), $reservation->getApartmentCurrency());
     }
     $this->assertTrue(method_exists($reservation, 'getCityTotType'), 'Booking Object does not have method getCityTotType');
     $this->assertTrue(method_exists($reservation, 'getCityTot'), 'Booking Object does not have method getCityTot');
     $this->assertTrue(method_exists($reservation, 'getTotIncluded'), 'Booking Object does not have method getTotIncluded');
     if ($reservation->getCityTotType() > 0 && $reservation->getCityTot() > 0) {
         $taxDiscounted = false;
         $totDuration = $reservation->getTotMaxDuration() ? min($reservation->getTotMaxDuration(), $nightCount) : $nightCount;
         $totValue = $reservation->getCityTot() + $reservation->getTotAdditional();
         if ($reservation->getCityTotType() == Taxes::TAXES_TYPE_PERCENT) {
             $cityTot = $price / 100 * $totValue * $totDuration / $nightCount;
             $taxValue = $totValue . ' %';
             if ($discounted) {
                 $taxDiscounted = true;
             }
             $percent = $totValue;
         } else {
             $cityTot = $totDuration * $totValue * $currencyRate;
             $taxValue = $currencySymbol . ' ' . number_format($totValue * $currencyRate, 2, '.', ' ') . ' ' . $textlineService->getUniversalTextline(1473);
             $percent = 0;
         }
         array_push($chargesList, ['label' => $textlineService->getUniversalTextline(1259) . ' (' . $taxValue . ($reservation->getTotIncluded() == 1 ? ', ' . $textlineService->getUniversalTextline(1472) : '') . ') ' . ($taxDiscounted ? $textlineService->getUniversalTextline(1633) : ''), 'price_view' => $currencySymbol . number_format($cityTot, 2, '.', ' '), 'price' => $cityTot, 'percent' => $percent, 'duration' => $totDuration, 'type' => 'tax', 'class' => 'text-primary', 'description' => $textlineService->getUniversalTextline(1429), 'tax_included' => $reservation->getTotIncluded() == 1 ?: '']);
         if ($reservation->getTotIncluded() != 1) {
             $totalPrice += $cityTot;
         }
     }
     $this->assertTrue(method_exists($reservation, 'getCityVatType'), 'Booking Object does not have method getCityVatType');
     $this->assertTrue(method_exists($reservation, 'getCityVat'), 'Booking Object does not have method getCityVat');
     $this->assertTrue(method_exists($reservation, 'getVatIncluded'), 'Booking Object does not have method getVatIncluded');
     if ($reservation->getCityVatType() > 0 && $reservation->getCityVat() > 0) {
         $taxDiscounted = false;
         $vatValue = $reservation->getCityVat();
         $vatDuration = $reservation->getVatMaxDuration() ? min($reservation->getVatMaxDuration(), $nightCount) : $nightCount;
         if ($reservation->getCityVatType() == Taxes::TAXES_TYPE_PERCENT) {
             $cityVat = $price / 100 * $vatValue * $vatDuration / $nightCount;
             $taxValue = $vatValue . ' %';
             if ($discounted) {
                 $taxDiscounted = true;
             }
             $percent = $vatValue;
         } else {
             $cityVat = $vatDuration * $vatValue * $currencyRate;
             $taxValue = $currencySymbol . number_format($vatValue * $currencyRate, 2, '.', ' ') . ' ' . $textlineService->getUniversalTextline(1473);
             $percent = 0;
         }
         array_push($chargesList, ['label' => $textlineService->getUniversalTextline(1260) . ' (' . $taxValue . ($reservation->getVatIncluded() == 1 ? ', ' . $textlineService->getUniversalTextline(1472) : '') . ') ' . ($taxDiscounted ? $textlineService->getUniversalTextline(1633) : ''), 'price_view' => $currencySymbol . number_format($cityVat, 2, '.', ' '), 'price' => $cityVat, 'percent' => $percent, 'duration' => $vatDuration, 'type' => 'tax', 'class' => 'text-primary', 'description' => $textlineService->getUniversalTextline(1430), 'tax_included' => $reservation->getVatIncluded() == 1 ?: '']);
         if ($reservation->getVatIncluded() != 1) {
             $totalPrice += $cityVat;
         }
     }
     $this->assertTrue(method_exists($reservation, 'getCitySalesTaxType'), 'Booking Object does not have method getCitySalesTaxType');
     $this->assertTrue(method_exists($reservation, 'getCitySalesTax'), 'Booking Object does not have method getCitySalesTax');
     $this->assertTrue(method_exists($reservation, 'getCitySalesTaxType'), 'Booking Object does not have method getCitySalesTaxType');
     $this->assertTrue(method_exists($reservation, 'getSalesTaxIncluded'), 'Booking Object does not have method getSalesTaxIncluded');
     if ($reservation->getCitySalesTaxType() > 0 && $reservation->getCitySalesTax() > 0) {
         $taxDiscounted = false;
         $salesTaxValue = $reservation->getCitySalesTax();
         $salesTaxDuration = $reservation->getSalesTaxMaxDuration() ? min($reservation->getSalesTaxMaxDuration(), $nightCount) : $nightCount;
         if ($reservation->getCitySalesTaxType() == Taxes::TAXES_TYPE_PERCENT) {
             $citySalesTax = $price / 100 * $salesTaxValue * $salesTaxDuration / $nightCount;
             $taxValue = $salesTaxValue . ' %';
             if ($discounted) {
                 $taxDiscounted = true;
             }
             $percent = $salesTaxValue;
         } else {
             $citySalesTax = $salesTaxDuration * $salesTaxValue * $currencyRate;
             $taxValue = $currencySymbol . ' ' . number_format($salesTaxValue * $currencyRate, 2, '.', ' ') . ' ' . $textlineService->getUniversalTextline(1473);
             $percent = 0;
         }
         array_push($chargesList, ['label' => $textlineService->getUniversalTextline(1261) . ' (' . $taxValue . ($reservation->getSalesTaxIncluded() == 1 ? ', ' . $textlineService->getUniversalTextline(1472) : '') . ') ' . ($taxDiscounted ? $textlineService->getUniversalTextline(1633) : ''), 'price_view' => $currencySymbol . number_format($citySalesTax, 2, '.', ' '), 'price' => $citySalesTax, 'percent' => $percent, 'duration' => $salesTaxDuration, 'type' => 'tax', 'class' => 'text-primary', 'description' => $textlineService->getUniversalTextline(1431), 'tax_included' => $reservation->getSalesTaxIncluded() == 1 ?: '']);
         if ($reservation->getSalesTaxIncluded() != 1) {
             $totalPrice += $citySalesTax;
         }
     }
     $this->assertTrue(method_exists($reservation, 'getCityTaxType'), 'Booking Object does not have method getCityTaxType');
     $this->assertTrue(method_exists($reservation, 'getCityTax'), 'Booking Object does not have method getCityTax');
     $this->assertTrue(method_exists($reservation, 'getCityTaxType'), 'Booking Object does not have method getCityTaxType');
     $this->assertTrue(method_exists($reservation, 'getCityTaxIncluded'), 'Booking Object does not have method getCityTaxIncluded');
     if ($reservation->getCityTaxType() > 0 && $reservation->getCityTax() > 0) {
         $taxDiscounted = false;
         $cityTaxValue = $reservation->getCityTax();
         $cityTaxDuration = $reservation->getCityTaxMaxDuration() ? min($reservation->getCityTaxMaxDuration(), $nightCount) : $nightCount;
         if ($reservation->getCityTaxType() == Taxes::TAXES_TYPE_PERCENT) {
             $cityTax = $price / 100 * $cityTaxValue * $cityTaxDuration / $nightCount;
             $taxValue = $cityTaxValue . ' %';
             if ($discounted) {
                 $taxDiscounted = true;
             }
             $percent = $cityTaxValue;
         } elseif ($reservation->getCityTaxType() == Taxes::TAXES_TYPE_PER_PERSON) {
             $cityTax = $cityTaxDuration * $cityTaxValue * $currencyRate * $reservation->getOccupancy();
             $taxValue = $currencySymbol . ' ' . number_format($cityTaxValue * $currencyRate, 2, '.', ' ') . ' ' . $textlineService->getUniversalTextline(1493);
             $percent = 0;
         } else {
             $cityTax = $cityTaxDuration * $cityTaxValue * $currencyRate;
             $taxValue = $currencySymbol . ' ' . number_format($cityTaxValue * $currencyRate, 2, '.', ' ') . ' ' . $textlineService->getUniversalTextline(1473);
             $percent = 0;
         }
         array_push($chargesList, ['label' => $textlineService->getUniversalTextline(1262) . ' (' . $taxValue . ($reservation->getCityTaxIncluded() == 1 ? ', ' . $textlineService->getUniversalTextline(1472) : '') . ') ' . ($taxDiscounted ? $textlineService->getUniversalTextline(1633) : ''), 'price_view' => $currencySymbol . number_format($cityTax, 2, '.', ' '), 'price' => $cityTax, 'percent' => $percent, 'duration' => $cityTaxDuration, 'type' => 'tax', 'class' => 'text-primary', 'description' => $textlineService->getUniversalTextline(1432), 'tax_included' => $reservation->getCityTaxIncluded() == 1 ?: '']);
         if ($reservation->getCityTaxIncluded() != 1) {
             $totalPrice += $cityTax;
         }
     }
     /********************************************************************************************************/
     /************************************** Check Parking taxes *********************************************/
     /********************************************************************************************************/
     $matches = [];
     $parkingNights = false;
     if (preg_match('/Parking space \\(per night: (?P<nights>\\d+)n\\)/', $reservation->getRemarks(), $matches)) {
         if (!empty($matches['nights'])) {
             $parkingNights = $matches['nights'];
         }
     }
     $accommodationDao = $this->getApplicationServiceLocator()->get('dao_accommodation_accommodations');
     $this->assertInstanceOf('\\DDD\\Dao\\Accommodation\\Accommodations', $accommodationDao);
     $apartmentSpotsDao = $this->getApplicationServiceLocator()->get('dao_apartment_spots');
     $this->assertInstanceOf('\\DDD\\Dao\\Apartment\\Spots', $apartmentSpotsDao);
     $reservationNightlyDao = $this->getApplicationServiceLocator()->get('dao_booking_reservation_nightly');
     $this->assertInstanceOf('\\DDD\\Dao\\Booking\\ReservationNightly', $reservationNightlyDao);
     $apartmentGeneralService = $this->getApplicationServiceLocator()->get('service_apartment_general');
     $this->assertInstanceOf('\\DDD\\Service\\Apartment\\General', $apartmentGeneralService);
     $this->assertTrue(method_exists($reservation, 'getDateFrom'), 'Booking Object does not have method getDateFrom');
     $this->assertTrue(method_exists($reservation, 'getDateTo'), 'Booking Object does not have method getDateTo');
     $this->assertTrue(method_exists($reservation, 'getApartmentIdAssigned'), 'Booking Object does not have method getApartmentIdAssigned');
     $this->assertTrue(method_exists($apartmentSpotsDao, 'getApartmentSpots'), 'ApartmentSpotsDao Object does not have method getApartmentSpots');
     $this->assertTrue(method_exists($apartmentGeneralService, 'getApartmentTimezoneById'), 'ApartmentGeneralService Object does not have method getApartmentTimezoneById');
     $this->assertTrue(method_exists($accommodationDao, 'getAvailableSpotsInLotForApartmentForDateRangeByPriority'), 'AccommodationDao Object does not have method getAvailableSpotsInLotForApartmentForDateRangeByPriority');
     if ($parkingNights) {
         $resStartDate = $reservation->getDateFrom();
         $resEndDate = $reservation->getDateTo();
         $date1 = date_create($resStartDate);
         $date2 = date_create($resEndDate);
         $dateDiff = date_diff($date2, $date1)->d + 1;
         $nightData = $reservationNightlyDao->fetchAll(['reservation_id' => $reservation->getId()], ['id', 'price', 'date', 'rate_name']);
         $nightlyArr = [];
         foreach ($nightData as $night) {
             array_push($nightlyArr, $night);
         }
         $parkingStart = $reservation->getDateFrom();
         $parkingEnd = date('Y-m-j', strtotime($reservation->getDateFrom() . '+' . $parkingNights . ' days'));
         $newApartmentPreferedSpotId = [];
         $availableSpot = [];
         $selectedSpot = [];
         $apartmentPreferSpots = $apartmentSpotsDao->getApartmentSpots($reservation->getApartmentIdAssigned());
         if ($apartmentPreferSpots->count()) {
             foreach ($apartmentPreferSpots as $apartmentPreferSpot) {
                 array_push($newApartmentPreferedSpotId, $apartmentPreferSpot['spot_id']);
             }
             $reservationApartmentId = $reservation->getApartmentIdAssigned();
             $apartmentTimezone = $apartmentGeneralService->getApartmentTimezoneById($reservationApartmentId)['timezone'];
             $datetime = new \DateTime('now');
             $datetime->setTimezone(new \DateTimeZone($apartmentTimezone));
             $dateToday = $datetime->format('Y-m-d');
             $availableSpot = $accommodationDao->getAvailableSpotsInLotForApartmentForDateRangeByPriority($reservationApartmentId, $parkingStart, $parkingEnd, [], false, [], $dateToday, true, $newApartmentPreferedSpotId);
             if (count($availableSpot)) {
                 foreach ($availableSpot as $row) {
                     $selectedSpot = $row;
                 }
             }
         }
         $parkingTotal = 0;
         if ($dateDiff >= $parkingNights && count($availableSpot) && count($selectedSpot)) {
             for ($iterator = 0; $iterator < $parkingNights; $iterator++) {
                 $parkingTotal += $selectedSpot['price'];
             }
         }
         if ($parkingTotal > 0) {
             $parkingTotal = $currencyRate * $parkingTotal;
             $totalPrice += $parkingTotal;
             array_push($chargesList, ['label' => 'Parking', 'price_view' => $currencySymbol . number_format($parkingTotal, 2, '.', ' '), 'price' => $parkingTotal, 'percent' => 0, 'type' => 'tax', 'class' => 'text-primary', 'description' => $textlineService->getUniversalTextline(1430), 'tax_included' => $reservation->getVatIncluded() == 1 ?: '']);
         }
     }
     /********************************************************************************************************/
     /************************************** Check Cleaning Fee **********************************************/
     /********************************************************************************************************/
     $apartmentMainService = $this->getApplicationServiceLocator()->get('service_apartment_main');
     $this->assertInstanceOf('\\DDD\\Service\\Apartment\\Main', $apartmentMainService);
     $cleaningFee = $apartmentMainService->getApartmentCleaningFeeInGuestCurrency($reservation->getApartmentId(), $reservation->getApartmentCurrency(), $reservation->getGuestCurrency(), $reservation->getCheckCurrency());
     if ($cleaningFee) {
         $cleaningFee = $cleaningFee * $currencyRate;
         $totalPrice += $cleaningFee;
         array_push($chargesList, ['label' => $textlineService->getUniversalTextline(1497), 'price_view' => $currencySymbol . number_format($cleaningFee, 2, '.', ' '), 'price' => $cleaningFee, 'percent' => 0, 'type' => 'fee', 'class' => 'text-primary', 'description' => $textlineService->getUniversalTextline(1498), 'tax_included' => '']);
     }
     $testTotal = 0;
     foreach ($chargesList as $charge) {
         if (!is_bool($charge['tax_included']) || !$charge['tax_included']) {
             if ($charge['type'] == 'discount') {
                 $testTotal -= $charge['price'];
             } else {
                 $testTotal += $charge['price'];
             }
         }
     }
     $this->assertEquals($testTotal, $totalPrice);
 }