Files
api-extranetwork/app/Core/Service/BookingService.php
ExtraNetwork e5c4b6aa13 first commit
2026-05-12 17:04:54 +03:00

953 lines
42 KiB
PHP

<?php
namespace App\Core\Service;
use App\Core\Repository\Booking\BookingRepository;
use App\Core\Repository\Booking\BookingRoomRepository;
use App\Core\Repository\Booking\BookingRoomPaxRepository;
use App\Core\Repository\Booking\BookingContactRepository;
use App\Core\Repository\Booking\BookingPaymentRepository;
use App\Core\Repository\Booking\BookingStatusRepository;
use App\Core\Repository\PaymentTransaction\PaymentTransactionRepository;
use App\Core\Repository\PropertyBookingEngine\PropertyBookingEngineRepository;
use App\Core\Repository\Booking\BookingPaymentDataCheckRepository;
use App\Core\Repository\PropertyChannel\PropertyChannelRepository;
use App\Core\Repository\PropertyBookingPaymentType\PropertyBookingPaymentTypeRepository;
use App\Core\Mail\BookingPaymentDataCodeMail;
use Carbon\Carbon;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\App;
use Exception;
use App\Exceptions\ApiErrorException;
class BookingService
{
private $bookingRepository;
private $bookingRoomRepository;
private $bookingRoomPaxRepository;
private $bookingContactRepository;
private $bookingPaymentRepository;
private $paymentTransactionRepository;
private $bookingStatusRepository;
public function __construct(
BookingRepository $bookingRepository,
BookingRoomRepository $bookingRoomRepository,
BookingRoomPaxRepository $bookingRoomPaxRepository,
BookingContactRepository $bookingContactRepository,
PaymentTransactionRepository $paymentTransactionRepository,
BookingPaymentRepository $bookingPaymentRepository,
BookingPaymentDataCheckRepository $bookingPaymentDataCheckRepository,
BookingStatusRepository $bookingStatusRepository,
PropertyBookingEngineRepository $propertyBookingEngineRepository,
PropertyChannelRepository $propertyChannelRepository,
PropertyBookingPaymentTypeRepository $propertyBookingPaymentTypeRepository,
Mailer $mailer
)
{
$this->bookingRepository = $bookingRepository;
$this->bookingRoomRepository = $bookingRoomRepository;
$this->bookingRoomPaxRepository = $bookingRoomPaxRepository;
$this->bookingContactRepository = $bookingContactRepository;
$this->bookingPaymentRepository = $bookingPaymentRepository;
$this->bookingPaymentDataCheckRepository = $bookingPaymentDataCheckRepository;
$this->paymentTransactionRepository = $paymentTransactionRepository;
$this->bookingStatusRepository = $bookingStatusRepository;
$this->propertyBookingEngineRepository = $propertyBookingEngineRepository;
$this->propertyChannelRepository = $propertyChannelRepository;
$this->propertyBookingPaymentTypeRepository = $propertyBookingPaymentTypeRepository;
$this->mailer = $mailer;
}
public function create($params = [])
{
$response = ['status' => -1, 'message' => '', 'data' => null];
try {
/*$validationResult = $this->propertyChannelAddValidator->validate($params);
if ($validationResult->errors()->first()) {
$errors = $validationResult->errors()->all();
throw new ApiErrorException($errors);
}*/
$insertData = [
'property_id' => fillOnUndefined($params, 'property_id'),
'channel_id' => fillOnUndefined($params, 'channel_id'),
'channel_manager_id' => fillOnUndefined($params, 'channel_manager_id'),
'booking_code' => fillOnUndefined($params, 'booking_code'),
'channel_booking_code' => fillOnUndefined($params, 'channel_booking_code'),
'search_key' => fillOnUndefined($params, 'search_key'),
'checkin_date' => fillOnUndefined($params, 'checkin_date'),
'checkout_date' => fillOnUndefined($params, 'checkout_date'),
'rooms' => fillOnUndefined($params, 'rooms'),
'payment_type_code' => fillOnUndefined($params, 'payment_type_code'),
'room_amount' => fillOnUndefined($params, 'room_amount'),
'addon_amount' => fillOnUndefined($params, 'addon_amount', 0),
'discount_amount' => fillOnUndefined($params, 'discount_amount', 0),
'total' => fillOnUndefined($params, 'total'),
'currency_code' => fillOnUndefined($params, 'currency_code'),
'channel_discount' => fillOnUndefined($params, 'channel_discount'),
'channel_markup' => fillOnUndefined($params, 'channel_markup'),
'channel_currency_code' => fillOnUndefined($params, 'channel_currency_code'),
'channel_currency_exchange' => fillOnUndefined($params, 'channel_currency_exchange'),
'channel_token' => fillOnUndefined($params, 'channel_token'),
'booking_engine_token' => fillOnUndefined($params, 'booking_engine_token'),
'extra_param' => fillOnUndefined($params, 'extra_param'),
'status' => fillOnUndefined($params, 'status', 1),
'reservation_time' => fillOnUndefined($params, 'reservation_time', Carbon::now()->timestamp),
'coupon_code' => fillOnUndefined($params,'coupon_code')
];
$createResult = $this->bookingRepository->create($insertData);
if ($createResult['status'] != 'success') {
throw new Exception('api-unknown_error');
}
$createData = $createResult['data'];
$response = [
'status' => true,
'data' => $createData,
];
} 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 output($response);
}
public function select($param = [], $column = ['*'])
{
$response = ['status' => -1, 'message' => '', 'data' => null];
try {
$data = $this->bookingRepository->findByCriteria($param, $column);
$response = [
'status' => true,
'data' => $data,
];
} catch (ApiErrorException $e) {
$response['message'] = $e->getMessage();
} catch (Exception $e) {
$message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage();
Log::error($message);
$response['message'] = $e->getMessage();
}
return output($response);
}
public function update($id, $param = [])
{
$response = ['status' => -1, 'message' => '', 'data' => null];
try {
$updateResult = $this->bookingRepository->update($id, $param);
if ($updateResult['status'] != 'success') {
throw new Exception('api-unknown_error');
}
$updateData = $updateResult['data'];
$response = [
'status' => true,
'data' => $updateData,
];
} 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 output($response);
}
public function getBookingList($param)
{
$response = ['status' => -1, 'message' => '', 'data' => null];
try {
$getListCriteria = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')],
],
'orderBy' => [/*['field' => 'is_viewed', 'value' => 'ASC'],*/
['field' => 'id', 'value' => 'DESC']],
'with' => ['bookingContact', 'bookingChannel', 'bookingPayment', 'bookingPaymentType', 'bookingStatus', 'bookingActiveMessageCount'],
];
if (isset($param['filter']) && !empty($param['filter'])) {
$filterParams = [
'channel_id' => [
'criteriaType' => 'EQUAL'
],
'booking_code' => [
'criteriaType' => 'LIKE'
],
'payment_type_code' => [
'criteriaType' => 'LIKE'
],
'status' => [
'criteriaType' => 'EQUAL'
],
];
foreach ($param['filter'] as $inputName => $inputValue) {
if (!is_null($inputValue) && key_exists($inputName, $filterParams)) {
if ($filterParams[$inputName]['criteriaType'] == 'EQUAL') {
$getListCriteria['criteria'][] = ['field' => $inputName, 'condition' => '=', 'value' => $inputValue];
} elseif ($filterParams[$inputName]['criteriaType'] == 'LIKE') {
$getListCriteria['criteria'][] = ['field' => $inputName, 'condition' => 'LIKE', 'value' => '%' . $inputValue . '%'];
}
}
}
if (isset($param['filter']['date_type']) && isset($param['filter']['date_range'])) {
if (in_array($param['filter']['date_type'], ['checkin_date', 'checkout_date'])) {
$dateRange = explode(' ', $param['filter']['date_range']);
$getListCriteria['criteria'][] = ['field' => $param['filter']['date_type'], 'condition' => '>=', 'value' => Carbon::parse($dateRange[0])->toDateString()];
$getListCriteria['criteria'][] = ['field' => $param['filter']['date_type'], 'condition' => '<', 'value' => Carbon::parse($dateRange[1])->addDay()->toDateString()];
}
if (in_array($param['filter']['date_type'], ['reservation_time'])) {
$dateRange = explode(' ', $param['filter']['date_range']);
$getListCriteria['criteria'][] = ['field' => $param['filter']['date_type'], 'condition' => '>=', 'value' => Carbon::parse($dateRange[0])->unix()];
$getListCriteria['criteria'][] = ['field' => $param['filter']['date_type'], 'condition' => '<', 'value' => Carbon::parse($dateRange[1])->addDay()->unix()];
}
}
$getListCriteria['take'] = 10000;
} else {
$getListCriteria['take'] = 200;
}
$booking = $this->select($getListCriteria, ['id', 'channel_id', 'booking_code', 'checkin_date', 'checkout_date', 'payment_type_code', 'total', 'currency_code', 'reservation_time', 'created_at', 'updated_at', 'status', 'is_viewed', 'channel_booking_code']);
if ($booking['status'] != 'success') {
throw new ApiErrorException('Property Booking Data not found');
}
$bookingStatusColor = [
0 => '#CC0000',
1 => '#007E33',
2 => '#FF8800',
3 => '#9933CC',
];
if (!empty($booking['data'])) {
foreach ($booking['data'] as $dataKey => $data) {
$booking['data'][$dataKey]['booking_active_message_count'] = count($data['booking_active_message_count']);
$booking['data'][$dataKey]['booking_status']['bg-color'] = isset($bookingStatusColor[$booking['data'][$dataKey]['status']]) ? $bookingStatusColor[$booking['data'][$dataKey]['status']] : '#E0E0E0';
$booking['data'][$dataKey]['is_viewed'] = empty($data['is_viewed']) ? false : true;
}
}
$response = [
'status' => true,
'data' => $booking['data']
];
} catch (ApiErrorException $e) {
$response['message'] = $e->getMessage();
} catch (Exception $e) {
$message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage();
Log::error($message);
$response['message'] = $e->getMessage();
}
return output($response);
}
public function getPropertyBookingListFilter($param)
{
$response = ['status' => -1, 'message' => '', 'data' => null];
try {
$filter = [];
$propertyChannelParam = ['criteria' => [['field' => 'status', 'condition' => '=', 'value' => 1]]];
$propertyChannel = $this->propertyChannelRepository->findByCriteria($propertyChannelParam, ['id', 'name', 'restriction']);
$propertyChannel = array_filter($propertyChannel, function ($channel) use ($param) {
if (!empty($channel['restriction'])) {
$channelRestriction = json_decode($channel['restriction'], 1);
if (in_array($param['property_id'], $channelRestriction)) {
return $channel;
}
} else {
return $channel;
}
});
$filter['channel'] = array_values($propertyChannel);
$propertyBookingPaymentTypeParam = ['criteria' => [['field' => 'status', 'condition' => '=', 'value' => 1]]];
$propertyBookingPaymentType = $this->propertyBookingPaymentTypeRepository->findByCriteria($propertyBookingPaymentTypeParam, ['code', 'name', 'language_key']);
$filter['payment_type'] = $propertyBookingPaymentType;
$bookingStatusParam = ['criteria' => [['field' => 'status', 'condition' => '=', 'value' => 1]]];
$bookingStatus = $this->bookingStatusRepository->findByCriteria($bookingStatusParam, ['id', 'name', 'language_key']);
$filter['status'] = $bookingStatus;
$filter['date_type'] = [];
$filter['date_type'][] = ['code' => 'checkin_date', 'name' => 'Checkin Date', 'language_key' => 'enw-filter-checkin_date'];
$filter['date_type'][] = ['code' => 'checkout_date', 'name' => 'Checkout Date', 'language_key' => 'enw-filter-checkout_date'];
$filter['date_type'][] = ['code' => 'reservation_time', 'name' => 'Booking Date', 'language_key' => 'enw-filter-booking_date'];
$response = [
'status' => true,
'data' => $filter
];
} catch (ApiErrorException $e) {
$response['message'] = $e->getMessage();
} catch (Exception $e) {
$message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage();
Log::error($message);
$response['message'] = $e->getMessage();
}
return output($response);
}
public function getBookingDetail($param)
{
$response = ['status' => -1, 'message' => '', 'data' => null];
try {
$requestData = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')],
['field' => 'id', 'condition' => '=', 'value' => fillOnUndefined($param, 'booking_id')]
],
'with' => [
'bookingContact', 'bookingChannel', 'bookingAddon.propertyChannelAddon.propertyAddon.fact',
'bookingRoom.roomRateMapping.propertyRoom.propertyRoomType', 'bookingRoom.roomRateMapping.propertyRoomRate.propertyRoomRateAccommodation',
'bookingRoom.roomPax.paxCountry', 'bookingPayment', 'bookingPaymentType', 'bookingPaymentTransaction.paymentTypeMapping.paymentType',
'bookingPaymentData',
'bookingRoom.roomRateMapping.propertyRoom.propertyRoomBedGroup.propertyRoomBedType', 'bookingRoom.roomRateMapping.propertyRoom.smokingPreference.propertyFact',
'bookingRoom.smokingFact','propertyBookingEngineSearch'
],
'firstRow' => true
];
$booking = $this->select($requestData, ['id', 'property_id', 'channel_id', 'booking_code', 'search_key','channel_booking_code', 'coupon_code', 'reservation_time', 'checkin_date', 'checkout_date', 'payment_type_code', 'total', 'currency_code', 'created_at', 'updated_at', 'status', 'is_viewed']);
if ($booking['status'] != 'success') {
throw new ApiErrorException('Property Booking Data not found');
}
$booking['data']['voucher'] = null;
$propertyBookingEngineParam = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => $booking['data']['property_id']],
//['field' => 'channel_id', 'condition' => '=', 'value' => $booking['data']['channel_id']],
],
'firstRow' => true,
];
$propertyBookingEngine = $this->propertyBookingEngineRepository->findByCriteria($propertyBookingEngineParam);
if (!empty($propertyBookingEngine)) {
$booking['data']['voucher'] = Config::get('app.bookingEngineUrl') . '/' . $propertyBookingEngine['token'] . '/' . fillOnUndefined($param, 'locale', 'en') . '/booking-detail/' . $booking['data']['booking_code'];
}
if (!empty($booking['data']) && !empty($booking['data']['booking_room'])) {
$bookingRooms = &$booking['data']['booking_room'];
foreach ($bookingRooms as &$bookingRoom) {
$bookingRoom['cancellation_policy'] = json_decode($bookingRoom['cancellation_policy'], true);
$bookingRoom['rate_detail'] = json_decode($bookingRoom['rate_detail'], true);
//80678
//property_room_bed_group
//unset($bookingDetail['data']['booking_room'][$roomKey]['room_rate_mapping']['property_room']['property_room_bed_group']);
$propertyRoomBedGroup = collect($bookingRoom['room_rate_mapping']['property_room']['property_room_bed_group'])->groupBy('bed_group');
$propertyRoomBedGroup = $propertyRoomBedGroup ? $propertyRoomBedGroup->toArray() : null;
$bookingRoom['property_room_bed_group'] = null;
if(isset($propertyRoomBedGroup[$bookingRoom['property_room_bed_group_id']])) {
$bookingRoom['property_room_bed_group'] = $propertyRoomBedGroup[$bookingRoom['property_room_bed_group_id']];
}
}
}
$booking = $booking['data'];
$booking['booking_payment_transaction'] = collect($booking['booking_payment_transaction'])->map(function ($value) {
$return = $value;
unset($return['params']);
unset($return['extra_params']);
unset($return['response']);
unset($return['extraParamsArray']);
unset($return['paramsArray']);
unset($return['responseArray']);
unset($return['payment_type_mapping']);
$return['credit_card_number'] = isset($value['paramsArray']['creditCard']['number']) ? $value['paramsArray']['creditCard']['number'] : null;
$return['bank_name'] = isset($value['payment_type_mapping']['payment_type']) ? $value['payment_type_mapping']['payment_type']['name'] : null;
$return['bank_icon'] = isset($value['payment_type_mapping']['payment_type']) ? $value['payment_type_mapping']['payment_type']['icon'] : null;
$return['created_at'] = date('Y-m-d H:i:s', $value['created_at']);
$return['updated_at'] = date('Y-m-d H:i:s', $value['updated_at']);
return $return;
});
$booking['isThereBookingPaymentData'] = !empty($booking['booking_payment_data']) ? true : false;
unset($booking['booking_payment_data']);
$response = [
'status' => true,
'data' => $booking
];
} catch (ApiErrorException $e) {
$response['message'] = $e->getMessage();
} catch (Exception $e) {
$message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage();
Log::error($message);
$response['message'] = $e->getMessage();
}
return output($response);
}
public function getBookingListCount($param)
{
$response = ['status' => -1, 'message' => '', 'data' => null];
try {
$requestData = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')],
['field' => 'status', 'condition' => '=', 'value' => 1] // status 1 = booking
],
'count' => true
];
if (fillOnUndefined($param, 'channel_id')) {
$requestData['criteria'][] = ['field' => 'channel_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'channel_id')];
}
$booking = $this->select($requestData, ['id']);
if ($booking['status'] != 'success') {
throw new ApiErrorException('Property Booking Count Data not found');
}
$response = [
'status' => true,
'data' => $booking['data']
];
} catch (ApiErrorException $e) {
$response['message'] = $e->getMessage();
} catch (Exception $e) {
$message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage();
Log::error($message);
$response['message'] = $e->getMessage();
}
return output($response);
}
public function getTransactionList($param)
{
$response = ['status' => -1, 'message' => '', 'data' => null];
try {
$requestData = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')]
],
'orderBy' => [['field' => 'id', 'value' => 'DESC']],
'with' => ['bookingDetail.bookingContact', 'paymentTypeMapping.paymentType', 'paymentTransactionStatus', 'parentTransaction']
];
if (isset($param['filter']) && !empty($param['filter'])) {
$filterParams = [
'code' => [
'criteriaType' => 'LIKE'
],
'order_id' => [
'criteriaType' => 'LIKE'
],
'status' => [
'criteriaType' => 'EQUAL'
],
];
foreach ($param['filter'] as $inputName => $inputValue) {
if (!is_null($inputValue) && key_exists($inputName, $filterParams)) {
if ($filterParams[$inputName]['criteriaType'] == 'EQUAL') {
$requestData['criteria'][] = ['field' => $inputName, 'condition' => '=', 'value' => $inputValue];
} elseif ($filterParams[$inputName]['criteriaType'] == 'LIKE') {
$requestData['criteria'][] = ['field' => $inputName, 'condition' => 'LIKE', 'value' => '%' . $inputValue . '%'];
}
}
}
if (isset($param['filter']['date_range'])) {
$dateRange = explode(' ', $param['filter']['date_range']);
$requestData['criteria'][] = ['field' => 'created_at', 'condition' => '>=', 'value' => Carbon::parse($dateRange[0])->timestamp];
$requestData['criteria'][] = ['field' => 'created_at', 'condition' => '<', 'value' => Carbon::parse($dateRange[1])->addDay()->timestamp];
}
$requestData['take'] = 10000;
} else {
$requestData['take'] = 200;
}
//dd($requestData);
$transactions = $this->paymentTransactionRepository->findByCriteria($requestData);
$transactions = collect($transactions)->map(function ($value) {
$return = $value;
unset($return['params']);
unset($return['extra_params']);
unset($return['response']);
unset($return['extraParamsArray']);
unset($return['paramsArray']);
unset($return['responseArray']);
unset($return['payment_type_mapping']);
$return['credit_card_number'] = isset($value['paramsArray']['creditCard']['number']) ? $value['paramsArray']['creditCard']['number'] : null;
$return['bank_name'] = isset($value['payment_type_mapping']['payment_type']) ? $value['payment_type_mapping']['payment_type']['name'] : null;
$return['bank_icon'] = isset($value['payment_type_mapping']['payment_type']) ? $value['payment_type_mapping']['payment_type']['icon'] : null;
$return['created_at'] = date('Y-m-d H:i:s', $value['created_at']);
$return['updated_at'] = date('Y-m-d H:i:s', $value['updated_at']);
$return['payment_link'] = $value['status'] == 5 && $value['transaction_type'] != 'BKG' ? Config::get('app.paymentFormLink') . $value['order_id'] : null;
$return['status_language_key'] = isset($value['payment_transaction_status']['language_key']) ? $value['payment_transaction_status']['language_key'] : null;
if ($value['parent_transaction']) {
if ($value['parent_transaction']['status'] == 5) {
$return['id'] = $value['parent_transaction']['id'];
}
}
return $return;
});
$response = [
'status' => true,
'data' => $transactions
];
} catch (ApiErrorException $e) {
$response['message'] = $e->getMessage();
} catch (Exception $e) {
$message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage();
Log::error($message);
$response['message'] = $e->getMessage();
}
return output($response);
}
public function getBookingDetailedList($param)
{
$response = ['status' => -1, 'message' => '', 'data' => null];
try {
$requestData = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')]
],
'orderBy' => [['field' => 'id', 'value' => 'DESC']],
'with' => ['bookingContact', 'bookingChannel', 'bookingRoom', 'bookingRoom.roomPax.paxCountry', 'bookingPayment', 'bookingPaymentType', 'bookingPaymentTransaction.paymentTypeMapping.paymentType'],
];
if (fillOnUndefined($param, 'channel_id')) {
$requestData['criteria'][] = ['field' => 'channel_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'channel_id')];
}
$booking = $this->select($requestData, ['id', 'channel_id', 'booking_code', 'checkin_date', 'checkout_date', 'payment_type_code', 'total', 'currency_code', 'created_at', 'updated_at', 'status']);
if ($booking['status'] != 'success') {
throw new ApiErrorException('Property Booking Data not found');
}
$response = [
'status' => true,
'data' => $booking['data']
];
} catch (ApiErrorException $e) {
$response['message'] = $e->getMessage();
} catch (Exception $e) {
$message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage();
Log::error($message);
$response['message'] = $e->getMessage();
}
return output($response);
}
public function getBookingstatusList($param = [], $column = ['*'])
{
$response = ['status' => -1, 'message' => '', 'data' => null];
try {
$data = $this->bookingStatusRepository->findByCriteria($param, $column);
$response = [
'status' => true,
'data' => $data,
];
} catch (ApiErrorException $e) {
$response['message'] = $e->getMessage();
} catch (Exception $e) {
$message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage();
Log::error($message);
$response['message'] = $e->getMessage();
}
return output($response);
}
public function getBookingPayment($param)
{
$response = ['status' => -1, 'message' => '', 'data' => null];
DB::beginTransaction();
try {
//TODO: Validator
$confirmCode = fillOnUndefined($param, 'confirmCode');
$requestData = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')],
['field' => 'id', 'condition' => '=', 'value' => fillOnUndefined($param, 'booking_id')]
],
'with' => ['bookingPaymentData', 'bookingPaymentDataCheck'],
'firstRow' => true
];
$bookingDetail = $this->select($requestData, ['id', 'property_id', 'channel_id', 'channel_manager_id', 'search_key', 'booking_code', 'channel_booking_code', 'reservation_time', 'checkin_date', 'checkout_date', 'payment_type_code', 'total', 'currency_code', 'created_at', 'updated_at', 'status']);
if ($bookingDetail['status'] != 'success') {
throw new ApiErrorException('Property Booking Data not found');
}
if ($bookingDetail['status'] != 'success' || empty($bookingDetail['data'])) {
throw new ApiErrorException('Booking not found');
}
$bookingDetail = $bookingDetail['data'];
if (in_array($bookingDetail['channel_manager_id'], [null])) {
if (!in_array($bookingDetail['payment_type_code'], ['HTL', 'CHN'])) {
throw new ApiErrorException('Only available for pay at hotel');
}
} elseif (in_array($bookingDetail['channel_manager_id'], [1, 2])) {
if (!in_array($bookingDetail['payment_type_code'], ['CRD', 'CHN'])) {
throw new ApiErrorException('Only available for pay at credit card');
}
}
if (empty($bookingDetail['booking_payment_data'])) {
throw new ApiErrorException('Payment information not available');
}
$bookingPaymentDataCheck = $bookingDetail['booking_payment_data_check'];
switch ($bookingDetail['channel_manager_id']) {
case '1':
$bookingPaymentData = $bookingDetail['booking_payment_data'];
$getBookingPaymentDataCollect = collect($bookingPaymentData);
$isChannelManagerPaymentData = $getBookingPaymentDataCollect->where('type', 'ch')->first();
if ($isChannelManagerPaymentData) {
$channelPaymentDataUrl = 'https://www.reseliva.com/siteBase/REST/tsr/?lang=tr&res_id=' . $bookingDetail['search_key'] . '&hash=' . $isChannelManagerPaymentData['data'];
$response = [
'status' => true,
'data' => [
'type' => 'redirect',
'redirectUrl' => $channelPaymentDataUrl,
'channel_manager_id' => $bookingDetail['channel_manager_id']
],
];
} else {
throw new ApiErrorException('Payment data not found.');
}
break;
case '2':
$isConfirmCodeRequire = true;
if (empty($confirmCode) && $isConfirmCodeRequire) {
if (count($bookingPaymentDataCheck) > 2) {
throw new ApiErrorException('Payment information can only be viewed 3 times');
}
$unlockCode = rand(1000, 9999);
$paymentDataCheckParam = [
'booking_id' => $bookingDetail['id'],
'code' => md5($unlockCode),
'status' => 2,
'expiry_time' => Carbon::now()->addMinutes(30)->timestamp,
'created_by' => fillOnUndefined($param, 'user_id'),
'updated_by' => fillOnUndefined($param, 'user_id'),
];
$createPaymentDataCheck = $this->bookingPaymentDataCheckRepository->create($paymentDataCheckParam);
if ($createPaymentDataCheck['status'] != 'success') {
throw new Exception('api-unknown_error');
}
$response = [
'status' => true,
'data' => [
'type' => 'code',
'expiry_time' => Carbon::createFromTimestamp($paymentDataCheckParam['expiry_time'])->toDateTimeString(),
'channel_manager_id' => $bookingDetail['channel_manager_id']
//'code' => $unlockCode
]
];
//BookingPaymentDataCode
$mailParams = [
'user_id' => $param['user_id'],
'booking_id' => $bookingDetail['id'],
'unlock_code' => $unlockCode
];
$this->mailer->send(new BookingPaymentDataCodeMail($mailParams));
//BookingPaymentDataCode
} else {
if ($isConfirmCodeRequire) {
$bookingPaymentDataCheckCollect = collect($bookingPaymentDataCheck);
$bookingPaymentDataCheckRow = $bookingPaymentDataCheckCollect
->where('code', md5($confirmCode))
->where('status', 2)
->where('expiry_time', '>', Carbon::now()->timestamp)
->first();
if (empty($bookingPaymentDataCheckRow)) {
throw new ApiErrorException('Code could not be verified, please check again');
}
}
$bookingPaymentData = $bookingDetail['booking_payment_data'];
$getBookingPaymentDataCollect = collect($bookingPaymentData);
$isChannelManagerPaymentData = $getBookingPaymentDataCollect->where('type', 'ch')->sortByDesc('id')->first();
$channelService = App::make("App\Core\Service\ChannelManager\Channex");
$sessionTokenParam = [
'session_token' => [
//'scope' => 'card'
'scope' => 'show_card'
]
];
$sessionToken = $channelService->getSessionToken($sessionTokenParam);
$sessionToken = $sessionToken['status'] ? $sessionToken['data']['id'] : null;
$serviceCodeTokenParam = [
'session_token' => [
//'scope' => 'service_code'
'scope' => 'show_service_code'
]
];
$serviceCodeToken = $channelService->getSessionToken($serviceCodeTokenParam);
$serviceCodeToken = $serviceCodeToken['status'] ? $serviceCodeToken['data']['id'] : null;
$channelPaymentDataUrl = 'https://pci.channex.io/api/v1/show_card?card_token=' . $isChannelManagerPaymentData['data'] . '&session_token=' . $sessionToken . '&service_code_token=' . $serviceCodeToken;
$response = [
'status' => true,
'data' => [
'type' => 'redirect',
'redirectUrl' => $channelPaymentDataUrl,
'channel_manager_id' => $bookingDetail['channel_manager_id']
],
];
}
break;
default :
if (empty($confirmCode)) {
if (count($bookingPaymentDataCheck) > 2) {
throw new ApiErrorException('Payment information can only be viewed 3 times');
}
$unlockCode = rand(1000, 9999);
$paymentDataCheckParam = [
'booking_id' => $bookingDetail['id'],
'code' => md5($unlockCode),
'status' => 2,
'expiry_time' => Carbon::now()->addMinutes(30)->timestamp,
'created_by' => fillOnUndefined($param, 'user_id'),
'updated_by' => fillOnUndefined($param, 'user_id'),
];
$createPaymentDataCheck = $this->bookingPaymentDataCheckRepository->create($paymentDataCheckParam);
if ($createPaymentDataCheck['status'] != 'success') {
throw new Exception('api-unknown_error');
}
$response = [
'status' => true,
'data' => [
'type' => 'code',
'expiry_time' => Carbon::createFromTimestamp($paymentDataCheckParam['expiry_time'])->toDateTimeString(),
'channel_manager_id' => $bookingDetail['channel_manager_id']
//'code' => $unlockCode
]
];
//BookingPaymentDataCode
$mailParams = [
'user_id' => $param['user_id'],
'booking_id' => $bookingDetail['id'],
'unlock_code' => $unlockCode
];
$this->mailer->send(new BookingPaymentDataCodeMail($mailParams));
//$this->mailer->onQueue('bookingPaymentDataCode', new BookingPaymentDataCodeMail($mailParams));
//BookingPaymentDataCode
} else {
if (empty($bookingPaymentDataCheck)) {
throw new ApiErrorException('No request to view payment information yet');
}
$bookingPaymentDataCheckCollect = collect($bookingPaymentDataCheck);
$bookingPaymentDataCheckRow = $bookingPaymentDataCheckCollect
->where('code', md5($confirmCode))
->where('status', 2)
->where('expiry_time', '>', Carbon::now()->timestamp)
->first();
if (empty($bookingPaymentDataCheckRow)) {
throw new ApiErrorException('Code could not be verified, please check again');
}
$bookingPaymentDataEncrypted = collect($bookingDetail['booking_payment_data'])->groupBy('type')->toArray();
$bookingPaymentData = [];
foreach ($bookingPaymentDataEncrypted as $type => $value) {
if ($type == 'cc') {
$value = collect($value)->sortBy('id')->toArray();
foreach ($value as $cardValue) {
$bookingPaymentData[$type][] = Crypt::decrypt($cardValue['data']);
}
$bookingPaymentData[$type] = implode(' ', $bookingPaymentData[$type]);
} else {
$cardValue = reset($value);
$bookingPaymentData[$type] = Crypt::decrypt($cardValue['data']);
}
}
$this->bookingPaymentDataCheckRepository->update($bookingPaymentDataCheckRow['id'], ['status' => 1, 'confirm_time' => Carbon::now()->timestamp]);
$bookingPaymentData['bookingCode'] = $bookingDetail['booking_code'];
$response = [
'status' => true,
'data' => $bookingPaymentData
];
}
break;
}
} catch (ApiErrorException $e) {
$response['message'] = $e->getMessage();
} catch (Exception $e) {
$message = $e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage();
Log::error($message);
$response['message'] = $e->getMessage();
}
if ($response['status']) {
DB::commit();
} else {
DB::rollBack();
}
return output($response);
}
}