885 lines
37 KiB
PHP
885 lines
37 KiB
PHP
<?php
|
|
|
|
|
|
namespace App\Http\Controllers\MetaSearch\Trivago\v1;
|
|
|
|
use App\Core\Service\ChannelManagerPropertyMappingService;
|
|
use App\Core\Service\CurrencyService;
|
|
use App\Core\Service\PropertyChannelCouponService;
|
|
use App\Exceptions\ApiErrorException;
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\PropertyChannel;
|
|
use App\Models\PropertyContact;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\App;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
use Exception;
|
|
|
|
|
|
class TrivagoController extends Controller
|
|
{
|
|
|
|
private $username;
|
|
private $password;
|
|
private $authorization;
|
|
private $channelManagerId;
|
|
private $channelManagerLogId;
|
|
private $mealCodeMapping;
|
|
private $paymentTypeMapping;
|
|
private $countryCodeCampaign;
|
|
|
|
public function __construct(
|
|
Request $request,
|
|
CurrencyService $currencyService,
|
|
ChannelManagerPropertyMappingService $channelManagerPropertyMappingService,
|
|
PropertyChannelCouponService $propertyChannelCouponService
|
|
)
|
|
{
|
|
|
|
$this->username = 'trivago';
|
|
$this->password = 'P8MUQtNP6TkKMz3E';
|
|
|
|
$this->channelManagerId = 11;//Trivago
|
|
|
|
$this->request = $request;
|
|
$this->currencyService = $currencyService;
|
|
$this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService;
|
|
$this->propertyChannelCouponService = $propertyChannelCouponService;
|
|
|
|
$payload = $this->request->getContent();
|
|
parse_str(urldecode($payload), $payloadDecode);
|
|
$this->param = $payloadDecode;
|
|
|
|
$this->authorization = $request->header('authorization');
|
|
|
|
$this->tax = 10;
|
|
$this->cityTax = 2;
|
|
|
|
|
|
$this->mealCodeMapping = [
|
|
10 => 'AI',
|
|
11 => 'BB',
|
|
13 => 'RO',
|
|
14 => 'FB',
|
|
15 => 'HB',
|
|
];
|
|
|
|
$this->paymentTypeMapping = [
|
|
'CRD' => 'prepaid',
|
|
'HTL' => 'postpaid'
|
|
];
|
|
|
|
$this->CPA['TR'] = ["1" => 9.60, "2" => 10.80, "3" => 11.00, "4" => 11.20, "5" => 11.40, "6" => 11.60, "7" => 11.80, "8" => 12.00];
|
|
$this->CPA['DE'] = ["1" => 10.80, "2" => 11.00, "3" => 11.20, "4" => 11.40, "5" => 11.60, "6" => 11.80, "7" => 12.00, "8" => 12.20];
|
|
$this->CPA['UK'] = ["1" => 10.80, "2" => 11.00, "3" => 11.20, "4" => 11.40, "5" => 11.60, "6" => 11.80, "7" => 12.00, "8" => 12.20];
|
|
$this->CPA['US'] = ["1" => 10.80, "2" => 11.00, "3" => 11.20, "4" => 11.40, "5" => 11.60, "6" => 11.80, "7" => 12.00, "8" => 12.20];
|
|
|
|
$this->countryCodeCampaign = [
|
|
'DE' => [
|
|
'code' => 'DE',
|
|
'campaignCode' => 7
|
|
],
|
|
'TR' => [
|
|
'code' => 'TR',
|
|
'campaignCode' => 8
|
|
],
|
|
'US' => [
|
|
'code' => 'US',
|
|
'campaignCode' => 7
|
|
],
|
|
'UK' => [
|
|
'code' => 'UK',
|
|
'campaignCode' => 7
|
|
]
|
|
];
|
|
|
|
}
|
|
|
|
|
|
public function checkAuthentication($authorization)
|
|
{
|
|
|
|
$response = ['status' => false, 'message' => ''];
|
|
|
|
$basicAuth = 'Basic ' . base64_encode($this->username . ':' . $this->password);
|
|
|
|
if ($authorization != $basicAuth) {
|
|
$response['message'] = 'Your username or password is incorrect.';
|
|
} else {
|
|
$response['status'] = true;
|
|
}
|
|
|
|
return $response;
|
|
|
|
}
|
|
|
|
|
|
public function responseError($errorMessage)
|
|
{
|
|
|
|
$response = [
|
|
'status' => false,
|
|
'message' => $errorMessage,
|
|
];
|
|
|
|
//channelManagerLogService
|
|
if (!is_null($this->channelManagerLogId)) {
|
|
$updateDataLog = [
|
|
'response' => json_encode($response),
|
|
'status' => 0
|
|
];
|
|
|
|
if (!is_null($this->channelManagerRequestTime)) {
|
|
$updateDataLog['response_time'] = microtime(true) - $this->channelManagerRequestTime;
|
|
}
|
|
|
|
$channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog);
|
|
}
|
|
//channelManagerLogService
|
|
|
|
|
|
return response()->json($response);
|
|
|
|
}
|
|
|
|
public function requestParamConverter($requestParam = [])
|
|
{
|
|
|
|
$searchRequestJson = [];
|
|
|
|
$searchRequestJson['date']['checkIn'] = Carbon::parse($requestParam['start_date'])->toDateString();
|
|
$searchRequestJson['date']['checkOut'] = Carbon::parse($requestParam['end_date'])->toDateString();
|
|
|
|
$rooms = [];
|
|
for ($i = 0; $i < $requestParam['num_rooms']; $i++) {
|
|
|
|
$roomCounter = ($i + 1);
|
|
|
|
if (isset($requestParam['room_adults_' . $roomCounter])) {
|
|
$rooms[$i]['adults'] = $requestParam['room_adults_' . $roomCounter];
|
|
}
|
|
|
|
|
|
$rooms[$i]['children'] = 0;
|
|
$rooms[$i]['age'] = null;
|
|
if (isset($requestParam['room_childs_' . $roomCounter])) {
|
|
|
|
$childAges = json_decode($requestParam['room_childs_' . $roomCounter]);
|
|
|
|
$rooms[$i]['children'] = count($childAges);
|
|
$rooms[$i]['age'] = $childAges;
|
|
}
|
|
|
|
}
|
|
|
|
$searchRequestJson['rooms'] = $rooms;
|
|
$searchRequestJson['property'] = json_decode($requestParam['hotels']);
|
|
|
|
return $searchRequestJson;
|
|
|
|
}
|
|
|
|
public function roomOccupancy($requestParam)
|
|
{
|
|
|
|
$roomOccupancy = [];
|
|
foreach ($requestParam as $room) {
|
|
$adults = str_repeat('A', $room['adults']);
|
|
|
|
$children = [];
|
|
if ($room['children'] > 0 && !empty($room['age'])) {
|
|
foreach ($room['age'] as $child) {
|
|
$children[] = 'C' . $child;
|
|
}
|
|
}
|
|
|
|
$roomOccupancy[] = $adults . implode('', $children);
|
|
|
|
}
|
|
|
|
return $roomOccupancy;
|
|
}
|
|
|
|
public function deepLinkGenerator($token, $requestParam = [])
|
|
{
|
|
|
|
$deepLink = 'https://be.extranetwork.com/' . $token . '/en/search/';
|
|
|
|
|
|
$deepLink .= Carbon::parse($requestParam['date']['checkIn'])->format('Ymd') . '/';
|
|
$deepLink .= Carbon::parse($requestParam['date']['checkOut'])->format('Ymd') . '/';
|
|
|
|
|
|
$roomOccupancy = $this->roomOccupancy($requestParam['rooms']);
|
|
|
|
$deepLink .= implode(',', $roomOccupancy);;
|
|
|
|
$deepLink .= '?utm_medium=trivago&utm_source=trivago&locale=' . $requestParam['locale'];
|
|
|
|
return $deepLink;
|
|
|
|
}
|
|
|
|
public function couponCodeCheck($propertyId, $checkIn, $checkOut)
|
|
{
|
|
//$propertyChannelCoupon
|
|
$propertyChannelCouponsCriteria = [
|
|
'criteria' => [
|
|
['field' => 'property_id', 'condition' => '=', 'value' => $propertyId],
|
|
['field' => 'channel_id', 'condition' => '=', 'value' => 1],
|
|
['field' => 'start_date', 'condition' => '<=', 'value' => Carbon::now()->toDateString()],
|
|
['field' => 'end_date', 'condition' => '>=', 'value' => Carbon::now()->toDateString()],
|
|
['field' => 'status', 'condition' => '=', 'value' => 1],
|
|
],
|
|
'orderBy' => [
|
|
['field' => 'id', 'value' => 'DESC']
|
|
],
|
|
];
|
|
|
|
$propertyChannelCoupons = $this->propertyChannelCouponService->select($propertyChannelCouponsCriteria);
|
|
|
|
if ($propertyChannelCoupons['status'] == 'success') {
|
|
$propertyChannelCoupons = $propertyChannelCoupons['data'];
|
|
|
|
foreach ($propertyChannelCoupons as $propertyChannelCouponKey => $propertyChannelCouponData) {
|
|
|
|
//Reservation Date Check
|
|
if (!is_null($propertyChannelCouponData['reservation_start_date']) && !is_null($propertyChannelCouponData['reservation_end_date'])) {
|
|
$reservationDateCheck = Carbon::parse($propertyChannelCouponData['reservation_start_date'])->lessThanOrEqualTo(Carbon::parse($checkIn))
|
|
&& Carbon::parse($propertyChannelCouponData['reservation_end_date'])->greaterThanOrEqualTo(Carbon::parse($checkOut));
|
|
if (!$reservationDateCheck) {
|
|
unset($propertyChannelCoupons[$propertyChannelCouponKey]);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
} else {
|
|
$propertyChannelCoupons = [];
|
|
}
|
|
|
|
$propertyChannelCoupon = !empty($propertyChannelCoupons) ? reset($propertyChannelCoupons) : null;
|
|
|
|
return $propertyChannelCoupon;
|
|
|
|
}
|
|
|
|
public function availability(Request $request)
|
|
{
|
|
|
|
$response = ['status' => true, 'message' => ''];
|
|
|
|
$checkAuthentication = $this->checkAuthentication($this->authorization);
|
|
if (!$checkAuthentication['status']) {
|
|
return $this->responseError($checkAuthentication['message']);
|
|
}
|
|
|
|
$searchController = App::make("App\Http\Controllers\BookingEngine\V1\SearchController");
|
|
|
|
$requestTime = microtime(true);
|
|
|
|
|
|
$hotelList['root'] = $this->param;
|
|
unset($hotelList['root']['hotels']);
|
|
$hotelList['root']['hotel_ids'] = json_decode($this->param['hotels']);
|
|
$hotelList['root']['hotels'] = [];
|
|
|
|
$hotelList['root']['api_version'] = (integer)$hotelList['root']['api_version'];
|
|
$hotelList['root']['num_rooms'] = (integer)$hotelList['root']['num_rooms'];
|
|
|
|
for ($i = 0; $i < $hotelList['root']['num_rooms']; $i++) {
|
|
$roomCounter = ($i + 1);
|
|
if (isset($hotelList['root']['room_adults_' . $roomCounter])) {
|
|
$hotelList['root']['room_adults_' . $roomCounter] = (integer)$hotelList['root']['room_adults_' . $roomCounter];
|
|
}
|
|
}
|
|
|
|
$requestCurrency = $this->param['currency'];
|
|
|
|
try {
|
|
|
|
|
|
//Hotels Check
|
|
$channelManagerPropertyList = [];
|
|
$channelManagerPropertyMappingCriteria['criteria'] = [
|
|
['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId],
|
|
['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => null],
|
|
['field' => 'status', 'condition' => '=', 'value' => 1],
|
|
];
|
|
$channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria);
|
|
if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) {
|
|
$channelManagerPropertyList = pickItemFromArray('property_id', $channelManagerPropertyMapping['data']);
|
|
}
|
|
|
|
$availableHotelIds = array_intersect($hotelList['root']['hotel_ids'], $channelManagerPropertyList);
|
|
|
|
if (empty($availableHotelIds)) {
|
|
throw new ApiErrorException('Hotel not found');
|
|
}
|
|
|
|
$this->param['hotels'] = json_encode($availableHotelIds);
|
|
//Hotels Check
|
|
|
|
|
|
$searchRequestJson = $this->requestParamConverter($this->param);
|
|
|
|
$searchRequestJson['ipAddress'] = $request->getClientIp();
|
|
$searchRequestJson['isMobile'] = null;
|
|
$searchRequestJson['noneCacheSearch'] = true;
|
|
$searchRequestJson['ipAddress'] = $request->getClientIp();
|
|
$searchRequestJson['justPriceValues'] = true;
|
|
|
|
|
|
$cacheKeyParam = $this->param;
|
|
unset($cacheKeyParam['currency']);
|
|
unset($cacheKeyParam['rate_model']);
|
|
unset($cacheKeyParam['lang']);
|
|
$cacheKey = 'TRV:' . md5(implode(',', $cacheKeyParam));
|
|
|
|
//Cache::forget($cacheKey);
|
|
|
|
if (Cache::has($cacheKey)) {
|
|
$search = Cache::get($cacheKey);
|
|
} else {
|
|
$requestCreate = Request::create(null, null, [], [], [], [], json_encode($searchRequestJson));
|
|
$requestCreate->headers->set('channelId', '1');
|
|
//$requestCreate->headers->set('bookingEnginePropertyId', null);
|
|
$requestCreate->headers->set('channelToken', 'ece3ef02-42e7-92b7-f379-08226ed7a0f3');//TODO: from DB
|
|
$requestCreate->headers->set('bookingEngineToken', null);
|
|
$search = $searchController->search($requestCreate);
|
|
|
|
Cache::put($cacheKey, $search, 60 * 60);//1 Day 24 * 60 * 60
|
|
}
|
|
|
|
$search = json_decode(json_encode($search), 1);
|
|
|
|
if ($search['original']['status'] != 200) {
|
|
throw new ApiErrorException('Hotel not found');
|
|
}
|
|
|
|
$properties = $search['original']['data']['properties'];
|
|
|
|
if (empty($properties)) {
|
|
throw new ApiErrorException('Hotel not found');
|
|
}
|
|
|
|
$hotelCounter = 0;
|
|
$numberOfStay = Carbon::parse($searchRequestJson['date']['checkIn'])->diffInDays(Carbon::parse($searchRequestJson['date']['checkOut']));
|
|
|
|
foreach ($properties as $propertyId => $property) {
|
|
|
|
if (!isset($property['currency'])) {
|
|
continue;
|
|
}
|
|
|
|
$currencyExchangeRate = 1;
|
|
if ($requestCurrency != $property['currency']) {
|
|
$currencyExchangeRate = $this->currencyService->lastExchangeRate($property['currency'], $requestCurrency);
|
|
if ($currencyExchangeRate['status'] == 'success') {
|
|
$currencyExchangeRate = $currencyExchangeRate['data'];
|
|
}
|
|
}
|
|
|
|
|
|
$languageLocale = explode('_', $this->param['lang'], 2);
|
|
$searchRequestJson['locale'] = $languageLocale[1];
|
|
|
|
$token = $property['booking_engine_token'];
|
|
$deepLinkGenerator = $this->deepLinkGenerator($token, $searchRequestJson);
|
|
|
|
$property = reset($property['availabilities']);
|
|
$propertyRooms = $property['rooms'];
|
|
|
|
//Standard Room Room Only FreeCancellation - Pay at Hotel
|
|
|
|
$requestedRoomPriceGroup = [];
|
|
foreach ($propertyRooms as $propertyRoomId => $propertyRoom) {
|
|
|
|
foreach ($propertyRoom['rates'] as $propertyRoomRateId => $propertyRoomRate) {
|
|
|
|
foreach ($propertyRoomRate['requestedRoomPrice'] as $occupancyCode => $requestedRoomPrices) {
|
|
|
|
foreach ($requestedRoomPrices['prices'] as $requestedRoomPriceKey => $requestedRoomPrice) {
|
|
|
|
$roomRateKeyName = $occupancyCode . ' ' . $requestedRoomPrice['room']['name'] . ' ' . $requestedRoomPrice['rate']['boardName'] . ' ' . $requestedRoomPrice['name'];
|
|
|
|
$roomRateKeycode = $requestedRoomPrice['rate']['accommodationCode'] . '|' . (isset($requestedRoomPrice['cancellationPolicy']['id']) ? $requestedRoomPrice['cancellationPolicy']['id'] : 0) . '|' . $requestedRoomPrice['bookingPaymentType']['code'];
|
|
|
|
//$requestedRoomPriceGroup[$roomRateKeycode][$occupancyCode][] = $roomRateKeyName . '-' . $requestedRoomPrice['rateKeyCode'];
|
|
$requestedRoomPrice['dailyAverageDiscount'] = $requestedRoomPrices['dailyAverageDiscount'];
|
|
$requestedRoomPriceGroup[$roomRateKeycode][$occupancyCode][] = $requestedRoomPrice;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
$roomOccupancy = $this->roomOccupancy($searchRequestJson['rooms']);
|
|
|
|
|
|
$roomRateBoardGroup = [];
|
|
foreach ($requestedRoomPriceGroup as $groupKey => $groupValue) {
|
|
|
|
$counter = 0;
|
|
|
|
foreach ($groupValue as $groupValueOccupancyCode => $groupValueOccupancy) {
|
|
foreach ($groupValueOccupancy as $groupValueOccupancyCodeX => $groupValueOccupancyVal) {
|
|
|
|
foreach ($roomOccupancy as $occupancyOrder => $occupancy) {
|
|
|
|
$occupancyCheckKey = $occupancy . '-' . $occupancyOrder;
|
|
|
|
if ($groupValueOccupancyCode == $occupancy && !isset($roomRateBoardGroup[$groupKey][$counter][$occupancyCheckKey])) {
|
|
$roomRateBoardGroup[$groupKey][$counter][$occupancyCheckKey] = $groupValueOccupancyVal;
|
|
if (count($roomRateBoardGroup[$groupKey][$counter]) == count($roomOccupancy)) {
|
|
$counter++;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
$roomRateTypes = [];
|
|
foreach ($roomRateBoardGroup as $boardGroups) {
|
|
|
|
foreach ($boardGroups as $boardGroups) {
|
|
|
|
|
|
$roomRateTypesGroup = [];
|
|
foreach ($boardGroups as $requestedRoomPrice) {
|
|
|
|
$roomRateKeyName = $requestedRoomPrice['room']['name'] . ' ' . $requestedRoomPrice['rate']['boardName'] . ' ' . $requestedRoomPrice['name'];
|
|
|
|
$total = $requestedRoomPrice['total'];
|
|
$totalBeforeDiscount = $requestedRoomPrice['total'];
|
|
$totalBeforeDiscountDailyAverage = ($totalBeforeDiscount / $numberOfStay);
|
|
|
|
$discounts = [];
|
|
if ($requestedRoomPrice['dailyAverageDiscount'] > 0) {
|
|
|
|
$totalBeforeDiscount = ($total / (100 - (double)$requestedRoomPrice['dailyAverageDiscount'])) * 100;
|
|
$totalBeforeDiscountDailyAverage = ($totalBeforeDiscount / $numberOfStay);
|
|
$totalDiscount = $totalBeforeDiscount - $total;
|
|
$dailyDiscountAverage = ($totalDiscount / $numberOfStay);
|
|
|
|
|
|
$netRate = $dailyDiscountAverage / (1 + ($this->tax / 100) + ($this->cityTax / 100));
|
|
$vat = $netRate * ($this->tax / 100);
|
|
$localTax = $netRate * ($this->cityTax / 100);
|
|
|
|
|
|
$finalRateDiscount = moneyDoubleFormatDecimal($localTax * $currencyExchangeRate) + moneyDoubleFormatDecimal($netRate * $currencyExchangeRate) + moneyDoubleFormatDecimal($vat * $currencyExchangeRate);
|
|
|
|
$discounts[] = [
|
|
'booking_fee' => 0,
|
|
'final_rate' => moneyDoubleFormatDecimal($finalRateDiscount), //moneyDoubleFormatDecimal($dailyDiscountAverage * $currencyExchangeRate),
|
|
'hotel_fee' => 0,
|
|
'local_tax' => moneyDoubleFormatDecimal($localTax * $currencyExchangeRate),
|
|
'marketing_text' => $requestedRoomPrice['dailyAverageDiscount'] . '% Special Discount',
|
|
'net_rate' => moneyDoubleFormatDecimal($netRate * $currencyExchangeRate),
|
|
'resort_fee' => 0,
|
|
'service_charge' => 0,
|
|
'vat' => moneyDoubleFormatDecimal($vat * $currencyExchangeRate),
|
|
];
|
|
|
|
}
|
|
|
|
$netRate = $totalBeforeDiscountDailyAverage / (1 + ($this->tax / 100) + ($this->cityTax / 100));
|
|
$vat = $netRate * ($this->tax / 100);
|
|
$localTax = $netRate * ($this->cityTax / 100);
|
|
|
|
|
|
$finalRate = moneyDoubleFormatDecimal($localTax * $currencyExchangeRate) + moneyDoubleFormatDecimal($netRate * $currencyExchangeRate) + moneyDoubleFormatDecimal($vat * $currencyExchangeRate);
|
|
|
|
$roomRateTypesGroup[][$roomRateKeyName] = [
|
|
'booking_fee' => 0,
|
|
'breakfast_included' => in_array($requestedRoomPrice['rate']['accommodationCode'], [10, 11, 14, 15]) ? true : false,
|
|
'currency' => $requestCurrency,
|
|
'discounts' => $discounts,
|
|
'final_rate' => moneyDoubleFormatDecimal($finalRate),//moneyDoubleFormatDecimal($totalBeforeDiscountDailyAverage * $currencyExchangeRate),
|
|
'free_cancellation' => $requestedRoomPrice['cancellationPolicy']['isFreeCancellation'] ? true : false,
|
|
//'free_cancellation_deadline' => '2018-04-25T16:00:00+00:00',
|
|
'hotel_fee' => 0,
|
|
'local_tax' => moneyDoubleFormatDecimal($localTax * $currencyExchangeRate),
|
|
'meal_code' => isset($this->mealCodeMapping[$requestedRoomPrice['rate']['accommodationCode']]) ? $this->mealCodeMapping[$requestedRoomPrice['rate']['accommodationCode']] : 'RO',
|
|
'net_rate' => moneyDoubleFormatDecimal($netRate * $currencyExchangeRate),
|
|
'payment_type' => isset($this->paymentTypeMapping[$requestedRoomPrice['bookingPaymentType']['code']]) ? $this->paymentTypeMapping[$requestedRoomPrice['bookingPaymentType']['code']] : 'postpaid',
|
|
'resort_fee' => 0,
|
|
'room_code' => $requestedRoomPrice['room']['name'],
|
|
'service_charge' => 0,
|
|
'url' => $deepLinkGenerator,
|
|
//'mobileURL' => null',
|
|
'vat' => moneyDoubleFormatDecimal($vat * $currencyExchangeRate),
|
|
'rate_type' => 'DEFAULT',
|
|
//'rateKeyCode' => $requestedRoomPrice['rateKeyCode'],
|
|
//'dailyAverageDiscount' => $requestedRoomPrice['dailyAverageDiscount'],
|
|
];
|
|
|
|
|
|
}
|
|
|
|
$roomRateTypes[] = $roomRateTypesGroup;
|
|
|
|
|
|
}
|
|
}
|
|
|
|
if (!empty($roomRateTypes)) {
|
|
|
|
//if (in_array($propertyId, [1275,1325])) {
|
|
|
|
$propertyCouponCodeCheck = $this->couponCodeCheck($propertyId, $searchRequestJson['date']['checkIn'], $searchRequestJson['date']['checkOut']);
|
|
|
|
if (!empty($propertyCouponCodeCheck)) {
|
|
$roomRateTypesWithCoupon = [];
|
|
foreach ($roomRateTypes as $roomRateTypeKey => $roomRateType) {
|
|
foreach ($roomRateType as $roomRateTypeDetailKey => $roomRateTypeDetails) {
|
|
|
|
//dd($roomRateTypeKey, $roomRateTypeDetailKey, $propertyCouponCodeCheck, $roomRateTypeDetail, key($roomRateTypeDetail));
|
|
|
|
$roomRateTypeDetail = reset($roomRateTypeDetails);
|
|
|
|
$couponPercentageValue = (100 - $propertyCouponCodeCheck['value']) / 100;
|
|
|
|
$finalRateDiscountBeforeReward = collect($roomRateTypeDetail['discounts'])->sum('final_rate');
|
|
$localTaxDiscountBeforeReward = collect($roomRateTypeDetail['discounts'])->sum('local_tax');
|
|
$netRateDiscountBeforeReward = collect($roomRateTypeDetail['discounts'])->sum('net_rate');
|
|
$vatDiscountBeforeReward = collect($roomRateTypeDetail['discounts'])->sum('vat');
|
|
|
|
$finalRateDiscountReward = ($roomRateTypeDetail['final_rate'] - $finalRateDiscountBeforeReward) * $propertyCouponCodeCheck['value'] / 100;
|
|
$localTaxDiscountReward = ($roomRateTypeDetail['local_tax'] - $localTaxDiscountBeforeReward) * $propertyCouponCodeCheck['value'] / 100;
|
|
$netRateDiscountReward = ($roomRateTypeDetail['net_rate'] - $netRateDiscountBeforeReward) * $propertyCouponCodeCheck['value'] / 100;
|
|
$vatDiscountReward = ($roomRateTypeDetail['vat'] - $vatDiscountBeforeReward) * $propertyCouponCodeCheck['value'] / 100;
|
|
|
|
$discountReward = [
|
|
'booking_fee' => 0,
|
|
'final_rate' => moneyDoubleFormatDecimal($finalRateDiscountBeforeReward + $finalRateDiscountReward),
|
|
'hotel_fee' => 0,
|
|
'local_tax' => moneyDoubleFormatDecimal($localTaxDiscountBeforeReward + $localTaxDiscountReward),
|
|
'marketing_text' => 'Special REWARD Discount',
|
|
'net_rate' => moneyDoubleFormatDecimal($netRateDiscountBeforeReward + $netRateDiscountReward),
|
|
'resort_fee' => 0,
|
|
'service_charge' => 0,
|
|
'vat' => moneyDoubleFormatDecimal($vatDiscountBeforeReward + $vatDiscountReward),
|
|
];
|
|
|
|
|
|
/*foreach ($roomRateTypeDetail['discounts'] as $discountKey => $discount) {
|
|
|
|
$discount['vat'] = moneyDoubleFormatDecimal($discount['vat'] * $couponPercentageValue);
|
|
$discount['net_rate'] = moneyDoubleFormatDecimal($discount['net_rate'] * $couponPercentageValue);
|
|
$discount['local_tax'] = moneyDoubleFormatDecimal($discount['local_tax'] * $couponPercentageValue);
|
|
$discount['final_rate'] = moneyDoubleFormatDecimal($discount['net_rate'] + $discount['vat'] + $discount['local_tax']);
|
|
|
|
$roomRateTypeDetail['discounts'][$discountKey] = $discount;
|
|
|
|
}
|
|
|
|
|
|
$roomRateTypeDetail['vat'] = moneyDoubleFormatDecimal($roomRateTypeDetail['vat'] * $couponPercentageValue);
|
|
$roomRateTypeDetail['net_rate'] = moneyDoubleFormatDecimal($roomRateTypeDetail['net_rate'] * $couponPercentageValue);
|
|
$roomRateTypeDetail['local_tax'] = moneyDoubleFormatDecimal($roomRateTypeDetail['local_tax'] * $couponPercentageValue);
|
|
$roomRateTypeDetail['final_rate'] = moneyDoubleFormatDecimal($roomRateTypeDetail['net_rate'] + $roomRateTypeDetail['vat'] + $roomRateTypeDetail['local_tax']);*/
|
|
|
|
unset($roomRateTypeDetail['discounts']);
|
|
|
|
$roomRateTypeDetail['discounts'][] = $discountReward;
|
|
|
|
$roomRateTypeDetail['rate_type'] = 'REWARD';
|
|
|
|
$roomRateTypesWithCoupon[$roomRateTypeKey][$roomRateTypeDetailKey][key($roomRateTypeDetails)] = $roomRateTypeDetail;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$roomRateTypes = array_merge($roomRateTypes, $roomRateTypesWithCoupon);
|
|
}
|
|
|
|
//}
|
|
|
|
|
|
$hotelList['root']['hotels'][$hotelCounter] = [
|
|
'hotel_id' => $propertyId,
|
|
'room_types' => $roomRateTypes
|
|
];
|
|
|
|
$hotelCounter++;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} 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();
|
|
}
|
|
|
|
if (!$response['status']) {
|
|
$hotelList['root']['hotels'] = [];
|
|
}
|
|
|
|
$responseTime = microtime(true) - $requestTime;
|
|
|
|
|
|
//Log::debug(json_encode($this->param) . ' - Response Time: ' . number_format($responseTime, 2) . ' - Status: ' . count($hotelList['root']['hotels']));
|
|
|
|
|
|
return response()->json($hotelList);
|
|
|
|
}
|
|
|
|
public function hotel(Request $request)
|
|
{
|
|
|
|
$response = ['status' => true, 'message' => ''];
|
|
|
|
|
|
$hotelList = [];
|
|
|
|
$hotelList['api_version'] = 4;
|
|
$hotelList['lang'] = 'en_GB';
|
|
$hotelList['hotels'] = [];
|
|
|
|
try {
|
|
|
|
|
|
$channelManagerPropertyMappingCriteria['criteria'] = [
|
|
['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId],
|
|
['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => null],
|
|
['field' => 'status', 'condition' => '=', 'value' => 1],
|
|
];
|
|
$channelManagerPropertyMappingCriteria['with'] = [
|
|
'property.propertyType', 'property.propertyContact', 'property.propertyWeb', 'property.country'
|
|
];
|
|
$channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria);
|
|
|
|
if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) {
|
|
|
|
foreach ($channelManagerPropertyMapping['data'] as $propertyMapping) {
|
|
|
|
if ($propertyMapping['status'] != 1) {
|
|
continue;
|
|
}
|
|
|
|
$metaAddress = json_decode($propertyMapping['property']['property_contact']['meta'], 1);
|
|
|
|
|
|
$hotelList['hotels'][] = [
|
|
'partner_reference' => $propertyMapping['property']['id'],
|
|
'name' => $propertyMapping['property']['name'],
|
|
'street' => fillOnUndefined($metaAddress, 'street'),
|
|
'city' => fillOnUndefined($metaAddress, 'city'),
|
|
'postal_code' => fillOnUndefined($metaAddress, 'zip_code'),
|
|
//'state' => null,
|
|
'country' => $propertyMapping['property']['country']['name'],
|
|
'latitude' => $propertyMapping['property']['property_contact']['latitude'],
|
|
'longitude' => $propertyMapping['property']['property_contact']['longitude'],
|
|
'desc' => $propertyMapping['property']['name'],
|
|
'amenities' => null,//['Beauty Center', 'Business Center', 'Café/ Bistro', 'Sauna'],
|
|
'url' => $propertyMapping['property']['property_web']['webProtocolUrl'],
|
|
'email' => $propertyMapping['property']['property_contact']['email'],
|
|
'phone' => $propertyMapping['property']['property_contact']['phone'],
|
|
'fax' => $propertyMapping['property']['property_contact']['fax']
|
|
];
|
|
|
|
//dd(json_decode($propertyMapping['property']['property_contact']['meta'],1));
|
|
|
|
$addressExplode = explode('/', $propertyMapping['property']['property_contact']['address'], 2);
|
|
$street = isset($addressExplode[0]) ? $addressExplode[0] : $propertyMapping['property']['property_contact']['address'];
|
|
$cityExplode = isset($addressExplode[1]) ? explode(',', $addressExplode[1]) : (isset($addressExplode[0]) ? explode(',', $addressExplode[0]) : null);
|
|
$city = isset($cityExplode[0]) ? $cityExplode[0] : null;
|
|
|
|
$streetExplode = explode(', ', $street);
|
|
unset($streetExplode[count($streetExplode) - 1]);
|
|
$street = implode(', ', $streetExplode);
|
|
|
|
$metaUpdate = [
|
|
'street' => $street,
|
|
'city' => $city,
|
|
'zip_code' => $propertyMapping['property']['property_contact']['zip_code'],
|
|
];
|
|
|
|
if (empty($propertyMapping['property']['property_contact']['meta'])) {
|
|
PropertyContact::where('id', $propertyMapping['property']['property_contact']['id'])->update(['meta' => json_encode($metaUpdate)]);
|
|
}
|
|
|
|
|
|
//dd($propertyMapping['property']['property_contact']['id'],$metaUpdate);
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} 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();
|
|
}
|
|
|
|
if (!$response['status']) {
|
|
$hotelList['root']['hotels'] = [];
|
|
}
|
|
|
|
|
|
return response()->json($hotelList);
|
|
|
|
}
|
|
|
|
public function campaign(Request $request)
|
|
{
|
|
|
|
|
|
$hotelList = [];
|
|
|
|
$hotelExcludeList = [];
|
|
$hotelExcludeList['TR'] = [721, 729];
|
|
|
|
try {
|
|
|
|
|
|
$channelManagerPropertyMappingCriteria['criteria'] = [
|
|
['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId],
|
|
['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => null],
|
|
['field' => 'status', 'condition' => '=', 'value' => 1],
|
|
];
|
|
$channelManagerPropertyMappingCriteria['with'] = [
|
|
'property.propertyType', 'property.propertyContact', 'property.propertyWeb', 'property.country'
|
|
];
|
|
$channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria);
|
|
|
|
|
|
if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) {
|
|
|
|
$hotelList[] = [
|
|
'partner_reference' => 'partner_reference',
|
|
'locale' => 'locale',
|
|
'campaign' => 'campaign'
|
|
];
|
|
|
|
foreach ($channelManagerPropertyMapping['data'] as $propertyMapping) {
|
|
|
|
foreach ($this->CPA as $countryCode => $countryValue) {
|
|
foreach ($countryValue as $campaignId => $campaignValue) {
|
|
|
|
if (isset($this->countryCodeCampaign[$countryCode]) && $this->countryCodeCampaign[$countryCode]['campaignCode'] == $campaignId) {
|
|
|
|
if (isset($hotelExcludeList[$countryCode])) {
|
|
if (in_array($propertyMapping['property_id'], $hotelExcludeList[$countryCode])) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
$hotelList[] = [
|
|
'partner_reference' => $propertyMapping['property']['id'],
|
|
'locale' => $countryCode,
|
|
'campaign' => $campaignId
|
|
];
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (ApiErrorException | Exception $e) {
|
|
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
|
|
Log::error($message);
|
|
}
|
|
|
|
$out = "";
|
|
foreach ($hotelList as $hotel) {
|
|
$out .= implode(",", $hotel) . PHP_EOL;
|
|
|
|
}
|
|
|
|
header("Content-Type: application/csv");
|
|
header("Content-Disposition: attachment; filename=Extranetwork-Campaign.csv");
|
|
header('Pragma: no-cache');
|
|
header("Expires: 0");
|
|
|
|
echo $out;
|
|
die();
|
|
|
|
//return response()->json($hotelList);
|
|
|
|
}
|
|
|
|
public function cpa(Request $request)
|
|
{
|
|
|
|
|
|
$cpaList[] = [
|
|
'locale' => 'locale',
|
|
'campaign' => 'campaign',
|
|
'cpa_value' => 'cpa_value'
|
|
];
|
|
|
|
|
|
try {
|
|
|
|
foreach ($this->CPA as $countryCode => $countryValue) {
|
|
foreach ($countryValue as $campaignId => $campaignValue) {
|
|
|
|
$cpaList[] = [
|
|
'locale' => $countryCode,
|
|
'campaign' => $campaignId,
|
|
'cpa_value' => $campaignValue
|
|
];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (ApiErrorException | Exception $e) {
|
|
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
|
|
Log::error($message);
|
|
}
|
|
|
|
|
|
$out = "";
|
|
foreach ($cpaList as $cpa) {
|
|
$out .= implode(",", $cpa) . PHP_EOL;
|
|
|
|
}
|
|
|
|
header("Content-Type: application/csv");
|
|
header("Content-Disposition: attachment; filename=Extranetwork-CPA.csv");
|
|
header('Pragma: no-cache');
|
|
header("Expires: 0");
|
|
|
|
echo $out;
|
|
die();
|
|
|
|
//return response()->json($hotelList);
|
|
|
|
}
|
|
|
|
|
|
}
|