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

2662 lines
125 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

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

<?php
namespace App\Http\Controllers\BookingEngine\V1;
use App\Core\Mail\BookingInvoiceUpdateMail;
use App\Core\Service\BookingService;
use App\Core\Service\BookingRoomService;
use App\Core\Service\BookingRoomPaxService;
use App\Core\Service\BookingContactService;
use App\Core\Service\BookingPaymentService;
use App\Core\Service\ChannelManagerBookingService;
use App\Core\Service\PropertyBookingEngineSearchService;
use App\Core\Service\PropertyChannelService;
use App\Core\Service\PropertyRoomAvailabilityService;
use App\Core\Service\PropertyChannelMappingService;
use App\Core\Service\PropertyPaymentService;
use App\Core\Service\NewBookingMailService;
use App\Core\Service\NotificationService;
use App\Core\Service\ChannelManagerPropertyMappingService;
use App\Core\Service\PropertyAddonService;
use App\Core\Service\BookingAddonService;
use App\Core\Service\PropertyChannelCouponService;
use App\Core\Mail\BookingPropertyAddonUpdateMail;
use App\Core\Mail\BookingCancellationConfirmCodeMail;
use App\Core\Service\PropertyBookingEngineService;
use App\Core\Mail\CancelBookingMail;
use App\Core\Mail\BookingCancellationRequestMail;
use App\Core\Service\CurrencyService;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Config;
use Exception;
use App\Exceptions\ApiErrorException;
class BookingController extends BookingEngineBaseController
{
private $request;
private $newBookingMailService;
public function __construct(
Request $request,
BookingService $bookingService,
BookingRoomService $bookingRoomService,
BookingRoomPaxService $bookingRoomPaxService,
BookingContactService $bookingContactService,
BookingPaymentService $bookingPaymentService,
PropertyRoomAvailabilityService $propertyRoomAvailabilityService,
PropertyChannelMappingService $propertyChannelMappingService,
NewBookingMailService $newBookingMailService,
PropertyPaymentService $propertyPaymentService,
NotificationService $notificationService,
ChannelManagerBookingService $channelManagerBookingService,
ChannelManagerPropertyMappingService $channelManagerPropertyMappingService,
PropertyAddonService $propertyAddonService,
BookingAddonService $bookingAddonService,
PropertyChannelCouponService $propertyChannelCouponService,
PropertyBookingEngineSearchService $propertyBookingEngineSearchService,
PropertyChannelService $channelService,
PropertyBookingEngineService $propertyBookingEngineService,
CurrencyService $currencyService,
Mailer $mailer
)
{
$this->request = $request;
$this->bookingService = $bookingService;
$this->bookingRoomService = $bookingRoomService;
$this->bookingRoomPaxService = $bookingRoomPaxService;
$this->bookingContactService = $bookingContactService;
$this->bookingPaymentService = $bookingPaymentService;
$this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService;
$this->propertyChannelMappingService = $propertyChannelMappingService;
$this->propertyPaymentService = $propertyPaymentService;
$this->channelManagerBookingService = $channelManagerBookingService;
$this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService;
$this->channelId = $this->request->channelId;
$this->channelToken = $this->request->channelToken;
$this->bookingEngineToken = $this->request->bookingEngineToken;
$this->bookingEnginePropertyId = $this->request->bookingEnginePropertyId;
$this->newBookingMailService = $newBookingMailService;
$this->notificationService = $notificationService;
$this->propertyAddonService = $propertyAddonService;
$this->bookingAddonService = $bookingAddonService;
$this->propertyChannelCouponService = $propertyChannelCouponService;
$this->propertyBookingEngineSearchService = $propertyBookingEngineSearchService;
$this->channelService = $channelService;
$this->propertyBookingEngineService = $propertyBookingEngineService;
$this->currencyService = $currencyService;
$this->mailer = $mailer;
}
public function checkRoomAndCacheData($roomInfo, $searchCacheData)
{
$checkRoomAndCache = true;
$roomPricesCollect = collect($searchCacheData['roomPrices']);
foreach ($roomInfo as $roomKey => $room) {
$cachedSearchPriceKeys = $roomPricesCollect->where('occupancyCode', $room['occupancyCode'])->keys()->toArray();
if (!in_array($room['rateKey'], $cachedSearchPriceKeys)) {
$checkRoomAndCache = false;
continue;
}
}
return $checkRoomAndCache;
}
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' => 'date', 'condition' => '>=', 'value' => $param['checkIn']],
['field' => 'date', 'condition' => '<', 'value' => $param['checkOut']],
['field' => 'status', 'condition' => '=', 'value' => 1],
],
'with' => ['roomDetail.propertyRoomConnected'],
'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 getChannelPropertyDetail($channelId, $propertyId)
{
$response = ['status' => false, 'message' => ''];
try {
$requestParam = [
'criteria' => [
['field' => 'channel_id', 'condition' => '=', 'value' => $channelId],
['field' => 'property_id', 'condition' => '=', 'value' => $propertyId],
['field' => 'status', 'condition' => '=', 'value' => 1],
],
'with' => [
'property', 'channelAvailabilityType', 'channelBookingType', 'channelRoomPricingType',
'channelBookingPaymentType.paymentType', 'channel'
],
'firstRow' => true,
];
$getChannelProperty = $this->propertyChannelMappingService->select($requestParam);
$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 booking(Request $request)
{
$response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
try {
if (is_null($this->request->getContent())) {
throw new ApiErrorException(lang('Parameter Error.'));
}
$params = json_decode($this->request->getContent(), 1);
$roomInfo = $params['roomInfo'];
$contactInfo = $params['contactInfo'];
$searchKey = $params['searchKey'];
$couponCode = fillOnUndefined($params, 'couponCode');
$propertyId = $this->bookingEnginePropertyId;
$extraParam = $params['extraParam'] ?? null;
if (empty($propertyId)) {
$propertyId = $params['propertyId'];
}
//SearchKey Check Data
$searchCacheData = $this->getCacheDataWithSearchKey($searchKey);
if (empty($searchCacheData)) {
throw new ApiErrorException(lang('Cache data was expired.'));
}
$requestParams = $searchCacheData['requestParams'];
//$checkRoomAndCacheData Check Data
$checkRoomAndCacheData = $this->checkRoomAndCacheData($roomInfo, $searchCacheData);
if (!$checkRoomAndCacheData) {
throw new ApiErrorException(lang('Room rate keys are not matched.'));
}
$getChannelPropertyDetail = $this->getChannelPropertyDetail($this->channelId, $propertyId);
if (!$getChannelPropertyDetail['status']) {
throw new ApiErrorException(lang('Property and Channel are not matched.'));
}
$getChannelPropertyDetail = $getChannelPropertyDetail['data'];
$currencyCode = null;
$currencyCodes = [];
$paymentCodes = [];
$propertyIds = [];
$totalRoomsPrice = 0;
$roomAvailabilityKeyGroup = [];
$searchCacheRoomPrices = $searchCacheData['roomPrices'];
foreach ($roomInfo as $roomOccupancy => $room) {
$rateKeyCodeDecoded = $this->rateKeyCodeDecode($searchCacheRoomPrices[$room['rateKey']]['rateKeyCode']);
if ($rateKeyCodeDecoded['availabilityTypeId'] == 1) {
if (!isset($roomAvailabilityKeyGroup[$rateKeyCodeDecoded['availabilityTypeId']][$rateKeyCodeDecoded['roomId']]['count'])) {
$roomAvailabilityKeyGroup[$rateKeyCodeDecoded['availabilityTypeId']][$rateKeyCodeDecoded['roomId']]['count'] = 0;
}
$roomAvailabilityKeyGroup[$rateKeyCodeDecoded['availabilityTypeId']][$rateKeyCodeDecoded['roomId']]['count']++;
$roomAvailabilityKeyGroup[$rateKeyCodeDecoded['availabilityTypeId']][$rateKeyCodeDecoded['roomId']]['detail'] = $rateKeyCodeDecoded;
} else {
if (!isset($roomAvailabilityKeyGroup[$rateKeyCodeDecoded['availabilityTypeId']][$rateKeyCodeDecoded['roomId']][$rateKeyCodeDecoded['rateMappingId']]['count'])) {
$roomAvailabilityKeyGroup[$rateKeyCodeDecoded['availabilityTypeId']][$rateKeyCodeDecoded['roomId']][$rateKeyCodeDecoded['rateMappingId']]['count'] = 0;
}
$roomAvailabilityKeyGroup[$rateKeyCodeDecoded['availabilityTypeId']][$rateKeyCodeDecoded['roomId']][$rateKeyCodeDecoded['rateMappingId']]['count']++;
$roomAvailabilityKeyGroup[$rateKeyCodeDecoded['availabilityTypeId']][$rateKeyCodeDecoded['roomId']][$rateKeyCodeDecoded['rateMappingId']]['detail'] = $rateKeyCodeDecoded;
}
$totalRoomsPrice += $searchCacheData['roomPrices'][$room['rateKey']]['total'];
$currencyCodes[] = $searchCacheData['roomPrices'][$room['rateKey']]['currency'];
$paymentCodes[] = $searchCacheData['roomPrices'][$room['rateKey']]['bookingPaymentType']['code'];
$propertyIds[] = $rateKeyCodeDecoded['propertyId'];
}
$currencyCodes = array_unique($currencyCodes);
if (count($currencyCodes) != 1) {
throw new ApiErrorException(lang('Currency Code not matched'));
}
$currencyCode = reset($currencyCodes);
$paymentCodes = array_unique($paymentCodes);
if (count($paymentCodes) != 1) {
throw new ApiErrorException(lang('Payment Code not matched'));
}
$paymentCode = reset($paymentCodes);
if ($paymentCode != $params['paymentInfo']['paymentCode']) {
throw new ApiErrorException(lang('Payment Code and Payment Code Param not matched'));
}
$propertyIds = array_unique($propertyIds);
if (count($propertyIds) != 1) {
throw new ApiErrorException(lang('Property ID not matched'));
}
if (reset($propertyIds) != $propertyId) {
throw new ApiErrorException(lang('Property ID not matched'));
}
//dd($roomInfo);
$roomInfoCollect = collect($roomInfo)->groupBy('occupancyCode')->toArray();
$roomsByOccupancies = $this->getRoomsByOccupancies($requestParams['rooms']);
foreach ($roomsByOccupancies as $roomOccupancyKey => $roomsByOccupancy) {
if (!isset($roomInfoCollect[$roomOccupancyKey])) {
throw new ApiErrorException(lang('Room Occupancy Key not matched'));
}
if ($roomsByOccupancy['roomCount'] != count($roomInfoCollect[$roomOccupancyKey])) {
throw new ApiErrorException(lang('Room Occupancy Count and Request Room Occupancy Count not matched'));
}
}
$propertyRoomAndRoomRateAvailabilityParam = [
'property_id' => $propertyId,
'checkIn' => $searchCacheData['requestParams']['date']['checkIn'],
'checkOut' => $searchCacheData['requestParams']['date']['checkOut'],
];
$getPropertyRoomAndRoomRateAvailability = $this->getPropertyRoomAndRoomRateAvailability($propertyRoomAndRoomRateAvailabilityParam);
if ($getPropertyRoomAndRoomRateAvailability['status'] != 'success' || empty($getPropertyRoomAndRoomRateAvailability['data'])) {
throw new ApiErrorException(lang('Room or rooms not available.'));
}
$propertyRoomAndRoomRateAvailability = collect($getPropertyRoomAndRoomRateAvailability['data']);
$dateByDay = $this->getDateByDay($searchCacheData['requestParams']['date']);
$bookingAddon = [];
$totalAddonPrice = 0;
if (isset($params['addonInfo'])) {
$propertyChannelAddonCriteria = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => $getChannelPropertyDetail['property_id']],
['field' => 'channel_id', 'condition' => '=', 'value' => $getChannelPropertyDetail['channel_id']],
['field' => 'status', 'condition' => '=', 'value' => 1],
],
'with' => ['propertyAddon.fact']
];
$columns = ['id', 'property_id', 'channel_id', 'property_addon_id', 'amount', 'type', 'min_stay'];
$selectPropertyChannelAddon = $this->propertyAddonService->selectPropertyChannelAddon($propertyChannelAddonCriteria, $columns);
$propertyChannelAddon = [];
if ($selectPropertyChannelAddon['status'] == 'success') {
$propertyChannelAddon = $selectPropertyChannelAddon['data'];
}
if (empty($propertyChannelAddon)) {
throw new ApiErrorException(lang('No additional defined products found.'));
}
$propertyChannelAddonCollect = collect($propertyChannelAddon);
$propertyChannelAddonIds = $propertyChannelAddonCollect->pluck('id');
$propertyChannelAddonIds = $propertyChannelAddonIds ? $propertyChannelAddonIds->toArray() : [];
$nightOfStay = Carbon::parse($searchCacheData['requestParams']['date']['checkIn'])->diff(Carbon::parse($searchCacheData['requestParams']['date']['checkOut']))->days;
$addonInfo = collect($params['addonInfo']);
$addonInfoIds = $addonInfo->pluck('id');
$addonInfoIds = $addonInfoIds ? $addonInfoIds->toArray() : [];
if (count(array_intersect($addonInfoIds, $propertyChannelAddonIds)) != count($addonInfoIds)) {
throw new ApiErrorException(lang('Additional product values submitted do not match.'));
}
foreach ($params['addonInfo'] as $addonInfo) {
$selectedAddon = $propertyChannelAddonCollect->where('id', $addonInfo['id'])->first();
$addonInfoAttribute = null;
/*if (isset($addonInfo['attribute'])) {
foreach ($addonInfo['attribute'] as $addonAttribute) {
if (count(array_intersect_key($addonAttribute, $selectedAddon['property_addon']['attributeArray'])) != count($addonAttribute)) {
throw new ApiErrorException(lang('Additional product attribute values submitted do not match.'));
}
}
$addonInfoAttribute = $addonInfo['attribute'];
}*/
if (!is_null($selectedAddon['min_stay']) && $selectedAddon['min_stay'] <= $nightOfStay) {
$selectedAddon['amount'] = 0;
}
$bookingAddon[$selectedAddon['id']] = [
'property_addon_id' => $selectedAddon['property_addon_id'],
'property_channel_addon_id' => $selectedAddon['id'],
'count' => $addonInfo['count'],
'amount' => $selectedAddon['amount'],
'total' => moneyDoubleFormatDecimal($addonInfo['count'] * $selectedAddon['amount']),
'currency_code' => $currencyCode,
'attribute' => $addonInfoAttribute
];
$totalAddonPrice += $bookingAddon[$selectedAddon['id']]['total'];
}
}
$couponCodeData = [];
if (!is_null($couponCode)) {
$propertyChannelCouponCriteria = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => $getChannelPropertyDetail['property_id']],
['field' => 'channel_id', 'condition' => '=', 'value' => $getChannelPropertyDetail['channel_id']],
['field' => 'code', 'condition' => '=', 'value' => $couponCode],
['field' => 'start_date', 'condition' => '<=', 'value' => Carbon::now()->toDateString()],
['field' => 'end_date', 'condition' => '>=', 'value' => Carbon::now()->toDateString()],
['field' => 'status', 'condition' => '=', 'value' => 1],
],
'firstRow' => true
];
$propertyChannelCoupon = $this->propertyChannelCouponService->select($propertyChannelCouponCriteria);
if ($propertyChannelCoupon['status'] == 'success') {
$couponCodeData = $propertyChannelCoupon['data'];
}
//Reservation Date Check
$reservationDateCheck = true;
if (!is_null($couponCodeData['reservation_start_date']) && !is_null($couponCodeData['reservation_end_date'])) {
if (isset($searchCacheData['requestParams']['date']['checkIn']) && isset($searchCacheData['requestParams']['date']['checkOut'])) {
$reservationDateCheck = Carbon::parse($couponCodeData['reservation_start_date'])->lessThanOrEqualTo(Carbon::parse($searchCacheData['requestParams']['date']['checkIn']))
&& Carbon::parse($couponCodeData['reservation_end_date'])->greaterThanOrEqualTo(Carbon::parse($searchCacheData['requestParams']['date']['checkOut']));
}
}
if(!$reservationDateCheck) {
$couponCodeData = [];
}
}
if (!isset($params['bookingCode'])) {
//TODO: VALIDATORs
//1. Roominfo içindeki her bir occupancyCode ile paxes alar validatorden geçecek
//2. paxes için valdiatorden geçecek, eğer çocuk ise dt zorunlu, type, name, surname, citizen zorunlu
//3. contactInfo içi komple zorunlu validatorden geçecek
//4. searchKey, propertyId, contactInfo, roomInfo, paymentInfo zorunlu
//5. gelen ödeme tipi ile rate lerde ödmee tipleri kontrol edilecek
///BOOKING START
DB::beginTransaction();
$bookingCode = getCodeGenerate('BKG');
$bookingStatus = in_array($params['paymentInfo']['paymentCode'], ['HTL', 'CHN']) ? 1 : 2;
//1. Booking
//2. PreBooking
$totalRoomsPriceBeforeDiscount = $totalRoomsPrice;
$bookingDiscountAmount = 0;
if (!empty($couponCodeData)) {
if ($couponCodeData['type'] == 'PER') {
$bookingDiscountAmount = ($totalRoomsPriceBeforeDiscount * $couponCodeData['value'] / 100);
} elseif ($couponCodeData['type'] == 'FIX') {
$bookingDiscountAmount = $couponCodeData['value'];
}
$totalRoomsPrice = $totalRoomsPrice - $bookingDiscountAmount;
}
$bookingTotalAmount = $totalRoomsPrice + $totalAddonPrice;
//Wholesaler MARKUP
$channelPropertyMarkup = [];
if (in_array($getChannelPropertyDetail['channel']['channel_category_id'], [7])) {
if (!is_null($getChannelPropertyDetail['markup']) && !empty($getChannelPropertyDetail['channel']['default_currency'])) {
$lastExchangeRate = 1;
if ($getChannelPropertyDetail['currency_code'] != $getChannelPropertyDetail['channel']['default_currency']) {
$lastExchangeRate = $this->currencyService->lastExchangeRate($getChannelPropertyDetail['currency_code'], $getChannelPropertyDetail['channel']['default_currency']);
if ($lastExchangeRate['status'] == 'success') {
$lastExchangeRate = $lastExchangeRate['data'];
}
}
$connectedChannelAction = !is_null($getChannelPropertyDetail['connected_channel_action']) ? json_decode($getChannelPropertyDetail['connected_channel_action'], 1) : null;
$channelPropertyMarkup = [
'channel_discount' => !empty($connectedChannelAction) && isset($connectedChannelAction['value']) ? $connectedChannelAction['value'] : null,
'channel_markup' => $getChannelPropertyDetail['markup'],
'channel_currency_code' => $getChannelPropertyDetail['channel']['default_currency'],
'channel_currency_exchange' => $lastExchangeRate,
];
}
}
//Wholesaler MARKUP
$bannedCharacters = ['<','>', ';', '(', ')', '=', ':', 'shell_exec'];
$bannedCheckParameter = ['name', 'surname', 'phone_number', 'email', 'note'];
$bookingCreateParam = [
'property_id' => $propertyId,
'channel_id' => $this->channelId,
'booking_code' => $bookingCode,
'search_key' => $params['searchKey'],
'checkin_date' => $searchCacheData['requestParams']['date']['checkIn'],
'checkout_date' => $searchCacheData['requestParams']['date']['checkOut'],
'rooms' => json_encode($searchCacheData['requestParams']['rooms']),
'payment_type_code' => $params['paymentInfo']['paymentCode'],
'room_amount' => $totalRoomsPriceBeforeDiscount,
'addon_amount' => $totalAddonPrice,
'discount_amount' => $bookingDiscountAmount,
'total' => $bookingTotalAmount,
'currency_code' => $currencyCode,
'channel_token' => $this->channelToken,
'booking_engine_token' => $this->bookingEngineToken,
'status' => $bookingStatus,
'channel_discount' => fillOnUndefined($channelPropertyMarkup, 'channel_discount'),
'channel_markup' => fillOnUndefined($channelPropertyMarkup, 'channel_markup'),
'channel_currency_code' => fillOnUndefined($channelPropertyMarkup, 'channel_currency_code'),
'channel_currency_exchange' => fillOnUndefined($channelPropertyMarkup, 'channel_currency_exchange'),
'extra_param' => !empty($extraParam) ? json_encode($extraParam) : null,
'coupon_code' => fillOnUndefined($couponCodeData,'code')
//Burada sor sat için bişey gelebilir
];
$bookingCreate = $this->bookingService->create($bookingCreateParam);
//$bookingCreate['status'] = 'success';
//$bookingCreate['data']['id'] = 16;
if ($bookingCreate['status'] != 'success') {
throw new ApiErrorException(lang('Booking could not be made'));
}
//INSERT CONTACT DATA
$bookingContactCreateParam = [
'booking_id' => $bookingCreate['data']['id'],
'name' => $params['contactInfo']['name'],
'surname' => $params['contactInfo']['surName'],
'phone_code' => $params['contactInfo']['phoneCode'],
'phone_number' => $params['contactInfo']['phoneNumber'],
'email' => $params['contactInfo']['email'],
'note' => fillOnUndefined($params['contactInfo'], 'note'),
'language_code' => fillOnUndefined($params['contactInfo'], 'language_code', 'en'),
'invoice_request' => fillOnUndefined($params['contactInfo'], 'invoice_request') ? 1 : null,
'status' => 1
];
foreach ($bannedCheckParameter as $checkParameter) {
if (isset($bookingContactCreateParam[$checkParameter])) {
foreach ($bannedCharacters as $bannedCharacter) {
if (str_contains($bookingContactCreateParam[$checkParameter], $bannedCharacter)) {
throw new ApiErrorException(lang('Booking could not be made! - Contact'));
}
}
}
}
$bookingContactCreate = $this->bookingContactService->create($bookingContactCreateParam);
//$bookingContactCreate['status'] = 'success';
if ($bookingContactCreate['status'] != 'success') {
throw new ApiErrorException(lang('Booking Contact could not be made'));
}
//INSERT ADDON DATA
foreach ($bookingAddon as $propertyAddonId => $propertyAddon) {
$bookingAddonCreateParam = [
'booking_id' => $bookingCreate['data']['id'],
'property_channel_addon_id' => $propertyAddon['property_channel_addon_id'],
'count' => $propertyAddon['count'],
'amount' => $propertyAddon['amount'],
'total' => $propertyAddon['total'],
'currency_code' => $propertyAddon['currency_code'],
'attribute' => !empty($propertyAddon['attribute']) ? json_encode($propertyAddon['attribute']) : null,
];
$bookingAddonCreate = $this->bookingAddonService->create($bookingAddonCreateParam);
//$bookingRoomCreate['status'] = 'success';
//$bookingRoomCreate['data']['id'] = 1;
if ($bookingAddonCreate['status'] != 'success') {
throw new ApiErrorException(lang('Booking Addon could not be made'));
}
}
//INSERT ROOM DATA
foreach ($roomInfo as $roomOrder => $room) {
$rateKeyCodeDecoded = $this->rateKeyCodeDecode($searchCacheRoomPrices[$room['rateKey']]['rateKeyCode']);
$roomPrice = $searchCacheRoomPrices[$room['rateKey']]['total'];
$roomPriceBeforeDiscount = $searchCacheRoomPrices[$room['rateKey']]['total'];
$roomDiscountAmount = 0;
if (!empty($couponCodeData)) {
if ($couponCodeData['type'] == 'PER') {
$roomDiscountAmount = ($roomPriceBeforeDiscount * $couponCodeData['value'] / 100);
} elseif ($couponCodeData['type'] == 'FIX') {
$roomDiscountAmount = $couponCodeData['value'];
}
$roomPrice = $roomPriceBeforeDiscount - $roomDiscountAmount;
}
$bookingRoomCreateParam = [
'booking_id' => $bookingCreate['data']['id'],
'room_order_number' => ($roomOrder + 1),
'occupancy_code' => $room['occupancyCode'],
'checkin_date' => $searchCacheData['requestParams']['date']['checkIn'],
'checkout_date' => $searchCacheData['requestParams']['date']['checkOut'],
'rate_key' => $room['rateKey'],
'rate_key_code' => $searchCacheRoomPrices[$room['rateKey']]['rateKeyCode'],
'availability_id' => $rateKeyCodeDecoded['availabilityTypeId'],
'availability_code' => $searchCacheRoomPrices[$room['rateKey']]['availability']['code'],
'room_id' => $rateKeyCodeDecoded['roomId'],
'room_name' => $searchCacheRoomPrices[$room['rateKey']]['room']['name'],
'room_rate_mapping_id' => $rateKeyCodeDecoded['rateMappingId'],
'room_rate_name' => $searchCacheRoomPrices[$room['rateKey']]['rate']['name'],
'cancellation_policy' => json_encode($searchCacheRoomPrices[$room['rateKey']]['cancellationPolicy']),
'payment_type_code' => $searchCacheRoomPrices[$room['rateKey']]['bookingPaymentType']['code'],
'daily_amount' => json_encode($searchCacheRoomPrices[$room['rateKey']]['policyPriceDaily']),
'rate_detail' => json_encode($searchCacheRoomPrices[$room['rateKey']]),
'amount' => $roomPriceBeforeDiscount,
'discount_amount' => $roomDiscountAmount,
'total' => $roomPrice,
'currency_code' => $searchCacheRoomPrices[$room['rateKey']]['currency'],
'status' => 1
];
$bookingRoomCreate = $this->bookingRoomService->create($bookingRoomCreateParam);
//$bookingRoomCreate['status'] = 'success';
//$bookingRoomCreate['data']['id'] = 1;
if ($bookingRoomCreate['status'] != 'success') {
throw new ApiErrorException(lang('Booking Room could not be made'));
}
foreach ($room['paxes'] as $roomPax) {
$bookingRoomPaxParam = [
'booking_id' => $bookingCreate['data']['id'],
'booking_room_id' => $bookingRoomCreate['data']['id'],
'type' => fillOnUndefined($roomPax, 'type'),
'name' => fillOnUndefined($roomPax, 'name'),
'surname' => fillOnUndefined($roomPax, 'surName'),
'gender' => fillOnUndefined($roomPax, 'gender'),
'citizen' => fillOnUndefined($roomPax, 'citizen'),
'birth_date' => fillOnUndefined($roomPax, 'birthDate'),
];
foreach ($bannedCheckParameter as $checkParameter) {
if (isset($bookingRoomPaxParam[$checkParameter])) {
foreach ($bannedCharacters as $bannedCharacter) {
if (str_contains($bookingRoomPaxParam[$checkParameter], $bannedCharacter)) {
throw new ApiErrorException(lang('Booking could not be made! - Pax'));
}
}
}
}
$bookingRoomPaxCreate = $this->bookingRoomPaxService->create($bookingRoomPaxParam);
//$bookingRoomCreate['status'] = 'success';
//$bookingRoomCreate['data']['id'] = 1;
if ($bookingRoomPaxCreate['status'] != 'success') {
throw new ApiErrorException(lang('Booking Room Pax could not be made'));
}
}
}
} else {
$bookingDetailParam = [
'criteria' => [
['field' => 'booking_code', 'condition' => '=', 'value' => $params['bookingCode']]
],
'with' => ['bookingPayment', 'bookingRoom', 'bookingAddon'],
'firstRow' => true
];
$bookingCreate = $this->bookingService->select($bookingDetailParam);
if ($bookingCreate['status'] != 'success' || empty($bookingCreate['data'])) {
throw new ApiErrorException(lang('Booking not found'));
}
$bookingDetail = $bookingCreate['data'];
//DELETE OLD ADDON DATA
if (!empty(pickItemFromArray('id', $bookingDetail['booking_addon']))) {
$this->bookingAddonService->delete(pickItemFromArray('id', $bookingDetail['booking_addon']));
}
//INSERT ADDON DATA
foreach ($bookingAddon as $propertyAddonId => $propertyAddon) {
$bookingAddonCreateParam = [
'booking_id' => $bookingDetail['id'],
'property_channel_addon_id' => $propertyAddon['property_channel_addon_id'],
'count' => $propertyAddon['count'],
'amount' => $propertyAddon['amount'],
'total' => $propertyAddon['total'],
'currency_code' => $propertyAddon['currency_code'],
'attribute' => !empty($propertyAddon['attribute']) ? json_encode($propertyAddon['attribute']) : null,
];
$bookingAddonCreate = $this->bookingAddonService->create($bookingAddonCreateParam);
if ($bookingAddonCreate['status'] != 'success') {
throw new ApiErrorException(lang('Booking Addon could not be made'));
}
}
$bookingCode = $bookingCreate['data']['booking_code'];
$bookingStatus = in_array($params['paymentInfo']['paymentCode'], ['HTL', 'CHN']) ? 1 : 2;
$totalRoomsPriceBeforeDiscount = $totalRoomsPrice;
$bookingDiscountAmount = 0;
if (!empty($couponCodeData)) {
if ($couponCodeData['type'] == 'PER') {
$bookingDiscountAmount = ($totalRoomsPriceBeforeDiscount * $couponCodeData['value'] / 100);
} elseif ($couponCodeData['type'] == 'FIX') {
$bookingDiscountAmount = $couponCodeData['value'];
}
$totalRoomsPrice = $totalRoomsPrice - $bookingDiscountAmount;
}
$bookingTotalAmount = $totalRoomsPrice + $totalAddonPrice;
$bookingDetailUpdate = [
'room_amount' => $totalRoomsPriceBeforeDiscount,
'addon_amount' => $totalAddonPrice,
'total' => $bookingTotalAmount,
];
$this->bookingService->update($bookingDetail['id'], $bookingDetailUpdate);
}
//Eğer kredi kartı ise
$initializePayment = [];
if (!in_array($params['paymentInfo']['paymentCode'], ['HTL', 'CHN'])) {
$isDirectPayment = true;
//TODO: validator
$params['paymentInfo']['creditCard']['cardExpireMonth'] = strlen($params['paymentInfo']['creditCard']['cardExpireMonth']) == 2 ? $params['paymentInfo']['creditCard']['cardExpireMonth'] : str_pad($params['paymentInfo']['creditCard']['cardExpireMonth'], 2, 0, STR_PAD_LEFT);
$initializePaymentParam = [
'propertyId' => $propertyId,
'orderId' => $bookingCode,
'installment' => isset($params['paymentInfo']['creditCard']['installment']) ? $params['paymentInfo']['creditCard']['installment'] : 1,
'amount' => (double)$bookingTotalAmount,
'currency' => $currencyCode,
'type' => 'BKG',
'responseUrl' => $params['paymentInfo']['responseUrl'],
'creditCard' => [
'name' => $params['paymentInfo']['creditCard']['cardHolder'],
'number' => $params['paymentInfo']['creditCard']['cardNumber'],
'month' => $params['paymentInfo']['creditCard']['cardExpireMonth'],
'year' => $params['paymentInfo']['creditCard']['cardExpireYear'],
'cvv' => $params['paymentInfo']['creditCard']['cardCvv'],
]
];
$initializePayment = $this->propertyPaymentService->initializePayment($initializePaymentParam);
if (!$initializePayment['status']) {
Log::error($initializePayment);
throw new ApiErrorException(lang('Initialize Payment could not be made'));
}
if (isset($initializePayment['data']['redirectUrl'])) {
$isDirectPayment = false;
}
}
//Eğer direk ödeme ile para çekilip işlem yapılmış ise
if (isset($isDirectPayment) && $isDirectPayment) {
$bookingStatus = 1;
$this->bookingService->update($bookingCreate['data']['id'], ['status' => 1]);
}
$bookingPaymentCreateParam = [
'booking_id' => $bookingCreate['data']['id'],
'payment_code' => isset($initializePayment['data']['paymentCode']) ? $initializePayment['data']['paymentCode'] : null,
'payment_type_code' => $params['paymentInfo']['paymentCode'],
'total' => in_array($params['paymentInfo']['paymentCode'], ['HTL', 'CHN']) || ($bookingStatus == 1 && $isDirectPayment) ? $bookingTotalAmount : null,
'currency_code' => in_array($params['paymentInfo']['paymentCode'], ['HTL', 'CHN']) || ($bookingStatus == 1 && $isDirectPayment) ? $currencyCode : null,
'status' => (isset($isDirectPayment) && $isDirectPayment) ? 1 : 2
];
$bookingPaymentCreate = $this->bookingPaymentService->create($bookingPaymentCreateParam);
//$bookingContactCreate['status'] = 'success';
if ($bookingPaymentCreate['status'] != 'success') {
throw new ApiErrorException(lang('Booking Payment could not be made'));
}
//Buradan eksiltme transaction ları başlatılacak ki ok ise düşsün
$roomAvailabilityStatus = true;
foreach ($roomAvailabilityKeyGroup as $roomAvailabilityKey => $roomAvailability) {
if ($roomAvailabilityKey == 1) {
foreach ($roomAvailability as $roomKey => $room) {
foreach ($dateByDay as $day) {
$roomAndRoomRateAvailability = $propertyRoomAndRoomRateAvailability
->where('date', $day)
->where('property_room_id', $room['detail']['roomId'])
->where('availability_type_id', $room['detail']['availabilityTypeId'])
->where('availability', '>=', $room['count'])
->where('status', 1)
->first();
if (is_null($roomAndRoomRateAvailability)) {
$roomAvailabilityStatus = false;
break 3;
}
//Kontenjan Azaltma
//Otelde öde ise düşürülecek kontenjan
if (in_array($params['paymentInfo']['paymentCode'], ['HTL', 'CHN']) || $isDirectPayment) {
$roomNewAvailability = $roomAndRoomRateAvailability['availability'] - $room['count'];
$this->propertyRoomAvailabilityService->update($roomAndRoomRateAvailability['id'], ['availability' => $roomNewAvailability]);
//Connected Room Case
if ($roomAndRoomRateAvailability['room_detail']['is_connected_room'] && $roomAndRoomRateAvailability['room_detail']['is_connected_room_availability']) {
foreach ($roomAndRoomRateAvailability['room_detail']['property_room_connected'] as $connectedRoom) {
$roomAndRoomRateAvailabilityConnected = $propertyRoomAndRoomRateAvailability
->where('date', $day)
->where('property_room_id', $connectedRoom['connected_room_id'])
->where('availability_type_id', $room['detail']['availabilityTypeId'])
->where('availability', '>=', $room['count'])
->where('status', 1)
->first();
if (is_null($roomAndRoomRateAvailabilityConnected)) {
continue;
}
$roomNewAvailabilityConnected = $roomAndRoomRateAvailabilityConnected['availability'] - $room['count'];
$this->propertyRoomAvailabilityService->update($roomAndRoomRateAvailabilityConnected['id'], ['availability' => $roomNewAvailabilityConnected]);
}
}
//Connected Room Case
}
}
}
//Connected Room Case
$roomAvailabilityUpdateForConnectedRoomParams = [
'property_id' => $propertyId,
'channel_id' => $this->channelId,
'availability_type_id' => [$roomAvailabilityKey],
'startDate' => reset($dateByDay),
'endDate' => last($dateByDay),
'user_id' => fillOnUndefined($params, "user_id", 0)
];
$this->propertyRoomAvailabilityService->roomAvailabilityUpdateForConnectedRooms($roomAvailabilityUpdateForConnectedRoomParams);
//Connected Room Case
} else {
foreach ($roomAvailability as $roomKey => $roomRateMapping) {
foreach ($roomRateMapping as $roomRateMappingKey => $roomRate) {
foreach ($dateByDay as $day) {
$roomAndRoomRateAvailability = $propertyRoomAndRoomRateAvailability
->where('date', $day)
->where('property_room_id', $roomRate['detail']['roomId'])
->where('availability_type_id', $roomRate['detail']['availabilityTypeId'])
->where('room_rate_mapping_id', $roomRate['detail']['rateMappingId'])
->where('channel_id', $roomRate['detail']['channelId'])
->where('availability', '>=', $roomRate['count'])
->where('status', 1)
->first();
if (is_null($roomAndRoomRateAvailability)) {
$roomAvailabilityStatus = false;
break 4;
}
//Kontenjan Azaltma
//Otelde öde ise düşürülecek kontenjan
if (in_array($params['paymentInfo']['paymentCode'], ['HTL', 'CHN']) || $isDirectPayment) {
//TODO: Garantili kontenjan ve limitlide havuzdan da azaltılmalı
$roomNewAvailability = $roomAndRoomRateAvailability['availability'] - $roomRate['count'];
$this->propertyRoomAvailabilityService->update($roomAndRoomRateAvailability['id'], ['availability' => $roomNewAvailability]);
}
}
}
}
}
}
if (!$roomAvailabilityStatus) {
throw new ApiErrorException(lang('One or more of the requested rooms are not available'));
}
//BOOKING FINISHED
$responseData = [
'bookingCode' => $bookingCode,
'total' => $bookingTotalAmount,
'currency' => $currencyCode,
'bookingStatus' => $bookingStatus,
'bookingStatusText' => $bookingStatus == 1 ? 'Booking' : 'PreBooking',
];
//TODO: Eğer Booking yapılmış ise
if (in_array($params['paymentInfo']['paymentCode'], ['HTL', 'CHN']) || ($bookingStatus == 1 && isset($isDirectPayment) && $isDirectPayment)) {
$mailParams = ['booking_id' => $bookingCreate['data']['id']];
$this->newBookingMailService->process($mailParams);
//PUSH NOTIFICATION
$newBookingNotificationParam = ['booking_id' => $bookingCreate['data']['id']];
$this->notificationService->sendNewBookingNotification($newBookingNotificationParam);
//PUSH NOTIFICATION
//PUSH CHANNEL MANAGER QUEUE
//if ($bookingCreate['data']['channel_id'] == 1) {
$channelManagerPropertyMappingCriteria = [
'criteria' =>
[
['field' => 'property_id', 'condition' => '=', 'value' => $bookingCreate['data']['property_id']],
//['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'])) {
foreach ($channelManagerPropertyMapping['data'] as $channelPropertyData) {
//Trivago
if ($channelPropertyData['channel_manager_id'] == 11 && !isset($params['extraParam']['trv_reference'])) {
continue;
}
//Hyperguest
if ($channelPropertyData['channel_manager_id'] != 10 && !is_null($channelPropertyData['channel_manager_property_id'])) {
continue;
}
if(in_array($channelPropertyData['channel_manager_id'],[13])) {
continue;
}
$channelManagerBookingCreateParam = [
'property_id' => $bookingCreate['data']['property_id'],
'booking_id' => $bookingCreate['data']['id'],
'channel_manager_id' => $channelPropertyData['channel_manager_id'],
'type' => 'Booking',
];
$channelManagerBookingCreate = $this->channelManagerBookingService->create($channelManagerBookingCreateParam);
}
}
//}
//PUSH CHANNEL MANAGER QUEUE
}
//Eğer kredi kartı ise ve ödeme başlamış ise
if (!empty($initializePayment)) {
$responseData['paymentCode'] = $initializePayment['data']['paymentCode'];
if (isset($initializePayment['data']['redirectUrl'])) {
$responseData['redirectUrl'] = $initializePayment['data']['redirectUrl'];
}
}
//Pay at Hotel - Info Store
if (in_array($params['paymentInfo']['paymentCode'], ['HTL', 'CHN']) && isset($params['paymentInfo']['creditCard']) && !empty($params['paymentInfo']['creditCard']['cardNumber'])) {
$creditCard = $params['paymentInfo']['creditCard'];
$cardNumber = $creditCard['cardNumber'];
$cardLengthSize = ceil(strlen($cardNumber) / 4);
$cardNumberParse = [];
for ($i = 0; $i < $cardLengthSize; $i++) {
$cardNumberParse['cc'][] = Crypt::encrypt(mb_substr($cardNumber, $i * 4, 4));
}
$cardNumberParse['cm'] = Crypt::encrypt($creditCard['cardExpireMonth']);
$cardNumberParse['cy'] = Crypt::encrypt(mb_substr($creditCard['cardExpireYear'], -2, 2));
$cardNumberParse['cv'] = Crypt::encrypt($creditCard['cardCvv']);
$cardNumberParse['ch'] = Crypt::encrypt($creditCard['cardHolder']);
foreach ($cardNumberParse as $type => $value) {
$bookingPaymentDataCreateParam = [];
if ($type == 'cc') {
foreach ($value as $cardValue) {
$bookingPaymentDataCreateParam = [
'booking_id' => $bookingCreate['data']['id'],
'type' => $type,
'data' => $cardValue,
];
$this->bookingPaymentService->createPaymentData($bookingPaymentDataCreateParam);
}
} else {
$bookingPaymentDataCreateParam = [
'booking_id' => $bookingCreate['data']['id'],
'type' => $type,
'data' => $value,
];
$this->bookingPaymentService->createPaymentData($bookingPaymentDataCreateParam);
}
}
}
//Pay at Hotel - Info Store
//Booking Engine Search Update
$bookingEngineSearchParam = [
'criteria' => [
['field' => 'search_key', 'condition' => '=', 'value' => $params['searchKey']],
['field' => 'status', 'condition' => '=', 'value' => 1],
],
'firstRow' => true
];
$bookingEngineSearch = $this->propertyBookingEngineSearchService->select($bookingEngineSearchParam);
if ($bookingEngineSearch['status'] == 'success' && !empty($bookingEngineSearch['data'])) {
$bookingEngineSearchUpdateParam = [
'booking_code' => $bookingCode,
'amount' => $bookingTotalAmount,
'status' => 2,
];
if (in_array($params['paymentInfo']['paymentCode'], ['HTL', 'CHN']) || ($bookingStatus == 1 && isset($isDirectPayment) && $isDirectPayment)) {
$bookingEngineSearchUpdateParam['status'] = 3;
}
$bookingEngineSearchUpdate = $this->propertyBookingEngineSearchService->update($bookingEngineSearch['data']['id'], $bookingEngineSearchUpdateParam);
}
$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;
}
if ($response['status']) {
DB::commit();
} else {
DB::rollBack();
}
return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']);
}
public function bookingConfirm(Request $request)
{
$response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
try {
if (is_null($this->request->getContent())) {
throw new ApiErrorException(lang('Parameter Error.'));
}
$params = json_decode($this->request->getContent(), 1);
$bookingCode = $params['bookingCode'];
$paymentCode = $params['paymentCode'];
$bookingDetailParam = [
'criteria' => [
['field' => 'booking_code', 'condition' => '=', 'value' => $bookingCode]
],
'with' => ['property', 'bookingPayment', 'bookingRoom'],
'firstRow' => true
];
$bookingDetail = $this->bookingService->select($bookingDetailParam);
if ($bookingDetail['status'] != 'success' || empty($bookingDetail['data'])) {
throw new ApiErrorException(lang('Booking not found'));
}
$bookingDetail = $bookingDetail['data'];
$paymentDetailParam = [
'criteria' => [
['field' => 'code', 'condition' => '=', 'value' => $paymentCode]
],
'firstRow' => true
];
$paymentDetail = $this->propertyPaymentService->selectPaymentTransaction($paymentDetailParam);
if ($paymentDetail['status'] != 'success' || empty($paymentDetail['data'])) {
throw new ApiErrorException(lang('Payment not found'));
}
$paymentDetail = $paymentDetail['data'];
if ($paymentDetail['status'] != 1) {
throw new ApiErrorException('Payment not confirmed');
}
if ($bookingDetail['status'] == 1) {
throw new ApiErrorException('Previously approved transaction');
}
DB::beginTransaction();
//Booking Confirm
$this->bookingService->update($bookingDetail['id'], ['status' => 1]);
//Availability Change
if ($bookingDetail['status'] == 2) {
$propertyRoomAndRoomRateAvailabilityParam = [
'property_id' => $bookingDetail['property_id'],
'checkIn' => $bookingDetail['checkin_date'],
'checkOut' => $bookingDetail['checkout_date'],
];
$getPropertyRoomAndRoomRateAvailability = $this->getPropertyRoomAndRoomRateAvailability($propertyRoomAndRoomRateAvailabilityParam);
if ($getPropertyRoomAndRoomRateAvailability['status'] != 'success' || empty($getPropertyRoomAndRoomRateAvailability['data'])) {
throw new ApiErrorException(lang('Room or rooms not available.'));
}
$propertyRoomAndRoomRateAvailability = collect($getPropertyRoomAndRoomRateAvailability['data']);
$roomAvailabilityStatus = true;
foreach ($bookingDetail['booking_room'] as $room) {
$dateByDay = $this->getDateByDay(['checkIn' => $room['checkin_date'], 'checkOut' => $room['checkout_date']]);
foreach ($dateByDay as $day) {
$roomRateDetail = json_decode($room['rate_detail'], 1);
$rateKeyCodeDecoded = $this->rateKeyCodeDecode($roomRateDetail['rateKeyCode']);
if ($rateKeyCodeDecoded['availabilityTypeId'] == 1) {
$roomAndRoomRateAvailability = $propertyRoomAndRoomRateAvailability
->where('date', $day)
->where('property_room_id', $rateKeyCodeDecoded['roomId'])
->where('availability_type_id', $rateKeyCodeDecoded['availabilityTypeId'])
->where('availability', '>=', 1)
->where('status', 1)
->first();
if (is_null($roomAndRoomRateAvailability)) {
$roomAvailabilityStatus = false;
break 2;
}
//Kontenjan Azaltma
$roomNewAvailability = $roomAndRoomRateAvailability['availability'] - 1;
$this->propertyRoomAvailabilityService->update($roomAndRoomRateAvailability['id'], ['availability' => $roomNewAvailability]);
//Connected Room Case
if ($roomAndRoomRateAvailability['room_detail']['is_connected_room'] && $roomAndRoomRateAvailability['room_detail']['is_connected_room_availability']) {
foreach ($roomAndRoomRateAvailability['room_detail']['property_room_connected'] as $connectedRoom) {
$roomAndRoomRateAvailabilityConnected = $propertyRoomAndRoomRateAvailability
->where('date', $day)
->where('property_room_id', $connectedRoom['connected_room_id'])
->where('availability_type_id', $rateKeyCodeDecoded['availabilityTypeId'])
->where('availability', '>=', 1)
->where('status', 1)
->first();
if (is_null($roomAndRoomRateAvailabilityConnected)) {
continue;
}
$roomNewAvailabilityConnected = $roomAndRoomRateAvailabilityConnected['availability'] - 1;
$this->propertyRoomAvailabilityService->update($roomAndRoomRateAvailabilityConnected['id'], ['availability' => $roomNewAvailabilityConnected]);
}
}
//Connected Room Case
} else {
$roomAndRoomRateAvailability = $propertyRoomAndRoomRateAvailability
->where('date', $day)
->where('property_room_id', $rateKeyCodeDecoded['roomId'])
->where('availability_type_id', $rateKeyCodeDecoded['availabilityTypeId'])
->where('room_rate_mapping_id', $rateKeyCodeDecoded['rateMappingId'])
->where('channel_id', $rateKeyCodeDecoded['channelId'])
->where('availability', '>=', 1)
->where('status', 1)
->first();
if (is_null($roomAndRoomRateAvailability)) {
$roomAvailabilityStatus = false;
break 2;
}
//TODO: Garantili kontenjan ve limitlide havuzdan da azaltılmalı
//Kontenjan Azaltma
$roomNewAvailability = $roomAndRoomRateAvailability['availability'] - 1;
$this->propertyRoomAvailabilityService->update($roomAndRoomRateAvailability['id'], ['availability' => $roomNewAvailability]);
}
}
}
//Connected Room Case
$roomAvailabilityUpdateForConnectedRoomParams = [
'property_id' => $bookingDetail['property_id'],
'channel_id' => $bookingDetail['channel_id'],
'availability_type_id' => [1],
'startDate' => reset($dateByDay),
'endDate' => last($dateByDay),
'user_id' => fillOnUndefined($params, "user_id", 0)
];
$this->propertyRoomAvailabilityService->roomAvailabilityUpdateForConnectedRooms($roomAvailabilityUpdateForConnectedRoomParams);
//Connected Room Case
if (!$roomAvailabilityStatus) {
throw new ApiErrorException(lang('One or more of the requested rooms are not available'));
}
}
//Booking Payment Update
$bookingPaymentUpdateParam = [
'status' => 1,
'total' => $paymentDetail['amount'],
'currency_code' => $paymentDetail['currency'],
];
$this->bookingPaymentService->update($bookingDetail['booking_payment']['id'], $bookingPaymentUpdateParam);
$mailParams = ['booking_id' => $bookingDetail['id']];
$this->newBookingMailService->process($mailParams);
//PUSH NOTIFICATION
$newBookingNotificationParam = ['booking_id' => $bookingDetail['id']];
$this->notificationService->sendNewBookingNotification($newBookingNotificationParam);
//PUSH NOTIFICATION
//PUSH CHANNEL MANAGER QUEUE
//if ($bookingDetail['channel_id'] == 1) {
$channelManagerPropertyMappingCriteria = [
'criteria' =>
[
['field' => 'property_id', 'condition' => '=', 'value' => $bookingDetail['property_id']],
//['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'])) {
foreach ($channelManagerPropertyMapping['data'] as $channelPropertyData) {
//Trivago
if ($channelPropertyData['channel_manager_id'] == 11 && !isset($params['extraParam']['trv_reference'])) {
continue;
}
//Hyperguest
if ($channelPropertyData['channel_manager_id'] != 10 && !is_null($channelPropertyData['channel_manager_property_id'])) {
continue;
}
//Yandex
if(in_array($channelPropertyData['channel_manager_id'],[13])) {
continue;
}
$channelManagerBookingCreateParam = [
'property_id' => $bookingDetail['property_id'],
'booking_id' => $bookingDetail['id'],
'channel_manager_id' => $channelPropertyData['channel_manager_id'],
'type' => 'Booking',
];
$channelManagerBookingCreate = $this->channelManagerBookingService->create($channelManagerBookingCreateParam);
}
}
//}
//PUSH CHANNEL MANAGER QUEUE
//Booking Engine Search Update
//if ($bookingDetail['channel_id'] == 1) {
$bookingEngineSearchParam = [
'criteria' => [
['field' => 'search_key', 'condition' => '=', 'value' => $bookingDetail['search_key']],
['field' => 'status', 'condition' => '=', 'value' => 2],
],
'firstRow' => true
];
$bookingEngineSearch = $this->propertyBookingEngineSearchService->select($bookingEngineSearchParam);
if ($bookingEngineSearch['status'] == 'success' && !empty($bookingEngineSearch['data'])) {
$bookingEngineSearchUpdateParam = [
'booking_code' => $bookingDetail['booking_code'],
'amount' => $bookingDetail['total'],
'currency_code' => $bookingDetail['currency_code'],
'status' => 3,
];
$bookingEngineSearchUpdate = $this->propertyBookingEngineSearchService->update($bookingEngineSearch['data']['id'], $bookingEngineSearchUpdateParam);
}
//}
$response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => []];
} 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;
}
if ($response['status']) {
DB::commit();
} else {
DB::rollBack();
}
return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']);
}
public function bookingDetail(Request $request, $bookingCode)
{
$response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
try {
$bookingDetailParam = [
'criteria' => [
['field' => 'booking_code', 'condition' => '=', 'value' => $bookingCode],
//['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId],//TODO: Kontrol gerekli!
],
'with' => [
'bookingPayment.paymentTypeCode', 'bookingRoom.roomPax.paxCountry', 'bookingRoom.roomRateMapping.propertyRoomRate', 'bookingRoom.roomRateMapping.propertyRoom', 'bookingContact',
'bookingProperty.propertyContact', 'bookingProperty.propertyBrand', 'bookingProperty.propertyAdditionalInfos.propertyAdditionalInfoKey',
'bookingAddon.propertyChannelAddon.propertyAddon.fact', 'bookingChannel','propertyChannelMapping.channelBookingPaymentType',
'bookingRoom.roomRateMapping.propertyRoom.propertyRoomBedGroup.propertyRoomBedType', 'bookingRoom.roomRateMapping.propertyRoom.smokingPreference.propertyFact',
'bookingRoom.propertyRoomBed', 'bookingRoom.smokingFact','propertyBookingEngineSearch'
],
'firstRow' => true
];
$bookingDetail = $this->bookingService->select($bookingDetailParam);
if ($bookingDetail['status'] != 'success' || empty($bookingDetail['data'])) {
throw new ApiErrorException(lang('Booking not found'));
}
$bookingDetail['data']['booking_property']['checkin_time'] = '14:00';
$bookingDetail['data']['booking_property']['checkout_time'] = '12:00';
if (!empty($bookingDetail['data']['booking_property']['property_additional_infos'])) {
$propertyAdditionalInfos = collect($bookingDetail['data']['booking_property']['property_additional_infos']);
$checkinTimeData = $propertyAdditionalInfos->where('property_additional_info_key.additional_info_key', 'checkin_time')->first();
$bookingDetail['data']['booking_property']['checkin_time'] = isset($checkinTimeData['value']) ? $checkinTimeData['value'] : '14:00';
$checkoutTimeData = $propertyAdditionalInfos->where('property_additional_info_key.additional_info_key', 'checkout_time')->first();
$bookingDetail['data']['booking_property']['checkout_time'] = isset($checkinTimeData['value']) ? $checkoutTimeData['value'] : '12:00';
}
unset($bookingDetail['data']['booking_property']['property_additional_infos']);
//BOOKING ADDON
$bookingAddons = $bookingDetail['data']['booking_addon'];
unset($bookingDetail['data']['booking_addon']);
$bookingAddonList = [];
foreach ($bookingAddons as $bookingAddon) {
$bookingAddonAttributeList = [];
$isHasAttribute = false;
$attributeArray = [];
if (!empty($bookingAddon['property_channel_addon']['property_addon']['attributeArray'])) {
$isHasAttribute = true;
$attributeArray = $bookingAddon['property_channel_addon']['property_addon']['attributeArray'];
$bookingAddonAttributes = json_decode($bookingAddon['attribute'], 1);
if (!is_null($bookingAddonAttributes)) {
foreach ($bookingAddonAttributes as $key => $bookingAddonAttribute) {
foreach ($bookingAddonAttribute as $bookingAddonAttributeKey => $bookingAddonAttributeValue) {
if (isset($bookingAddon['property_channel_addon']['property_addon']['attributeArray'][$bookingAddonAttributeKey])) {
$bookingAddonAttributeList[$key][$bookingAddonAttributeKey] = [
'name' => $bookingAddon['property_channel_addon']['property_addon']['attributeArray'][$bookingAddonAttributeKey]['name'],
'language_key' => $bookingAddon['property_channel_addon']['property_addon']['attributeArray'][$bookingAddonAttributeKey]['language_key'],
'value' => $bookingAddonAttributeValue,
];
}
}
}
}
}
$bookingAddonList[] = [
'id' => $bookingAddon['id'],
'booking_id' => $bookingAddon['booking_id'],
'property_channel_addon_id' => $bookingAddon['property_channel_addon_id'],
'count' => $bookingAddon['count'],
'amount' => $bookingAddon['amount'],
'total' => $bookingAddon['total'],
'currency_code' => $bookingAddon['currency_code'],
'name' => $bookingAddon['property_channel_addon']['property_addon']['fact']['name'],
'title' => $bookingAddon['property_channel_addon']['title'],
'language_key' => $bookingAddon['property_channel_addon']['property_addon']['fact']['language_key'],
'icon' => $bookingAddon['property_channel_addon']['property_addon']['fact']['icon'],
'isHasAttribute' => $isHasAttribute,
'attributeArray' => $attributeArray,
'attribute' => $bookingAddonAttributeList
];
}
$bookingDetail['data']['booking_addon'] = $bookingAddonList;
//BOOKING ADDON
//DAILY AMOUNT BY ROOM
$hasNonRefundableRoom = false;
foreach ($bookingDetail['data']['booking_room'] as $roomKey => $roomDetail) {
if (!empty($roomDetail['room_rate_mapping']['property_room'])) {
$bookingDetail['data']['booking_room'][$roomKey]['room_name'] = $roomDetail['room_rate_mapping']['property_room']['name'];
}
if (!empty($roomDetail['room_rate_mapping']['property_room_rate'])) {
$bookingDetail['data']['booking_room'][$roomKey]['room_rate_name'] = $roomDetail['room_rate_mapping']['property_room_rate']['name'];
}
$diffInDays = Carbon::parse($roomDetail['checkin_date'])->diffInDays(Carbon::parse($roomDetail['checkout_date']));
$baseRateDaily = moneyDoubleFormatDecimal($roomDetail['total'] / $diffInDays);
$roomDailyAmount = [];
if (!empty($roomDetail['daily_amount'])) {
$roomDetailDailyAmount = json_decode($roomDetail['daily_amount'], 1);
if (!empty($roomDetailDailyAmount) && isset($roomDetailDailyAmount)) {
foreach ($roomDetailDailyAmount as $roomRateAmount) {
$roomDailyAmount[] = [
'date' => $roomRateAmount['date'],
'amount' => $roomRateAmount['amount'],
'currency_code' => $roomRateAmount['currency_code'],
];
}
}
}
if (empty($roomDailyAmount)) {
$roomRateDetail = json_decode($roomDetail['rate_detail'], 1);
if (!empty($roomRateDetail) && isset($roomRateDetail['days'])) {
foreach ($roomRateDetail['days'] as $roomRateDay => $roomRateAmount) {
$roomDailyAmount[] = [
'date' => Carbon::parse($roomRateDay)->toDateString(),
'amount' => $roomRateAmount,
'currency_code' => $roomDetail['currency_code'],
];
}
}
}
if (empty($roomDailyAmount)) {
$currentDate = $roomDetail['checkin_date'];
for ($i = 0; $i < $diffInDays; $i++) {
$roomDailyAmount[] = [
'date' => $currentDate,
'amount' => $baseRateDaily,
'currency_code' => $roomDetail['currency_code'],
];
$currentDate = Carbon::parse($currentDate)->addDay()->toDateString();
}
}
$bookingDetail['data']['booking_room'][$roomKey]['daily_amount'] = $roomDailyAmount;
$extraParam = null;
if (!empty($roomDetail['extra_param'])) {
$extraParamDecode = json_decode($roomDetail['extra_param'], 1);
foreach ($extraParamDecode as $extraParamKey => $extraParamValue) {
$extraParamTitle = explode('_', $extraParamKey);
foreach ($extraParamTitle as $extraParamTitleKey => $extraParamTitleValue) {
$extraParamTitle[$extraParamTitleKey] = ucwords($extraParamTitleValue);
}
$extraParamTitle = implode(' ', $extraParamTitle);
$extraParam[$extraParamKey] = [
'title' => $extraParamTitle,
'value' => $extraParamValue,
];
}
}
$bookingDetail['data']['booking_room'][$roomKey]['extra_param'] = $extraParam;
$bookingDetail['data']['booking_room'][$roomKey]['occupancyFormatted'] = occupancyCodeFormatted($roomDetail['occupancy_code']);
$cancellationPolicy = !empty($roomDetail['cancellation_policy']) ? json_decode($roomDetail['cancellation_policy'], 1) : null;
if (is_array($cancellationPolicy) && isset($cancellationPolicy['isNonRefundable']) && $cancellationPolicy['isNonRefundable']) {
$hasNonRefundableRoom = true;
}
//property_room_bed_group
//unset($bookingDetail['data']['booking_room'][$roomKey]['room_rate_mapping']['property_room']['property_room_bed_group']);
$propertyRoomBedGroup = collect($roomDetail['room_rate_mapping']['property_room']['property_room_bed_group'])->groupBy('bed_group');
$propertyRoomBedGroup = $propertyRoomBedGroup ? $propertyRoomBedGroup->toArray() : null;
$bookingDetail['data']['booking_room'][$roomKey]['room_rate_mapping']['property_room']['property_room_bed_group'] = $propertyRoomBedGroup;
$bookingDetail['data']['booking_room'][$roomKey]['property_room_bed_group'] = null;
if(isset($propertyRoomBedGroup[$bookingDetail['data']['booking_room'][$roomKey]['property_room_bed_group_id']])) {
$bookingDetail['data']['booking_room'][$roomKey]['property_room_bed_group'] = $propertyRoomBedGroup[$bookingDetail['data']['booking_room'][$roomKey]['property_room_bed_group_id']];
}
}
//DAILY AMOUNT BY ROOM
$bookingChannel = $bookingDetail['data']['booking_channel'];
unset($bookingDetail['data']['booking_channel']);
$bookingDetail['data']['booking_channel'] = [
'name' => $bookingChannel['name'],
'logo' => $bookingChannel['logoUrl'],
'channel_category_id' => $bookingChannel['channel_category_id'],
];
$bookingContactExtraParam = null;
if (!empty($bookingDetail['data']['booking_contact']['extra_param'])) {
$bookingContactExtraParam = json_decode($bookingDetail['data']['booking_contact']['extra_param'], 1);
}
$bookingDetail['data']['booking_contact']['extra_param'] = $bookingContactExtraParam;
$bookingDetail = $bookingDetail['data'];
$bookingDetail['isOnlineCancellation'] = false;
if ($bookingDetail['status'] == 1 && in_array($bookingDetail['booking_channel']['channel_category_id'], [2]) && !$hasNonRefundableRoom) {
$bookingDetail['isOnlineCancellation'] = false;
}
if ($bookingDetail['status'] == 1 && in_array($bookingDetail['booking_channel']['channel_category_id'], [3]) && in_array($bookingDetail['booking_property']['country'], ['GE'])) {
$bookingDetail['isOnlineCancellation'] = false;
}
$payAtHotelCreditCardCheck = collect($bookingDetail['property_channel_mapping']['channel_booking_payment_type'])->where('is_get_payment_data',1)->where('payment_type_id',2)->isNotEmpty();
$bookingDetail['credit_card_required'] = $payAtHotelCreditCardCheck;
unset($bookingDetail['property_channel_mapping']);
//Wholesaler MARKUP CALCULATE
$getChannelPropertyDetail = $this->getChannelPropertyDetail($this->channelId, $bookingDetail['property_id']);
if (!$getChannelPropertyDetail['status']) {
throw new ApiErrorException(lang('Property and Channel are not matched.'));
}
$getChannelPropertyDetail = $getChannelPropertyDetail['status'] ? $getChannelPropertyDetail['data'] : null;
if ($getChannelPropertyDetail && in_array($getChannelPropertyDetail['channel']['channel_category_id'], [7])) {
$channelCurrencyCode = fillOnUndefined($bookingDetail, 'channel_currency_code', $bookingDetail['currency_code']);
$channelCurrencyExchange = fillOnUndefined($bookingDetail, 'channel_currency_exchange', 1);
$channelMarkup = 1;
if (!is_null($bookingDetail['channel_markup'])) {
$channelMarkup = (($bookingDetail['channel_markup'] + 100) / 100);
}
foreach ($bookingDetail['booking_room'] as $roomKey => $room) {
foreach ($room['daily_amount'] as $dailKey => $dailyAmount) {
$bookingDetail['booking_room'][$roomKey]['daily_amount'][$dailKey]['currency_code'] = $channelCurrencyCode;
$bookingDetail['booking_room'][$roomKey]['daily_amount'][$dailKey]['amount'] = moneyDoubleFormatDecimal($dailyAmount['amount'] * $channelMarkup * $channelCurrencyExchange);
}
$bookingDetail['booking_room'][$roomKey]['amount'] = moneyDoubleFormatDecimal(collect($bookingDetail['booking_room'][$roomKey]['daily_amount'])->sum('amount'));
$bookingDetail['booking_room'][$roomKey]['discount_amount'] = moneyDoubleFormatDecimal($room['discount_amount'] * $channelMarkup * $channelCurrencyExchange);
$bookingDetail['booking_room'][$roomKey]['total'] = moneyDoubleFormatDecimal(collect($bookingDetail['booking_room'][$roomKey]['daily_amount'])->sum('amount'));
$bookingDetail['booking_room'][$roomKey]['currency_code'] = $channelCurrencyCode;
unset($bookingDetail['booking_room'][$roomKey]['rate_detail']);
}
$bookingDetail['currency_code'] = $channelCurrencyCode;
$bookingDetail['room_amount'] = moneyDoubleFormatDecimal(collect($bookingDetail['booking_room'])->sum('amount'));
$bookingDetail['addon_amount'] = moneyDoubleFormatDecimal($bookingDetail['addon_amount'] * $channelMarkup * $channelCurrencyExchange);
$bookingDetail['discount_amount'] = moneyDoubleFormatDecimal(collect($bookingDetail['booking_room'])->sum('discount_amount'));
$bookingDetail['total'] = moneyDoubleFormatDecimal(collect($bookingDetail['booking_room'])->sum('amount'));
$bookingDetail['booking_payment']['currency_code'] = $channelCurrencyCode;
$bookingDetail['booking_payment']['total'] = moneyDoubleFormatDecimal(collect($bookingDetail['booking_room'])->sum('total'));
}
//Wholesaler MARKUP CALCULATE
unset($bookingDetail['channel_markup']);
unset($bookingDetail['channel_currency_code']);
unset($bookingDetail['channel_currency_exchange']);
$response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $bookingDetail];
} 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']);
}
public function bookingUpdate(Request $request, $bookingCode)
{
DB::beginTransaction();
$response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
try {
if (is_null($this->request->getContent())) {
throw new ApiErrorException(lang('Parameter Error.'));
}
$params = json_decode($this->request->getContent(), 1);
$bookingDetailParam = [
'criteria' => [
['field' => 'booking_code', 'condition' => '=', 'value' => $bookingCode],
],
'with' => [
'bookingRoom.roomRateMapping.propertyRoom',
'bookingRoom.roomRateMapping.propertyRoom.propertyRoomBedGroup.propertyRoomBedType',
'bookingRoom.roomRateMapping.propertyRoom.smokingPreference.propertyFact',
'bookingRoom.propertyRoomBed','bookingRoom.smokingFact'
],
'firstRow' => true
];
$bookingDetail = $this->bookingService->select($bookingDetailParam);
if ($bookingDetail['status'] != 'success' || empty($bookingDetail['data'])) {
throw new ApiErrorException(lang('Booking not found'));
}
$bookingDetail = $bookingDetail['data'];
if(fillOnUndefined($params,'propertyId') != fillOnUndefined($bookingDetail,'property_id')) {
throw new ApiErrorException('PropertyI ID is not matching.');
}
$bookingRoomUpdateParam = ['smoking_fact_id','property_room_bed_id','property_room_bed_group_id'];
if(isset($params['booking_room']) && isset($params['booking_room']['id'])) {
$bookingRoomIds = collect($bookingDetail['booking_room'])->pluck('id');
$bookingRoomIds = $bookingRoomIds ? $bookingRoomIds->toArray() : null;
if(empty($bookingRoomIds)) {
throw new ApiErrorException('Booking Room ID not found.');
}
if(!in_array($params['booking_room']['id'],$bookingRoomIds )) {
throw new ApiErrorException('Booking Room ID not matching.');
}
$bookingRoomDetail = collect($bookingDetail['booking_room'])->where('id',$params['booking_room']['id'])->first();
foreach ($bookingRoomUpdateParam as $updateColumn) {
//smoking_fact_id
if($updateColumn == 'smoking_fact_id' && isset($params['booking_room']['smoking_fact_id'])) {
$smokingPreferenceIds = collect($bookingRoomDetail['room_rate_mapping']['property_room']['smoking_preference'])->pluck('fact_id')->toArray();
if(!in_array($params['booking_room']['smoking_fact_id'],$smokingPreferenceIds)) {
throw new ApiErrorException('smoking_fact_id: ID params not matching.');
}
$this->bookingRoomService->update($params['booking_room']['id'], ['smoking_fact_id' => $params['booking_room']['smoking_fact_id']]);
}
//property_room_bed_id
if($updateColumn == 'property_room_bed_id' && isset($params['booking_room']['property_room_bed_id'])) {
$propertyRoomBedGroupIds = collect($bookingRoomDetail['room_rate_mapping']['property_room']['property_room_bed_group'])->pluck('id')->toArray();
if(!in_array($params['booking_room']['property_room_bed_id'],$propertyRoomBedGroupIds)) {
throw new ApiErrorException('property_room_bed_id: ID params not matching.');
}
$this->bookingRoomService->update($params['booking_room']['id'], ['property_room_bed_id' => $params['booking_room']['property_room_bed_id']]);
}
//property_room_bed_group_id
if($updateColumn == 'property_room_bed_group_id' && isset($params['booking_room']['property_room_bed_group_id'])) {
$propertyRoomBedGroupIds = collect($bookingRoomDetail['room_rate_mapping']['property_room']['property_room_bed_group'])->pluck('bed_group')->toArray();
if(!in_array($params['booking_room']['property_room_bed_group_id'],$propertyRoomBedGroupIds)) {
throw new ApiErrorException('property_room_bed_group_id: ID params not matching.');
}
$this->bookingRoomService->update($params['booking_room']['id'], ['property_room_bed_group_id' => $params['booking_room']['property_room_bed_group_id']]);
}
}
} else {
throw new ApiErrorException('Property Room ID not found.');
}
$response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => null];
} 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;
}
if ($response['status']) {
DB::commit();
} else {
DB::rollBack();
}
return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']);
}
public function bookingPaymentInstallment(Request $request)
{
$response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
try {
$paymentData = [];
$paymentData['isExchangeAmount'] = false;
if (is_null($this->request->getContent())) {
throw new ApiErrorException(lang('Parameter Error.'));
}
$params = json_decode($this->request->getContent(), 1);
$propertyId = $this->bookingEnginePropertyId;
$cardBinNumber = $params['cardBinNumber'];
$amount = $params['amount'];
$currency = $params['currency'];
$paymentData['amount'] = $amount;
$paymentData['currency'] = $currency;
$paymentData['installment'] = [];
$paymentType = $this->propertyPaymentService->getPaymentTypeMapping($propertyId, $currency, $cardBinNumber);
if (is_null($paymentType['propertyPaymentMappingId'])) {
throw new ApiErrorException(lang('Payment Type not found'));
}
if ($params['currency'] != $paymentType['propertyPaymentMappingCurrency']) {
$exchangeRate = $this->propertyPaymentService->getExchangeRates();
if (isset($exchangeRate[$params['currency'] . $paymentType['propertyPaymentMappingCurrency']])) {
$exchangeRateValue = $exchangeRate[$params['currency'] . $paymentType['propertyPaymentMappingCurrency']];
} else {
throw new ApiErrorException(lang('Currency exchange value not found.'));
}
$paymentData['isExchangeAmount'] = true;
$paymentData['amount'] = moneyDoubleFormatDecimal($amount * $exchangeRateValue);
$paymentData['currency'] = $paymentType['propertyPaymentMappingCurrency'];
$paymentData['base_amount'] = $amount;
$paymentData['base_currency'] = $currency;
$paymentData['exchangeRate'] = $exchangeRateValue;
}
if (!empty($paymentType['propertyPaymentMappingInstallment'])) {
$amountBeforeInstallment = $amount;
if ($paymentData['isExchangeAmount']) {
$amountBeforeInstallment = $paymentData['amount'];
}
foreach ($paymentType['propertyPaymentMappingInstallment'] as $installmentData) {
$paymentData['installment'][$installmentData['installment']] = [
'installment' => $installmentData['installment'],
'commission' => $installmentData['commission'],
'amount' => moneyDoubleFormatDecimal($amountBeforeInstallment + ($amountBeforeInstallment * $installmentData['commission'] / 100))
];
}
}
$response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $paymentData];
} 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;
}
if ($response['status']) {
DB::commit();
} else {
DB::rollBack();
}
return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']);
}
public function couponCodeCheck(Request $request)
{
$response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
try {
if (is_null($this->request->getContent())) {
throw new ApiErrorException(lang('Parameter Error.'));
}
$params = json_decode($this->request->getContent(), 1);
$couponData = [];
$channelId = $this->channelId;
$propertyId = $this->bookingEnginePropertyId;
$getChannelPropertyDetail = $this->getChannelPropertyDetail($this->channelId, $propertyId);
if (!$getChannelPropertyDetail['status']) {
throw new ApiErrorException(lang('Property and Channel are not matched.'));
}
$getChannelPropertyDetail = $getChannelPropertyDetail['data'];
$propertyChannelCouponCriteria = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => $getChannelPropertyDetail['property_id']],
['field' => 'channel_id', 'condition' => '=', 'value' => $getChannelPropertyDetail['channel_id']],
['field' => 'code', 'condition' => '=', 'value' => $params['code']],
['field' => 'start_date', 'condition' => '<=', 'value' => Carbon::now()->toDateString()],
['field' => 'end_date', 'condition' => '>=', 'value' => Carbon::now()->toDateString()],
['field' => 'status', 'condition' => '=', 'value' => 1],
],
'firstRow' => true
];
$propertyChannelCoupon = $this->propertyChannelCouponService->select($propertyChannelCouponCriteria);
if ($propertyChannelCoupon['status'] == 'success') {
$propertyChannelCoupon = $propertyChannelCoupon['data'];
}
if (empty($propertyChannelCoupon)) {
throw new ApiErrorException(lang('Code that has expired or is not available.'));
}
$codeChecked = fillOnUndefined($propertyChannelCoupon,'checked', 0); $codeChecked++;
$this->propertyChannelCouponService->update($propertyChannelCoupon['id'], ['checked' => $codeChecked]);
//Reservation Date Check
if (!is_null($propertyChannelCoupon['reservation_start_date']) && !is_null($propertyChannelCoupon['reservation_end_date'])) {
if (isset($params['checkIn']) && isset($params['checkOut'])) {
$reservationDateCheck = Carbon::parse($propertyChannelCoupon['reservation_start_date'])->lessThanOrEqualTo(Carbon::parse($params['checkIn']))
&& Carbon::parse($propertyChannelCoupon['reservation_end_date'])->greaterThanOrEqualTo(Carbon::parse($params['checkOut']));
if (!$reservationDateCheck) {
throw new ApiErrorException(lang('The code is not within the reservation period entered.'));
}
}
}
$couponData = [
'code' => $propertyChannelCoupon['code'],
'type' => $propertyChannelCoupon['type'],
'value' => $propertyChannelCoupon['value'],
];
$response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $couponData];
} 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']);
}
public function couponCodeNotify(Request $request)
{
$response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
try {
if (is_null($this->request->getContent())) {
throw new ApiErrorException(lang('Parameter Error.'));
}
$params = json_decode($this->request->getContent(), 1);
$channelId = $this->channelId;
$propertyId = $this->bookingEnginePropertyId;
$getChannelPropertyDetail = $this->getChannelPropertyDetail($this->channelId, $propertyId);
if (!$getChannelPropertyDetail['status']) {
throw new ApiErrorException(lang('Property and Channel are not matched.'));
}
$getChannelPropertyDetail = $getChannelPropertyDetail['data'];
$propertyChannelCouponCriteria = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => $getChannelPropertyDetail['property_id']],
['field' => 'channel_id', 'condition' => '=', 'value' => $getChannelPropertyDetail['channel_id']],
//['field' => 'code', 'condition' => '=', 'value' => $params['code']],
['field' => 'start_date', 'condition' => '<=', 'value' => Carbon::now()->toDateString()],
['field' => 'end_date', 'condition' => '>=', 'value' => Carbon::now()->toDateString()],
['field' => 'status', 'condition' => '=', 'value' => 1],
['field' => 'is_notify', 'condition' => '=', 'value' => 1],
],
"orderBy" => [
["field" => "id", "value" => "DESC"]
],
'firstRow' => true
];
//dd($propertyChannelCouponCriteria);
$propertyChannelCoupon = $this->propertyChannelCouponService->select($propertyChannelCouponCriteria);
if ($propertyChannelCoupon['status'] == 'success') {
$propertyChannelCoupon = $propertyChannelCoupon['data'];
}
if (empty($propertyChannelCoupon)) {
throw new ApiErrorException(lang('No active code to notify was found'));
}
//Reservation Date Check
if (!is_null($propertyChannelCoupon['reservation_start_date']) && !is_null($propertyChannelCoupon['reservation_end_date'])) {
if (isset($params['checkIn']) && isset($params['checkOut'])) {
$reservationDateCheck = Carbon::parse($propertyChannelCoupon['reservation_start_date'])->lessThanOrEqualTo(Carbon::parse($params['checkIn']))
&& Carbon::parse($propertyChannelCoupon['reservation_end_date'])->greaterThanOrEqualTo(Carbon::parse($params['checkOut']));
if (!$reservationDateCheck) {
throw new ApiErrorException(lang('The code is not within the reservation period entered.'));
}
}
}
$couponData = [
'code' => $propertyChannelCoupon['code'],
'type' => $propertyChannelCoupon['type'],
'value' => $propertyChannelCoupon['value'],
];
$response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $couponData];
} 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']);
}
public function bookingAddonAttribute(Request $request)
{
$response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
try {
if (is_null($this->request->getContent())) {
throw new ApiErrorException(lang('Parameter Error.'));
}
$params = json_decode($this->request->getContent(), 1);
$channelId = $this->channelId;
$propertyId = $this->bookingEnginePropertyId;
$bookingCode = $params['bookingCode'];
$bookingAddonId = $params['bookingAddonId'];
//TODO: Validator,
$getChannelPropertyDetail = $this->getChannelPropertyDetail($channelId, $propertyId);
if (!$getChannelPropertyDetail['status']) {
throw new ApiErrorException(lang('Property and Channel are not matched.'));
}
$bookingDetailParam = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => $propertyId],
['field' => 'channel_id', 'condition' => '=', 'value' => $channelId],
['field' => 'booking_code', 'condition' => '=', 'value' => $bookingCode]
],
'with' => ['bookingAddon.propertyChannelAddon.propertyAddon.fact'],
'firstRow' => true
];
$bookingDetail = $this->bookingService->select($bookingDetailParam);
if ($bookingDetail['status'] != 'success' || empty($bookingDetail['data'])) {
throw new ApiErrorException('Booking not found');
}
$bookingDetail = $bookingDetail['data'];
if (empty($bookingDetail['booking_addon'])) {
throw new ApiErrorException('Booking Addon not found');
}
$bookingAddonCollect = collect($bookingDetail['booking_addon']);
$selectedAddon = $bookingAddonCollect->where('id', $bookingAddonId)->first();
if (empty($selectedAddon)) {
throw new ApiErrorException('Booking Selected Addon not found');
}
$attributeArray = $selectedAddon['property_channel_addon']['property_addon']['attributeArray'];
$addonInfoAttribute = null;
if (isset($params['attribute'])) {
foreach ($params['attribute'] as $addonAttribute) {
if (count(array_intersect_key($addonAttribute, $attributeArray)) != count($addonAttribute)) {
throw new ApiErrorException('Additional product attribute values submitted do not match.');
}
}
$addonInfoAttribute = $params['attribute'];
}
if ($selectedAddon['count'] != count($addonInfoAttribute)) {
throw new ApiErrorException('The number of additional items purchased and the number of additional information entered do not match');
}
$updateParam['attribute'] = null;
if (!is_null($addonInfoAttribute)) {
$updateParam['attribute'] = json_encode($addonInfoAttribute);
}
$this->bookingAddonService->update($bookingAddonId, $updateParam);
$bookingPropertyAddonUpdateMail = [
'propertyId' => $bookingDetail['property_id'],
'bookingCode' => $bookingDetail['booking_code'],
'addonLanguageKey' => $selectedAddon['property_channel_addon']['property_addon']['fact']['language_key']
];
$this->mailer->onQueue('bookingPropertyAddonUpdateMail', new BookingPropertyAddonUpdateMail($bookingPropertyAddonUpdateMail));
$response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => []];
} 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']);
}
public function bookingCancellation(Request $request)
{
$response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
try {
$confirmCodeGenerate = null;
$propertyBookingController = \Illuminate\Support\Facades\App::make("App\Http\Controllers\V1\PropertyBookingController");
if (is_null($this->request->getContent())) {
throw new ApiErrorException(lang('Parameter Error.'));
}
$params = json_decode($this->request->getContent(), 1);
$channelId = $this->channelId;
$propertyId = $this->bookingEnginePropertyId;
$bookingCode = $params['bookingCode'];
$confirmCode = fillOnUndefined($params, 'confirmCode');
$getChannelPropertyDetail = $this->getChannelPropertyDetail($channelId, $propertyId);
if (!$getChannelPropertyDetail['status']) {
throw new ApiErrorException(lang('Property and Channel are not matched.'));
}
$getChannelPropertyDetail = $getChannelPropertyDetail['data'];
$bookingDetailParam = [
'criteria' => [
['field' => 'channel_id', 'condition' => '=', 'value' => $channelId],
['field' => 'booking_code', 'condition' => '=', 'value' => $bookingCode]
],
'with' => ['bookingChannel.propertyChannelCategory', 'bookingProperty', 'bookingRoom'],
'firstRow' => true
];
$bookingDetail = $this->bookingService->select($bookingDetailParam);
if ($bookingDetail['status'] != 'success' || ($bookingDetail['status'] == 'success' && empty($bookingDetail['data']))) {
throw new ApiErrorException('Property and Booking Code are not matched.');
}
$bookingDetail = $bookingDetail['data'];
if ($bookingDetail['status'] != 1) {
throw new ApiErrorException('Reservation status not available.');
}
//Only GE Hotels
if ($bookingDetail['status'] == 1 && in_array($bookingDetail['booking_channel']['channel_category_id'], [3]) && in_array($bookingDetail['booking_property']['country'], ['GE'])) {
//Check Cancellation Policy
$isBookingRefundable = false;
foreach ($bookingDetail['booking_room'] as $bookingRoom) {
$cancellationPolicy = json_decode($bookingRoom['cancellation_policy'], 1);
if (!empty($cancellationPolicy)) {
if ($cancellationPolicy['isNonRefundable']) {
break;
}
if ($cancellationPolicy['isFreeCancellation']) {
if (isset($cancellationPolicy['beforeArrivalDay'])) {
if (Carbon::now()->startOfDay()->lessThan(Carbon::parse($bookingRoom['checkin_date'])->subDays($cancellationPolicy['beforeArrivalDay'])->toDateString())) {
$isBookingRefundable = true;
}
} else {
$isBookingRefundable = true;
}
}
}
}
if ($isBookingRefundable) {
//Cancellation Process
$updateBookingParam = [
'locale' => $request->getLocale(),
'property_id' => $bookingDetail['property_id'],
'booking_id' => $bookingDetail['id'],
'total' => $bookingDetail['total'],
'currency_code' => $bookingDetail['currency_code'],
'status' => 0
];
$request['requestParams'] = $updateBookingParam;
$updateBooking = $propertyBookingController->updateBooking($request);
$updateBooking = $updateBooking->getData();
if ($updateBooking->status != 200) {
throw new ApiErrorException($updateBooking->message);
}
$mailParams = ['booking_id' => $bookingDetail['id']];
$this->mailer->onQueue('cancelBookingMail', new CancelBookingMail($mailParams));
$response = [
'status' => 1,
'statusCode' => 200,
'data' => [
'isCancellationRequest' => true
],
'message' => __('api-cancellation_confirm-message', [], $request->getLocale())
];
} else {
$mailParams = [
'bookingCode' => $bookingCode
];
$this->mailer->send(new BookingCancellationRequestMail($mailParams));
$response = [
'status' => 1,
'statusCode' => 200,
'data' => [
'isCancellationRequest' => true
],
'message' => __('api-cancellation_request-message', [], $request->getLocale())
];
}
return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']);
}
//Just Offline Booking Engines
if (!in_array($bookingDetail['booking_channel']['channel_category_id'], [2, 7])) {
throw new ApiErrorException('Online reservation cancellation is not active for this channel.');
}
//TODO: Checkin tarihi geçmemiş olmalı kontrol eklenecek
$cacheKey = md5('BookingCancellation-' . $bookingDetail['booking_code']);
if (!empty($confirmCode) || in_array($bookingDetail['booking_channel']['channel_category_id'], [7])) {
if (!in_array($bookingDetail['booking_channel']['channel_category_id'], [7])) {
if (!Cache::has($cacheKey)) {
throw new ApiErrorException('Verification code not found, please try again.');
}
if ($confirmCode != Cache::get($cacheKey)) {
throw new ApiErrorException('The entered code could not be verified, please enter the updated code sent to your e-mail address.');
}
}
//Cancellation Process
$updateBookingParam = [
'locale' => $request->getLocale(),
'property_id' => $bookingDetail['property_id'],
'booking_id' => $bookingDetail['id'],
'total' => $bookingDetail['total'],
'currency_code' => $bookingDetail['currency_code'],
'status' => 0
];
$request['requestParams'] = $updateBookingParam;
$updateBooking = $propertyBookingController->updateBooking($request);
$updateBooking = $updateBooking->getData();
if ($updateBooking->status != 200) {
throw new ApiErrorException($updateBooking->message);
}
$mailParams = ['booking_id' => $bookingDetail['id']];
$this->mailer->onQueue('cancelBookingMail', new CancelBookingMail($mailParams));
Cache::forget($cacheKey);
$response = [
'status' => 1,
'statusCode' => 200,
'data' => null,
'message' => null
];
} else {
$confirmCodeGenerate = rand(1000, 9999);
Cache::put($cacheKey, $confirmCodeGenerate, 60 * 5);//600 10 dk
//$confirmCode
$mailParams = [
'bookingCode' => $bookingCode,
'confirmCode' => $confirmCodeGenerate
];
$this->mailer->send(new BookingCancellationConfirmCodeMail($mailParams));
$response = [
'status' => 1,
'statusCode' => 200,
'data' => null,
'message' => 'Please enter the cancellation verification code sent to your e-mail address.'
];
}
} 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']);
}
public function bookingInvoice(Request $request)
{
$response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
try {
if (is_null($this->request->getContent())) {
throw new ApiErrorException(lang('Parameter Error.'));
}
$params = json_decode($this->request->getContent(), 1);
$channelId = $this->channelId;
$propertyId = $this->bookingEnginePropertyId;
$bookingCode = $params['bookingCode'];
$getChannelPropertyDetail = $this->getChannelPropertyDetail($channelId, $propertyId);
if (!$getChannelPropertyDetail['status']) {
throw new ApiErrorException(lang('Property and Channel are not matched.'));
}
$getChannelPropertyDetail = $getChannelPropertyDetail['data'];
$bookingDetailParam = [
'criteria' => [
['field' => 'channel_id', 'condition' => '=', 'value' => $channelId],
['field' => 'booking_code', 'condition' => '=', 'value' => $bookingCode]
],
'with' => ['bookingChannel.propertyChannelCategory', 'bookingProperty', 'bookingRoom', 'bookingContact'],
'firstRow' => true
];
$bookingDetail = $this->bookingService->select($bookingDetailParam);
if ($bookingDetail['status'] != 'success' || ($bookingDetail['status'] == 'success' && empty($bookingDetail['data']))) {
throw new ApiErrorException('Property and Booking Code are not matched.');
}
$bookingDetail = $bookingDetail['data'];
if ($bookingDetail['status'] != 1) {
throw new ApiErrorException('Reservation status not available.');
}
if ($bookingDetail['booking_contact']['invoice_request'] != 1) {
throw new ApiErrorException('Reservation invoice status not available.');
}
$invoiceParam = [
'name_surname' => fillOnUndefined($params, 'name_surname'),
'citizen_number' => fillOnUndefined($params, 'citizen_number'),
'company' => fillOnUndefined($params, 'company'),
'tax_number' => fillOnUndefined($params, 'tax_number'),
'address' => fillOnUndefined($params, 'address'),
];
$bookingInvoiceUpdate = $this->bookingContactService->update($bookingDetail['booking_contact']['id'], ['invoice' => json_encode($invoiceParam)]);
if ($bookingInvoiceUpdate['status'] != 'success') {
throw new ApiErrorException('Invoice update operation could not be performed.');
}
$bookingPropertyAddonUpdateMail = [
'bookingCode' => $bookingDetail['booking_code']
];
$this->mailer->onQueue('bookingInvoiceUpdateMail', new BookingInvoiceUpdateMail($bookingPropertyAddonUpdateMail));
$response = [
'status' => 1,
'statusCode' => 200,
'data' => null,
'message' => null
];
} 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']);
}
public function propertyList(Request $request)
{
$response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
try {
$ipAddress = $request->ip();
$channelToken = $request->header('channelToken');
if (!$channelToken) {
return apiResponse(0, 'Token not provided.', null, 401);
}
$ipRestriction = [
//City Travel
'1500c5d5-b55e-4fa0-966b-698f4f168f48' => [
'127.0.0.1',
'185.137.215.118',
'176.236.59.130',
'176.236.59.131',
'176.236.59.132',
'176.236.59.133',
'176.236.59.134',
'176.236.59.135',
'176.236.59.136',
'176.236.59.137',
'176.236.59.138',
'176.236.59.139',
'54.72.215.85',
'54.77.48.206',
'34.252.23.103',
'52.19.162.59',
'54.72.80.155',
'52.210.166.9',
'54.72.220.60',
'52.17.235.55',
'176.236.59.130',
'54.72.215.85',
'54.77.48.206',
'52.213.250.14',
'34.252.23.103'
]
];
if (isset($ipRestriction[$channelToken]) && !in_array($ipAddress, $ipRestriction[$channelToken])) {
return apiResponse(0, 'Cannot be accessed via this IP address: ' . $ipAddress, null, 401);
}
$channelRequest = [
'criteria' => [
['field' => 'token', 'condition' => '=', 'value' => $channelToken],
['field' => 'status', 'condition' => '=', 'value' => 1],
],
'firstRow' => 1
];
$channelCheck = $this->channelService->select($channelRequest);
if ($channelCheck['status'] != 'success' || empty($channelCheck['data'])) {
return apiResponse(0, 'Channel Token not found.', null, 401);
}
$channelCheck = $channelCheck['data'];
$propertyBookingEngineParam = [
'criteria' => [
['field' => 'channel_id', 'condition' => '=', 'value' => $channelCheck['id']],
['field' => 'status', 'condition' => '=', 'value' => 1],
],
'with' => ['channel', 'property.propertyBookingEngineToken', 'property.propertyType', 'property.propertyContact', 'property.propertyDestination'],
"orderBy" => [
["field" => "id", "value" => "DESC"]
]
];
$propertyBookingEngine = $this->propertyBookingEngineService->select($propertyBookingEngineParam);
$propertyBookingEngine = $propertyBookingEngine['status'] == 'success' ? $propertyBookingEngine['data'] : [];
$propertyList = [];
foreach ($propertyBookingEngine as $bookingEngine) {
$propertyList[] = [
'id' => $bookingEngine['property']['id'],
'name' => $bookingEngine['property']['name'],
'type' => $bookingEngine['property']['property_type']['name'],
'country' => $bookingEngine['property']['country'],
'destination' => $bookingEngine['property']['property_destination']['name'],
'destination_id' => $bookingEngine['property']['destination_id'],
'token' => $bookingEngine['token'],
'mapping' => !empty($bookingEngine['property']['mapping']) ? json_decode($bookingEngine['property']['mapping'], 1) : null,
'contact' => [
'address' => $bookingEngine['property']['property_contact']['address'],
'phone' => $bookingEngine['property']['property_contact']['view_full_phone'],
'email' => $bookingEngine['property']['property_contact']['email'],
'latitude' => $bookingEngine['property']['property_contact']['latitude'],
'longitude' => $bookingEngine['property']['property_contact']['longitude'],
],
];
}
$response = [
'status' => 1,
'statusCode' => 200,
'data' => $propertyList,
'message' => null
];
} 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']);
}
}