request = $request; $this->propertyChannelService = $propertyChannelService; $this->propertyChannelMappingService = $propertyChannelMappingService; $this->propertyRoomRateChannelMappingService = $propertyRoomRateChannelMappingService; $this->propertyRoomRatePriceService = $propertyRoomRatePriceService; $this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService; $this->channelId = $this->request->channelId; $this->channelToken = $this->request->channelToken; $this->bookingEngineToken = $this->request->bookingEngineToken; $this->bookingEnginePropertyId = $this->request->bookingEnginePropertyId; $this->findCountryCodeService = $findCountryCodeService; $this->propertyPromotionService = $propertyPromotionService; $this->propertyAddonService = $propertyAddonService; $this->propertyBookingEngineSearchService = $propertyBookingEngineSearchService; $this->propertyPaymentService = $propertyPaymentService; $this->currencyService = $currencyService; $this->channelConnectedId = null; $this->cachePrefix = 'enwAPISearch:'; $this->cacheExpireTime = 15;//minute } public function getPropertyRoomAndRoomRateMappingData($channelPropertyRoomRate = []) { $propertyRoomAndRoomRateMappingData = []; foreach ($channelPropertyRoomRate as $propertyRoomRate) { $propertyRoomFacts = []; foreach ($propertyRoomRate['property_room_rate_mapping']['property_room']['property_room_fact_mapping'] as $propertyRoomFact) { $propertyRoomFacts[$propertyRoomFact['fact_id']] = [ 'name' => __($propertyRoomFact['property_fact']['language_key']), 'icon' => $propertyRoomFact['property_fact']['icon'], 'is_feature' => $propertyRoomFact['is_feature'], ]; } if (!empty($propertyRoomFacts)) { unset($propertyRoomRate['property_room_rate_mapping']['property_room']['property_room_fact_mapping']); $propertyRoomRate['property_room_rate_mapping']['property_room']['attributes'] = $propertyRoomFacts; } $propertyRoomBedGroups = []; $propertyRoomBedGroupCollection = collect($propertyRoomRate['property_room_rate_mapping']['property_room']['property_room_bed_group'])->groupBy('bed_group')->sortBy('bed_group')->toArray(); foreach ($propertyRoomBedGroupCollection as $propertyRoomBedGroupKey => $propertyRoomBedGroup) { foreach ($propertyRoomBedGroup as $bedGroup) { $propertyRoomBedGroups[$propertyRoomBedGroupKey][$bedGroup['id']] = [ 'count' => $bedGroup['count'], 'name' => __($bedGroup['property_room_bed_type']['language_key']), 'icon' => $bedGroup['property_room_bed_type']['bedTypeIcon'], ]; } } if (!empty($propertyRoomBedGroups)) { unset($propertyRoomRate['property_room_rate_mapping']['property_room']['property_room_bed_group']); $propertyRoomRate['property_room_rate_mapping']['property_room']['bedGroups'] = $propertyRoomBedGroups; } $propertyRoomPhotos = []; foreach ($propertyRoomRate['property_room_rate_mapping']['property_room']['property_room_photo_mapping'] as $propertyRoomPhoto) { $propertyRoomPhotos[$propertyRoomPhoto['property_room_photo']['id']] = [ 'url' => $propertyRoomPhoto['property_room_photo']['photoUrl'], 'is_default' => $propertyRoomPhoto['property_room_photo']['is_default'], 'photo_order' => $propertyRoomPhoto['property_room_photo']['photo_order'], ]; } $propertyRoomRate['property_room_rate_mapping']['property_room']['photos'] = $propertyRoomPhotos; if (!empty($propertyRoomPhotos)) { unset($propertyRoomRate['property_room_rate_mapping']['property_room']['property_room_photo_mapping']); } $propertyRoomAndRoomRateMappingData['room'][$propertyRoomRate['property_room_rate_mapping']['property_room']['id']] = $propertyRoomRate['property_room_rate_mapping']['property_room']; $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRate['property_room_rate_mapping']['id']] = $propertyRoomRate['property_room_rate_mapping']; //Child Policy $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRate['property_room_rate_mapping']['id']]['roomRateMappingChildPolicy'] = []; if (!empty($propertyRoomRate['property_room_rate_channel_pricing_child_policy'])) { $roomRateMappingChildPolicy = []; foreach ($propertyRoomRate['property_room_rate_channel_pricing_child_policy'] as $childPolicy) { $roomRateMappingChildPolicy[$childPolicy['property_pricing_policy_child']['id']] = $childPolicy['property_pricing_policy_child']; } $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRate['property_room_rate_mapping']['id']]['roomRateMappingChildPolicy'] = $roomRateMappingChildPolicy; } //Adult Policy $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRate['property_room_rate_mapping']['id']]['roomRateMappingAdultPolicy'] = []; if (!empty($propertyRoomRate['property_room_rate_channel_pricing_adult_policy'])) { $roomRateMappingAdultPolicy = []; foreach ($propertyRoomRate['property_room_rate_channel_pricing_adult_policy'] as $adultPolicy) { $roomRateMappingAdultPolicy[$adultPolicy['property_pricing_policy_adult']['id']] = $adultPolicy['property_pricing_policy_adult']; } $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRate['property_room_rate_mapping']['id']]['roomRateMappingAdultPolicy'] = $roomRateMappingAdultPolicy; } $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRate['property_room_rate_mapping']['id']]['roomRateDescription'] = $propertyRoomRate['property_room_rate_mapping']['property_room_rate']['descriptionArray']; $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRate['property_room_rate_mapping']['id']]['roomRateMappingCancellationPolicy'] = []; if (!empty($propertyRoomRate['property_room_rate_channel_cancellation_policy'])) { $roomRateMappingCancellationPolicy = []; foreach ($propertyRoomRate['property_room_rate_channel_cancellation_policy'] as $cancellationPolicy) { if ($cancellationPolicy['property_cancellation_policy']['status'] == 0) { continue; } $roomRateMappingCancellationPolicy[$cancellationPolicy['property_cancellation_policy']['id']] = [ 'id' => $cancellationPolicy['cancellation_policy_id'], 'name' => $cancellationPolicy['property_cancellation_policy']['name'], 'beforeArrivalDay' => $cancellationPolicy['property_cancellation_policy']['before_arrival'], 'isNonRefundable' => $cancellationPolicy['property_cancellation_policy']['is_nonrefundable'], 'isFreeCancellation' => $cancellationPolicy['property_cancellation_policy']['is_free_cancellation'], 'type' => $cancellationPolicy['property_cancellation_policy']['type'], 'value' => $cancellationPolicy['property_cancellation_policy']['value'], 'isAffectedPrice' => $cancellationPolicy['property_cancellation_policy']['is_affected_price'], 'affectPriceActionType' => $cancellationPolicy['property_cancellation_policy']['affect_price_action_type'], 'affectPriceType' => $cancellationPolicy['property_cancellation_policy']['affect_price_type'], 'affectPriceValue' => $cancellationPolicy['property_cancellation_policy']['affect_price_value'], 'is_date_range' => $cancellationPolicy['property_cancellation_policy']['is_date_range'], 'start_date' => $cancellationPolicy['property_cancellation_policy']['start_date'], 'finish_date' => $cancellationPolicy['property_cancellation_policy']['finish_date'], ]; } $roomRateMappingCancellationPolicy = collect($roomRateMappingCancellationPolicy)->sortByDesc('beforeArrivalDay')->toArray(); $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRate['property_room_rate_mapping']['id']]['roomRateMappingCancellationPolicy'] = $roomRateMappingCancellationPolicy; } } return $propertyRoomAndRoomRateMappingData; } public function getChannelProperty($property = []) { $response = ['status' => false, 'message' => '']; try { $requestParam = [ 'criteria' => [ ['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId], ['field' => 'status', 'condition' => '=', 'value' => 1], ], 'with' => ['property.propertyBookingEngineToken', 'channelAvailabilityType', 'channelBookingType', 'channelRoomPricingType', 'channelBookingPaymentType.paymentType', 'channel'] ]; if (!empty($property)) { $requestParam['whereIn'][] = ['field' => 'property_id', 'value' => $property]; } $getChannelProperty = $this->propertyChannelMappingService->select($requestParam); if ($getChannelProperty['status'] != 'success' || empty($getChannelProperty['data'])) { throw new ApiErrorException(lang('Property not found')); } //if (!empty($property)) { foreach ($getChannelProperty['data'] as $channelPropertyKey => $channelProperty) { if (!empty($property) && !in_array($channelProperty['property_id'], $property)) { unset($getChannelProperty['data'][$channelPropertyKey]); } else { $channelBookingPaymentType = []; foreach ($channelProperty['channel_booking_payment_type'] as $paymentType) { if ($paymentType['is_selected'] && $paymentType['status']) { $channelBookingPaymentType[$paymentType['payment_type']['id']] = [ 'paymentType' => __($paymentType['payment_type']['language_key']), //'paymentTypeId' => $paymentType['payment_type_id'], 'paymentTypeCode' => $paymentType['payment_type']['code'], 'cancellationPolicy' => $paymentType['cancellationPolicyArray'], 'isAffectedPrice' => $paymentType['is_affected_price'], 'isGetPaymentData' => $paymentType['is_get_payment_data'], 'actionType' => $paymentType['action_type'], 'valueType' => $paymentType['value_type'], 'value' => $paymentType['value'], ]; } } $getChannelProperty['data'][$channelPropertyKey]['channel_booking_payment_type'] = $channelBookingPaymentType; } } //} $getChannelProperty['data'] = array_values($getChannelProperty['data']); $response = [ 'status' => true, 'data' => $getChannelProperty['data'], ]; } catch (ApiErrorException $e) { $response['message'] = implode(', ', $e->getMessageArr()); } catch (Exception $e) { $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); Log::error($message); $response['message'] = $e->getMessage(); } return $response; } public function getChannelPropertyRoomRate($propertyId) { $response = ['status' => false, 'message' => '']; try { $channelId = $this->channelId; if (!empty($this->channelConnectedId)) { $channelId = $this->channelConnectedId; } $requestParam = [ 'criteria' => [ ['field' => 'channel_id', 'condition' => '=', 'value' => $channelId], ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId], ['field' => 'status', 'condition' => '=', 'value' => 1], ], 'with' => [ 'propertyRoomRateMapping.propertyRoomRate.propertyRoomRateAccommodation', 'propertyRoomRateMapping.propertyRoom.propertyRoomType', 'propertyRoomRateMapping.propertyRoom.propertyRoomFactMapping.propertyFact', 'propertyRoomRateMapping.propertyRoom.propertyRoomPhotoMapping.propertyRoomPhoto', 'propertyRoomRateMapping.propertyRoom.propertyRoomBedGroup.propertyRoomBedType', 'propertyRoomRateChannelPricingAdultPolicy.propertyPricingPolicyAdult', 'propertyRoomRateChannelPricingChildPolicy.propertyPricingPolicyChild', 'propertyRoomRateChannelCancellationPolicy.propertyCancellationPolicy', //'propertyRoomRateChannelActivePromotion', ] ]; $getChannelPropertyRoomRate = $this->propertyRoomRateChannelMappingService->select($requestParam); if ($getChannelPropertyRoomRate['status'] != 'success' || empty($getChannelPropertyRoomRate['data'])) { throw new ApiErrorException(lang('Property Room Rate not found')); } $getChannelPropertyRoomRateCollect = collect($getChannelPropertyRoomRate['data']); //Date Filtered $channelPropertyRoomRateCollectNonDateFiltered = $getChannelPropertyRoomRateCollect ->where('has_date', '=', 0); $channelPropertyRoomRateCollectDateFiltered = $getChannelPropertyRoomRateCollect ->where('has_date', '=', 1) ->where('start_date', '<=', Carbon::now()->format('Y-m-d')) ->where('end_date', '>=', Carbon::now()->format('Y-m-d')); $channelPropertyRoomRateCollectFiltered = $channelPropertyRoomRateCollectNonDateFiltered->merge($channelPropertyRoomRateCollectDateFiltered); //Date Filtered //Channel Room Rate Active Filtered $channelPropertyRoomRateCollectFiltered = $channelPropertyRoomRateCollectFiltered->where('property_room_rate_mapping.status', 1); //Room Rate Filtered $channelPropertyRoomRateCollectFiltered = $channelPropertyRoomRateCollectFiltered->where('property_room_rate_mapping.property_room.status', 1); $channelPropertyRoomRateCollectFiltered = $channelPropertyRoomRateCollectFiltered->toArray(); $response = [ 'status' => true, 'data' => $channelPropertyRoomRateCollectFiltered ]; } catch (ApiErrorException $e) { $response['message'] = implode(', ', $e->getMessageArr()); } catch (Exception $e) { $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); Log::error($message); $response['message'] = $e->getMessage(); } return $response; } public function getPropertyRoomRatePrice($param = []) { $response = ['status' => false, 'message' => '']; try { $requestParam = [ 'criteria' => [ ['field' => 'channel_id', 'condition' => '=', 'value' => $param['channel_id']], ['field' => 'property_id', 'condition' => '=', 'value' => $param['property_id']], ['field' => 'stop_sell', 'condition' => '=', 'value' => 0], ['field' => 'date', 'condition' => '>=', 'value' => $param['checkIn']], ['field' => 'date', 'condition' => '<', 'value' => $param['checkOut']], ['field' => 'amount', 'condition' => '<>', 'value' => null], ['field' => 'amount', 'condition' => '<>', 'value' => 0], ['field' => 'status', 'condition' => '=', 'value' => 1], ], 'orderBy' => [ ['field' => 'availability_type_id', 'value' => 'ASC'], ['field' => 'property_room_id', 'value' => 'ASC'], ['field' => 'room_rate_mapping_id', 'value' => 'ASC'], ['field' => 'date', 'value' => 'ASC'] ], ]; $getPropertyRoomRatePrice = $this->propertyRoomRatePriceService->select($requestParam); if ($getPropertyRoomRatePrice['status'] != 'success' || empty($getPropertyRoomRatePrice['data'])) { throw new ApiErrorException(lang('PropertyRoomRatePrice not found')); } //dd($getPropertyRoomRatePrice['data']); $response = [ 'status' => true, 'data' => $getPropertyRoomRatePrice['data'] ]; } catch (ApiErrorException $e) { $response['message'] = implode(', ', $e->getMessageArr()); } catch (Exception $e) { $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); Log::error($message); $response['message'] = $e->getMessage(); } return $response; } public function getPropertyRoomAndRoomRateAvailability($param = []) { $response = ['status' => false, 'message' => '']; try { $requestParam = [ 'criteria' => [ ['field' => 'property_id', 'condition' => '=', 'value' => $param['property_id']], ['field' => 'availability', 'condition' => '>', 'value' => 0], ['field' => 'stop_sell', 'condition' => '=', 'value' => 0], ['field' => 'date', 'condition' => '>=', 'value' => $param['checkIn']], ['field' => 'date', 'condition' => '<', 'value' => $param['checkOut']], ['field' => 'status', 'condition' => '=', 'value' => 1], ], 'orderBy' => [ ['field' => 'availability_type_id', 'value' => 'ASC'], ['field' => 'property_room_id', 'value' => 'ASC'], ['field' => 'room_rate_mapping_id', 'value' => 'ASC'], ['field' => 'date', 'value' => 'ASC'] ], ]; $getPropertyRoomAndRoomRateAvailability = $this->propertyRoomAvailabilityService->select($requestParam); if ($getPropertyRoomAndRoomRateAvailability['status'] != 'success' || empty($getPropertyRoomAndRoomRateAvailability['data'])) { throw new ApiErrorException(lang('PropertyRoomAndRoomRateAvailability not found')); } $response = [ 'status' => true, 'data' => $getPropertyRoomAndRoomRateAvailability['data'] ]; } catch (ApiErrorException $e) { $response['message'] = implode(', ', $e->getMessageArr()); } catch (Exception $e) { $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); Log::error($message); $response['message'] = $e->getMessage(); } return $response; } public function search(Request $request) { //dd(Cache::get($this->cachePrefix.'4d354fd2-8fc3-0725-38bc-1f2f7e749ea8')); $minStayCheckProperty = null; $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500, 'errorCode' => null]; try { $this->channelToken = empty($this->channelToken) ? $request->header('channelToken') : $this->channelToken; $this->bookingEngineToken = empty($this->bookingEngineToken) ? $request->header('bookingEngineToken') : $this->bookingEngineToken; $this->channelId = empty($this->channelId) ? $request->header('channelId') : $this->channelId; $this->bookingEnginePropertyId = empty($this->bookingEnginePropertyId) ? $request->header('bookingEnginePropertyId') : $this->bookingEnginePropertyId; $this->language = empty($this->language) ? $request->header('language') : $this->language; $searchKey = md5(getGuid()); if (is_null($request->getContent())) { throw new ApiErrorException(lang('Parameter Error.')); } $params = json_decode($request->getContent(), 1); //TODO: Burada validator olacak, date zorunlu, en az 1 oda zorunlu if ($params['date']['checkIn'] < Carbon::now()->toDateString()) { throw new ApiErrorException(lang('Check-in time cannot be earlier than today')); } $isMinStayDisabled = (isset($params['min_stay_disabled']) && $params['min_stay_disabled']) ? true : false; if (Carbon::parse($params['date']['checkIn'])->diff(Carbon::parse($params['date']['checkOut']))->days > 60) { throw new ApiErrorException(lang('You can book up to 60 days')); } $roomsByOccupancies = $this->getRoomsByOccupancies($params['rooms']); $this->roomsByOccupancies = $roomsByOccupancies; $dateByDay = $this->getDateByDay($params['date']); $this->dateByDay = $dateByDay; $channelAvailabilityType = $this->propertyRoomRateChannelMappingService->selectChannelAvailabilityType([]); $channelAvailabilityType = $channelAvailabilityType['status'] == 'success' ? $channelAvailabilityType['data'] : []; $channelAvailabilityType = collect($channelAvailabilityType)->groupBy(['id'])->toArray(); $daysLeftForCheckin = Carbon::parse($params['date']['checkIn'])->diff(Carbon::now()->toDateString())->days; //Eğer $this->bookingEngineToken var ise bu token a ait prporty çekilip gönderilen veriler ezilcek ve sadece o property için fiyat verieclek if (!is_null($this->bookingEngineToken) && isset($this->bookingEnginePropertyId)) { $params['property'] = []; $params['property'][] = $this->bookingEnginePropertyId; } //Wholesaler if (in_array($request->bookingEngineChannelCategoryId, [7])) { //$params['property'] = []; return $response; } $channelProperty = $this->getChannelProperty($params['property']); if (!$channelProperty['status']) { throw new ApiErrorException($channelProperty['message']); } $searchPricesCacheWithKey = []; $calculatedRoomPriceFormatted = []; //Channel ile maplenmiş tüm oteller foreach ($channelProperty['data'] as $channelProperty) { $payAtHotelCreditCardCheck = collect($channelProperty['channel_booking_payment_type'])->where('isGetPaymentData',1)->isNotEmpty(); //Wholesaler MARKUP $channelPropertyMarkup = []; if (in_array($channelProperty['channel']['channel_category_id'], [7])) { if (!is_null($channelProperty['markup']) && !empty($channelProperty['channel']['default_currency'])) { $channelPropertyMarkup['markup'] = 1; if (!is_null($channelProperty['markup'])) { $channelPropertyMarkup['markup'] = (($channelProperty['markup'] + 100) / 100); } $lastExchangeRate = 1; if ($channelProperty['currency_code'] != $channelProperty['channel']['default_currency']) { $lastExchangeRate = $this->currencyService->lastExchangeRate($channelProperty['currency_code'], $channelProperty['channel']['default_currency']); if ($lastExchangeRate['status'] == 'success') { $lastExchangeRate = $lastExchangeRate['data']; } } $channelPropertyMarkup['exchange'] = $lastExchangeRate; $channelPropertyMarkup['currency_code'] = $channelProperty['channel']['default_currency']; } else { $channelPropertyMarkup = []; } } //Wholesaler MARKUP //Bağlı kanala ait özelliklerin alınması if (!is_null($channelProperty['connected_channel_id']) && $channelProperty['connected_channel_id'] != 5) { $requestConnectedChannelParam = [ 'criteria' => [ ['field' => 'property_id', 'condition' => '=', 'value' => $channelProperty['property_id']], ['field' => 'channel_id', 'condition' => '=', 'value' => $channelProperty['connected_channel_id']], ], 'with' => ['channelAvailabilityType', 'channelBookingType', 'channelRoomPricingType', 'channelBookingPaymentType.paymentType'], 'firstRow' => true ]; $getConnectedChannel = $this->propertyChannelMappingService->select($requestConnectedChannelParam); if ($getConnectedChannel['status'] != 'success' || empty($getConnectedChannel['data'])) { continue; } $channelProperty['currency_code'] = $getConnectedChannel['data']['currency_code']; $channelProperty['property_booking_type_id'] = $getConnectedChannel['data']['property_booking_type_id']; $channelProperty['property_availability_type_id'] = $getConnectedChannel['data']['property_availability_type_id']; $channelProperty['property_room_pricing_type_id'] = $getConnectedChannel['data']['property_room_pricing_type_id']; $channelProperty['channel_availability_type'] = $getConnectedChannel['data']['channel_availability_type']; $channelProperty['channel_booking_type'] = $getConnectedChannel['data']['channel_booking_type']; $channelProperty['channel_room_pricing_type'] = $getConnectedChannel['data']['channel_room_pricing_type']; } //$channelBookingPaymentTypePolicy $channelBookingPaymentTypePolicy = []; if (!empty($channelProperty['channel_booking_payment_type'])) { foreach ($channelProperty['channel_booking_payment_type'] as $channelBookingPaymentTypeId => $channelBookingPaymentType) { $channelBookingPaymentTypePolicy[$channelBookingPaymentTypeId] = [ 'name' => $channelBookingPaymentType['paymentType'], 'code' => $channelBookingPaymentType['paymentTypeCode'], 'isAffectedPrice' => $channelBookingPaymentType['isAffectedPrice'], 'isGetPaymentData' => $channelBookingPaymentType['isGetPaymentData'], 'affectPriceActionType' => $channelBookingPaymentType['actionType'], 'affectPriceType' => $channelBookingPaymentType['valueType'], 'affectPriceValue' => $channelBookingPaymentType['value'], 'cancellationPolicy' => $channelBookingPaymentType['cancellationPolicy'], 'paymentTypeMapping' => null, ]; if ($channelBookingPaymentType['paymentTypeCode'] == 'CRD') { $paymentMappingRequest = $this->propertyPaymentService->getPaymentMappingList(['property_id' => $channelProperty['property_id']]); $paymentMappingRequest = $paymentMappingRequest['status'] == 'success' ? collect($paymentMappingRequest['data'])->pluck('pos_code')->toArray() : null; $channelBookingPaymentTypePolicy[$channelBookingPaymentTypeId]['paymentTypeMapping'] = $paymentMappingRequest; } } } //Eğer bağlı bir kanal ise ve bu kanal acente tipinde ise if (!is_null($channelProperty['connected_channel_id']) && $channelProperty['connected_channel_id'] != 5 && in_array($channelProperty['channel']['channel_category_id'], [2, 7])) { $this->channelConnectedId = $channelProperty['connected_channel_id']; } //Kanala ait otelin aktif olan room rate leri $getChannelPropertyRoomRate = $this->getChannelPropertyRoomRate($channelProperty['property_id']); if ($getChannelPropertyRoomRate['status'] != 'success' || empty($getChannelPropertyRoomRate['data'])) { continue; } //Kanala ait otelin aktif olan room rate fiyatları $propertyRoomRatePriceParam = [ 'channel_id' => $channelProperty['channel_id'], 'property_id' => $channelProperty['property_id'], 'checkIn' => $params['date']['checkIn'], 'checkOut' => $params['date']['checkOut'], ]; //connected_channel_id manipulation if (!is_null($channelProperty['connected_channel_id']) && $channelProperty['connected_channel_id'] != 5) { $propertyRoomRatePriceParam['channel_id'] = $channelProperty['connected_channel_id']; } // if($request->getClientIp() == '185.137.215.118') { //dd($propertyRoomRatePriceParam); //} $getPropertyRoomRatePrice = $this->getPropertyRoomRatePrice($propertyRoomRatePriceParam); if ($getPropertyRoomRatePrice['status'] != 'success' || empty($getPropertyRoomRatePrice['data'])) { continue; } //connected_channel_id manipulation if (!is_null($channelProperty['connected_channel_id']) && !is_null($channelProperty['connected_channel_action']) && $channelProperty['connected_channel_id'] != 5) { $connectedChannelAction = json_decode($channelProperty['connected_channel_action'], 1); foreach ($getPropertyRoomRatePrice['data'] as $roomRatePriceKey => $roomRatePrice) { $roomRatePriceAffected = 0; if ($connectedChannelAction['type'] == 'PER') { $roomRatePriceAffected = ($roomRatePrice['amount'] * $connectedChannelAction['value']) / 100; } elseif ($connectedChannelAction['type'] == 'FIX') { $roomRatePriceAffected = $connectedChannelAction['value']; } if ($connectedChannelAction['action_type'] == 'INC') { $getPropertyRoomRatePrice['data'][$roomRatePriceKey]['amount'] = $roomRatePrice['amount'] + $roomRatePriceAffected; } if ($connectedChannelAction['action_type'] == 'DEC') { $getPropertyRoomRatePrice['data'][$roomRatePriceKey]['amount'] = $roomRatePrice['amount'] - $roomRatePriceAffected; } } } //connected_channel_id manipulation $propertyRoomAndRoomRateAvailabilityParam = [ 'property_id' => $channelProperty['property_id'], 'checkIn' => $params['date']['checkIn'], 'checkOut' => $params['date']['checkOut'], ]; $getPropertyRoomAndRoomRateAvailability = $this->getPropertyRoomAndRoomRateAvailability($propertyRoomAndRoomRateAvailabilityParam); if ($getPropertyRoomAndRoomRateAvailability['status'] != 'success' || empty($getPropertyRoomAndRoomRateAvailability['data'])) { continue; } //Room ve Room Date Mapping datası $propertyRoomAndRoomRateMappingData = $this->getPropertyRoomAndRoomRateMappingData($getChannelPropertyRoomRate['data']); /**** PROMOTION START ****/ $promotionGroupByDay = []; $propertyPromotionMappingCriteria = [ 'criteria' => [ ['field' => 'property_id', 'condition' => '=', 'value' => $channelProperty['property_id']], ['field' => 'status', 'condition' => '=', 'value' => 1], ], 'with' => ['propertyPromotion.promotionType', 'propertyRoomRateChannelMapping'] ]; $propertyPromotionMapping = $this->propertyPromotionService->selectPropertyPromotionMapping($propertyPromotionMappingCriteria); if ($propertyPromotionMapping['status'] == 'success' && !empty($propertyPromotionMapping['data'])) { $propertyPromotionMapping = $propertyPromotionMapping['data']; } else { $propertyPromotionMapping = []; } //Eğer bağlı bir kanal var ise ve booking engine e bağlıysa burada promosyon çalıştırılmaz! if (!is_null($channelProperty['connected_channel_id']) && $channelProperty['connected_channel_id'] == 1 && !in_array($channelProperty['channel']['channel_category_id'], [2, 3, 7])) { $propertyPromotionMapping = []; } //Hangi room rate channel datası için komisyon verilecek... $roomRateChannelMappingIdList = array_values(array_unique(pickItemFromArray('room_rate_channel_mapping_id', $propertyPromotionMapping))); $propertyPromotionMapping = collect($propertyPromotionMapping); $propertyPromotionMappingGrouped = $propertyPromotionMapping->groupBy(['property_promotion.promotion_type.type_code'])->toArray(); //dd($propertyPromotionMappingGrouped); foreach ($roomRateChannelMappingIdList as $roomRateChannelMappingId) { foreach ($propertyPromotionMappingGrouped as $promotionType => $promotions) { $promotionsCollect = collect($promotions)->sortByDesc('property_promotion.amount'); foreach ($dateByDay as $day) { $promotionsCollectFiltered = null; if ($promotionType == 'PRD') { //burada promosyonun işleneceği eşleştirmeinin de oluşturulması lazım gün bazında //"1-1-1-2021-12-28" /* "property_id" => 1 "room_rate_mapping_id" => 1 "channel_id" => 1 "date" => "2021-12-28" * */ $promotionsCollectFiltered = $promotionsCollect ->where('room_rate_channel_mapping_id', '=', $roomRateChannelMappingId) ->where('property_promotion.start_date', '<=', Carbon::now()->toDateString()) ->where('property_promotion.end_date', '>=', Carbon::now()->toDateString()) ->where('property_promotion.reservation_start_date', '<=', $day) ->where('property_promotion.reservation_end_date', '>=', $day) ->where('property_promotion.min_stay', '<=', count($dateByDay)) ->filter(function ($propertyPromotion) use ($day) { $weekDay = Carbon::parse($day)->weekday() == 0 ? 7 : Carbon::parse($day)->weekday(); if (is_array($propertyPromotion['property_promotion']['daysArray']) && in_array($weekDay, $propertyPromotion['property_promotion']['daysArray'])) { return $propertyPromotion; } }); if (count($promotionsCollectFiltered) > 1) { if (isset($params['isMobile']) && $params['isMobile'] == 1) { $promotionsCollectFiltered = $promotionsCollectFiltered->where('property_promotion.is_mobile', '=', 1); } else { $promotionsCollectFiltered = $promotionsCollectFiltered->where('property_promotion.is_mobile', '!=', 1); } } else { if ($promotionsCollectFiltered->pluck('property_promotion.is_mobile')->first() == 1) { if (!isset($params['isMobile']) || $params['isMobile'] != 1) { $promotionsCollectFiltered = $promotionsCollectFiltered->where('property_promotion.is_mobile', '!=', 1); } } } $promotionsCollectFiltered = $promotionsCollectFiltered->sortByDesc('property_promotion.min_stay')->first(); $promotionHashKey = null; if (!is_null($promotionsCollectFiltered)) { /*$isPromotionJustMobile = $promotionsCollectFiltered['property_promotion']['is_mobile']; if($isPromotionJustMobile && (!isset($params['isMobile']) || empty($params['isMobile']))) { continue; }*/ $promotionKey = $promotionsCollectFiltered['property_room_rate_channel_mapping']['property_id'] . '-' . $promotionsCollectFiltered['property_room_rate_channel_mapping']['room_rate_mapping_id'] . '-' . $promotionsCollectFiltered['property_room_rate_channel_mapping']['channel_id'] . '-' . Carbon::parse($day)->format('Ymd'); if (!isset($promotionGroupByDay[$promotionKey]) && $promotionsCollectFiltered['property_promotion']['amount'] < 100) { $promotionGroupByDay[$promotionKey] = [ 'discountRate' => $promotionsCollectFiltered['property_promotion']['amount'], 'type_code' => $promotionsCollectFiltered['property_promotion']['promotion_type']['type_code'], 'id' => $promotionsCollectFiltered['property_promotion']['id'] ]; } elseif (isset($promotionGroupByDay[$promotionKey]) && $promotionsCollectFiltered['property_promotion']['amount'] > $promotionGroupByDay[$promotionKey]['discountRate']) { $promotionGroupByDay[$promotionKey] = [ 'discountRate' => $promotionsCollectFiltered['property_promotion']['amount'], 'type_code' => $promotionsCollectFiltered['property_promotion']['promotion_type']['type_code'], 'id' => $promotionsCollectFiltered['property_promotion']['id'] ]; } } } if ($promotionType == 'BFD') { //dd($dateByDay[0], Carbon::now()->toDateString(), Carbon::parse($dateByDay[0])->diff(Carbon::now())->days); $promotionsCollectFiltered = $promotionsCollect ->where('room_rate_channel_mapping_id', '=', $roomRateChannelMappingId) ->where('property_promotion.day_before', '<=', Carbon::parse($dateByDay[0])->diff(Carbon::now()->toDateString())->days) ->where('property_promotion.min_stay', '<=', count($dateByDay)) ->filter(function ($propertyPromotion) use ($day) { $weekDay = Carbon::parse($day)->weekday() == 0 ? 7 : Carbon::parse($day)->weekday(); if (is_array($propertyPromotion['property_promotion']['daysArray']) && in_array($weekDay, $propertyPromotion['property_promotion']['daysArray'])) { return $propertyPromotion; } })->sortByDesc('property_promotion.day_before'); if (count($promotionsCollectFiltered) > 1) { if (isset($params['isMobile']) && $params['isMobile'] == 1) { $promotionsCollectFiltered = $promotionsCollectFiltered->where('property_promotion.is_mobile', '=', 1); } else { $promotionsCollectFiltered = $promotionsCollectFiltered->where('property_promotion.is_mobile', '!=', 1); } } else { if ($promotionsCollectFiltered->pluck('property_promotion.is_mobile')->first() == 1) { if (!isset($params['isMobile']) || $params['isMobile'] != 1) { $promotionsCollectFiltered = $promotionsCollectFiltered->where('property_promotion.is_mobile', '!=', 1); } } } $promotionsCollectFiltered = $promotionsCollectFiltered->first(); $promotionHashKey = null; if (!is_null($promotionsCollectFiltered)) { /*$isPromotionJustMobile = $promotionsCollectFiltered['property_promotion']['is_mobile']; if($isPromotionJustMobile && (!isset($params['isMobile']) || empty($params['isMobile']))) { continue; }*/ //excludeDatesArray if (isset($promotionsCollectFiltered['property_promotion']['excludeDatesArray']) && in_array($day, $promotionsCollectFiltered['property_promotion']['excludeDatesArray'])) { continue; } $promotionKey = $promotionsCollectFiltered['property_room_rate_channel_mapping']['property_id'] . '-' . $promotionsCollectFiltered['property_room_rate_channel_mapping']['room_rate_mapping_id'] . '-' . $promotionsCollectFiltered['property_room_rate_channel_mapping']['channel_id'] . '-' . Carbon::parse($day)->format('Ymd'); if (!isset($promotionGroupByDay[$promotionKey]) && $promotionsCollectFiltered['property_promotion']['amount'] < 100) { $promotionGroupByDay[$promotionKey] = [ 'discountRate' => $promotionsCollectFiltered['property_promotion']['amount'], 'type_code' => $promotionsCollectFiltered['property_promotion']['promotion_type']['type_code'], 'id' => $promotionsCollectFiltered['property_promotion']['id'] ]; } elseif (isset($promotionGroupByDay[$promotionKey]) && $promotionsCollectFiltered['property_promotion']['amount'] > $promotionGroupByDay[$promotionKey]['discountRate']) { $promotionGroupByDay[$promotionKey] = [ 'discountRate' => $promotionsCollectFiltered['property_promotion']['amount'], 'type_code' => $promotionsCollectFiltered['property_promotion']['promotion_type']['type_code'], 'id' => $promotionsCollectFiltered['property_promotion']['id'] ]; } } } if ($promotionType == 'LST') { //dd($dateByDay[0], Carbon::now()->toDateString(), Carbon::parse($dateByDay[0])->diff(Carbon::now())->days); $promotionsCollectFiltered = $promotionsCollect ->where('room_rate_channel_mapping_id', '=', $roomRateChannelMappingId) ->where('property_promotion.day_before', '>=', Carbon::parse($dateByDay[0])->diff(Carbon::now()->toDateString())->days) ->where('property_promotion.min_stay', '<=', count($dateByDay)) ->where('property_promotion.is_time', null) ->filter(function ($propertyPromotion) use ($day) { $weekDay = Carbon::parse($day)->weekday() == 0 ? 7 : Carbon::parse($day)->weekday(); if (is_array($propertyPromotion['property_promotion']['daysArray']) && in_array($weekDay, $propertyPromotion['property_promotion']['daysArray'])) { return $propertyPromotion; } })->sortBy('property_promotion.day_before'); if (count($promotionsCollectFiltered) > 1) { if (isset($params['isMobile']) && $params['isMobile'] == 1) { $promotionsCollectFiltered = $promotionsCollectFiltered->where('property_promotion.is_mobile', '=', 1); } else { $promotionsCollectFiltered = $promotionsCollectFiltered->where('property_promotion.is_mobile', '!=', 1); } } else { if ($promotionsCollectFiltered->pluck('property_promotion.is_mobile')->first() == 1) { if (!isset($params['isMobile']) || $params['isMobile'] != 1) { $promotionsCollectFiltered = $promotionsCollectFiltered->where('property_promotion.is_mobile', '!=', 1); } } } //If there is a promotion with a fixed time, it gets priority. $promotionsCollectFilteredCertainTime = $promotionsCollect ->where('room_rate_channel_mapping_id', '=', $roomRateChannelMappingId) ->where('property_promotion.day_before', '>=', Carbon::parse($dateByDay[0])->diff(Carbon::now()->toDateString())->days) ->where('property_promotion.min_stay', '<=', count($dateByDay)) ->where('property_promotion.is_time', 1) ->where('property_promotion.start_time', '<=', Carbon::now()->format('H:i:s')) ->where('property_promotion.end_time', '>=', Carbon::now()->format('H:i:s')) ->filter(function ($propertyPromotion) use ($day) { $weekDay = Carbon::parse($day)->weekday() == 0 ? 7 : Carbon::parse($day)->weekday(); if (is_array($propertyPromotion['property_promotion']['daysArray']) && in_array($weekDay, $propertyPromotion['property_promotion']['daysArray'])) { return $propertyPromotion; } })->sortByDesc('property_promotion.amount'); if (!is_null($promotionsCollectFilteredCertainTime->first())) { $promotionsCollectFiltered = $promotionsCollectFilteredCertainTime->first(); } else { $promotionsCollectFiltered = $promotionsCollectFiltered->first(); } $promotionHashKey = null; if (!is_null($promotionsCollectFiltered)) { /*$isPromotionJustMobile = $promotionsCollectFiltered['property_promotion']['is_mobile']; if($isPromotionJustMobile && (!isset($params['isMobile']) || empty($params['isMobile']))) { continue; }*/ $promotionKey = $promotionsCollectFiltered['property_room_rate_channel_mapping']['property_id'] . '-' . $promotionsCollectFiltered['property_room_rate_channel_mapping']['room_rate_mapping_id'] . '-' . $promotionsCollectFiltered['property_room_rate_channel_mapping']['channel_id'] . '-' . Carbon::parse($day)->format('Ymd'); if (!isset($promotionGroupByDay[$promotionKey]) && $promotionsCollectFiltered['property_promotion']['amount'] < 100) { $promotionGroupByDay[$promotionKey] = [ 'discountRate' => $promotionsCollectFiltered['property_promotion']['amount'], 'type_code' => $promotionsCollectFiltered['property_promotion']['promotion_type']['type_code'], 'id' => $promotionsCollectFiltered['property_promotion']['id'] ]; } elseif (isset($promotionGroupByDay[$promotionKey]) && $promotionsCollectFiltered['property_promotion']['amount'] > $promotionGroupByDay[$promotionKey]['discountRate']) { $promotionGroupByDay[$promotionKey] = [ 'discountRate' => $promotionsCollectFiltered['property_promotion']['amount'], 'type_code' => $promotionsCollectFiltered['property_promotion']['promotion_type']['type_code'], 'id' => $promotionsCollectFiltered['property_promotion']['id'] ]; } } } if ($promotionType == 'DSC') { //Default $defaultPromotionDiscount = $promotionsCollect ->where('room_rate_channel_mapping_id', '=', $roomRateChannelMappingId) ->where('property_promotion.is_time', null) ->where('property_promotion.min_stay', '<=', count($dateByDay)) ->filter(function ($propertyPromotion) use ($day) { $weekDay = Carbon::parse($day)->weekday() == 0 ? 7 : Carbon::parse($day)->weekday(); if (is_array($propertyPromotion['property_promotion']['daysArray']) && in_array($weekDay, $propertyPromotion['property_promotion']['daysArray'])) { return $propertyPromotion; } })->sortByDesc('property_promotion.amount'); if (isset($params['isMobile']) && $params['isMobile'] == 1) { $defaultPromotionDiscountMobile = $defaultPromotionDiscount->where('property_promotion.is_mobile', '=', 1); if ($defaultPromotionDiscountMobile->isNotEmpty()) { $defaultPromotionDiscount = $defaultPromotionDiscountMobile; } } else { $defaultPromotionDiscount = $defaultPromotionDiscount->where('property_promotion.is_mobile', '!=', 1); } $promotionsCollectFiltered = $promotionsCollect ->where('room_rate_channel_mapping_id', '=', $roomRateChannelMappingId) ->where('property_promotion.is_time', 1) ->where('property_promotion.start_time', '<=', Carbon::now()->format('H:i:s')) ->where('property_promotion.end_time', '>=', Carbon::now()->format('H:i:s')) ->where('property_promotion.min_stay', '<=', count($dateByDay)) ->filter(function ($propertyPromotion) use ($day) { $weekDay = Carbon::parse($day)->weekday() == 0 ? 7 : Carbon::parse($day)->weekday(); if (is_array($propertyPromotion['property_promotion']['daysArray']) && in_array($weekDay, $propertyPromotion['property_promotion']['daysArray'])) { return $propertyPromotion; } })->sortByDesc('property_promotion.amount'); if (isset($params['isMobile']) && $params['isMobile'] == 1) { $promotionsCollectFiltered = $promotionsCollectFiltered->where('property_promotion.is_mobile', '=', 1); if ($promotionsCollectFiltered->isNotEmpty()) { $promotionsCollectFiltered = $promotionsCollectFiltered; } } else { $promotionsCollectFiltered = $promotionsCollectFiltered->where('property_promotion.is_mobile', '!=', 1); } if ($promotionsCollectFiltered->isEmpty()) { $promotionsCollectFiltered = $defaultPromotionDiscount; } $promotionsCollectFiltered = $promotionsCollectFiltered->first(); $promotionHashKey = null; if (!is_null($promotionsCollectFiltered)) { /*$isPromotionJustMobile = $promotionsCollectFiltered['property_promotion']['is_mobile']; if($isPromotionJustMobile && (!isset($params['isMobile']) || empty($params['isMobile']))) { continue; }*/ //excludeDatesArray if (isset($promotionsCollectFiltered['property_promotion']['excludeDatesArray']) && in_array($day, $promotionsCollectFiltered['property_promotion']['excludeDatesArray'])) { continue; } $promotionKey = $promotionsCollectFiltered['property_room_rate_channel_mapping']['property_id'] . '-' . $promotionsCollectFiltered['property_room_rate_channel_mapping']['room_rate_mapping_id'] . '-' . $promotionsCollectFiltered['property_room_rate_channel_mapping']['channel_id'] . '-' . Carbon::parse($day)->format('Ymd'); if (!isset($promotionGroupByDay[$promotionKey]) && $promotionsCollectFiltered['property_promotion']['amount'] < 100) { $promotionGroupByDay[$promotionKey] = [ 'discountRate' => $promotionsCollectFiltered['property_promotion']['amount'], 'type_code' => $promotionsCollectFiltered['property_promotion']['promotion_type']['type_code'], 'id' => $promotionsCollectFiltered['property_promotion']['id'] ]; } elseif (isset($promotionGroupByDay[$promotionKey]) && $promotionsCollectFiltered['property_promotion']['amount'] > $promotionGroupByDay[$promotionKey]['discountRate']) { $promotionGroupByDay[$promotionKey] = [ 'discountRate' => $promotionsCollectFiltered['property_promotion']['amount'], 'type_code' => $promotionsCollectFiltered['property_promotion']['promotion_type']['type_code'], 'id' => $promotionsCollectFiltered['property_promotion']['id'] ]; } } } //Log::debug($promotionGroupByDay); } } } //dd($promotionGroupByDay, $propertyPromotionMapping); /**** PROMOTION FINISH ****/ //dd($promotionGroupByDay); $getPropertyRoomRatePrice = collect($getPropertyRoomRatePrice['data']); $minStayCheckProperty = $getPropertyRoomRatePrice->sortByDesc('min_stay')->groupBy('min_stay')->keys()->first(); //Kanala ait otelin aktif olan room rate lerin gruplanarak gün bazında fiyat var mı hesalanması // Availability Type - Property Room - Room Rate Mapping $getPropertyRoomRatePriceGrouped = $getPropertyRoomRatePrice->groupBy(['availability_type_id', 'property_room_id', 'room_rate_mapping_id', 'date'])->toArray(); foreach ($getPropertyRoomRatePriceGrouped as $getPropertyRoomRatePriceAvailabilityKey => $getPropertyRoomRatePriceAvailability) { foreach ($getPropertyRoomRatePriceAvailability as $getPropertyRoomRatePriceAvailabilityRoomKey => $getPropertyRoomRatePriceAvailabilityRoom) { foreach ($getPropertyRoomRatePriceAvailabilityRoom as $getPropertyRoomRatePriceAvailabilityRoomRateKey => $getPropertyRoomRatePriceAvailabilityRoomRate) { unset($getPropertyRoomRatePriceGrouped[$getPropertyRoomRatePriceAvailabilityKey][$getPropertyRoomRatePriceAvailabilityRoomKey][$getPropertyRoomRatePriceAvailabilityRoomRateKey]); if (!empty(array_diff($this->dateByDay, array_keys($getPropertyRoomRatePriceAvailabilityRoomRate)))) { unset($getPropertyRoomRatePriceGrouped[$getPropertyRoomRatePriceAvailabilityKey][$getPropertyRoomRatePriceAvailabilityRoomKey][$getPropertyRoomRatePriceAvailabilityRoomRateKey]); } else { $getPropertyRoomRatePriceAvailabilityRoomRate = array_map(function ($propertyRoomRatePriceAvailabilityRoomRate) { return reset($propertyRoomRatePriceAvailabilityRoomRate); }, $getPropertyRoomRatePriceAvailabilityRoomRate); //MIN_STAY CHECK $minStayCheckCollect = collect($getPropertyRoomRatePriceAvailabilityRoomRate); $minStayCheck = $minStayCheckCollect->sortByDesc('min_stay')->first(); //$isMinStayDisabled if ($isMinStayDisabled) { $minStayCheck['min_stay'] = 0; } if (intval($minStayCheck['min_stay']) > count($this->dateByDay)) { unset($getPropertyRoomRatePriceGrouped[$getPropertyRoomRatePriceAvailabilityKey][$getPropertyRoomRatePriceAvailabilityRoomKey][$getPropertyRoomRatePriceAvailabilityRoomRateKey]); } else { //PROMOTION CALCULATE foreach ($getPropertyRoomRatePriceAvailabilityRoomRate as $day => $dailyDetail) { $getPropertyRoomRatePriceAvailabilityRoomRate[$day]['baseAmount'] = $dailyDetail['amount']; $getPropertyRoomRatePriceAvailabilityRoomRate[$day]['discountRate'] = 0; //TODO : Delete /*$dailyDetailPromoCheckKey = $dailyDetail['property_id'] . '-' . $dailyDetail['room_rate_mapping_id'] . '-' . $dailyDetail['channel_id'] . '-' . Carbon::parse($day)->format('Ymd'); if (array_key_exists($dailyDetailPromoCheckKey, $promotionGroupByDay)) { $getPropertyRoomRatePriceAvailabilityRoomRate[$day]['discountRate'] = $promotionGroupByDay[$dailyDetailPromoCheckKey]['discountRate']; $getPropertyRoomRatePriceAvailabilityRoomRate[$day]['amount'] = moneyDoubleFormatDecimal($dailyDetail['amount'] - ($dailyDetail['amount'] * ($promotionGroupByDay[$dailyDetailPromoCheckKey]['discountRate'] / 100))); }*/ } $getPropertyRoomRatePriceGrouped[$getPropertyRoomRatePriceAvailabilityKey][$getPropertyRoomRatePriceAvailabilityRoomKey][$getPropertyRoomRatePriceAvailabilityRoomRateKey] = $getPropertyRoomRatePriceAvailabilityRoomRate; } } } if (empty($getPropertyRoomRatePriceGrouped[$getPropertyRoomRatePriceAvailabilityKey][$getPropertyRoomRatePriceAvailabilityRoomKey])) { unset($getPropertyRoomRatePriceGrouped[$getPropertyRoomRatePriceAvailabilityKey][$getPropertyRoomRatePriceAvailabilityRoomKey]); } } if (empty($getPropertyRoomRatePriceGrouped[$getPropertyRoomRatePriceAvailabilityKey])) { unset($getPropertyRoomRatePriceGrouped[$getPropertyRoomRatePriceAvailabilityKey]); } } //Kanala ait otelin aktif olan room rate lerin gruplanarak gün bazında fiyat var mı hesaplanması //Kanalın müsaitlik type ına göre kullanılacak olanların seçilmesi $selectedPropertyRoomRatePriceGrouped = []; if (isset($getPropertyRoomRatePriceGrouped[$channelProperty['channel_availability_type']['id']])) { $selectedPropertyRoomRatePriceGrouped[$channelProperty['channel_availability_type']['id']] = $getPropertyRoomRatePriceGrouped[$channelProperty['channel_availability_type']['id']]; } if ($channelProperty['channel_availability_type']['code'] == 'GRT') { if (isset($getPropertyRoomRatePriceGrouped[1])) { $selectedPropertyRoomRatePriceGrouped[1] = $getPropertyRoomRatePriceGrouped[1]; } } //Kanalın müsaitlik type ına göre kullanılacak olanların seçilmesi if (empty($selectedPropertyRoomRatePriceGrouped)) { //Hiç fiyat çekilememiş ise diğer proprty ye geç continue; } //TODO: burada her istenen oda tipi için fiyat hesaplanacak ve $calculatedRoomPrice = []; // Availability Type - Property Room - Room Rate Mapping foreach ($selectedPropertyRoomRatePriceGrouped as $propertyAvailabilityKey => $propertyAvailability) { foreach ($propertyAvailability as $propertyRoomKey => $propertyRoom) { //Olmayan bir oda için fiyat gelirse devam et if (!in_array($propertyRoomKey, array_keys($propertyRoomAndRoomRateMappingData['room']))) { continue; } foreach ($propertyRoom as $propertyRoomRateKey => $propertyRoomRate) { $roomsByOccupancyPrices = []; foreach ($this->roomsByOccupancies as $roomsByOccupancyKey => $roomsByOccupancy) { if ($roomsByOccupancy['adultCount'] > $propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey]['max_adult']) { //Bu oda için istenen yetişkin sayısı kadar kapasite yok continue; } if ($roomsByOccupancy['childCount'] > $propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey]['max_child']) { //Bu oda için istenen çocuk sayısı kadar kapasite yok continue; } if ($roomsByOccupancy['occupancy'] > $propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey]['max_occupancy']) { //Bu oda için istenen misafir sayısı kadar kapasite yok continue; } if (isset($roomsByOccupancy['childAges']) && !is_null($propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey]['max_child_number'])) { foreach ($roomsByOccupancy['childAges'] as $childAge) { if ($childAge > $propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey]['max_child_number']) { continue 2; } } } $roomRateExcludeOccupancy = !is_null($propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey]['exclude_occupancy']) ? json_decode($propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey]['exclude_occupancy'], 1) : []; if (in_array($roomsByOccupancy['occupancyCode'], $roomRateExcludeOccupancy)) { //Bu odada istenmeyen bir occupancy grubu olduğu için kullanılmıyor continue; } if (!isset($propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey])) { //Mapping olmayan bir rate gelirse devam et continue 2; } if ($propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['property_room']['occupancy_lock']) { if ($propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['included_occupancy'] != $roomsByOccupancy['adultCount']) { //Occupancy Lock Durumu continue 1; } } //Fiyatlama kısmı baş $propertyRoomAndRoomRateAvailability = collect($getPropertyRoomAndRoomRateAvailability['data']); $roomRateDaily = []; foreach ($propertyRoomRate as $dailyKey => $dailyRoomRate) { //Pool için genel kontenjan if ($propertyAvailabilityKey == 1) { $roomAndRoomRateAvailability = $propertyRoomAndRoomRateAvailability ->where('date', $dailyRoomRate['date']) ->where('property_room_id', $dailyRoomRate['property_room_id']) ->where('availability_type_id', $dailyRoomRate['availability_type_id']) ->where('status', 1) ->first(); } else { $roomAndRoomRateAvailability = $propertyRoomAndRoomRateAvailability ->where('date', $dailyRoomRate['date']) ->where('property_room_id', $dailyRoomRate['property_room_id']) ->where('availability_type_id', $dailyRoomRate['availability_type_id']) ->where('room_rate_mapping_id', $dailyRoomRate['room_rate_mapping_id']) ->where('channel_id', $channelProperty['channel_id']) ->where('status', 1) ->first(); } if ($channelProperty['channel_room_pricing_type']['code'] == 'ROM') { $dailyRoomRateRackPrice = $dailyRoomRate['amount']; $propertyRoomRateIncludedOccupancy = $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['included_occupancy']; $oneAdultRoomRateRackPrice = $dailyRoomRateRackPrice / $propertyRoomRateIncludedOccupancy; //NEW Promotoin Affect $dailyDetailPromoCheckKey = $dailyRoomRate['property_id'] . '-' . $dailyRoomRate['room_rate_mapping_id'] . '-' . $dailyRoomRate['channel_id'] . '-' . Carbon::parse($dailyKey)->format('Ymd'); if (array_key_exists($dailyDetailPromoCheckKey, $promotionGroupByDay)) { $dailyRoomRate['discountRate'] = $promotionGroupByDay[$dailyDetailPromoCheckKey]['discountRate']; $dailyRoomRateRackPrice = moneyDoubleFormatDecimal($dailyRoomRateRackPrice - ($dailyRoomRateRackPrice * ($promotionGroupByDay[$dailyDetailPromoCheckKey]['discountRate'] / 100))); } //NEW Promotoin Affect $roomRateDaily[$dailyKey] = [ 'date' => $dailyKey, 'amount' => $dailyRoomRateRackPrice, 'allotment' => fillOnUndefined($roomAndRoomRateAvailability, 'availability', 0), 'rackRateAmount' => $dailyRoomRateRackPrice, 'rackRateBaseAmount' => $dailyRoomRate['baseAmount'], 'discountRate' => $dailyRoomRate['discountRate'], 'oneAdultRackRateAmount' => $oneAdultRoomRateRackPrice, 'min_stay' => $dailyRoomRate['min_stay'] ]; } elseif ($channelProperty['channel_room_pricing_type']['code'] == 'PRS') { $roomPrice = 0; $adultPrice = 0; $childPrice = 0; $dailyRoomRateRackPrice = $dailyRoomRate['amount']; $propertyRoomRateIncludedOccupancy = $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['included_occupancy']; $oneAdultRoomRateRackPrice = $dailyRoomRateRackPrice / $propertyRoomRateIncludedOccupancy; //ADULT, CHILD POLICIES $roomRateMappingAdultPolicy = $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['roomRateMappingAdultPolicy']; $roomRateMappingChildPolicy = $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['roomRateMappingChildPolicy']; //ADULT PRICE $adultPrice = $dailyRoomRateRackPrice; if (!empty($roomRateMappingAdultPolicy)) { $roomRateMappingAdultPolicyCollect = collect($roomRateMappingAdultPolicy); $roomOccupancyAdultActionType = null; $roomOccupancyAdultActionDiff = null; if ($roomsByOccupancy['adultCount'] > $propertyRoomRateIncludedOccupancy) { $roomOccupancyAdultActionType = 'INC'; $roomOccupancyAdultActionDiff = $roomsByOccupancy['adultCount'] - $propertyRoomRateIncludedOccupancy; $roomOccupancyAdultActionDiff = ceil($roomOccupancyAdultActionDiff); } elseif ($roomsByOccupancy['adultCount'] < $propertyRoomRateIncludedOccupancy) { $roomOccupancyAdultActionType = 'DEC'; $roomOccupancyAdultActionDiff = $propertyRoomRateIncludedOccupancy - $roomsByOccupancy['adultCount']; $roomOccupancyAdultActionDiff = floor($roomOccupancyAdultActionDiff); } if (!is_null($roomOccupancyAdultActionType)) { $roomOccupancyAdultPolicy = $roomRateMappingAdultPolicyCollect ->where('adult_action_type', $roomOccupancyAdultActionType) ->where('adult', $roomOccupancyAdultActionDiff) ->where('reservation_start_date', null) ->where('reservation_end_date', null) ->sortByDesc('id') ->first(); $roomOccupancyAdultPolicyDate = $roomRateMappingAdultPolicyCollect ->where('adult_action_type', $roomOccupancyAdultActionType) ->where('adult', $roomOccupancyAdultActionDiff) ->where('reservation_start_date', '<=', $dailyKey) ->where('reservation_end_date', '>=', $dailyKey) ->sortByDesc('id') ->first(); if ($roomOccupancyAdultPolicyDate) { $roomOccupancyAdultPolicy = $roomOccupancyAdultPolicyDate; } if (!empty($roomOccupancyAdultPolicy)) { if ($roomOccupancyAdultPolicy['type'] == 'PER') { $roomOccupancyAdultActionDiffAffected = ($dailyRoomRateRackPrice * $roomOccupancyAdultPolicy['value']) / 100; } elseif ($roomOccupancyAdultPolicy['type'] == 'FIX') { $roomOccupancyAdultActionDiffAffected = $roomOccupancyAdultPolicy['value']; } if ($roomOccupancyAdultPolicy['action_type'] == 'INC') { $adultPrice = $dailyRoomRateRackPrice + $roomOccupancyAdultActionDiffAffected; } if ($roomOccupancyAdultPolicy['action_type'] == 'DEC') { $adultPrice = $dailyRoomRateRackPrice - $roomOccupancyAdultActionDiffAffected; } } } } //dd($adultPrice); if ($adultPrice <= 0) { //Eğer günlük fiyat 0 ya da - ye düşerse bu rate için hesaplama yapmayacak continue 2; } //CHILD PRICE $childPriceRaw = []; $roomRateMappingChildPolicyCollect = collect($roomRateMappingChildPolicy); //dd($roomRateMappingChildPolicyCollect); $childOrder = 1; for ($i = 0; $i < $roomsByOccupancy['childCount']; $i++) { $childPriceRaw[$i] = $oneAdultRoomRateRackPrice; if (!empty($roomRateMappingChildPolicy)) { $childAgePolicyAffected = $oneAdultRoomRateRackPrice; $childAgePolicy = $roomRateMappingChildPolicyCollect ->where('adult', 0) ->where('child_order', $childOrder) ->where('child_age_start', '<=', $roomsByOccupancy['childAges'][$i]) ->where('child_age_end', '>', $roomsByOccupancy['childAges'][$i]) ->where('reservation_start_date', null) ->where('reservation_end_date', null) ->sortByDesc('id') ->first(); $childAgePolicyPeriod = $roomRateMappingChildPolicyCollect ->where('adult', 0) ->where('child_order', $childOrder) ->where('child_age_start', '<=', $roomsByOccupancy['childAges'][$i]) ->where('child_age_end', '>', $roomsByOccupancy['childAges'][$i]) ->where('reservation_start_date', '<=', $dailyKey) ->where('reservation_end_date', '>=', $dailyKey) ->sortByDesc('id') ->first(); if ($childAgePolicyPeriod) { $childAgePolicy = $childAgePolicyPeriod; } $childAgePolicyAdult = $roomRateMappingChildPolicyCollect ->where('adult', $roomsByOccupancy['adultCount']) ->where('child_order', $childOrder) ->where('child_age_start', '<=', $roomsByOccupancy['childAges'][$i]) ->where('child_age_end', '>', $roomsByOccupancy['childAges'][$i]) ->where('reservation_start_date', null) ->where('reservation_end_date', null) ->sortByDesc('id') ->first(); if ($childAgePolicyAdult) { $childAgePolicy = $childAgePolicyAdult; } $childAgePolicyDate = $roomRateMappingChildPolicyCollect ->where('adult', $roomsByOccupancy['adultCount']) ->where('child_order', $childOrder) ->where('child_age_start', '<=', $roomsByOccupancy['childAges'][$i]) ->where('child_age_end', '>', $roomsByOccupancy['childAges'][$i]) ->where('reservation_start_date', '<=', $dailyKey) ->where('reservation_end_date', '>=', $dailyKey) ->sortByDesc('id') ->first(); if ($childAgePolicyDate) { $childAgePolicy = $childAgePolicyDate; } if (!empty($childAgePolicy)) { if ($childAgePolicy['type'] == 'PER') { $childAgePolicyAffected = ($oneAdultRoomRateRackPrice * $childAgePolicy['value']) / 100; } elseif ($childAgePolicy['type'] == 'FIX') { $childAgePolicyAffected = $childAgePolicy['value']; } $childOrder++; } $childPriceRaw[$i] = $childAgePolicyAffected; } } $childPrice = array_sum($childPriceRaw); $roomPrice = $adultPrice + $childPrice; //NEW Promotoin Affect $dailyDetailPromoCheckKey = $dailyRoomRate['property_id'] . '-' . $dailyRoomRate['room_rate_mapping_id'] . '-' . $dailyRoomRate['channel_id'] . '-' . Carbon::parse($dailyKey)->format('Ymd'); if (array_key_exists($dailyDetailPromoCheckKey, $promotionGroupByDay)) { $dailyRoomRate['discountRate'] = $promotionGroupByDay[$dailyDetailPromoCheckKey]['discountRate']; $roomPrice = moneyDoubleFormatDecimal($roomPrice - ($roomPrice * ($promotionGroupByDay[$dailyDetailPromoCheckKey]['discountRate'] / 100))); } //NEW Promotoin Affect $roomRateDaily[$dailyKey] = [ 'date' => $dailyKey, 'amount' => $roomPrice, 'allotment' => fillOnUndefined($roomAndRoomRateAvailability, 'availability', 0), 'rackRateAmount' => $dailyRoomRateRackPrice, 'rackRateBaseAmount' => $dailyRoomRate['baseAmount'], 'discountRate' => $dailyRoomRate['discountRate'], 'oneAdultRackRateAmount' => $oneAdultRoomRateRackPrice, 'min_stay' => $dailyRoomRate['min_stay'] ]; } } //Eğer günlere ait kontenjanlardan olmadığı bir gün gelir ise $dailyRoomRateAvailabilityCheck = collect($roomRateDaily)->where('allotment', '<=', '0')->toArray(); if (!empty($dailyRoomRateAvailabilityCheck)) { continue; } //Günler için de minimum doluluk oranına göre müsaitliğin alınması $dailyRoomRateAvailabilityMin = collect($roomRateDaily)->sortBy('allotment')->first(); $dailyRoomRateAllotment = $dailyRoomRateAvailabilityMin['allotment']; //POLICY PRICES $baseTotalPrice = array_sum(array_column($roomRateDaily, 'amount')); $dailyAverageDiscount = floatval(array_sum(array_column($roomRateDaily, 'discountRate')) / count($roomRateDaily)); $roomRateMappingCancellationPolicy = $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['roomRateMappingCancellationPolicy']; if (!empty($roomRateMappingCancellationPolicy)) { foreach ($roomRateMappingCancellationPolicy as $roomRateMappingCancellationPolicyKey => $roomRateMappingCancellationPolicyValue) { //Do not take into account if the number of rule days is greater than the remaining days. /*if ($roomRateMappingCancellationPolicyValue['beforeArrivalDay'] > $daysLeftForCheckin && $roomRateMappingCancellationPolicyValue['isNonRefundable'] == 0) { unset($roomRateMappingCancellationPolicy[$roomRateMappingCancellationPolicyKey]); }*/ if ($roomRateMappingCancellationPolicyValue['is_date_range']) { $isDateInCancellationPolicyRange = false; foreach ($this->dateByDay as $date) { if ($date >= $roomRateMappingCancellationPolicyValue['start_date'] && $date <= $roomRateMappingCancellationPolicyValue['finish_date']) { $isDateInCancellationPolicyRange = true; break; } } if (!$isDateInCancellationPolicyRange) { unset($roomRateMappingCancellationPolicy[$roomRateMappingCancellationPolicyKey]); } } } } if (empty($roomRateMappingCancellationPolicy)) { $roomRateMappingCancellationPolicy[] = [ 'isAffectedPrice' => false, 'isFreeCancellation' => true, 'isNonRefundable' => false ]; } //Wholesalers can only use CHN payment type if (in_array($channelProperty['channel']['channel_category_id'], [7])) { if (empty($channelBookingPaymentTypePolicy)) { $channelBookingPaymentTypePolicy[2] = [ 'name' => 'Channel Manager', 'code' => 'CHN', 'isAffectedPrice' => false ]; } } else { if (empty($channelBookingPaymentTypePolicy)) { $channelBookingPaymentTypePolicy[2] = [ 'name' => 'Pay at Hotel', 'code' => 'HTL', 'isAffectedPrice' => false ]; } } //dd($roomRateMappingCancellationPolicy, $channelBookingPaymentTypePolicy); $policyPrices = []; foreach ($roomRateMappingCancellationPolicy as $roomRateMappingCancellationPolicyKey => $roomRateMappingCancellationPolicy) { foreach ($channelBookingPaymentTypePolicy as $channelBookingPaymentTypeKey => $channelBookingPaymentType) { //dd($channelBookingPaymentType['cancellationPolicy'], $roomRateMappingCancellationPolicyKey); if (!empty($channelBookingPaymentType['cancellationPolicy'])) { if (!in_array($roomRateMappingCancellationPolicyKey, $channelBookingPaymentType['cancellationPolicy'])) { continue; } } $cancellationPolicyAffectPrice = 0; if ($roomRateMappingCancellationPolicy['isAffectedPrice']) { if ($roomRateMappingCancellationPolicy['affectPriceType'] == 'PER') { $cancellationPolicyAffectPrice = ($baseTotalPrice * $roomRateMappingCancellationPolicy['affectPriceValue']) / 100; } elseif ($roomRateMappingCancellationPolicy['affectPriceType'] == 'FIX') { $cancellationPolicyAffectPrice = $roomRateMappingCancellationPolicy['affectPriceValue']; } $cancellationPolicyAffectPrice = $roomRateMappingCancellationPolicy['affectPriceActionType'] == 'DEC' ? (-1 * $cancellationPolicyAffectPrice) : $cancellationPolicyAffectPrice; } $cancellationPolicyAffectPriceName = fillOnUndefined($roomRateMappingCancellationPolicy, 'name'); if ($roomRateMappingCancellationPolicy['isNonRefundable']) { $cancellationPolicyAffectPriceName = 'NonRefundable'; } elseif ($roomRateMappingCancellationPolicy['isFreeCancellation']) { $cancellationPolicyAffectPriceName = 'FreeCancellation'; } $bookingPaymentTypeAffectPrice = 0; if ($channelBookingPaymentType['isAffectedPrice']) { if ($channelBookingPaymentType['affectPriceType'] == 'PER') { $bookingPaymentTypeAffectPrice = ($baseTotalPrice * $channelBookingPaymentType['affectPriceValue']) / 100; } elseif ($channelBookingPaymentType['affectPriceType'] == 'FIX') { $bookingPaymentTypeAffectPrice = $channelBookingPaymentType['affectPriceValue']; } $bookingPaymentTypeAffectPrice = $channelBookingPaymentType['affectPriceActionType'] == 'DEC' ? (-1 * $bookingPaymentTypeAffectPrice) : $bookingPaymentTypeAffectPrice; } $bookingPaymentTypeAffectPriceName = fillOnUndefined($channelBookingPaymentType, 'name'); //Bu dataları 10dk lık cache de tutacaksın, search_id ve $policyPriceKeyHashed bazında $policyPriceKey = $channelProperty['property_id'] . '-' . $channelProperty['channel_id'] . '-' . $propertyAvailabilityKey . '-' . $propertyRoomKey . '-' . $propertyRoomRateKey . '-' . $roomsByOccupancyKey . '-' . Carbon::parse($params['date']['checkIn'])->format('Ymd') . '-' . Carbon::parse($params['date']['checkOut'])->format('Ymd') . '-' . $roomRateMappingCancellationPolicyKey . '-' . $channelBookingPaymentTypeKey; $policyPriceKeyHashed = md5($policyPriceKey); $policyPriceTotal = $baseTotalPrice + $cancellationPolicyAffectPrice + $bookingPaymentTypeAffectPrice; $policyPriceDaily = []; $policyPriceRate = ($policyPriceTotal / $baseTotalPrice); foreach ($roomRateDaily as $daily) { $policyPriceDaily[] = [ 'date' => $daily['date'], 'amount' => moneyDoubleFormatDecimal($daily['amount'] * $policyPriceRate), 'currency_code' => $channelProperty['currency_code'], 'min_stay' => fillOnUndefined($daily, 'min_stay', 0), ]; } $policyPrices[$policyPriceKeyHashed] = [ 'rateKey' => $policyPriceKeyHashed, 'rateKeyCode' => $policyPriceKey, 'occupancyCode' => $roomsByOccupancyKey, 'name' => $cancellationPolicyAffectPriceName . ' - ' . $bookingPaymentTypeAffectPriceName, 'total' => moneyDoubleFormatDecimal($policyPriceTotal), 'currency' => $channelProperty['currency_code'], 'availability' => [ 'name' => __($channelAvailabilityType[$propertyAvailabilityKey][0]['language_key']), 'code' => $channelAvailabilityType[$propertyAvailabilityKey][0]['code'], ], 'room' => [ 'name' => $propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey]['name'], 'type' => __($propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey]['property_room_type']['language_key']), 'allotment' => ($propertyAvailabilityKey == 1) ? $dailyRoomRateAllotment : null, ], 'rate' => [ 'name' => $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['property_room_rate']['name'], 'boardCode' => $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['property_room_rate']['id'], 'boardName' => __($propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['property_room_rate']['property_room_rate_accommodation']['language_key']), 'accommodationCode' => $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['property_room_rate']['property_room_rate_accommodation']['id'], 'allotment' => ($propertyAvailabilityKey != 1) ? $dailyRoomRateAllotment : null, ], 'cancellationPolicy' => $roomRateMappingCancellationPolicy, 'bookingPaymentType' => $channelBookingPaymentType, 'policyPriceRate' => $policyPriceRate, 'policyPriceDaily' => $policyPriceDaily, ]; //Add to Cache $searchPricesCacheWithKey['requestParams'] = $params; $searchPricesCacheWithKey['roomPrices'][$policyPriceKeyHashed] = $policyPrices[$policyPriceKeyHashed]; } } $policyPrices = collect($policyPrices)->sortBy('total')->toArray(); //POLICY PRICES $dailyCalculatedPrices = [ 'prices' => $policyPrices, 'baseTotalPrice' => $baseTotalPrice, 'dailyAverageDiscount' => number_format($dailyAverageDiscount, 0, '', ''), 'allotment' => $dailyRoomRateAllotment, 'room' => [ 'adults' => $roomsByOccupancy['adultCount'], 'children' => $roomsByOccupancy['childCount'], 'childAges' => $roomsByOccupancy['childAges'], ], 'daily' => $roomRateDaily, ]; $calculatedRoomPrice [$propertyAvailabilityKey] [$propertyRoomKey] [$propertyRoomRateKey] [$roomsByOccupancyKey] = $dailyCalculatedPrices; //Fiyatlama kısmı son } //dd($roomsByOccupancy, $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['included_occupancy']); } } } //TODO: Burayı taşıyabilirz')); foreach ($calculatedRoomPrice as $propertyAvailabilityKey => $propertyAvailability) { $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['name'] = $channelProperty['property']['name']; $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['currency'] = $channelProperty['currency_code']; $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['token'] = $channelProperty['token']; $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['booking_engine_token'] = $channelProperty['property']['property_booking_engine_token']['token']; $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['credit_card_required'] = $payAtHotelCreditCardCheck; //Wholesaler Currency SET if (!empty($channelPropertyMarkup)) { $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['currency'] = $channelPropertyMarkup['currency_code']; } //Wholesaler Currency SET //$calculatedRoomPriceFormatted[$channelProperty['property']['id']]['paymentType'] = $channelProperty['channel_booking_payment_type']; $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['name'] = __($channelAvailabilityType[$propertyAvailabilityKey][0]['language_key']); $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['code'] = $channelAvailabilityType[$propertyAvailabilityKey][0]['code']; //En düşük fiyata göre sıralama $propertyAvailability = collect($propertyAvailability); $propertyAvailabilitySorted = $propertyAvailability->sortBy(function ($room, $roomKey) { $firstRate = reset($room); $firstRateOccupancy = reset($firstRate); return $firstRateOccupancy['baseTotalPrice']; }); $propertyAvailability = $propertyAvailabilitySorted->toArray(); foreach ($propertyAvailability as $propertyRoomKey => $propertyRoom) { $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['name'] = $propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey]['name']; $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['type'] = __($propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey]['property_room_type']['language_key']); $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['attributes'] = fillOnUndefined($propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey], 'attributes', []); $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['bedGroups'] = fillOnUndefined($propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey], 'bedGroups', []); $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['photos'] = fillOnUndefined($propertyRoomAndRoomRateMappingData['room'][$propertyRoomKey], 'photos', []); //Wholesaler if (in_array($channelProperty['channel']['channel_category_id'], [7]) && empty($this->bookingEngineToken) || fillOnUndefined($params, 'justPriceValues')) { unset($calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['attributes']); unset($calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['bedGroups']); unset($calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['photos']); } foreach ($propertyRoom as $propertyRoomRateKey => $propertyRoomRate) { if ($propertyAvailabilityKey == 1) { $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['allotment'] = reset($propertyRoomRate)['allotment']; } $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['rates'][$propertyRoomRateKey]['name'] = $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['property_room_rate']['name']; $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['rates'][$propertyRoomRateKey]['boardCode'] = $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['property_room_rate']['property_room_rate_accommodation']['id']; $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['rates'][$propertyRoomRateKey]['boardName'] = __($propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['property_room_rate']['property_room_rate_accommodation']['language_key']); $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['rates'][$propertyRoomRateKey]['rateDescription'] = isset($propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['property_room_rate']['descriptionArray'][$this->language]) ? $propertyRoomAndRoomRateMappingData['roomRateMapping'][$propertyRoomRateKey]['property_room_rate']['descriptionArray'][$this->language]: null; if ($propertyAvailabilityKey != 1) { $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['rates'][$propertyRoomRateKey]['allotment'] = reset($propertyRoomRate)['allotment']; } foreach ($propertyRoomRate as $propertyRoomOccupancyKey => $propertyRoomOccupancy) { $propertyRoomOccupancy['baseTotalPrice'] = moneyDoubleFormatDecimal($propertyRoomOccupancy['baseTotalPrice']); foreach ($propertyRoomOccupancy['daily'] as $dailyKey => $daily) { $propertyRoomOccupancy['daily'][$dailyKey]['amount'] = moneyDoubleFormatDecimal($daily['amount']); $propertyRoomOccupancy['daily'][$dailyKey]['rackRateAmount'] = moneyDoubleFormatDecimal($daily['rackRateAmount']); $propertyRoomOccupancy['daily'][$dailyKey]['oneAdultRackRateAmount'] = moneyDoubleFormatDecimal($daily['oneAdultRackRateAmount']); } //Wholesaler MARKUP CALCULATE if (!empty($channelPropertyMarkup)) { foreach ($propertyRoomOccupancy['prices'] as $rateKey => $propertyRoomOccupancyPrice) { $currency = $channelPropertyMarkup['currency_code']; $propertyRoomOccupancy['prices'][$rateKey]['currency'] = $currency; foreach ($propertyRoomOccupancyPrice['policyPriceDaily'] as $policyPriceDailyKey => $policyPriceDaily) { $policyPriceDailyAmount = moneyDoubleFormatDecimal($policyPriceDaily['amount'] * $channelPropertyMarkup['markup'] * $channelPropertyMarkup['exchange']); $propertyRoomOccupancy['prices'][$rateKey]['policyPriceDaily'][$policyPriceDailyKey]['amount'] = $policyPriceDailyAmount; $propertyRoomOccupancy['prices'][$rateKey]['policyPriceDaily'][$policyPriceDailyKey]['currency_code'] = $currency; } $propertyRoomOccupancy['prices'][$rateKey]['total'] = collect($propertyRoomOccupancy['prices'][$rateKey]['policyPriceDaily'])->sum('amount'); $propertyRoomOccupancy['prices'][$rateKey]['total'] = moneyDoubleFormatDecimal($propertyRoomOccupancy['prices'][$rateKey]['total']); } foreach ($propertyRoomOccupancy['daily'] as $propertyRoomOccupancyDateKey => $propertyRoomOccupancyDate) { $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['amount'] = $propertyRoomOccupancyDate['amount'] * $channelPropertyMarkup['markup']; $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['amount'] *= $channelPropertyMarkup['exchange']; $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['amount'] = moneyDoubleFormatDecimal($propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['amount']); $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['rackRateAmount'] = $propertyRoomOccupancyDate['rackRateAmount'] * $channelPropertyMarkup['markup']; $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['rackRateAmount'] *= $channelPropertyMarkup['exchange']; $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['rackRateAmount'] = moneyDoubleFormatDecimal($propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['rackRateAmount']); $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['rackRateBaseAmount'] = $propertyRoomOccupancyDate['rackRateBaseAmount'] * $channelPropertyMarkup['markup']; $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['rackRateBaseAmount'] *= $channelPropertyMarkup['exchange']; $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['rackRateBaseAmount'] = moneyDoubleFormatDecimal($propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['rackRateBaseAmount']); $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['oneAdultRackRateAmount'] = $propertyRoomOccupancyDate['oneAdultRackRateAmount'] * $channelPropertyMarkup['markup']; $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['oneAdultRackRateAmount'] *= $channelPropertyMarkup['exchange']; $propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['oneAdultRackRateAmount'] = moneyDoubleFormatDecimal($propertyRoomOccupancy['daily'][$propertyRoomOccupancyDateKey]['oneAdultRackRateAmount']); } $propertyRoomOccupancy['baseTotalPrice'] = collect($propertyRoomOccupancy['daily'])->sum('amount'); $propertyRoomOccupancy['baseTotalPrice'] = moneyDoubleFormatDecimal($propertyRoomOccupancy['baseTotalPrice']); } //Wholesaler MARKUP CALCULATE $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['availabilities'][$propertyAvailabilityKey]['rooms'][$propertyRoomKey]['rates'][$propertyRoomRateKey]['requestedRoomPrice'][$propertyRoomOccupancyKey] = $propertyRoomOccupancy; } } } } //ADDON Setup if (!empty($calculatedRoomPriceFormatted)) { $propertyChannelAddonCriteria = [ 'criteria' => [ ['field' => 'property_id', 'condition' => '=', 'value' => $channelProperty['property_id']], ['field' => 'channel_id', 'condition' => '=', 'value' => $channelProperty['channel_id']], ['field' => 'status', 'condition' => '=', 'value' => 1], ], 'with' => ['propertyAddon.fact'] ]; $columns = ['id', 'property_id', 'channel_id', 'property_addon_id', 'amount', 'type', 'title', 'description', 'min_stay']; $selectPropertyChannelAddon = $this->propertyAddonService->selectPropertyChannelAddon($propertyChannelAddonCriteria, $columns); $nightOfStay = Carbon::parse($params['date']['checkIn'])->diff(Carbon::parse($params['date']['checkOut']))->days; $propertyChannelAddon = []; if ($selectPropertyChannelAddon['status'] == 'success') { $propertyChannelAddon = $selectPropertyChannelAddon['data']; } $propertyChannelAddonList = []; foreach ($propertyChannelAddon as $addon) { if (!is_null($addon['min_stay']) && $addon['min_stay'] <= $nightOfStay) { $addon['amount'] = 0; } $propertyChannelAddonList[$addon['property_addon_id']][] = [ 'id' => $addon['id'], 'property_addon_id' => $addon['property_addon_id'], 'property_channel_addon_id' => $addon['id'], 'title' => $addon['title'], 'description' => $addon['description'], 'descriptionArray' => $addon['descriptionArray'], 'amount' => $addon['amount'], 'currency_code' => $channelProperty['currency_code'], 'name' => $addon['property_addon']['title'], 'language_key' => $addon['property_addon']['fact']['language_key'], 'icon' => $addon['property_addon']['fact']['icon'], 'attribute' => $addon['property_addon']['attribute'], 'attributeArray' => $addon['property_addon']['attributeArray'], 'type' => $addon['type'], 'count' => $addon['type'] == 'ONT' ? 1 : 10, 'min_stay' => $addon['min_stay'], ]; } $propertyChannelAddonList = array_values($propertyChannelAddonList); $calculatedRoomPriceFormatted[$channelProperty['property']['id']]['addon'] = $propertyChannelAddonList; } //ADDON Setup } //Add Prices to Cache With SearchKey //If this parameter (noneCacheSearch) exists, it is not cached. if (!isset($params['noneCacheSearch'])) { $this->setCacheDataWithSearchKey($searchKey, $searchPricesCacheWithKey); } $ip = isset($params['ipAddress']) ? $params['ipAddress'] : config("app.myIP"); $countryCodeWithIP = $this->findCountryCodeService->findCountryWithIpAddress($ip); $responseData = [ 'searchKey' => $searchKey, 'properties' => $calculatedRoomPriceFormatted, 'requestParams' => $params, 'countryCodeWithIP' => isset($countryCodeWithIP['data']['code']) ? $countryCodeWithIP['data']['code'] : '' ]; if (empty($calculatedRoomPriceFormatted) && (integer)$minStayCheckProperty > 1 && count($dateByDay) < (integer)$minStayCheckProperty) { throw new ApiErrorException(__('be-minstay-warning', ['minStay' => $minStayCheckProperty], $this->language), 201); } $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'errorCode' => null, 'data' => $responseData]; } catch (ApiErrorException $e) { $response['message'] = implode(', ', $e->getMessageArr()); $response['statusCode'] = 400; $response['errorCode'] = $e->getCode(); } catch (Exception $e) { $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); Log::error($message); $response['message'] = $e->getMessage(); $response['statusCode'] = 500; } //201: be-minstay-warning //For Booking Engine if (isset($channelProperty['channel']['channel_category_id']) && in_array($channelProperty['channel']['channel_category_id'], [3, 7])) { $createSearchStatus = 0; if (isset($response['data']['properties'])) { $calculatedRoomPriceFormattedReset = reset($calculatedRoomPriceFormatted); if (isset($calculatedRoomPriceFormattedReset['name'])) { $createSearchStatus = 1; } } $createSearchExcludeIps = ['127.0.0.1', '185.137.215.118']; if ((isset($params['ipAddress']) && !in_array($params['ipAddress'], $createSearchExcludeIps)) || in_array($channelProperty['channel_id'], [393])) { $isRobot = fillOnUndefined($params, 'isRobot'); if (isset($params['noneCacheSearch'])) { $isRobot = true; } if (!$isRobot) { $createSearchParam = [ 'search_key' => $searchKey, 'property_id' => fillOnUndefined($channelProperty, 'property_id'), 'channel_id' => fillOnUndefined($channelProperty, 'channel_id', 1), 'checkin_date' => $params['date']['checkIn'], 'checkout_date' => $params['date']['checkOut'], 'pax' => array_key_first($this->roomsByOccupancies), 'rooms' => json_encode($params['rooms']), 'booking_code' => fillOnUndefined($params, 'booking_code'), 'best_amount' => fillOnUndefined($params, 'best_amount'), 'currency_code' => fillOnUndefined($channelProperty, 'currency_code'), 'ip_address' => fillOnUndefined($params, 'ipAddress'), 'country_code' => isset($countryCodeWithIP['data']['code']) ? $countryCodeWithIP['data']['code'] : null, 'language_code' => $this->language, 'detail' => json_encode($params), 'referrer' => fillOnUndefined($params, 'referrer'), 'status' => $createSearchStatus, ]; if (in_array($channelProperty['channel_id'], [393])) { $createSearchParam['property_id'] = null; } $createSearch = $this->propertyBookingEngineSearchService->create($createSearchParam); } } } return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode'], $response['errorCode']); } public function bestAvailableRate(Request $request) { $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500]; try { $excludePropertyIds = [643,644,645,738,163,164,165,166,236,366]; $this->channelToken = empty($this->channelToken) ? $request->header('channelToken') : $this->channelToken; $this->bookingEngineToken = empty($this->bookingEngineToken) ? $request->header('bookingEngineToken') : $this->bookingEngineToken; $this->channelId = empty($this->channelId) ? $request->header('channelId') : $this->channelId; $this->bookingEnginePropertyId = empty($this->bookingEnginePropertyId) ? $request->header('bookingEnginePropertyId') : $this->bookingEnginePropertyId; $this->language = empty($this->language) ? $request->header('language') : $this->language; $params = json_decode($request->getContent(), 1); $cacheKeyParam[] = $this->bookingEnginePropertyId; $cacheKeyParam[] = $params['period']; $cacheKey = 'CRR:' . md5(implode(',', $cacheKeyParam)); if(in_array($this->bookingEnginePropertyId, $excludePropertyIds)) { throw new ApiErrorException('Property Channel not found'); } //Cache::forget($cacheKey); if (Cache::has($cacheKey)) { $responseData = Cache::get($cacheKey); } else { $requestParam = [ 'criteria' => [ ['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId], ['field' => 'property_id', 'condition' => '=', 'value' => $this->bookingEnginePropertyId], ['field' => 'status', 'condition' => '=', 'value' => 1], ], 'with' => ['currency'], 'firstRow' => true ]; $getChannelProperty = $this->propertyChannelMappingService->select($requestParam); $getChannelProperty = $getChannelProperty['status'] == 'success' && !empty($getChannelProperty['data']) ? $getChannelProperty['data'] : null; if (!$getChannelProperty) { throw new ApiErrorException('Property Channel not found'); } $requestParam = [ 'criteria' => [ ['field' => 'channel_id', 'condition' => '=', 'value' => 5], ['field' => 'property_id', 'condition' => '=', 'value' => $this->bookingEnginePropertyId], ['field' => 'stop_sell', 'condition' => '=', 'value' => 0], ['field' => 'date', 'condition' => '>=', 'value' => Carbon::parse($params['period'])->format('Y-m-d')], ['field' => 'date', 'condition' => '<', 'value' => Carbon::parse($params['period'])->addMonth()->format('Y-m-d')], ['field' => 'amount', 'condition' => '<>', 'value' => null], ['field' => 'amount', 'condition' => '<>', 'value' => 0], ['field' => 'status', 'condition' => '=', 'value' => 1], ], 'with' => [ 'roomRateMapping.propertyRoomRate' ], 'orderBy' => [ ['field' => 'date', 'value' => 'ASC'], ['field' => 'amount', 'value' => 'ASC'] ], ]; $getPropertyRoomRatePrice = $this->propertyRoomRatePriceService->select($requestParam); if ($getPropertyRoomRatePrice['status'] != 'success' || empty($getPropertyRoomRatePrice['data'])) { throw new ApiErrorException(lang('PropertyRoomRatePrice not found')); } $getPropertyRoomRatePrice = $getPropertyRoomRatePrice['status'] == 'success' && !empty($getPropertyRoomRatePrice['data']) ? $getPropertyRoomRatePrice['data'] : []; $firstDate = Carbon::parse($params['period'])->format('Y-m-d'); $lastDate = Carbon::parse($params['period'])->addMonth()->format('Y-m-d'); $dateDiff = Carbon::parse($firstDate)->diffInDays(Carbon::parse($lastDate)); $rateAndAvailability = []; for ($i = 0; $i < $dateDiff; $i++) { $date = Carbon::parse($firstDate)->addDays($i)->toDateString(); $bestPrice = collect($getPropertyRoomRatePrice) ->where('date', $date) ->where('room_rate_mapping.property_room_rate.name', 'Best Available Rate') ->sortBy('amount')->first(); $bestPrice = $bestPrice ? $bestPrice['amount'] : null; $rateAndAvailability[$date] = [ 'rate' => round($bestPrice), 'available' => $bestPrice ? true : false, ]; } $responseData = [ 'currency' => $getChannelProperty['currency']['code'], 'currency_icon' => $getChannelProperty['currency']['symbol'], 'date' => $rateAndAvailability ]; if (count($rateAndAvailability) == collect($rateAndAvailability)->where('available', false)->count()) { $responseData = null; } Cache::put($cacheKey, $responseData, 60 * 60);//1h 60 * 60 } $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $responseData]; } catch (ApiErrorException $e) { $response['message'] = implode(', ', $e->getMessageArr()); $response['statusCode'] = 400; } catch (Exception $e) { $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); Log::error($message); $response['message'] = $e->getMessage(); $response['statusCode'] = 500; } return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']); } }