Files
api-extranetwork/app/Http/Controllers/BookingEngine/V1/SearchController.php
ExtraNetwork e5c4b6aa13 first commit
2026-05-12 17:04:54 +03:00

2137 lines
128 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Http\Controllers\BookingEngine\V1;
use App\Core\Service\PropertyAddonService;
use App\Core\Service\PropertyChannelService;
use App\Core\Service\PropertyChannelMappingService;
use App\Core\Service\PropertyRoomRateChannelMappingService;
use App\Core\Service\PropertyRoomRatePriceService;
use App\Core\Service\PropertyRoomAvailabilityService;
use App\Core\Service\FindCountryCodeService;
use App\Core\Service\PropertyPromotionService;
use App\Core\Service\PropertyBookingEngineSearchService;
use App\Core\Service\PropertyPaymentService;
use App\Core\Service\CurrencyService;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Config;
use Exception;
use App\Exceptions\ApiErrorException;
class SearchController extends BookingEngineBaseController
{
private $request;
private $propertyChannelService;
private $propertyChannelMappingService;
private $propertyRoomRatePriceService;
private $findCountryCodeService;
private $propertyAddonService;
private $channelId;
private $channelConnectedId;
private $roomsByOccupancies;
private $dateByDay;
private $currencyService;
public function __construct(
Request $request,
PropertyChannelService $propertyChannelService,
PropertyChannelMappingService $propertyChannelMappingService,
PropertyRoomRateChannelMappingService $propertyRoomRateChannelMappingService,
PropertyRoomRatePriceService $propertyRoomRatePriceService,
PropertyRoomAvailabilityService $propertyRoomAvailabilityService,
FindCountryCodeService $findCountryCodeService,
PropertyPromotionService $propertyPromotionService,
PropertyAddonService $propertyAddonService,
PropertyBookingEngineSearchService $propertyBookingEngineSearchService,
PropertyPaymentService $propertyPaymentService,
CurrencyService $currencyService
)
{
$this->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']);
}
}