/** * @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]); }
/** * @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; }
/** * @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 }
/** * @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; }
/** * @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; }
/** * @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]; }
/** * @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'])]; }
/** * @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; }
/** * 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); } }
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]); }
/** * @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; }
/** * @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]; }
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; }
/** * 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); }