2137 lines
128 KiB
PHP
2137 lines
128 KiB
PHP
<?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']);
|
||
|
||
|
||
}
|
||
|
||
|
||
}
|