894 lines
36 KiB
PHP
894 lines
36 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers\ChannelManager\ElektraWeb\v1;
|
||
|
||
use App\Core\Service\PropertyChannelService;
|
||
use App\Core\Service\PropertyChannelMappingService;
|
||
use App\Core\Service\PropertyRoomRateChannelMappingService;
|
||
use App\Core\Service\PropertyRoomRatePriceService;
|
||
use App\Core\Service\PropertyRoomAvailabilityService;
|
||
use App\Core\Service\PropertyRoomService;
|
||
use App\Core\Service\BookingService;
|
||
use App\Core\Service\ChannelManagerLogService;
|
||
use App\Core\Service\ChannelManagerPropertyMappingService;
|
||
use App\Http\Controllers\Controller;
|
||
use Carbon\Carbon;
|
||
use Illuminate\Http\Request;
|
||
|
||
use App;
|
||
use Illuminate\Support\Facades\Cache;
|
||
use Illuminate\Support\Facades\DB;
|
||
use Illuminate\Support\Facades\Log;
|
||
use Illuminate\Support\Facades\Config;
|
||
use Exception;
|
||
use App\Exceptions\ApiErrorException;
|
||
|
||
class ElektraWebController extends Controller
|
||
{
|
||
|
||
|
||
private $username;
|
||
private $password;
|
||
|
||
private $request;
|
||
private $propertyChannelService;
|
||
private $propertyChannelMappingService;
|
||
private $propertyRoomRatePriceService;
|
||
private $param;
|
||
private $channelId;
|
||
private $channelManagerLogId;
|
||
private $channelManagerRequestTime;
|
||
|
||
|
||
public function __construct(
|
||
Request $request,
|
||
PropertyChannelService $propertyChannelService,
|
||
PropertyChannelMappingService $propertyChannelMappingService,
|
||
PropertyRoomRateChannelMappingService $propertyRoomRateChannelMappingService,
|
||
PropertyRoomRatePriceService $propertyRoomRatePriceService,
|
||
PropertyRoomAvailabilityService $propertyRoomAvailabilityService,
|
||
PropertyRoomService $propertyRoomService,
|
||
BookingService $bookingService,
|
||
ChannelManagerPropertyMappingService $channelManagerPropertyMappingService,
|
||
ChannelManagerLogService $channelManagerLogService
|
||
)
|
||
{
|
||
|
||
//Note: channel_manager_property_mapping tablosunda channel_manager_property_id alanı NULL ise, bu ENW nin CHANNEL tarafından yönetiliyor olması demek.
|
||
//Eğer channel_manager_property_id alanında bir otel id var ise, bu CHANNEL ın ENW tarafından güncelleniyor olması demek.
|
||
|
||
$this->username = 'elektraweb';
|
||
$this->password = 'XGgK2BSYCERDaVAx';
|
||
|
||
$this->request = $request;
|
||
$this->propertyChannelService = $propertyChannelService;
|
||
$this->propertyChannelMappingService = $propertyChannelMappingService;
|
||
$this->propertyRoomRateChannelMappingService = $propertyRoomRateChannelMappingService;
|
||
$this->propertyRoomRatePriceService = $propertyRoomRatePriceService;
|
||
$this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService;
|
||
$this->propertyRoomService = $propertyRoomService;
|
||
$this->bookingService = $bookingService;
|
||
$this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService;
|
||
$this->channelManagerLogService = $channelManagerLogService;
|
||
|
||
$payload = $this->request->getContent();
|
||
$payloadJson = json_decode($payload, 1);
|
||
$this->param = $payloadJson;
|
||
|
||
$this->channelId = 1;
|
||
$this->channelManagerId = 4; //ElektraWeb
|
||
|
||
$getRequestUri = $request->getRequestUri();
|
||
$getRequestUriExplode = explode('/', $getRequestUri);
|
||
$serviceRequestName = last($getRequestUriExplode);
|
||
|
||
//channelManagerLogService
|
||
$logArray = ['update-room-availability', 'update-room-rate'];
|
||
$this->channelManagerLogId = null;
|
||
$this->channelManagerRequestTime = microtime(true);
|
||
if (in_array($serviceRequestName, $logArray)) {
|
||
$insertDataLog = [
|
||
'property_id' => $this->param['hotel_id'],
|
||
'channel_manager_id' => $this->channelManagerId,
|
||
'type' => 'C2E',
|
||
'service' => $serviceRequestName,
|
||
'request' => json_encode($payloadJson),
|
||
'ip_address' => $this->request->ip(),
|
||
'response' => null,
|
||
'status' => null
|
||
];
|
||
|
||
|
||
$channelManagerLog = $this->channelManagerLogService->create($insertDataLog);
|
||
if ($channelManagerLog['status'] == 'success') {
|
||
$this->channelManagerLogId = $channelManagerLog['data']['id'];
|
||
}
|
||
}
|
||
//channelManagerLogService
|
||
|
||
}
|
||
|
||
public function checkAuthentication($username, $password)
|
||
{
|
||
|
||
$response = ['status' => false, 'message' => ''];
|
||
|
||
if ($this->username != $username || $this->password != $password) {
|
||
$response['message'] = 'Your username or password is incorrect.';
|
||
} else {
|
||
$response['status'] = true;
|
||
}
|
||
|
||
return $response;
|
||
|
||
}
|
||
|
||
|
||
public function responseError($errorMessage)
|
||
{
|
||
|
||
$response = [
|
||
'status' => false,
|
||
'message' => $errorMessage,
|
||
];
|
||
|
||
//channelManagerLogService
|
||
if (!is_null($this->channelManagerLogId)) {
|
||
$updateDataLog = [
|
||
'response' => json_encode($response),
|
||
'status' => 0
|
||
];
|
||
|
||
if (!is_null($this->channelManagerRequestTime)) {
|
||
$updateDataLog['response_time'] = microtime(true) - $this->channelManagerRequestTime;
|
||
}
|
||
|
||
$channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog);
|
||
}
|
||
//channelManagerLogService
|
||
|
||
return response()->json($response);
|
||
|
||
}
|
||
|
||
public function responseSuccess($responseData = null)
|
||
{
|
||
|
||
$response = [
|
||
'status' => true,
|
||
'message' => null,
|
||
'data' => $responseData,
|
||
];
|
||
|
||
//channelManagerLogService
|
||
if (!is_null($this->channelManagerLogId)) {
|
||
$updateDataLog = [
|
||
'response' => json_encode($response),
|
||
'status' => 1
|
||
];
|
||
|
||
if (!is_null($this->channelManagerRequestTime)) {
|
||
$updateDataLog['response_time'] = microtime(true) - $this->channelManagerRequestTime;
|
||
}
|
||
|
||
$channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog);
|
||
}
|
||
//channelManagerLogService
|
||
|
||
return response()->json($response);
|
||
|
||
}
|
||
|
||
public function propertyChannelMapping($propertyId)
|
||
{
|
||
|
||
$response = ['status' => false, 'message' => ''];
|
||
|
||
try {
|
||
|
||
$propertyChannelMappingCriteria = [
|
||
'criteria' => [
|
||
['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId],
|
||
['field' => 'property_id', 'condition' => '=', 'value' => $propertyId],
|
||
['field' => 'status', 'condition' => '=', 'value' => 1],
|
||
],
|
||
'firstRow' => true
|
||
];
|
||
|
||
|
||
$propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria);
|
||
|
||
if ($propertyChannelMapping['status'] != 'success') {
|
||
throw new ApiErrorException($propertyChannelMapping['message']);
|
||
}
|
||
|
||
$response = [
|
||
'status' => true,
|
||
'data' => $propertyChannelMapping['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 channelPropertyRoomRate($propertyId)
|
||
{
|
||
|
||
$response = ['status' => false, 'message' => ''];
|
||
|
||
try {
|
||
|
||
$requestParam = [
|
||
'criteria' => [
|
||
['field' => 'channel_id', 'condition' => '=', 'value' => $this->channelId],
|
||
['field' => 'property_id', 'condition' => '=', 'value' => $propertyId],
|
||
['field' => 'status', 'condition' => '=', 'value' => 1],
|
||
],
|
||
'with' => [
|
||
'propertyRoomRateMapping.propertyRoomRate.propertyRoomRateAccommodation',
|
||
'propertyRoomRateMapping.propertyRoom.propertyRoomType',
|
||
]
|
||
];
|
||
|
||
$getChannelPropertyRoomRate = $this->propertyRoomRateChannelMappingService->select($requestParam);
|
||
|
||
if ($getChannelPropertyRoomRate['status'] != 'success' || empty($getChannelPropertyRoomRate['data'])) {
|
||
throw new ApiErrorException('Property Room Rate not found');
|
||
}
|
||
|
||
$getChannelPropertyRoomRate['data'] = collect($getChannelPropertyRoomRate['data'])->where('property_room_rate_mapping.property_room.status',1)->toArray();
|
||
|
||
$response = [
|
||
'status' => true,
|
||
'data' => $getChannelPropertyRoomRate['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 channelManagerPropertyCheck($propertyId)
|
||
{
|
||
|
||
$response = ['status' => false, 'message' => ''];
|
||
|
||
try {
|
||
|
||
$requestParam =
|
||
[
|
||
'criteria' =>
|
||
[
|
||
['field' => 'status', 'condition' => '=', 'value' => 1],
|
||
['field' => 'property_id', 'condition' => '=', 'value' => $propertyId],
|
||
['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId],
|
||
],
|
||
'firstRow' => true
|
||
];
|
||
|
||
$channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($requestParam);
|
||
|
||
|
||
//TODO: burada otelinde kendisine bakmak lazım status
|
||
|
||
|
||
if ($channelManagerPropertyMapping['status'] != 'success' || empty($channelManagerPropertyMapping['data'])) {
|
||
throw new ApiErrorException('Property Room Rate not found');
|
||
}
|
||
|
||
$channelManagerPropertyMapping = $channelManagerPropertyMapping['data'];
|
||
|
||
if (!is_null($channelManagerPropertyMapping['channel_manager_property_id'])) {
|
||
throw new ApiErrorException('This hotel can only be updated by ENW');
|
||
}
|
||
|
||
$response = [
|
||
'status' => true
|
||
];
|
||
|
||
|
||
} 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 roomRate(Request $request)
|
||
{
|
||
|
||
$response = ['status' => false, 'message' => ''];
|
||
|
||
//checkAuthentication
|
||
$checkAuthentication = $this->checkAuthentication($this->param['username'], $this->param['password']);
|
||
if (!$checkAuthentication['status']) {
|
||
return $this->responseError($checkAuthentication['message']);
|
||
}
|
||
|
||
try {
|
||
|
||
$propertyId = $this->param['hotel_id'];
|
||
|
||
$channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId);
|
||
if (!$channelManagerPropertyCheck['status']) {
|
||
throw new ApiErrorException($channelManagerPropertyCheck['message']);
|
||
}
|
||
|
||
|
||
$channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId);
|
||
if (!$channelPropertyRoomRate['status']) {
|
||
throw new ApiErrorException($channelPropertyRoomRate['message']);
|
||
}
|
||
|
||
$channelPropertyRoomRate = $channelPropertyRoomRate['data'];
|
||
|
||
|
||
$propertyChannelMapping = $this->propertyChannelMapping($propertyId);
|
||
if (!$propertyChannelMapping['status']) {
|
||
throw new ApiErrorException($propertyChannelMapping['message']);
|
||
}
|
||
|
||
$propertyChannelMapping = $propertyChannelMapping['data'];
|
||
|
||
|
||
$response = [];
|
||
|
||
$roomRates = [];
|
||
foreach ($channelPropertyRoomRate as $roomRate) {
|
||
|
||
if($roomRate['property_room_rate_mapping']['property_room_rate']['name'] == 'Best Available Rate') {
|
||
continue;
|
||
}
|
||
|
||
$roomRates[$roomRate['property_room_rate_mapping']['room_id']]['room'] = [
|
||
'id' => $roomRate['property_room_rate_mapping']['property_room']['id'],
|
||
'name' => $roomRate['property_room_rate_mapping']['property_room']['name'],
|
||
'status' => 'Active',
|
||
'max_adult' => $roomRate['property_room_rate_mapping']['property_room']['max_adult'],
|
||
'max_child' => $roomRate['property_room_rate_mapping']['property_room']['max_child'],
|
||
'max_occupancy' => $roomRate['property_room_rate_mapping']['property_room']['max_occupancy'],
|
||
];
|
||
|
||
$roomRates[$roomRate['property_room_rate_mapping']['room_id']]
|
||
['rate'][$roomRate['property_room_rate_mapping']['id']] = [
|
||
'id' => $roomRate['property_room_rate_mapping']['id'],
|
||
'name' => $roomRate['property_room_rate_mapping']['property_room_rate']['property_room_rate_accommodation']['name'],
|
||
'rate' => $roomRate['property_room_rate_mapping']['property_room_rate']['name'],
|
||
'accommodationId' => $roomRate['property_room_rate_mapping']['property_room_rate']['property_room_rate_accommodation']['id'],
|
||
'included_occupancy' => $roomRate['property_room_rate_mapping']['included_occupancy'],
|
||
];
|
||
|
||
}
|
||
|
||
$roomKey = 0;
|
||
$response['rooms'] = [];
|
||
foreach ($roomRates as $roomId => $roomRate) {
|
||
|
||
$response['rooms'][$roomKey] = [
|
||
'id' => $roomId,
|
||
'room_name' => $roomRate['room']['name'],
|
||
'max_adult' => $roomRate['room']['max_adult'],
|
||
'max_child' => $roomRate['room']['max_child'],
|
||
'max_occupancy' => $roomRate['room']['max_occupancy'],
|
||
];
|
||
|
||
$roomRateKey = 0;
|
||
$response['rooms'][$roomKey]['rates'] = [];
|
||
foreach ($roomRate['rate'] as $roomRateMappingId => $rateData) {
|
||
|
||
$response['rooms'][$roomKey]['rates'][$roomRateKey] = [
|
||
'id' => $roomRateMappingId,
|
||
'rate_name' => $rateData['name'] . ' - ' . $rateData['rate'],
|
||
'board_id' => $rateData['accommodationId'],
|
||
'board_name' => $rateData['name'],
|
||
'included_occupancy' => floor($rateData['included_occupancy']),
|
||
];
|
||
|
||
$roomRateKey++;
|
||
|
||
}
|
||
|
||
$roomKey++;
|
||
}
|
||
|
||
return $this->responseSuccess($response);
|
||
|
||
|
||
} catch (ApiErrorException $e) {
|
||
$response['message'] = implode(', ', $e->getMessageArr());
|
||
} catch (Exception $e) {
|
||
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
|
||
Log::error($message);
|
||
$response['message'] = $e->getMessage();
|
||
}
|
||
|
||
if (!$response['status']) {
|
||
return $this->responseError($response['message']);
|
||
}
|
||
|
||
}
|
||
|
||
public function updateRoomAvailability(Request $request)
|
||
{
|
||
|
||
$response = ['status' => false, 'message' => ''];
|
||
|
||
try {
|
||
|
||
//checkAuthentication
|
||
$checkAuthentication = $this->checkAuthentication($this->param['username'], $this->param['password']);
|
||
if (!$checkAuthentication['status']) {
|
||
return $this->responseError($checkAuthentication['message']);
|
||
}
|
||
|
||
$propertyId = $this->param['hotel_id'];
|
||
|
||
$channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId);
|
||
if (!$channelManagerPropertyCheck['status']) {
|
||
throw new ApiErrorException($channelManagerPropertyCheck['message']);
|
||
}
|
||
|
||
$channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId);
|
||
if (!$channelPropertyRoomRate['status']) {
|
||
throw new ApiErrorException($channelPropertyRoomRate['message']);
|
||
}
|
||
|
||
$channelPropertyRoomRate = $channelPropertyRoomRate['data'];
|
||
$channelPropertyRoomRateCollect = collect($channelPropertyRoomRate);
|
||
|
||
|
||
$propertyChannelMapping = $this->propertyChannelMapping($propertyId);
|
||
if (!$propertyChannelMapping['status']) {
|
||
throw new ApiErrorException($propertyChannelMapping['message']);
|
||
}
|
||
|
||
$propertyChannelMapping = $propertyChannelMapping['data'];
|
||
|
||
$roomAvailabilities = $this->param['rooms'];
|
||
|
||
// Merge consecutive dates with same availability and stop_sell
|
||
usort($roomAvailabilities, function ($a, $b) {
|
||
if ($a['room_id'] === $b['room_id']) {
|
||
return strcmp($a['start_date'], $b['start_date']);
|
||
}
|
||
return $a['room_id'] <=> $b['room_id'];
|
||
});
|
||
|
||
$mergedAvailabilities = [];
|
||
$currentAvailability = null;
|
||
|
||
foreach ($roomAvailabilities as $availability) {
|
||
if ($currentAvailability === null) {
|
||
$currentAvailability = $availability;
|
||
continue;
|
||
}
|
||
|
||
$currentEnd = Carbon::parse($currentAvailability['end_date']);
|
||
$nextStart = Carbon::parse($availability['start_date']);
|
||
|
||
$isConsecutive = $currentEnd->addDay()->toDateString() === $nextStart->toDateString();
|
||
|
||
$sameRoomId = ($currentAvailability['room_id'] === $availability['room_id']);
|
||
$sameAvailability = (isset($currentAvailability['availability']) && isset($availability['availability']) && $currentAvailability['availability'] === $availability['availability']) || (!isset($currentAvailability['availability']) && !isset($availability['availability']));
|
||
$sameStopSell = (isset($currentAvailability['stop_sell']) && isset($availability['stop_sell']) && $currentAvailability['stop_sell'] === $availability['stop_sell']) || (!isset($currentAvailability['stop_sell']) && !isset($availability['stop_sell']));
|
||
|
||
if ($isConsecutive && $sameRoomId && $sameAvailability && $sameStopSell) {
|
||
$currentAvailability['end_date'] = $availability['end_date'];
|
||
} else {
|
||
$mergedAvailabilities[] = $currentAvailability;
|
||
$currentAvailability = $availability;
|
||
}
|
||
}
|
||
|
||
if ($currentAvailability !== null) {
|
||
$mergedAvailabilities[] = $currentAvailability;
|
||
}
|
||
|
||
$roomAvailabilities = $mergedAvailabilities;
|
||
$roomAvailabilitiesCollect = collect($roomAvailabilities);
|
||
|
||
DB::beginTransaction();
|
||
|
||
$startDate = $roomAvailabilitiesCollect->sortBy('start_date')->first();
|
||
$startDate = $startDate['start_date'];
|
||
|
||
$endDate = $roomAvailabilitiesCollect->sortByDesc('end_date')->first();
|
||
$endDate = $endDate['end_date'];
|
||
|
||
if (Carbon::parse($startDate)->isBefore(Carbon::now()->toDateString()) || Carbon::parse($endDate)->isBefore(Carbon::now()->toDateString())) {
|
||
throw new ApiErrorException('Dates to be updated cannot be earlier than today');
|
||
}
|
||
|
||
foreach ($roomAvailabilities as $availability) {
|
||
|
||
$roomId = $availability['room_id'];
|
||
|
||
$roomCheck = $channelPropertyRoomRateCollect->where('property_room_rate_mapping.room_id', $roomId)->isEmpty();
|
||
if ($roomCheck) {
|
||
throw new ApiErrorException('Undefined or inactive room accommodation');
|
||
}
|
||
|
||
$totalInventoryAvailable = null;
|
||
if (isset($availability['availability'])) {
|
||
$totalInventoryAvailable = $availability['availability'];
|
||
}
|
||
|
||
$startDate = Carbon::parse($availability['start_date'])->toDateString();
|
||
$endDate = Carbon::parse($availability['end_date'])->toDateString();
|
||
|
||
$requestParamBase = [
|
||
'property_id' => fillOnUndefined($propertyChannelMapping, 'property_id'),
|
||
'channel_id' => fillOnUndefined($propertyChannelMapping, 'channel_id'),
|
||
'availability_type_id' => fillOnUndefined($propertyChannelMapping, 'property_availability_type_id', 1),
|
||
'start_date' => $startDate,
|
||
'end_date' => $endDate,
|
||
'include_days' => ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
||
];
|
||
|
||
|
||
if (!is_null($totalInventoryAvailable)) {
|
||
|
||
$requestParams = [];
|
||
$requestParams = $requestParamBase;
|
||
$requestParams['update_type'] = 'availability';
|
||
$requestParams['value'] = $totalInventoryAvailable;
|
||
$requestParams['room_rates'] = [
|
||
['room_id' => $roomId]
|
||
];
|
||
|
||
$propertyRoomRateMapping = $this->propertyRoomAvailabilityService->bulkUpdate($requestParams);
|
||
|
||
if ($propertyRoomRateMapping['status'] != 'success') {
|
||
throw new ApiErrorException($propertyRoomRateMapping['message']);
|
||
}
|
||
|
||
}
|
||
|
||
|
||
if (isset($availability['stop_sell']) && !is_null($availability['stop_sell'])) {
|
||
|
||
$requestParams = [];
|
||
$requestParams = $requestParamBase;
|
||
$requestParams['update_type'] = 'room_stop_sell';
|
||
$requestParams['value'] = $availability['stop_sell'];
|
||
$requestParams['room_rates'] = [
|
||
['room_id' => $roomId]
|
||
];
|
||
|
||
$propertyRoomRateMapping = $this->propertyRoomAvailabilityService->bulkUpdate($requestParams);
|
||
|
||
if ($propertyRoomRateMapping['status'] != 'success') {
|
||
throw new ApiErrorException($propertyRoomRateMapping['message']);
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
DB::commit();
|
||
|
||
return $this->responseSuccess(['confirmCode' => $this->channelManagerLogId]);
|
||
|
||
} 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();
|
||
}
|
||
|
||
DB::rollBack();
|
||
|
||
if (!$response['status']) {
|
||
return $this->responseError($response['message']);
|
||
}
|
||
|
||
}
|
||
|
||
public function updateRoomRate(Request $request)
|
||
{
|
||
|
||
$response = ['status' => false, 'message' => ''];
|
||
|
||
try {
|
||
|
||
//checkAuthentication
|
||
$checkAuthentication = $this->checkAuthentication($this->param['username'], $this->param['password']);
|
||
if (!$checkAuthentication['status']) {
|
||
return $this->responseError($checkAuthentication['message']);
|
||
}
|
||
|
||
$propertyId = $this->param['hotel_id'];
|
||
|
||
$channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId);
|
||
if (!$channelManagerPropertyCheck['status']) {
|
||
throw new ApiErrorException($channelManagerPropertyCheck['message']);
|
||
}
|
||
|
||
$channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId);
|
||
if (!$channelPropertyRoomRate['status']) {
|
||
throw new ApiErrorException($channelPropertyRoomRate['message']);
|
||
}
|
||
|
||
$channelPropertyRoomRate = $channelPropertyRoomRate['data'];
|
||
$channelPropertyRoomRateCollect = collect($channelPropertyRoomRate);
|
||
|
||
|
||
$propertyChannelMapping = $this->propertyChannelMapping($propertyId);
|
||
if (!$propertyChannelMapping['status']) {
|
||
throw new ApiErrorException($propertyChannelMapping['message']);
|
||
}
|
||
|
||
$propertyChannelMapping = $propertyChannelMapping['data'];
|
||
|
||
$roomRates = $this->param['rooms'];
|
||
$roomRatesCollect = collect($roomRates);
|
||
|
||
$paramsListChannel = [];
|
||
$paramsListChannel[] = $this->channelId;
|
||
|
||
//CONNECTED CHANNEL RATE UPDATE
|
||
/*$propertyChannelMappingConnectedCriteria = [
|
||
'criteria' => [
|
||
['field' => 'property_id', 'condition' => '=', 'value' => $propertyId],
|
||
['field' => 'connected_channel_id', 'condition' => '=', 'value' => $this->channelId],
|
||
['field' => 'channel_id', 'condition' => '=', 'value' => 5],//JUST CM
|
||
['field' => 'status', 'condition' => '=', 'value' => 1],
|
||
],
|
||
'with' => ['channel']
|
||
];
|
||
|
||
$propertyChannelMappingConnected = $this->propertyChannelMappingService->select($propertyChannelMappingConnectedCriteria);
|
||
if ($propertyChannelMappingConnected['status'] == 'success') {
|
||
|
||
foreach ($propertyChannelMappingConnected['data'] as $channel) {
|
||
|
||
if (!is_null($channel['channel']['parent_id'])) {
|
||
continue;
|
||
}
|
||
|
||
$paramsListChannel[] = $channel['channel_id'];
|
||
|
||
}
|
||
|
||
}*/
|
||
//CONNECTED CHANNEL RATE UPDATE
|
||
|
||
|
||
DB::beginTransaction();
|
||
|
||
foreach ($roomRates as $roomRate) {
|
||
|
||
$roomId = $roomRate['room_id'];
|
||
|
||
$roomCheck = $channelPropertyRoomRateCollect->where('property_room_rate_mapping.room_id', $roomId)->isEmpty();
|
||
if ($roomCheck) {
|
||
//throw new ApiErrorException('Undefined or inactive room accommodation');
|
||
continue;
|
||
}
|
||
|
||
$rates = $roomRate['rates'];
|
||
if (empty($rates)) {
|
||
continue;
|
||
}
|
||
|
||
// Sort by rate_id and then start_date to ensure we process them in order for each rate_id
|
||
usort($rates, function ($a, $b) {
|
||
if ($a['rate_id'] === $b['rate_id']) {
|
||
return strcmp($a['start_date'], $b['start_date']);
|
||
}
|
||
return strcmp($a['rate_id'], $b['rate_id']);
|
||
});
|
||
|
||
$mergedRates = [];
|
||
$currentRate = null;
|
||
|
||
foreach ($rates as $rate) {
|
||
if ($currentRate === null) {
|
||
$currentRate = $rate;
|
||
continue;
|
||
}
|
||
|
||
$currentEnd = Carbon::parse($currentRate['end_date']);
|
||
$nextStart = Carbon::parse($rate['start_date']);
|
||
|
||
$isConsecutive = $currentEnd->addDay()->toDateString() === $nextStart->toDateString();
|
||
|
||
$sameRateId = ($currentRate['rate_id'] === $rate['rate_id']);
|
||
$sameAmount = (isset($currentRate['amount']) && isset($rate['amount']) && (float)$currentRate['amount'] === (float)$rate['amount']) || (!isset($currentRate['amount']) && !isset($rate['amount']));
|
||
$sameStopSell = (isset($currentRate['stop_sell']) && isset($rate['stop_sell']) && $currentRate['stop_sell'] === $rate['stop_sell']) || (!isset($currentRate['stop_sell']) && !isset($rate['stop_sell']));
|
||
$sameMinStay = (isset($currentRate['min_stay']) && isset($rate['min_stay']) && $currentRate['min_stay'] === $rate['min_stay']) || (!isset($currentRate['min_stay']) && !isset($rate['min_stay']));
|
||
|
||
if ($isConsecutive && $sameRateId && $sameAmount && $sameStopSell && $sameMinStay) {
|
||
$currentRate['end_date'] = $rate['end_date'];
|
||
} else {
|
||
$mergedRates[] = $currentRate;
|
||
$currentRate = $rate;
|
||
}
|
||
}
|
||
|
||
if ($currentRate !== null) {
|
||
$mergedRates[] = $currentRate;
|
||
}
|
||
|
||
|
||
$roomRatesCollect = collect($mergedRates);
|
||
|
||
$startDate = $roomRatesCollect->sortBy('start_date')->first();
|
||
$startDate = $startDate['start_date'];
|
||
|
||
$endDate = $roomRatesCollect->sortByDesc('end_date')->first();
|
||
$endDate = $endDate['end_date'];
|
||
|
||
if (Carbon::parse($startDate)->isBefore(Carbon::now()->toDateString()) || Carbon::parse($endDate)->isBefore(Carbon::now()->toDateString())) {
|
||
throw new ApiErrorException('Dates to be updated cannot be earlier than today');
|
||
}
|
||
|
||
foreach ($mergedRates as $rate) {
|
||
|
||
$startDate = Carbon::parse($rate['start_date'])->toDateString();
|
||
$endDate = Carbon::parse($rate['end_date'])->toDateString();
|
||
|
||
$requestParamBase = [
|
||
'property_id' => fillOnUndefined($propertyChannelMapping, 'property_id'),
|
||
'channel_id' => fillOnUndefined($propertyChannelMapping, 'channel_id'),
|
||
'availability_type_id' => fillOnUndefined($propertyChannelMapping, 'property_availability_type_id', 1),
|
||
'start_date' => $startDate,
|
||
'end_date' => $endDate,
|
||
'include_days' => ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
||
];
|
||
|
||
|
||
$roomRateMappingId = $rate['rate_id'];
|
||
|
||
$isCloseRoomRateMappingSale = null;
|
||
if (isset($rate['stop_sell'])) {
|
||
$isCloseRoomRateMappingSale = $rate['stop_sell'] == 1 ? true : false;
|
||
}
|
||
|
||
|
||
$channelRoomRateMappingCheck = $channelPropertyRoomRateCollect->where('room_rate_mapping_id', $roomRateMappingId)->isEmpty();
|
||
if ($channelRoomRateMappingCheck) {
|
||
//throw new ApiErrorException('Undefined or inactive room accommodation');
|
||
continue;
|
||
}
|
||
|
||
$roomRates = [];
|
||
$roomRates[] = [
|
||
'room_id' => $roomId,
|
||
'room_rate_mapping_id' => [
|
||
$roomRateMappingId
|
||
]
|
||
];
|
||
|
||
foreach ($paramsListChannel as $paramChannelId) {
|
||
|
||
//Eğer Rate var ise currency check yapılmalı ve PerDay var mı check edilmeli, burada sonra günceleme yaptırılabilri
|
||
if (isset($rate['amount'])) {
|
||
|
||
$currency = $this->param['currency'];
|
||
|
||
$currencyCheck = ($currency == $propertyChannelMapping['currency_code']) ? true : false;
|
||
|
||
if (!$currencyCheck) {
|
||
throw new ApiErrorException('Exchange rate that does not match the channel exchange rate, channel exchange rate: ' . $propertyChannelMapping['currency_code']);
|
||
}
|
||
|
||
$channelRoomRateMapping = $channelPropertyRoomRateCollect->where('room_rate_mapping_id', $roomRateMappingId)->first();
|
||
|
||
$requestParams = [];
|
||
$requestParams = $requestParamBase;
|
||
$requestParams['update_type'] = 'rate';
|
||
$requestParams['value'] = $rate['amount'];
|
||
$requestParams['room_rates'] = $roomRates;
|
||
|
||
$requestParams['channel_id'] = $paramChannelId;
|
||
$requestParams['ip_address'] = $this->request->ip();
|
||
|
||
$propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams);
|
||
|
||
if ($propertyRoomRateMapping['status'] != 'success') {
|
||
throw new ApiErrorException($propertyRoomRateMapping['message']);
|
||
}
|
||
|
||
}
|
||
|
||
|
||
//Room Rate Stop Sale
|
||
if (!is_null($isCloseRoomRateMappingSale)) {
|
||
$requestParams = [];
|
||
$requestParams = $requestParamBase;
|
||
$requestParams['update_type'] = 'rate_stop_sell';
|
||
$requestParams['value'] = $isCloseRoomRateMappingSale ? 1 : 0;
|
||
$requestParams['room_rates'] = $roomRates;
|
||
|
||
$requestParams['channel_id'] = $paramChannelId;
|
||
$requestParams['ip_address'] = $this->request->ip();
|
||
|
||
$propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams);
|
||
|
||
if ($propertyRoomRateMapping['status'] != 'success') {
|
||
throw new ApiErrorException($propertyRoomRateMapping['message']);
|
||
}
|
||
}
|
||
|
||
|
||
//Kısıtlamalar var ise min los
|
||
if (isset($rate['min_stay'])) {
|
||
|
||
//Minimum Konaklama Gün Sayısı
|
||
if (isset($rate['min_stay'])) {
|
||
|
||
$requestParams = [];
|
||
$requestParams = $requestParamBase;
|
||
$requestParams['update_type'] = 'min_stay';
|
||
$requestParams['value'] = $rate['min_stay'];
|
||
$requestParams['room_rates'] = $roomRates;
|
||
|
||
$requestParams['channel_id'] = $paramChannelId;
|
||
$requestParams['ip_address'] = $this->request->ip();
|
||
|
||
$propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams);
|
||
|
||
if ($propertyRoomRateMapping['status'] != 'success') {
|
||
throw new ApiErrorException($propertyRoomRateMapping['message']);
|
||
}
|
||
|
||
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
}
|
||
}
|
||
|
||
DB::commit();
|
||
|
||
|
||
return $this->responseSuccess(['confirmCode' => $this->channelManagerLogId]);
|
||
|
||
} 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();
|
||
}
|
||
|
||
DB::rollBack();
|
||
|
||
if (!$response['status']) {
|
||
return $this->responseError($response['message']);
|
||
}
|
||
|
||
}
|
||
|
||
|
||
}
|