first commit

This commit is contained in:
ExtraNetwork
2026-05-12 17:04:54 +03:00
commit e5c4b6aa13
1425 changed files with 284735 additions and 0 deletions

View File

View File

@@ -0,0 +1,48 @@
<?php
namespace App\Console\Commands\ApplicationLanguageFiles;
use App\Core\Service\LanguageBaseService;
use App\Exceptions\ApiErrorException;
use Illuminate\Console\Command;
use Exception;
use Illuminate\Support\Facades\Log;
class ApplicationFillTableLanguageKey extends Command
{
protected $signature = 'cron:create-application-fill-table-language-key'; // read table name column, update table key column
protected $description = '';
private $languageBaseService;
public function __construct(
LanguageBaseService $languageBaseService
)
{
$this->languageBaseService = $languageBaseService;
parent::__construct();
}
public function handle()
{
try {
$this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' LANGUAGE BASE START');
$process = $this->languageBaseService->fillApplicationLanguageKeys();
if($process['status'] != 'success'){
throw new Exception($process['message']) ;
}
$this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' LANGUAGE BASE FINISHED');
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message);
}
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace App\Console\Commands\ApplicationLanguageFiles;
use App\Core\Service\LanguageBaseService;
use App\Exceptions\ApiErrorException;
use Illuminate\Console\Command;
use Exception;
use Illuminate\Support\Facades\Log;
class ApplicationLanguageBaseData extends Command
{
protected $signature = 'cron:create-application-language-base-data'; // tables to translate_base table import data ..
protected $description = '';
private $languageBaseService;
public function __construct(
LanguageBaseService $languageBaseService
)
{
$this->languageBaseService = $languageBaseService;
parent::__construct();
}
public function handle()
{
try {
$this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' LANGUAGE BASE START');
$process = $this->languageBaseService->createApplicationLanguageBaseData();
if($process['status'] != 'success'){
throw new Exception($process['message']) ;
}
$this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' LANGUAGE BASE FINISHED');
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message);
}
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace App\Console\Commands\ApplicationLanguageFiles;
use App\Core\Service\LanguageBaseService;
use App\Exceptions\ApiErrorException;
use Illuminate\Console\Command;
use Exception;
use Illuminate\Support\Facades\Log;
class ApplicationLanguageFiles extends Command
{
protected $signature = 'cron:create-application-language-files'; // fill common.json ...
protected $description = '';
private $languageBaseService;
public function __construct(
LanguageBaseService $languageBaseService
)
{
$this->languageBaseService = $languageBaseService;
parent::__construct();
}
public function handle()
{
try {
$this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' LANGUAGE CREATE JSON START');
$process = $this->languageBaseService->createApplicationLanguageFiles();
if($process['status'] != 'success'){
throw new Exception($process['message']) ;
}
$this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' LANGUAGE CREATE JSON FINISHED');
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message);
}
}
}

View File

@@ -0,0 +1,356 @@
<?php
namespace App\Console\Commands\ChannelManager;
use App\Core\Mail\LogMail;
use App\Core\Service\ChannelManagerPropertyMappingService;
use App\Core\Service\PropertyBookingEngineService;
use App\Core\Service\PropertyChannelMappingService;
use App\Core\Service\PropertyRoomRateChannelMappingService;
use App\Core\Service\PropertyRoomRatePriceService;
use App\Exceptions\ApiErrorException;
use App\Http\Controllers\BookingEngine\V1\SearchController;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class BestAvailableRateSyncService extends Command
{
protected $signature = 'cron:bar-sync-service {--property_id=}';
protected $description = '';
protected $mailer;
public function __construct(
Mailer $mailer,
ChannelManagerPropertyMappingService $channelManagerPropertyMappingService,
PropertyRoomRateChannelMappingService $propertyRoomRateChannelMappingService,
PropertyBookingEngineService $propertyBookingEngineService,
PropertyRoomRatePriceService $propertyRoomRatePriceService
)
{
parent::__construct();
$this->mailer = $mailer;
$this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService;
$this->propertyRoomRateChannelMappingService = $propertyRoomRateChannelMappingService;
$this->propertyBookingEngineService = $propertyBookingEngineService;
$this->propertyRoomRatePriceService = $propertyRoomRatePriceService;
}
public function handle()
{
$this->info(date('Y-m-d H:i:s') . ' : Start');
$requestParam =
[
'criteria' =>
[
['field' => 'status', 'condition' => '=', 'value' => 1],
['field' => 'channel_manager_id', 'condition' => '=', 'value' => 2],//Channex
['field' => 'channel_manager_property_id', 'condition' => '!=', 'value' => null],
],
'with' => ['property']
];
$howManyDays = 90;
if (!is_null($this->option('property_id'))) {
$requestParam['criteria'][] = ['field' => 'property_id', 'condition' => '=', 'value' => $this->option('property_id')];
$howManyDays = 6 * 30;
}
$channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($requestParam);
$channelManagerPropertyMapping = $channelManagerPropertyMapping['status'] == 'success' ? $channelManagerPropertyMapping['data'] : [];
foreach ($channelManagerPropertyMapping as $propertyMapping) {
if ($propertyMapping['property']['status'] != 1) {
$this->error(date('Y-m-d H:i:s') . ' : ' . $propertyMapping['property']['name']);
continue;
}
$response = ['status' => false, 'message' => ''];
try {
$propertyRoomRateChannelMappingParam = [
'criteria' => [
['field' => 'channel_id', 'condition' => '=', 'value' => 5],//Kanal Yöentimi
['field' => 'property_id', 'condition' => '=', 'value' => $propertyMapping['property_id']],
['field' => 'status', 'condition' => '=', 'value' => 1],
],
'with' => [
'propertyRoomRateMapping.propertyRoomRate.propertyRoomRateAccommodation',
'propertyRoomRateMapping.propertyRoom.propertyRoomType',
]
];
$propertyRoomRateChannelMapping = $this->propertyRoomRateChannelMappingService->select($propertyRoomRateChannelMappingParam);
$propertyRoomRateChannelMapping = $propertyRoomRateChannelMapping['status'] == 'success' ? $propertyRoomRateChannelMapping['data'] : [];
$propertyRoomRateChannelMappingCollect = collect($propertyRoomRateChannelMapping);
$propertyBookingEngineParam = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => $propertyMapping['property_id']],
['field' => 'channel_id', 'condition' => '=', 'value' => 1],
['field' => 'status', 'condition' => '=', 'value' => 1],
],
'with' => ['channel', 'property.propertyBookingEngineToken'],
'firstRow' => 1
];
$propertyBookingEngine = $this->propertyBookingEngineService->select($propertyBookingEngineParam, ['id', 'property_id', 'channel_id', 'token']);
$propertyBookingEngine = $propertyBookingEngine['status'] == 'success' ? $propertyBookingEngine['data'] : [];
if (empty($propertyBookingEngine)) {
$this->info(date('Y-m-d H:i:s') . ' : None Booking Engine!');
continue;
}
$searchController = App::make("App\Http\Controllers\BookingEngine\V1\SearchController");
$roomRateFormatted = [];
$today = Carbon::now()->startOfDay()->toDateTimeString();
if (!is_null($this->option('property_id'))) {
$today = Carbon::now()->startOfDay()->toDateTimeString();
} else {
//00:00 04:00 08:00 12:00 16:00 20:00
$processHour = (integer)Carbon::now()->format('H');
switch ($processHour) {
case ($processHour >= 0 && $processHour <= 2) :
case ($processHour > 8 && $processHour <= 10):
case ($processHour > 16 && $processHour <= 18):
$today = Carbon::now()->startOfDay()->toDateTimeString();
break;
case ($processHour > 2 && $processHour <= 4) :
case ($processHour > 10 && $processHour <= 12):
case ($processHour > 18 && $processHour <= 20) :
$today = Carbon::now()->startOfDay()->addDays($howManyDays)->toDateTimeString();
break;
case ($processHour > 4 && $processHour <= 6) :
case ($processHour > 12 && $processHour <= 14):
case ($processHour > 20 && $processHour <= 22) :
$today = Carbon::now()->startOfDay()->addDays($howManyDays * 2)->toDateTimeString();
break;
case ($processHour > 6 && $processHour <= 8) :
case ($processHour > 14 && $processHour <= 16):
case ($processHour > 22 && $processHour < 24) :
$today = Carbon::now()->startOfDay()->addDays($howManyDays * 3)->toDateTimeString();
break;
}
}
for ($i = 0; $i < $howManyDays; $i++) {
$checkIn = Carbon::parse($today)->addDays($i)->toDateString();
$checkOut = Carbon::parse($checkIn)->addDay()->toDateString();
$searchRequestJson = [
'date' => [
'checkIn' => $checkIn,
'checkOut' => $checkOut,
],
'rooms' => [
[
'adults' => 2,
'children' => 0,
'age' => [],
]
],
'property' => [],
'ipAddress' => '185.137.215.118',
'isMobile' => null,
'noneCacheSearch' => true,
'min_stay_disabled' => true
];
$requestCreate = Request::create(null, null, [], [], [], [], json_encode($searchRequestJson));
$requestCreate->headers->set('channelId', '1');
$requestCreate->headers->set('bookingEnginePropertyId', $propertyMapping['property_id']);
$requestCreate->headers->set('channelToken', $propertyBookingEngine['channel']['token']);
$requestCreate->headers->set('bookingEngineToken', $propertyBookingEngine['property']['property_booking_engine_token']['token']);
$search = $searchController->search($requestCreate);
$search = json_decode(json_encode($search), 1);
$this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['name'] . ' - ' . $checkIn);
if ($search['original']['status'] == 200) {
if (empty($search['original']['data']['properties'])) {
//Rate Stop or Price 0 Case
foreach ($propertyRoomRateChannelMapping as $roomRateChannelMapping) {
$referenceRoomRateMapping = $propertyRoomRateChannelMappingCollect
->where('property_room_rate_mapping.room_id', $roomRateChannelMapping['property_room_rate_mapping']['room_id'])
->where('property_room_rate_mapping.property_room_rate.name', 'Best Available Rate')->first();
if (!empty($referenceRoomRateMapping)) {
$roomRateKey = '1|' . $referenceRoomRateMapping['property_room_rate_mapping']['room_id'] . '|' . $referenceRoomRateMapping['property_room_rate_mapping']['id'] . '|' . $checkIn;
$roomRateFormatted[$roomRateKey] = [
'setup_type_id' => '1',
'room_id' => $referenceRoomRateMapping['property_room_rate_mapping']['room_id'],
'room_rate_mapping_id' => $referenceRoomRateMapping['property_room_rate_mapping']['id'],
'date' => $checkIn,
'amount' => 0
];
}
}
//Rate Stop or Price 0 Case
$this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['name'] . ' - ' . $checkIn . ' - NONE');
continue;
}
$property = reset($search['original']['data']['properties']);
if (empty($property)) {
$this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['name'] . ' - ' . $checkIn . ' - NONE');
continue;
}
if (!isset($property['availabilities'])) {
$this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['name'] . ' - ' . $checkIn . ' - NONE');
continue;
}
$propertyAvailability = reset($property['availabilities']);
if (empty($propertyAvailability)) {
$this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['name'] . ' - ' . $checkIn . ' - NONE');
continue;
}
/*dd($propertyAvailability['rooms']);
$propertyAvailabilityRoom = reset($propertyAvailability['rooms']);
if (empty($propertyAvailability)) {
$this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['name'] . ' - ' . $checkIn . ' - NONE');
continue;
}
$propertyAvailabilityRoom['rates'] = collect($propertyAvailabilityRoom['rates'])->sortBy('total')->toArray();
*/
foreach ($propertyAvailability['rooms'] as $roomId => $room) {
foreach ($room['rates'] as $roomRateInnerKey => $roomRate) {
/*$propertyAvailabilityRoomRate = reset($propertyAvailabilityRoom['rates']);
if (empty($propertyAvailabilityRoomRate)) {
$this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['name'] . ' - ' . $checkIn . ' - NONE');
continue;
}*/
$propertyAvailabilityRoomRatePrices = reset($roomRate['requestedRoomPrice']);
if (empty($propertyAvailabilityRoomRatePrices)) {
$this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['name'] . ' - ' . $checkIn . ' - NONE');
continue;
}
$propertyAvailabilityRoomRatePrice = reset($propertyAvailabilityRoomRatePrices['prices']);
if (empty($propertyAvailabilityRoomRatePrice)) {
$this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['name'] . ' - ' . $checkIn . ' - NONE');
continue;
}
$this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['id'] . ' - ' . $propertyBookingEngine['property']['name'] . ' - ' . $checkIn . ' - ' . $propertyAvailabilityRoomRatePrice['total']);
$referenceRoomRateMapping = $propertyRoomRateChannelMappingCollect
->where('property_room_rate_mapping.room_id', $roomId)
->where('property_room_rate_mapping.property_room_rate.name', 'Best Available Rate')->first();
if (empty($referenceRoomRateMapping)) {
$this->info(date('Y-m-d H:i:s') . ' : None Best Available Rate! PropertyId: ' . $propertyMapping['property_id'] . ' Room: ' . $room['name']);
continue;
}
/*if($referenceRoomRateMapping['property_room_rate_mapping']['id'] != 6003) {
continue;
}*/
$roomRateKey = '1|' . $referenceRoomRateMapping['property_room_rate_mapping']['room_id'] . '|' . $referenceRoomRateMapping['property_room_rate_mapping']['id'] . '|' . $checkIn;
if (!isset($roomRateFormatted[$roomRateKey])) {
$roomRateFormatted[$roomRateKey] = [
'setup_type_id' => '1',
'room_id' => $referenceRoomRateMapping['property_room_rate_mapping']['room_id'],
'room_rate_mapping_id' => $referenceRoomRateMapping['property_room_rate_mapping']['id'],
'date' => $checkIn,
'amount' => $propertyAvailabilityRoomRatePrice['total']
];
}
if ($propertyAvailabilityRoomRatePrice['total'] < $roomRateFormatted[$roomRateKey]['amount']) {
$roomRateFormatted[$roomRateKey]['amount'] = $propertyAvailabilityRoomRatePrice['total'];
}
}
}
} else {
$this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['name'] . ' - ' . $checkIn . ' - NONE');
}
}
$requestParams = [
'property_id' => $propertyMapping['property_id'],
'channel_id' => 5,
'availability' => [],
'user_id' => 1,
'rates' => $roomRateFormatted
];
$roomRateUpdate = $this->propertyRoomRatePriceService->roomRateUpdate($requestParams);
if ($roomRateUpdate['status'] != 'success') {
throw new ApiErrorException($roomRateUpdate['message']);
}
$response['status'] = true;
$this->info(date('Y-m-d H:i:s') . ' : ' . $propertyBookingEngine['property']['id'] . ' : ' . $propertyBookingEngine['property']['name'] . ' - Today: ' . $today . ' - OK');
Log::debug($propertyBookingEngine['property']['id'] . ' : ' . $propertyBookingEngine['property']['name'] . ' - Today: ' . $today . ' - OK');
} catch (ApiErrorException $e) {
$response['message'] = implode(', ', $e->getMessageArr());
$this->error(date('Y-m-d H:i:s') . ' : ' . $response['message']);
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$response['message'] = $e->getMessage();
}
}
$this->info(date('Y-m-d H:i:s') . ' : Finished');
}
}

View File

@@ -0,0 +1,130 @@
<?php
namespace App\Console\Commands\ChannelManager;
use App\Core\Mail\LogMail;
use App\Core\Service\ChannelManagerBookingService;
use App\Exceptions\ApiErrorException;
use App\Models\Booking;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Log;
use Exception;
class MetaCancellationService extends Command
{
protected $signature = 'cron:meta-cancellation-service';
protected $description = '';
protected $channelService;
public function __construct(
Mailer $mailer,
ChannelManagerBookingService $channelManagerBookingService
)
{
parent::__construct();
$this->mailer = $mailer;
$this->channelManagerBookingService = $channelManagerBookingService;
}
public function handle()
{
$this->info(date('Y-m-d H:i:s') . ' : Start');
$today = Carbon::now()->startOfDay()->toDateString();
if(!Carbon::parse($today)->isLastOfMonth()) {
$this->alert(date('Y-m-d H:i:s') . ' : Not Today!');
return false;
}
$fistDayOfMonth = Carbon::parse($today)->startOfMonth()->toDateString();
$lastDayOfMonth = Carbon::parse($today)->addMonth()->startOfMonth()->toDateString();
$cancellationBooking = Booking::where('channel_id', 1)
->where('status', 0)
->where('checkout_date', '>', $fistDayOfMonth)
->where('checkout_date', '<', $lastDayOfMonth)
//->where('id', 68690)
->with('channelManagerBooking')
->with('bookingRoom')
->get();
//11 - Trivago
$cancellationBooking = $cancellationBooking ? $cancellationBooking->toArray() : [];
foreach ($cancellationBooking as $booking) {
try {
if (empty($booking['channel_manager_booking'])) {
$this->line(date('Y-m-d H:i:s') . ' : Booking ID: ' . $booking['id']);
continue;
}
$channelBookingCheck = collect($booking['channel_manager_booking'])
->where('channel_manager_id', 11)
->where('type', 'Booking')
->where('is_pushed', 1)
->isEmpty();
if ($channelBookingCheck) {
$this->line(date('Y-m-d H:i:s') . ' : Booking ID: ' . $booking['id']);
continue;
}
$channelCancelCheck = collect($booking['channel_manager_booking'])
->where('channel_manager_id', 11)
->where('type', 'Cancel')
->where('is_pushed', 1)
->isEmpty();
if (!$channelCancelCheck) {
$this->line(date('Y-m-d H:i:s') . ' : Booking ID: ' . $booking['id']);
continue;
}
$channelManagerBookingCreateParam = [
'property_id' => $booking['property_id'],
'booking_id' => $booking['id'],
'channel_manager_id' => 11,
'type' => 'Cancel',
];
$this->channelManagerBookingService->create($channelManagerBookingCreateParam);
$this->info(date('Y-m-d H:i:s') . ' : Booking ID: ' . $booking['id']);
} catch (ApiErrorException $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage());
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message);
}
}
$this->info(date('Y-m-d H:i:s') . ' : Finished');
}
}

View File

@@ -0,0 +1,72 @@
<?php
namespace App\Console\Commands\ChannelManager;
use App\Core\Mail\LogMail;
use App\Core\Service\PropertyRoomRatePriceService;
use App\Core\Service\PropertyRoomService;
use App\Exceptions\ApiErrorException;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Maatwebsite\Excel\Facades\Excel;
use PhpOffice\PhpSpreadsheet\IOFactory;
class PropertyBookingSyncService extends Command
{
protected $signature = 'cron:propertybooking-sync-service';
protected $description = '';
protected $mailer;
public function __construct(
Mailer $mailer,
PropertyRoomService $propertyRoomService,
PropertyRoomRatePriceService $propertyRoomRatePriceService
)
{
parent::__construct();
$this->mailer = $mailer;
$this->propertyRoomService = $propertyRoomService;
$this->propertyRoomRatePriceService = $propertyRoomRatePriceService;
}
public function handle()
{
$sourcePath = 'C:\www\api.extranetwork.com\app\Console\Commands\ChannelManager\akgun.xlsx';
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$spreadsheet = $reader->load($sourcePath);
$sheet = $spreadsheet->getSheet($spreadsheet->getFirstSheetIndex());
$rows = $sheet->toArray();
$rowKey = 0;
foreach ($rows as $row) {
$rowKey++;
if($rowKey < 3) {
continue;
}
dd($row);
}
//dd(file_exists($sourcePath));
$this->info(date('Y-m-d H:i:s') . ' : Start');
$this->info(date('Y-m-d H:i:s') . ' : Finished');
}
}

View File

@@ -0,0 +1,222 @@
<?php
namespace App\Console\Commands\ChannelManager;
use App\Core\Mail\LogMail;
use App\Core\Service\ChannelManager\Reseliva;
use App\Core\Service\ChannelManagerService;
use App\Core\Service\PropertyRoomAvailabilityQueueService;
use App\Core\Service\PropertyRoomRatePriceService;
use App\Core\Service\PropertyRoomService;
use App\Exceptions\ApiErrorException;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class PropertyChannelSyncService extends Command
{
protected $signature = 'cron:propertychannel-sync-service';
protected $description = '';
protected $mailer;
public function __construct(
Mailer $mailer,
PropertyRoomService $propertyRoomService,
PropertyRoomRatePriceService $propertyRoomRatePriceService
)
{
parent::__construct();
$this->mailer = $mailer;
$this->propertyRoomService = $propertyRoomService;
$this->propertyRoomRatePriceService = $propertyRoomRatePriceService;
}
public function handle()
{
$sourceChannelId = 1; //Booking Engine
$targetChannelId = 5; //Channel Manager
$propertyIdList = [1098];
$this->info(date('Y-m-d H:i:s') . ' : Start');
foreach ($propertyIdList as $propertyId) {
$this->info(date('Y-m-d H:i:s') . ' - AVAILABILITY START : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId);
$isPropertyRoomAvailabilityUpdate = false;
DB::beginTransaction();
try {
$propertyRoomAvailabilityUpdateQuery = <<<BUR
UPDATE property_room_availability SET status = 1 WHERE property_id = {$propertyId} AND date >= curdate() AND channel_id IS NULL AND status = 1;
BUR;
$propertyRoomAvailabilityUpdate = DB::select(DB::raw($propertyRoomAvailabilityUpdateQuery));
$isPropertyRoomAvailabilityUpdate = true;
} catch (ApiErrorException $e) {
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage());
} catch (\Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message);
}
if ($isPropertyRoomAvailabilityUpdate) {
DB::commit();
$this->info(date('Y-m-d H:i:s') . ' - AVAILABILITY SUCCESS : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId);
} else {
DB::rollBack();
$this->info(date('Y-m-d H:i:s') . ' - AVAILABILITY ERROR : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId);
}
$this->info(date('Y-m-d H:i:s') . ' - AVAILABILITY FINISHED : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId);
$this->info(date('Y-m-d H:i:s') . ' - RATE START : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId);
$requestParams = [
'property_id' => $propertyId,
'channel_id' => $sourceChannelId,
'start_date' => Carbon::now()->toDateString(),
'end_date' => Carbon::now()->addMonths(6)->subDay()->toDateString(),
//'start_date' => '2023-03-01',
//'end_date' => '2024-01-01',
];
$propertyRoomType = $this->propertyRoomService->getPropertyRoomInventory($requestParams);
if ($propertyRoomType['status'] != 'success') {
throw new ApiErrorException($propertyRoomType['message']);
}
$propertyRoomType = $propertyRoomType['data'];
$propertyRoomRateAvailability = collect($propertyRoomType);
$roomRates = [];
foreach ($propertyRoomRateAvailability as $room) {
foreach ($room['property_room_rate_mapping'] as $roomRateMapping) {
foreach ($room['room_availability'] as $date => $roomAvailability) {
$roomRates[$room['id']]['availability'][$date] = $roomAvailability['value'];
}
$roomRates[$room['id']]['rate'][$roomRateMapping['id']] = [
'roomName' => $room['name'],
'roomRateName' => $roomRateMapping['name'],
'currencyCode' => $roomRateMapping['currency_code'],
];
$roomRatePrices = reset($roomRateMapping['prices']);
foreach ($roomRatePrices['price'] as $date => $roomRatePrice) {
$roomRates[$room['id']]['rate'][$roomRateMapping['id']]['price'][$date] = $roomRatePrice['value'];
$roomRates[$room['id']]['rate'][$roomRateMapping['id']]['stopSell'][$date] = $roomRatePrice['stop_sell'];
}
foreach ($roomRatePrices['stop_sell'] as $date => $stopSell) {
$roomRates[$room['id']]['rate'][$roomRateMapping['id']]['stopSell'][$date] = $stopSell['value'];
}
foreach ($roomRatePrices['min_stay'] as $date => $minStay) {
$roomRates[$room['id']]['rate'][$roomRateMapping['id']]['minStay'][$date] = $minStay['value'];
}
}
}
$roomRateFormatted = [];
foreach ($roomRates as $roomId => $roomRateMapping) {
foreach ($roomRateMapping['rate'] as $roomRateMappingId => $roomRate) {
foreach ($roomRate['price'] as $date => $price) {
$roomRateKey = '1|' . $roomId . '|' . $roomRateMappingId . '|' . $date;
$roomRateFormatted[$roomRateKey] = [
'setup_type_id' => '1',
'room_id' => $roomId,
'room_rate_mapping_id' => $roomRateMappingId,
'date' => $date,
'amount' => is_null($price) ? 0 : $price,
'min_stay' => $roomRate['minStay'][$date],
'stop_sell' => $roomRate['stopSell'][$date],
];
}
}
}
$isPropertyRoomRateUpdate = false;
DB::beginTransaction();
try {
$roomRateFormattedChunked = array_chunk($roomRateFormatted, 1000);
foreach ($roomRateFormattedChunked as $roomRateFormattedParsed) {
$requestParams = [
'property_id' => $propertyId,
'channel_id' => $targetChannelId,
'rates' => $roomRateFormattedParsed
];
$roomRateUpdate = $this->propertyRoomRatePriceService->roomRateUpdate($requestParams);
if ($roomRateUpdate['status'] != 'success') {
throw new ApiErrorException($roomRateUpdate['message']);
}
}
$isPropertyRoomRateUpdate = true;
} catch (ApiErrorException $e) {
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage());
} catch (\Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message);
}
if ($isPropertyRoomRateUpdate) {
DB::commit();
$this->info(date('Y-m-d H:i:s') . ' - RATE SUCCESS : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId);
} else {
DB::rollBack();
$this->info(date('Y-m-d H:i:s') . ' - RATE ERROR : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId);
}
$this->info(date('Y-m-d H:i:s') . ' - RATE FINISHED : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId);
}
$this->info(date('Y-m-d H:i:s') . ' : Finished');
}
}

View File

@@ -0,0 +1,344 @@
<?php
namespace App\Console\Commands\ChannelManager;
use App\Core\Mail\LogMail;
use App\Exceptions\ApiErrorException;
use App\Models\PropertyMeta;
use App\Models\PropertyMetaRoomRate;
use App\Models\PropertyMetaRoomRatePrice;
use App\Models\PropertyRoomRatePrice;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class PropertyMetaRoomRatePriceService extends Command
{
protected $signature = 'cron:propertymeta-roomrateprice-service {--property_id=}';
protected $description = '';
protected $mailer;
public function __construct(
Mailer $mailer
)
{
parent::__construct();
$this->mailer = $mailer;
}
public function handle()
{
$this->info(date('Y-m-d H:i:s') . ' : Start');
if (!is_null($this->option('property_id'))) {
$propertyMeta = PropertyMeta::where('status', 1)->where('property_id', $this->option('property_id'))->with('property')->orderBy('id', 'ASC')->get(['id', 'property_id', 'cancellation_policy', 'adult_policy', 'child_policy', 'promotion', 'status'])->toArray();
} else {
$propertyMeta = PropertyMeta::where('status', 1)->with('property')->orderBy('id', 'ASC')->get(['id', 'property_id', 'cancellation_policy', 'adult_policy', 'child_policy', 'promotion', 'status'])->toArray();
}
foreach ($propertyMeta as $property) {
$this->info(date('Y-m-d H:i:s') . ' : Property Room Rate Price Start: ' . $property['property']['name']);
$roomRateOccupancyPriceParam = [];
$propertyId = $property['property_id'];
$startDate = Carbon::now()->toDateString();
$finishDate = Carbon::parse($startDate)->addDays(360)->toDateString();
$propertyCancellationPolicy = json_decode($property['cancellation_policy'], 1);
$propertyAdultPolicy = json_decode($property['adult_policy'], 1);
$propertyChildPolicy = json_decode($property['child_policy'], 1);
$propertyPromotion = json_decode($property['promotion'], 1);
$propertyRoomRatePrice = PropertyRoomRatePrice::where('property_id', $propertyId)
->where('date', '>=', $startDate)
->where('date', '<=', $finishDate)
->where('channel_id', 1)
//->where('room_rate_mapping_id', 79)//TODO: Delete
//->where('date', '2024-09-01')//TODO: Delete
->where('availability_type_id', 1)
->where('status', 1)
->get(['id', 'property_id', 'property_room_id', 'room_rate_mapping_id', 'date', 'amount', 'currency', 'min_stay', 'stop_sell']);
$propertyRoomRatePrice = $propertyRoomRatePrice->toArray();
$roomRateOccupancy = PropertyMetaRoomRate::where('property_id', $propertyId)->get()->toArray();
//TODO: DEL
//$roomRateOccupancy = collect($roomRateOccupancy)->where('occupancy_code', 'A')->toArray();
$propertyAllPriceCounter = 0;
$roomRateOccupancyPrice = [];
foreach ($propertyRoomRatePrice as $perPropertyRoomRatePrice) {
$roomRateOccupancySelected = collect($roomRateOccupancy)->where('room_rate_mapping_id', $perPropertyRoomRatePrice['room_rate_mapping_id'])->toArray();
foreach ($roomRateOccupancySelected as $roomRateOccupancyKey => $perRoomRateOccupancy) {
$baseAmount = $perPropertyRoomRatePrice['amount'];
$roomRateOccupancyKey = $perRoomRateOccupancy['code'];
$affectedAmountArray = [];
$roomRateMappingId = $perPropertyRoomRatePrice['room_rate_mapping_id'];
$cancellationPolicy = isset($propertyCancellationPolicy[$roomRateMappingId]) ? $propertyCancellationPolicy[$roomRateMappingId] : [];
$adultPolicy = isset($propertyAdultPolicy[$roomRateMappingId]) ? $propertyAdultPolicy[$roomRateMappingId] : [];
$childPolicy = isset($propertyChildPolicy[$roomRateMappingId]) ? $propertyChildPolicy[$roomRateMappingId] : [];
$promotions = isset($propertyPromotion[$roomRateMappingId]) ? $propertyPromotion[$roomRateMappingId] : [];
//dd($promotions,$perPropertyRoomRatePrice,$baseAmount);
$perPersonAmount = $baseAmount / $perRoomRateOccupancy['included_occupancy'];
//Kişi bazlı fiyat hesaplamada baz fiyat dikkate alınır, daha sonra $perPersonAmount baz fiyat üzerinden alınıp çocuk hespaplanır.
//Adult Policy
$affectedAmount = 0;
if ($perRoomRateOccupancy['included_occupancy'] != strlen($perRoomRateOccupancy['occupancy_code'])) {
if (!empty($adultPolicy)) {
if ($perRoomRateOccupancy['included_occupancy'] > strlen($perRoomRateOccupancy['occupancy_code'])) {
$occupancyDifference = $perRoomRateOccupancy['included_occupancy'] - strlen($perRoomRateOccupancy['occupancy_code']);
$adultPolicySelected = collect($adultPolicy)
->where('adult', $occupancyDifference)
->where('adult_action_type', 'DEC')
->first();
if (!empty($adultPolicySelected)) {
if ($adultPolicySelected['type'] == 'PER') {
$affectedAmount = ($baseAmount * $adultPolicySelected['value'] / 100);
} elseif ($adultPolicySelected['type'] == 'FIX') {
$affectedAmount = $adultPolicySelected['value'];
}
$affectedAmountArray[] = $adultPolicySelected['action_type'] == 'DEC' ? ($affectedAmount * -1) : $affectedAmount;
}
}
if (strlen($perRoomRateOccupancy['occupancy_code']) > $perRoomRateOccupancy['included_occupancy']) {
$occupancyDifference = strlen($perRoomRateOccupancy['occupancy_code']) - $perRoomRateOccupancy['included_occupancy'];
$adultPolicySelected = collect($adultPolicy)
->where('adult', $occupancyDifference)
->where('adult_action_type', 'INC')
->first();
if (!empty($adultPolicySelected)) {
if ($adultPolicySelected['type'] == 'PER') {
$affectedAmount = ($baseAmount * $adultPolicySelected['value'] / 100);
} elseif ($adultPolicySelected['type'] == 'FIX') {
$affectedAmount = $adultPolicySelected['value'];
}
$affectedAmountArray[] = $adultPolicySelected['action_type'] == 'DEC' ? ($affectedAmount * -1) : $affectedAmount;
}
}
}
}
//Adult Policy
//Önce Oda Fiyatı Hesaplanır, Yetişkine Göre
$roomAmount = $baseAmount + array_sum($affectedAmountArray);
//Oluşan fiyata göre de iptal politikası uygulanır
//$cancellationPolicy
$affectedAmount = 0;
$isCancellationPolicyActive = false;
if (isset($cancellationPolicy[$perRoomRateOccupancy['cancellation_policy_id']])) {
$cancellationPolicySelected = $cancellationPolicy[$perRoomRateOccupancy['cancellation_policy_id']];
//dd($cancellationPolicy,$perRoomRateOccupancy,$cancellationPolicySelected,$perPropertyRoomRatePrice['date']);
//if ($cancellationPolicySelected['is_affected_price'] == 1) {
$isDateRange = $cancellationPolicySelected['is_date_range'];
$isDateRangeDate = Carbon::parse($perPropertyRoomRatePrice['date'])->between($cancellationPolicySelected['start_date'], $cancellationPolicySelected['finish_date']);
if (($isDateRange && $isDateRangeDate) || empty($isDateRange)) {
if ($cancellationPolicySelected['affect_price_type'] == 'PER') {
$affectedAmount = ($roomAmount * $cancellationPolicySelected['affect_price_value'] / 100);
} elseif ($cancellationPolicySelected['affect_price_type'] == 'FIX') {
$affectedAmount = $cancellationPolicySelected['affect_price_value'];
}
$affectedAmountArray[] = $cancellationPolicySelected['affect_price_action_type'] == 'DEC' ? ($affectedAmount * -1) : $affectedAmount;
$isCancellationPolicyActive = true;
}
//}
}
//$cancellationPolicy
//dd($perRoomRateOccupancy, $perPropertyRoomRatePrice, $cancellationPolicy);
$isCancellationPolicyActive = true;
if ($isCancellationPolicyActive) {
$calculatedAmount = $baseAmount + array_sum($affectedAmountArray);
$promotionsGrouped = collect($promotions)->groupBy('type')->toArray();
/**** PROMOTION START ****/
$totalPromotionDiscount = 0;
foreach ($promotionsGrouped as $promotionsGroupKey => $promotions) {
$promotions = collect($promotions)->sortByDesc('amount')->toArray();
foreach ($promotions as $promotion) {
if ($promotion['min_stay'] > 1) {
continue;
}
if ($promotion['is_mobile']) {
continue;
}
$daysArray = !empty($promotion['days']) ? json_decode($promotion['days'], 1) : [];
if (!in_array((Carbon::parse($perPropertyRoomRatePrice['date'])->dayOfWeek + 1), $daysArray)) {
continue;
}
if ($promotion['type'] == 'PRD') {
if (!Carbon::now()->startOfDay()->between(Carbon::parse($promotion['start_date'])->toDateString(), Carbon::parse($promotion['end_date'])->toDateString())) {
continue;
}
if (!Carbon::parse($perPropertyRoomRatePrice['date'])->startOfDay()->between(Carbon::parse($promotion['reservation_start_date'])->toDateString(), Carbon::parse($promotion['reservation_end_date'])->toDateString())) {
continue;
}
$totalPromotionDiscount += ($calculatedAmount * $promotion['amount']) / 100;
break;
}
if ($promotion['type'] == 'BFD') {
if (Carbon::parse($perPropertyRoomRatePrice['date'])->diffInDays(Carbon::now()->startOfDay()->toDateString()) < $promotion['day_before']) {
continue;
}
$totalPromotionDiscount += ($calculatedAmount * $promotion['amount']) / 100;
break;
}
if ($promotion['type'] == 'DSC') {
$totalPromotionDiscount += ($calculatedAmount * $promotion['amount']) / 100;
break;
}
}
}
$calculatedAmount = moneyDoubleFormatDecimal($calculatedAmount - $totalPromotionDiscount);
$calculatedAmount = $calculatedAmount > 0 ? $calculatedAmount : 0;
/**** PROMOTION FINISHED ****/
$roomRateOccupancyPriceParam[] = [
'property_id' => $property['property_id'],
'room_id' => $perRoomRateOccupancy['room_id'],
'room_rate_mapping_id' => $roomRateMappingId,
'date' => $perPropertyRoomRatePrice['date'],
'code' => $roomRateOccupancyKey,
//'title' => $perRoomRateOccupancy['title'],
//'baseAmount' => $perPropertyRoomRatePrice['amount'],
'amount' => $calculatedAmount,
'currency' => $perPropertyRoomRatePrice['currency'],
'status' => 1,
'created_by' => 1,
'updated_by' => 1,
'created_at' => Carbon::now()->unix(),
'updated_at' => Carbon::now()->unix(),
];
$propertyAllPriceCounter++;
}
}
}
$this->info(date('Y-m-d H:i:s') . ' : Property Room Rate Price Finished: ' . $property['property']['name']);
//dd(collect($roomRateOccupancyPriceParam)->sortBy('room_id')->sortBy('amount')->toArray());
$insertRows = [];
$updateRows = [];
$rowChunk = 0;
foreach ($roomRateOccupancyPriceParam as $roomRateOccupancyPrice) {
$insertRows[$rowChunk][] = $roomRateOccupancyPrice;
if (count($insertRows[$rowChunk]) > 1000) {
$rowChunk++;
}
}
$this->info(date('Y-m-d H:i:s') . ' : Property Room Rate Price to DB Start: ' . $property['property']['name']);
DB::beginTransaction();
PropertyMetaRoomRatePrice::where('property_id', $propertyId)->delete();
if (!empty($insertRows)) {
foreach ($insertRows as $insertRow) {
PropertyMetaRoomRatePrice::insert($insertRow);
}
}
DB::commit();
$this->info(date('Y-m-d H:i:s') . ' : Property Room Rate Price to DB Finished: ' . $property['property']['name']);
}
$this->info(date('Y-m-d H:i:s') . ' : Finished');
}
}

View File

@@ -0,0 +1,309 @@
<?php
namespace App\Console\Commands\ChannelManager;
use App\Core\Mail\LogMail;
use App\Core\Service\ChannelManager\Mirai;
use App\Exceptions\ApiErrorException;
use App\Models\ChannelManagerPropertyMapping;
use App\Models\PropertyMeta;
use App\Models\PropertyMetaRoomRate;
use App\Models\PropertyMetaRoomRateMapping;
use App\Models\PropertyMetaRoomRatePrice;
use App\Models\PropertyRoomAvailability;
use App\Models\PropertyRoomRatePrice;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class PropertyMetaRoomRatePushService extends Command
{
protected $signature = 'cron:propertymeta-roomratepush-service {--property_id=}';
protected $description = '';
protected $mailer;
public function __construct(
Mailer $mailer,
Mirai $miraiService
)
{
parent::__construct();
$this->mailer = $mailer;
$this->miraiService = $miraiService;
}
function getMonthlyPeriod($endDate)
{
$diffInMonths = Carbon::parse()->floorMonth()->diffInMonths(Carbon::parse($endDate)->floorMonth());
$diffInMonths++;
$monthlyPeriod = [];
$startDate = null;
$finishDate = null;
for ($i = 0; $i < $diffInMonths; $i++) {
if (empty($startDate)) {
$startDate = Carbon::now()->toDateString();
$finishDate = Carbon::parse($startDate)->endOfMonth()->toDateString();
} else {
$startDate = Carbon::now()->addMonths($i)->startOfMonth()->toDateString();
$finishDate = Carbon::parse($startDate)->endOfMonth()->toDateString();
}
if ($finishDate > $endDate) {
$finishDate = $endDate;
}
$monthlyPeriod[] = [
'startDate' => $startDate,
'finishDate' => $finishDate,
];
}
return $monthlyPeriod;
}
public function handle()
{
$this->info(date('Y-m-d H:i:s') . ' : Start');
if (!is_null($this->option('property_id'))) {
$propertyMeta = PropertyMeta::where('status', 1)->where('property_id', $this->option('property_id'))->with('property')->orderBy('id', 'ASC')->get(['id', 'property_id', 'cancellation_policy', 'adult_policy', 'child_policy', 'param', 'status'])->toArray();
} else {
$propertyMeta = PropertyMeta::where('status', 1)->with('property')->orderBy('id', 'ASC')->get(['id', 'property_id', 'cancellation_policy', 'adult_policy', 'child_policy', 'param', 'status'])->toArray();
}
foreach ($propertyMeta as $property) {
$propertyId = $property['property_id'];
//Mirai User Setup
$this->miraiService->setupUser($property['paramsArray']['login'], $property['paramsArray']['password']);
$this->info(date('Y-m-d H:i:s') . ' : Property Room Rate Push Start: ' . $property['property']['name']);
//$propertyRoomRatePriceEndDate = PropertyRoomRatePrice::where('property_id', $propertyId)->orderBy('date', 'DESC')->first();
//$propertyRoomRatePriceEndDate = $propertyRoomRatePriceEndDate->toArray() ? $propertyRoomRatePriceEndDate['date'] : null;
//$propertyRoomRatePriceEndDate = '2023-10-31';
//$getMonthlyPeriod = $this->getMonthlyPeriod($propertyRoomRatePriceEndDate);
$getMonthlyPeriod = [];
$getMonthlyPeriod[] = [
'startDate' => Carbon::now()->toDateString(),
//'finishDate' => Carbon::now()->addYear()->toDateString(),
'finishDate' => Carbon::now()->addDays(360)->toDateString(),
];
$propertyMetaRoomRateMapping = PropertyMetaRoomRateMapping::where('property_id', $propertyId)->with('propertyMetaRoomRate')->get()->toArray();
$propertyMetaRoomRateMappingCollect = collect($propertyMetaRoomRateMapping);
$channelManagerPropertyMapping = ChannelManagerPropertyMapping::where('property_id', $propertyId)->where('status', 1)->where('channel_manager_id', 7)->first()->toArray();
if (empty($channelManagerPropertyMapping)) {
continue;
}
$metaRoomRateMapping = [];
$propertyMetaRoomRateMappingGroup = $propertyMetaRoomRateMappingCollect->groupBy('property_meta_room_rate.room_id')->toArray();
foreach ($propertyMetaRoomRateMappingGroup as $roomGroup) {
$roomGroup = reset($roomGroup);
$metaRoomRateMapping[$roomGroup['property_meta_room_rate']['room_id']]['meta_code'] = $roomGroup['meta_code'];
}
foreach ($getMonthlyPeriod as $period) {
$this->info(date('Y-m-d H:i:s') . ' : Meta Availability Start: ' . $property['property']['name'] . ' - ' . $period['startDate'] . ' / ' . $period['finishDate']);
try {
$propertyRoomAvailability = PropertyRoomAvailability::where('property_id', $propertyId)
->where('status', 1)->where('channel_id', null)
->whereBetween('date', [$period['startDate'], $period['finishDate']])
->get(['property_room_id', 'date', 'stop_sell', 'availability'])
->toArray();
$propertyRoomAvailabilityCollect = collect($propertyRoomAvailability);
foreach ($metaRoomRateMapping as $roomId => $metaRoom) {
$metaRoomRateMapping[$roomId]['data'] = $propertyRoomAvailabilityCollect->where('property_room_id', $roomId)->sortBy('date')->toArray();
}
$xmlResponse = new \SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><inventoryUpdate></inventoryUpdate>');
$xmlResponse->addAttribute('hotelId', $channelManagerPropertyMapping['channel_manager_property_id']);
foreach ($metaRoomRateMapping as $roomId => $metaRoom) {
$room = $xmlResponse->addChild('room');
$room->addAttribute('id', $metaRoom['meta_code']);
$roomInventory = $room->addChild('inventory');
foreach ($metaRoom['data'] as $roomRate) {
$roomInventoryAvailability = $roomInventory->addChild('availability');
$roomRate['availability'] = $roomRate['stop_sell'] == 1 ? 0 : $roomRate['availability'];
$roomInventoryAvailability->addAttribute('date', $roomRate['date']);
$roomInventoryAvailability->addAttribute('quantity', $roomRate['availability']);
}
}
$request = $this->miraiService->inventoryRoomRateUpdate('webservice_updater.apro', $xmlResponse->asXML());
if (!$request['status']) {
throw new ApiErrorException('webservice_updater AVAILABILITY Error: ' . $request['message']);
}
} catch (ApiErrorException $e) {
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage());
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message);
}
$this->info(date('Y-m-d H:i:s') . ' : Meta Price Start: ' . $property['property']['name'] . ' - ' . $period['startDate'] . ' / ' . $period['finishDate']);
try {
$propertyMetaRoomRatePrice = PropertyMetaRoomRatePrice::where('property_id', $propertyId)
->whereBetween('date', [$period['startDate'], $period['finishDate']])->where('status', 1)
->whereIn('code', pickItemFromArray('code', $propertyMetaRoomRateMapping))
->get(['date', 'code', 'amount', 'currency'])
->toArray();
$propertyMetaRoomRatePriceCollect = collect($propertyMetaRoomRatePrice);
if (empty($propertyMetaRoomRatePrice)) {
$this->error(date('Y-m-d H:i:s') . ' : ' . $property['property']['name'] . ' : Price not found!');
continue;
}
$metaRoomRatePrice = [];
$metaRoomPricesOrdered = [];
foreach ($propertyMetaRoomRateMapping as $metaRoom) {
$metaRoomPrices = $propertyMetaRoomRatePriceCollect->where('code', $metaRoom['code'])->sortBy('date')->toArray();
$metaRoomPricesCollect = collect($metaRoomPrices);
$metaRoomPricesGroup = [];
foreach ($metaRoomPrices as $metaRoomPrice) {
$metaRoomPricesGroup[md5($metaRoomPrice['amount'])][$metaRoomPrice['date']] = $metaRoomPrice;
ksort($metaRoomPricesGroup[md5($metaRoomPrice['amount'])]);
}
foreach ($metaRoomPricesGroup as $priceGroupKey => $priceGroup) {
$priceDateGroup = 0;
foreach ($priceGroup as $priceGroupDate => $price) {
if (!isset($metaRoomPricesOrdered[$metaRoom['meta_code']][$priceGroupKey][$priceDateGroup]['startDate'])) {
$metaRoomPricesOrdered[$metaRoom['meta_code']][$priceGroupKey][$priceDateGroup]['startDate'] = $price['date'];
$metaRoomPricesOrdered[$metaRoom['meta_code']][$priceGroupKey][$priceDateGroup]['finishDate'] = $price['date'];
} else {
if (Carbon::parse($metaRoomPricesOrdered[$metaRoom['meta_code']][$priceGroupKey][$priceDateGroup]['finishDate'])->addDay()->toDateString() != $price['date']) {
$priceDateGroup++;
$metaRoomPricesOrdered[$metaRoom['meta_code']][$priceGroupKey][$priceDateGroup]['startDate'] = $price['date'];
} else {
$metaRoomPricesOrdered[$metaRoom['meta_code']][$priceGroupKey][$priceDateGroup]['finishDate'] = $price['date'];
}
$metaRoomPricesOrdered[$metaRoom['meta_code']][$priceGroupKey][$priceDateGroup]['finishDate'] = $price['date'];
}
$metaRoomPricesOrdered[$metaRoom['meta_code']][$priceGroupKey][$priceDateGroup]['amount'] = $price['amount'];
$metaRoomPricesOrdered[$metaRoom['meta_code']][$priceGroupKey][$priceDateGroup]['currency'] = $price['currency'];
//$metaRoomPricesOrdered[$priceGroupKey][$priceDateGroup]['metaCode'] = $metaRoom['meta_code'];
$metaRoomPricesOrdered[$metaRoom['meta_code']][$priceGroupKey][$priceDateGroup]['title'] = $metaRoom['property_meta_room_rate']['title'];
}
}
}
$xmlResponse = new \SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><inventoryUpdate></inventoryUpdate>');
$xmlResponse->addAttribute('hotelId', $channelManagerPropertyMapping['channel_manager_property_id']);
foreach ($metaRoomPricesOrdered as $roomRateMetaCode => $metaRoom) {
foreach ($metaRoom as $priceGroupKey => $metaRoomPriceGroup) {
$room = $xmlResponse->addChild('room');
$room->addAttribute('id', $roomRateMetaCode);
$currency = !empty($metaRoomPriceGroup) ? reset($metaRoomPriceGroup)['currency'] : 'EUR';
$rate = $room->addChild('rate');
$rate->addAttribute('currency', $currency);
foreach ($metaRoomPriceGroup as $metaRoomPrice) {
$planning = $rate->addChild('planning');
$planning->addAttribute('from', $metaRoomPrice['startDate']);
$planning->addAttribute('to', $metaRoomPrice['finishDate']);
$planning->addAttribute('unitPrice', $metaRoomPrice['amount']);
}
}
}
$request = $this->miraiService->inventoryRoomRateUpdate('webservice_updater.apro', $xmlResponse->asXML());
if (!$request['status']) {
throw new ApiErrorException('webservice_updater PRICE Error: ' . $request['message']);
}
//Remove all prices then push to meta
PropertyMetaRoomRatePrice::where('property_id', $propertyId)->delete();
} catch (ApiErrorException $e) {
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage());
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message);
}
}
}
$this->info(date('Y-m-d H:i:s') . ' : Finished');
}
}

View File

@@ -0,0 +1,288 @@
<?php
namespace App\Console\Commands\ChannelManager;
use App\Core\Mail\LogMail;
use App\Exceptions\ApiErrorException;
use App\Models\PropertyMeta;
use App\Models\PropertyMetaRoomRate;
use App\Models\PropertyRoomRateChannelMapping;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class PropertyMetaRoomRateService extends Command
{
protected $signature = 'cron:propertymeta-roomrate-service {--property_id=}';
protected $description = '';
protected $mailer;
public function __construct(
Mailer $mailer
)
{
parent::__construct();
$this->mailer = $mailer;
}
public function handle()
{
$this->info(date('Y-m-d H:i:s') . ' : Start');
if (!is_null($this->option('property_id'))) {
$propertyMeta = PropertyMeta::where('status', 1)->where('property_id', $this->option('property_id'))->with('property')->orderBy('id', 'ASC')->get(['id', 'property_id', 'status'])->toArray();
} else {
$propertyMeta = PropertyMeta::where('status', 1)->with('property')->orderBy('id', 'ASC')->get(['id', 'property_id', 'status'])->toArray();
}
foreach ($propertyMeta as $property) {
$this->info(date('Y-m-d H:i:s') . ' : Property Policy Start: ' . $property['property']['name']);
//Property All Room Rate Price Policy
$propertyRoomRateChannelMapping = PropertyRoomRateChannelMapping::with('propertyRoomRateMapping')
->with('propertyRoomRateMapping.propertyRoom')
->with('propertyRoomRateMapping.propertyRoomRate')
->with('propertyRoomRateChannelCancellationPolicy.propertyCancellationPolicy')
->with('propertyRoomRateChannelPricingAdultPolicy.propertyPricingPolicyAdult')
->with('propertyRoomRateChannelPricingChildPolicy.propertyPricingPolicyChild')
->with('propertyRoomRateChannelPromotion.propertyPromotion.promotionType')
->get()
->where('property_id', $property['property_id'])->where('channel_id', 1)
->where('status', 1);
$propertyRoomRateChannelMapping = $propertyRoomRateChannelMapping->where('propertyRoomRateMapping', '!=', null)->toArray();
//dd($propertyRoomRateChannelMapping);
$roomRateMappingPolicy = [];
foreach ($propertyRoomRateChannelMapping as $propertyRoom) {
$roomRateMappingPolicy['promotion'][$propertyRoom['room_rate_mapping_id']] = [];
foreach ($propertyRoom['property_room_rate_channel_promotion'] as $propertyRoomRateChannelPromotion) {
if($propertyRoomRateChannelPromotion['status'] != 1) {
continue;
}
$roomRateMappingPolicy['promotion'][$propertyRoom['room_rate_mapping_id']][$propertyRoomRateChannelPromotion['property_promotion_id']] = [
'type' => $propertyRoomRateChannelPromotion['property_promotion']['promotion_type']['type_code'],
'start_date' => $propertyRoomRateChannelPromotion['property_promotion']['start_date'],
'end_date' => $propertyRoomRateChannelPromotion['property_promotion']['end_date'],
'reservation_start_date' => $propertyRoomRateChannelPromotion['property_promotion']['reservation_start_date'],
'reservation_end_date' => $propertyRoomRateChannelPromotion['property_promotion']['reservation_end_date'],
'day_before' => $propertyRoomRateChannelPromotion['property_promotion']['day_before'],
'amount' => $propertyRoomRateChannelPromotion['property_promotion']['amount'],
'min_stay' => $propertyRoomRateChannelPromotion['property_promotion']['min_stay'],
'is_mobile' => $propertyRoomRateChannelPromotion['property_promotion']['is_mobile'],
'days' => $propertyRoomRateChannelPromotion['property_promotion']['days'],
];
}
$roomRateMappingPolicy['cancellation_policy'][$propertyRoom['room_rate_mapping_id']] = [];
foreach ($propertyRoom['property_room_rate_channel_cancellation_policy'] as $propertyRoomRateCancellationPolicy) {
$roomRateMappingPolicy['cancellation_policy'][$propertyRoom['room_rate_mapping_id']][$propertyRoomRateCancellationPolicy['cancellation_policy_id']] = [
'is_affected_price' => $propertyRoomRateCancellationPolicy['property_cancellation_policy']['is_affected_price'],
'affect_price_action_type' => $propertyRoomRateCancellationPolicy['property_cancellation_policy']['affect_price_action_type'],
'affect_price_type' => $propertyRoomRateCancellationPolicy['property_cancellation_policy']['affect_price_type'],
'affect_price_value' => $propertyRoomRateCancellationPolicy['property_cancellation_policy']['affect_price_value'],
'is_date_range' => $propertyRoomRateCancellationPolicy['property_cancellation_policy']['is_date_range'],
'start_date' => $propertyRoomRateCancellationPolicy['property_cancellation_policy']['start_date'],
'finish_date' => $propertyRoomRateCancellationPolicy['property_cancellation_policy']['finish_date'],
];
}
$roomRateMappingPolicy['adult_policy'][$propertyRoom['room_rate_mapping_id']] = [];
foreach ($propertyRoom['property_room_rate_channel_pricing_adult_policy'] as $propertyRoomRateAdultPolicy) {
$roomRateMappingPolicy['adult_policy'][$propertyRoom['room_rate_mapping_id']][$propertyRoomRateAdultPolicy['pricing_policy_adult_id']] = [
'adult_action_type' => $propertyRoomRateAdultPolicy['property_pricing_policy_adult']['adult_action_type'],
'adult' => $propertyRoomRateAdultPolicy['property_pricing_policy_adult']['adult'],
'action_type' => $propertyRoomRateAdultPolicy['property_pricing_policy_adult']['action_type'],
'type' => $propertyRoomRateAdultPolicy['property_pricing_policy_adult']['type'],
'value' => $propertyRoomRateAdultPolicy['property_pricing_policy_adult']['value'],
];
}
$roomRateMappingPolicy['child_policy'][$propertyRoom['room_rate_mapping_id']] = [];
foreach ($propertyRoom['property_room_rate_channel_pricing_child_policy'] as $propertyRoomRateChildPolicy) {
$roomRateMappingPolicy['child_policy'][$propertyRoom['room_rate_mapping_id']][$propertyRoomRateChildPolicy['pricing_policy_child_id']] = [
'adult' => $propertyRoomRateChildPolicy['property_pricing_policy_child']['adult'],
'child_order' => $propertyRoomRateChildPolicy['property_pricing_policy_child']['child_order'],
'child_age_start' => $propertyRoomRateChildPolicy['property_pricing_policy_child']['child_age_start'],
'child_age_end' => $propertyRoomRateChildPolicy['property_pricing_policy_child']['child_age_end'],
'type' => $propertyRoomRateChildPolicy['property_pricing_policy_child']['type'],
'value' => $propertyRoomRateChildPolicy['property_pricing_policy_child']['value'],
];
}
}
//Property All Room Rate Price Policy
$propertyMetaPolicyUpdate = [
'cancellation_policy' => json_encode($roomRateMappingPolicy['cancellation_policy']),
'adult_policy' => json_encode($roomRateMappingPolicy['adult_policy']),
'child_policy' => json_encode($roomRateMappingPolicy['child_policy']),
'promotion' => json_encode($roomRateMappingPolicy['promotion']),
];
PropertyMeta::where('id', $property['id'])->update($propertyMetaPolicyUpdate);
$this->info(date('Y-m-d H:i:s') . ' : Property Policy Finished: ' . $property['property']['name']);
//$propertyMetaTemp
/*$propertyMetaTemp = PropertyMeta::where('property_id', $property['property_id'])->with('property')->get()->first();
$propertyMetaTemp = $propertyMetaTemp->toArray();
$propertyMetaPolicyUpdate = [
'cancellation_policy' => json_decode($propertyMetaTemp['cancellation_policy'], 1),
'adult_policy' => json_decode($propertyMetaTemp['adult_policy'], 1),
'child_policy' => json_decode($propertyMetaTemp['child_policy'], 1),
];*/
//$propertyMetaTemp
$this->info(date('Y-m-d H:i:s') . ' : Property Room Rate Occupancy Start: ' . $property['property']['name']);
//Property All Price Combination
/*$propertyRoomRateChannelMapping = PropertyRoomRateChannelMapping::with('propertyRoomRateMapping')
->with('propertyRoomRateMapping.propertyRoom')
->with('propertyRoomRateMapping.propertyRoomRate')
->with('propertyRoomRateChannelCancellationPolicy.propertyCancellationPolicy')
->with('propertyRoomRateChannelPricingAdultPolicy')
->with('propertyRoomRateChannelPricingChildPolicy')
->get()
->where('property_id', $property['property_id'])->where('channel_id', 1)
->where('status', 1);
$propertyRoomRateChannelMapping = $propertyRoomRateChannelMapping->where('propertyRoomRateMapping', '!=', null)->toArray();*/
$roomRateOccupancy = [];
foreach ($propertyRoomRateChannelMapping as $propertyRoom) {
$roomId = $propertyRoom['property_room_rate_mapping']['room_id'];
$propertyRoomRateMappingId = $propertyRoom['property_room_rate_mapping']['id'];
$occupancyGroup = occupancyGroup(
$propertyRoom['property_room_rate_mapping']['property_room']['max_adult'],
$propertyRoom['property_room_rate_mapping']['property_room']['max_child'],
$propertyRoom['property_room_rate_mapping']['property_room']['max_occupancy']
);
//TODO: Burası incelenebilir, cancellation policy yok ise gelmiyor çünkü....
/*if(empty($propertyRoom['property_room_rate_channel_cancellation_policy'])) {
$propertyRoom['property_room_rate_channel_cancellation_policy'][] = [
'cancellation_policy_id' => 0,
'property_cancellation_policy' => [
'name' => 'Refundable',
'is_nonrefundable' => 0,
]
];
}*/
foreach ($propertyRoom['property_room_rate_channel_cancellation_policy'] as $propertyRoomRateCancellationPolicy) {
foreach ($occupancyGroup as $occupancyCode) {
$roomRateOccupancyKey = $roomId . '-' . $propertyRoomRateMappingId . '-' . $propertyRoomRateCancellationPolicy['cancellation_policy_id'] . '-' . $occupancyCode;
$roomRateOccupancyKey = md5($roomRateOccupancyKey);
$cancellationPolicyName = [];
$cancellationPolicyName[] = $propertyRoomRateCancellationPolicy['property_cancellation_policy']['is_nonrefundable'] ? 'NonRefundable' : 'Refundable';
$cancellationPolicyName[] = !empty($propertyRoomRateCancellationPolicy['property_cancellation_policy']['name']) ? '(' . $propertyRoomRateCancellationPolicy['property_cancellation_policy']['name'] . ')' : null;
$cancellationPolicyName = implode(' ', $cancellationPolicyName);
$roomRateOccupancyTitle = [];
$roomRateOccupancyTitle[] = $propertyRoom['property_room_rate_mapping']['property_room']['name'];
$roomRateOccupancyTitle[] = $propertyRoom['property_room_rate_mapping']['property_room_rate']['name'];
$roomRateOccupancyTitle[] = $cancellationPolicyName;
$roomRateOccupancyTitle[] = $occupancyCode;
$roomRateOccupancyTitle = implode(' - ', $roomRateOccupancyTitle);
$roomRateOccupancy[$roomRateOccupancyKey] = [
'propertyId' => $property['property_id'],
'roomId' => $roomId,
'roomName' => $propertyRoom['property_room_rate_mapping']['property_room']['name'],
'roomRateMappingId' => $propertyRoomRateMappingId,
'roomRateMappingName' => $propertyRoom['property_room_rate_mapping']['property_room_rate']['name'],
'cancellationPolicyId' => $propertyRoomRateCancellationPolicy['cancellation_policy_id'],
'cancellationPolicyName' => $propertyRoomRateCancellationPolicy['property_cancellation_policy']['name'],
'occupancyCode' => $occupancyCode,
'includedOccupancy' => $propertyRoom['property_room_rate_mapping']['included_occupancy'],
'title' => $roomRateOccupancyTitle
];
}
}
}
//Property All Price Combination
$propertyMetaRoomRateParam = [];
foreach ($roomRateOccupancy as $roomRateOccupancyKey => $roomRate) {
//$propertyMetaRoomRateCheck = PropertyMetaRoomRate::where('code', $roomRateOccupancyKey)->count();
$propertyMetaRoomRateParam[] = [
'code' => $roomRateOccupancyKey,
'title' => $roomRate['title'],
'property_id' => $roomRate['propertyId'],
'room_id' => $roomRate['roomId'],
'room_rate_mapping_id' => $roomRate['roomRateMappingId'],
'cancellation_policy_id' => $roomRate['cancellationPolicyId'],
'included_occupancy' => $roomRate['includedOccupancy'],
'occupancy_code' => $roomRate['occupancyCode'],
'status' => 1,
'created_by' => 1,
'updated_by' => 1,
'created_at' => Carbon::now()->unix(),
'updated_at' => Carbon::now()->unix(),
];
/*if ($propertyMetaRoomRateCheck) {
$propertyMetaRoomRateUpdate = PropertyMetaRoomRate::where('code', $roomRateOccupancyKey)->update($propertyMetaRoomRateParam);
} else {
$propertyMetaRoomRateCreate = PropertyMetaRoomRate::create($propertyMetaRoomRateParam);
}*/
//$this->info(date('Y-m-d H:i:s') . ' : Property Room Rate Occupancy: ' . $roomRate['title']);
}
//Delete all codes
if (!empty($propertyMetaRoomRateParam)) {
PropertyMetaRoomRate::where('property_id', $property['property_id'])->delete();
PropertyMetaRoomRate::insert($propertyMetaRoomRateParam);
}
$this->info(date('Y-m-d H:i:s') . ' : Property Room Rate Occupancy Finished: ' . $property['property']['name']);
}
$this->info(date('Y-m-d H:i:s') . ' : Finished');
}
}

View File

@@ -0,0 +1,116 @@
<?php
namespace App\Console\Commands\ChannelManager;
use App\Core\Mail\LogMail;
use App\Core\Service\BookingPaymentService;
use App\Exceptions\ApiErrorException;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class RemovePaymentTokenService extends Command
{
protected $signature = 'cron:remove-payment-token-service';
protected $description = '';
protected $mailer;
public function __construct(
Mailer $mailer,
BookingPaymentService $bookingPaymentService
)
{
parent::__construct();
$this->mailer = $mailer;
$this->bookingPaymentService = $bookingPaymentService;
}
public function handle()
{
try {
$this->info(date('Y-m-d H:i:s') . ' : Start');
$bookingPaymentDataCriteria =
[
'criteria' =>
[
['field' => 'status', 'condition' => '=', 'value' => 2],
['field' => 'type', 'condition' => '=', 'value' => 'ch'],
],
'with' => ['bookingDetail.channelManager'],
'orderBy' => [
['field' => 'id', 'value' => 'ASC']
]
];
$bookingPaymentData = $this->bookingPaymentService->selectPaymentData($bookingPaymentDataCriteria);
$bookingPaymentData = $bookingPaymentData['status'] == 'success' && !empty($bookingPaymentData['data']) ? $bookingPaymentData['data'] : [];
if (!empty($bookingPaymentData)) {
$bookingPaymentDataCollect = collect($bookingPaymentData);
$bookingPaymentData = $bookingPaymentDataCollect->where('booking_detail.checkout_date', '<', Carbon::now()->subDays(7))->toArray();
}
//$bookingPaymentData
foreach ($bookingPaymentData as $bookingPaymentKey => $bookingPayment) {
if (empty($bookingPayment['booking_detail']['channel_manager_id'])) {
continue;
}
$channelManagerId = $bookingPayment['booking_detail']['channel_manager_id'];
switch ($channelManagerId) {
case 2 :
$channelService = App::make("App\Core\Service\ChannelManager\\{$bookingPayment['booking_detail']['channel_manager']['name']}");
$removeCreditCardToken = $channelService->removeCreditCardToken($bookingPayment['data']);
if (!$removeCreditCardToken['status']) {
//Hata maili atılsın
$this->error(date('Y-m-d H:i:s') . ' : Channel: ' . $bookingPayment['booking_detail']['channel_manager']['name'] . ' Token: ' . $bookingPayment['data']);
} else {
$this->bookingPaymentService->updatePaymentData($bookingPayment['id'], ['status' => 1]);
$this->info(date('Y-m-d H:i:s') . ' : Channel: ' . $bookingPayment['booking_detail']['channel_manager']['name'] . ' Token: ' . $bookingPayment['data']);
}
break;
default;
break;
}
}
$this->info(date('Y-m-d H:i:s') . ' : Finished');
} catch (ApiErrorException $e) {
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage());
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message);
}
}
}

View File

@@ -0,0 +1,957 @@
<?php
namespace App\Console\Commands\ChannelManager;
use App\Core\Mail\CancelBookingMail;
use App\Core\Mail\LogMail;
use App\Core\Mail\ModifiedBookingMail;
use App\Core\Service\BookingContactService;
use App\Core\Service\BookingPaymentService;
use App\Core\Service\BookingRoomService;
use App\Core\Service\BookingService;
use App\Core\Service\ChannelManager\Reseliva;
use App\Core\Service\ChannelManagerBookingService;
use App\Core\Service\ChannelManagerMappingService;
use App\Core\Service\ChannelManagerPropertyMappingService;
use App\Core\Service\ChannelManagerPropertyRateMappingService;
use App\Core\Service\ChannelManagerService;
use App\Core\Service\NewBookingMailService;
use App\Core\Service\PropertyRoomAvailabilityService;
use App\Exceptions\ApiErrorException;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class ReservationPullService extends Command
{
protected $signature = 'cron:reservation-pull-service';
protected $description = '';
protected $mailer;
protected $channelService;
protected $channelManagerPropertyMappingService;
protected $bookingService;
protected $propertyRoomAvailabilityService;
protected $newBookingMailService;
public function __construct(
Mailer $mailer,
ChannelManagerMappingService $channelManagerMappingService,
ChannelManagerPropertyMappingService $channelManagerPropertyMappingService,
BookingService $bookingService,
BookingContactService $bookingContactService,
BookingRoomService $bookingRoomService,
BookingPaymentService $bookingPaymentService,
PropertyRoomAvailabilityService $propertyRoomAvailabilityService,
NewBookingMailService $newBookingMailService,
ChannelManagerService $channelManagerService,
ChannelManagerBookingService $channelManagerBookingService
)
{
parent::__construct();
$this->mailer = $mailer;
$this->channelManagerMappingService = $channelManagerMappingService;
$this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService;
$this->bookingService = $bookingService;
$this->bookingContactService = $bookingContactService;
$this->bookingRoomService = $bookingRoomService;
$this->bookingPaymentService = $bookingPaymentService;
$this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService;
$this->newBookingMailService = $newBookingMailService;
$this->channelManagerService = $channelManagerService;
$this->channelManagerBookingService = $channelManagerBookingService;
}
public function getDateByDay($dates = [])
{
$dateByDay = [];
$diffInDays = Carbon::parse($dates['checkIn'])->floatDiffInDays(Carbon::parse($dates['checkOut']));
for ($i = 0; $i < $diffInDays; $i++) {
$dateByDay[] = Carbon::parse($dates['checkIn'])->addDay($i)->format('Y-m-d');
}
return $dateByDay;
}
public function createBooking($channelCode, $param)
{
$response = ['status' => false, 'message' => ''];
DB::beginTransaction();
try {
$channelService = App::make("App\Core\Service\ChannelManager\\{$channelCode}");
$bookingCode = getCodeGenerate('BKG');
$param['booking']['booking_code'] = $bookingCode;
$param['booking']['extra_param'] = json_encode($param['channel_manager']);
$bookingCreate = $this->bookingService->create($param['booking']);
//$bookingCreate['status'] = 'success';//TODO: Delete
//$bookingCreate['data']['id'] = 1106;
if ($bookingCreate['status'] != 'success') {
throw new ApiErrorException('Booking could not be made, Reservation: ' . $param['booking']['search_key']);
}
$param['booking']['id'] = $bookingCreate['data']['id'];
//INSERT CONTACT DATA
$bookingContactCreateParam = [
'booking_id' => $bookingCreate['data']['id'],
'name' => $param['contact']['name'],
'surname' => $param['contact']['surname'],
'phone_code' => $param['contact']['phone_code'],
'phone_number' => $param['contact']['phone_number'],
'email' => $param['contact']['email'],
'country_code' => fillOnUndefined($param['contact'], 'country_code'),
'note' => !empty($param['contact']['note']) ? $param['contact']['note'] : null,
'language_code' => fillOnUndefined($param['contact'], 'language', 'en'),
'extra_param' => fillOnUndefined($param['contact'], 'extra_param'),
'status' => 1
];
$bookingContactCreate = $this->bookingContactService->create($bookingContactCreateParam);
//$bookingContactCreate['status'] = 'success';
if ($bookingContactCreate['status'] != 'success') {
throw new ApiErrorException('Booking Contact could not be made');
}
//INSERT ROOM DATA
foreach ($param['room'] as $roomOrder => $room) {
$bookingRoomCreateParam = [
'booking_id' => $bookingCreate['data']['id'],
'room_order_number' => ($roomOrder + 1),
'occupancy_code' => $room['occupancy_code'],
'checkin_date' => $room['checkin_date'], //$room['checkin'],
'checkout_date' => $room['checkout_date'],//$room['checkout'],
'rate_key' => fillOnUndefined($room, 'rate_key'),
'rate_key_code' => fillOnUndefined($room, 'rate_key_code'),
'availability_id' => 1,
'availability_code' => 'ROM',
'room_id' => $room['room_id'],
'room_name' => $room['room_name'],
'room_rate_mapping_id' => $room['room_rate_mapping_id'],
'room_rate_name' => $room['room_rate_name'],
'cancellation_policy' => fillOnUndefined($room, 'cancellation_policy'),
'payment_type_code' => fillOnUndefined($room, 'payment_type_code', 'CHN'),
'daily_amount' => fillOnUndefined($room, 'daily_amount'),
'extra_param' => fillOnUndefined($room, 'extra_param'),
'rate_detail' => fillOnUndefined($room, 'rate_detail'),
'total' => $room['total'],
'currency_code' => $room['currency_code'],
'status' => fillOnUndefined($room, 'status', 1),
];
$bookingRoomCreate = $this->bookingRoomService->create($bookingRoomCreateParam);
//$bookingRoomCreate['status'] = 'success';
if ($bookingRoomCreate['status'] != 'success') {
throw new ApiErrorException('Booking Room could not be made');
}
/* ROOM AVAILABILITY */
$dateByDay = [];
$dateByDay = $this->getDateByDay(['checkIn' => $room['checkin_date'], 'checkOut' => $room['checkout_date']]);
foreach ($dateByDay as $day) {
$requestParam = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => $param['booking']['property_id']],
['field' => 'property_room_id', 'condition' => '=', 'value' => $room['room_id']],
['field' => 'availability_type_id', 'condition' => '=', 'value' => 1],
['field' => 'date', 'condition' => '=', 'value' => $day]
],
];
$getPropertyRoomAndRoomRateAvailability = $this->propertyRoomAvailabilityService->select($requestParam);
if ($getPropertyRoomAndRoomRateAvailability['status'] != 'success') {
throw new ApiErrorException('getPropertyRoomAndRoomRateAvailability Empty');
}
foreach ($getPropertyRoomAndRoomRateAvailability['data'] as $roomAvailability) {
$roomAvailabilityUpdated = $roomAvailability['availability'] <= 0 ? 0 : ($roomAvailability['availability'] - 1);
$this->propertyRoomAvailabilityService->update($roomAvailability['id'], ['availability' => $roomAvailabilityUpdated]);
}
}
/* ROOM AVAILABILITY */
}
//INSERT PAYMENT DATA
$bookingPaymentCreateParam = [
'booking_id' => $bookingCreate['data']['id'],
'payment_code' => fillOnUndefined($param['payment'], 'payment_code'),
'payment_type_code' => fillOnUndefined($param['payment'], 'payment_type_code'),//Type: CHN
'payment_source_code' => fillOnUndefined($param['payment'], 'payment_source_code'),
'extra_param' => fillOnUndefined($param['payment'], 'extra_param'),
'total' => fillOnUndefined($param['payment'], 'total'),
'currency_code' => fillOnUndefined($param['payment'], 'currency_code'),
'status' => fillOnUndefined($param['payment'], 'status'),//Type: 2
];
$bookingPaymentCreate = $this->bookingPaymentService->create($bookingPaymentCreateParam);
//$bookingPaymentCreate['status'] = 'success';
if ($bookingPaymentCreate['status'] != 'success') {
throw new ApiErrorException('Booking Payment could not be made');
}
//INSERT PAYMENT DATA
//INSERT CHANNEL PAYMENT DATA
if (isset($param['payment_channel']) && !empty($param['payment_channel'])) {
$bookingPaymentDataCreateParam = [
'booking_id' => $bookingCreate['data']['id'],
'type' => fillOnUndefined($param['payment_channel'], 'type'),
'data' => fillOnUndefined($param['payment_channel'], 'data'),
'status' => fillOnUndefined($param['payment_channel'], 'status', 1),
];
$bookingPaymentDataCreate = $this->bookingPaymentService->createPaymentData($bookingPaymentDataCreateParam);
if ($bookingPaymentDataCreate['status'] != 'success') {
throw new ApiErrorException('Booking Channel Payment could not be made');
}
}
//INSERT CHANNEL PAYMENT DATA
$reservationConfirmParam = $channelService->reservationConfirmParam($param['channel_manager']['property_id'], $param['channel_manager']['booking_id'], $bookingCode, $param);
$reservationConfirm = $channelService->reservationConfirm($reservationConfirmParam);
if (!$reservationConfirm['status']) {
throw new ApiErrorException($reservationConfirm['message']);
}
//PUSH CHANNEL MANAGER QUEUE
/*
538 Euphoria Hotel Batumi
541 Intourist Palace Hotel & SPA
545 Metro Sky Tower Hotel
546 Legend Hotel Batumi Convention Center & Spa
548 Legend Business Hotel Batumi
549 Euphoria Apartments
550 City Hotel Batumi
*/
/*if (in_array($bookingCreate['data']['property_id'], [546])) {
$channelManagerBookingParam = [
'property_id' => $bookingCreate['data']['property_id'],
'booking_id' => $bookingCreate['data']['id'],
'channel_manager_id' => $bookingCreate['data']['channel_manager_id'],
'type' => 'Booking',
];
$this->channelManagerBookingService->create($channelManagerBookingParam);
}*/
$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) {
if(in_array($channelPropertyData['channel_manager_id'],[11,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
DB::commit();
$mailParams = ['booking_id' => $bookingCreate['data']['id']];
$this->newBookingMailService->process($mailParams);
$response['status'] = true;
$response['data'] = $param;
} 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']) {
DB::rollBack();
}
return $response;
}
public function modifiedBooking($channelCode, $param)
{
$response = ['status' => false, 'message' => ''];
DB::beginTransaction();
try {
$channelService = App::make("App\Core\Service\ChannelManager\\{$channelCode}");
$bookingCode = null;
$bookingDetailParam = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => $param['booking']['property_id']],
['field' => 'search_key', 'condition' => '=', 'value' => $param['booking']['search_key']],
//['field' => 'channel_manager_id', 'condition' => '=', 'value' => $param['booking']['channel_manager_id']],
],
'with' => ['bookingRoom', 'bookingContact', 'bookingChannel', 'bookingPayment'],
'firstRow' => true
];
$bookingDetail = $this->bookingService->select($bookingDetailParam);
if ($bookingDetail['status'] != 'success') {
throw new ApiErrorException(lang('Booking could not be found, Reservation: ' . $param['booking']['search_key']));
}
if (!empty($bookingDetail['data'])) {
$bookingCode = $bookingDetail['data']['booking_code'];
$param['booking']['id'] = $bookingDetail['data']['id'];
$param['booking']['booking_code'] = $bookingDetail['data']['booking_code'];
$bookingUpdateParam = [
'channel_booking_code' => fillOnUndefined($param['booking'], 'channel_booking_code'),
'search_key' => $param['booking']['search_key'],
'checkin_date' => $param['booking']['checkin_date'],
'checkout_date' => $param['booking']['checkout_date'],
'payment_type_code' => $param['booking']['payment_type_code'],
'total' => $param['booking']['total'],
'currency_code' => $param['booking']['currency_code'],
];
$bookingUpdate = $this->bookingService->update($bookingDetail['data']['id'], $bookingUpdateParam);
$bookingContactUpdateParam = [
'name' => $param['contact']['name'],
'surname' => $param['contact']['surname'],
'phone_code' => $param['contact']['phone_code'],
'phone_number' => $param['contact']['phone_number'],
'email' => $param['contact']['email'],
'country_code' => !empty($param['contact']['country_code']) ? $param['contact']['country_code'] : null,
'note' => !empty($param['contact']['note']) ? $param['contact']['note'] : null,
'language_code' => fillOnUndefined($param['contact'], 'language_code', 'en')
];
$bookingContactUpdate = $this->bookingContactService->update($bookingDetail['data']['booking_contact']['id'], $bookingContactUpdateParam);
foreach ($bookingDetail['data']['booking_room'] as $roomOrder => $room) {
foreach ($param['room'] as $roomOrderChannel => $roomChannel) {
if ($roomOrder == $roomOrderChannel) {
$bookingRoomUpdateParam = [
'occupancy_code' => $roomChannel['occupancy_code'],
'checkin_date' => $roomChannel['checkin_date'],
'checkout_date' => $roomChannel['checkout_date'],
'room_id' => $roomChannel['room_id'],
'room_name' => $roomChannel['room_name'],
'room_rate_mapping_id' => $roomChannel['room_rate_mapping_id'],
'room_rate_name' => $roomChannel['room_rate_name'],
'rate_detail' => json_encode($roomChannel),
'total' => $roomChannel['total'],
'currency_code' => $roomChannel['currency_code'],
'daily_amount' => fillOnUndefined($roomChannel, 'daily_amount'),
];
$bookingRoomUpdate = $this->bookingRoomService->update($room['id'], $bookingRoomUpdateParam);
/* ROOM AVAILABILITY */
//Eğer odaya ait tarihler farklı ise buraya gelecek.
if (($room['checkin_date'] != $roomChannel['checkin_date']) || ($room['checkout_date'] != $roomChannel['checkout_date'])) {
$dateByDay = [];
$dateByDay['update'] = [];
$dateByDay['current'] = $this->getDateByDay(['checkIn' => $room['checkin_date'], 'checkOut' => $room['checkout_date']]);
$dateByDay['modified'] = $this->getDateByDay(['checkIn' => $roomChannel['checkin_date'], 'checkOut' => $roomChannel['checkout_date']]);
foreach ($dateByDay['current'] as $date) {
$dateByDay['update'][$date] = !isset($dateByDay['update'][$date]) ? 0 : $dateByDay['update'][$date];
$dateByDay['update'][$date]++;
}
foreach ($dateByDay['modified'] as $date) {
$dateByDay['update'][$date] = !isset($dateByDay['update'][$date]) ? 0 : $dateByDay['update'][$date];
$dateByDay['update'][$date]--;
}
ksort($dateByDay['update']);
foreach ($dateByDay['update'] as $day => $availabilityModified) {
$requestParam = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => $param['booking']['property_id']],
['field' => 'property_room_id', 'condition' => '=', 'value' => $room['room_id']],
['field' => 'availability_type_id', 'condition' => '=', 'value' => 1],
['field' => 'date', 'condition' => '=', 'value' => $day]
],
];
$getPropertyRoomAndRoomRateAvailability = $this->propertyRoomAvailabilityService->select($requestParam);
if ($getPropertyRoomAndRoomRateAvailability['status'] != 'success') {
throw new ApiErrorException('getPropertyRoomAndRoomRateAvailability Empty');
}
foreach ($getPropertyRoomAndRoomRateAvailability['data'] as $roomAvailability) {
$roomAvailabilityUpdated = 0;
$roomAvailabilityUpdated = $roomAvailability['availability'] + $availabilityModified;
if($roomAvailabilityUpdated < 0) {
$roomAvailabilityUpdated = 0;
}
$this->propertyRoomAvailabilityService->update($roomAvailability['id'], ['availability' => $roomAvailabilityUpdated]);
}
}
}
/* ROOM AVAILABILITY */
}
}
}
//Added New Room Case
if (count($bookingDetail['data']['booking_room']) != count($param['room']) && count($param['room']) > count($bookingDetail['data']['booking_room']) ) {
foreach ($param['room'] as $roomOrderChannel => $roomChannel) {
foreach ($bookingDetail['data']['booking_room'] as $roomOrder => $room) {
if ($roomOrder != $roomOrderChannel) {
$bookingRoomCreateParam = [
'booking_id' => $bookingDetail['data']['id'],
'room_order_number' => ($roomOrderChannel + 1),
'occupancy_code' => $roomChannel['occupancy_code'],
'checkin_date' => $roomChannel['checkin_date'], //$room['checkin'],
'checkout_date' => $roomChannel['checkout_date'],//$room['checkout'],
'rate_key' => fillOnUndefined($roomChannel, 'rate_key'),
'rate_key_code' => fillOnUndefined($roomChannel, 'rate_key_code'),
'availability_id' => 1,
'availability_code' => 'ROM',
'room_id' => $roomChannel['room_id'],
'room_name' => $roomChannel['room_name'],
'room_rate_mapping_id' => $roomChannel['room_rate_mapping_id'],
'room_rate_name' => $roomChannel['room_rate_name'],
'cancellation_policy' => fillOnUndefined($roomChannel, 'cancellation_policy'),
'payment_type_code' => fillOnUndefined($roomChannel, 'payment_type_code', 'CHN'),
'daily_amount' => fillOnUndefined($roomChannel, 'daily_amount'),
'extra_param' => fillOnUndefined($roomChannel, 'extra_param'),
'rate_detail' => fillOnUndefined($roomChannel, 'rate_detail'),
'total' => $roomChannel['total'],
'currency_code' => $roomChannel['currency_code'],
'status' => fillOnUndefined($roomChannel, 'status', 1),
];
$bookingRoomCreate = $this->bookingRoomService->create($bookingRoomCreateParam);
}
}
}
}
//UPDATE PAYMENT DATA
$bookingPaymentUpdateParam = [
'payment_type_code' => fillOnUndefined($param['payment'], 'payment_type_code'),
'payment_source_code' => fillOnUndefined($param['payment'], 'payment_source_code'),
'extra_param' => fillOnUndefined($param['payment'], 'extra_param'),
'total' => fillOnUndefined($param['payment'], 'total'),
'currency_code' => fillOnUndefined($param['payment'], 'currency_code')
];
$bookingPaymentUpdate = $this->bookingPaymentService->update($bookingDetail['data']['booking_payment']['id'], $bookingPaymentUpdateParam);
//UPDATE PAYMENT DATA
//INSERT CHANNEL PAYMENT DATA
if (isset($param['payment_channel']) && !empty($param['payment_channel'])) {
$bookingPaymentDataCreateParam = [
'booking_id' => $bookingDetail['data']['id'],
'type' => fillOnUndefined($param['payment_channel'], 'type'),
'data' => fillOnUndefined($param['payment_channel'], 'data'),
'status' => fillOnUndefined($param['payment_channel'], 'status', 1),
];
$bookingPaymentDataCreate = $this->bookingPaymentService->createPaymentData($bookingPaymentDataCreateParam);
if ($bookingPaymentDataCreate['status'] != 'success') {
throw new ApiErrorException('Booking Channel Payment could not be made');
}
}
//INSERT CHANNEL PAYMENT DATA
} else {
return $this->createBooking($channelCode, $param);
}
$bookingCode = is_null($bookingCode) ? 'ENW' . $param['booking']['search_key'] : $bookingCode;
$reservationConfirmParam = $channelService->reservationConfirmParam($param['channel_manager']['property_id'], $param['channel_manager']['booking_id'], $bookingCode, $param);
$reservationConfirm = $channelService->reservationConfirm($reservationConfirmParam);
if (!$reservationConfirm['status']) {
throw new ApiErrorException($reservationConfirm['message']);
}
$notificationModifiedToPropertyUser = [
'booking_id' => $param['booking']['id'],
];
$this->mailer->onQueue('modifiedBookingMail', new ModifiedBookingMail($notificationModifiedToPropertyUser));
$response['status'] = true;
$response['data'] = $param;
} 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']) {
//PUSH CHANNEL MANAGER QUEUE
$channelManagerPropertyMappingCriteria = [
'criteria' =>
[
['field' => 'property_id', 'condition' => '=', 'value' => $bookingDetail['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) {
if(in_array($channelPropertyData['channel_manager_id'],[11,13])) {
continue;
}
$channelManagerBookingCreateParam = [
'property_id' => $bookingDetail['data']['property_id'],
'booking_id' => $bookingDetail['data']['id'],
'channel_manager_id' => $channelPropertyData['channel_manager_id'],
'type' => 'Modify',
];
$channelManagerBookingCreate = $this->channelManagerBookingService->create($channelManagerBookingCreateParam);
}
}
//PUSH CHANNEL MANAGER QUEUE
DB::commit();
} else {
DB::rollBack();
}
return $response;
}
public function cancelBooking($channelCode, $param)
{
$response = ['status' => false, 'message' => ''];
DB::beginTransaction();
try {
$channelService = App::make("App\Core\Service\ChannelManager\\{$channelCode}");
$bookingCode = null;
$bookingDetailParam = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => $param['booking']['property_id']],
['field' => 'search_key', 'condition' => '=', 'value' => $param['booking']['search_key']],
//['field' => 'channel_manager_id', 'condition' => '=', 'value' => $param['booking']['channel_manager_id']],
],
'with' => ['bookingRoom', 'bookingContact', 'bookingChannel'],
'firstRow' => true
];
$bookingDetail = $this->bookingService->select($bookingDetailParam);
if ($bookingDetail['status'] != 'success') {
throw new ApiErrorException(lang('Booking could not be found, Reservation: ' . $param['booking']['search_key']));
}
if (!empty($bookingDetail['data'])) {
$bookingCode = $bookingDetail['data']['booking_code'];
$param['booking']['id'] = $bookingDetail['data']['id'];
$param['booking']['booking_code'] = $bookingDetail['data']['booking_code'];
$this->bookingService->update($bookingDetail['data']['id'], ['status' => 0]);
foreach ($bookingDetail['data']['booking_room'] as $roomOrder => $room) {
$bookingRoomUpdate = $this->bookingRoomService->update($room['id'], ['status' => 0]);
/* ROOM AVAILABILITY */
$dateByDay = [];
$dateByDay = $this->getDateByDay(['checkIn' => $room['checkin_date'], 'checkOut' => $room['checkout_date']]);
foreach ($dateByDay as $day) {
$requestParam = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => $param['booking']['property_id']],
['field' => 'property_room_id', 'condition' => '=', 'value' => $room['room_id']],
['field' => 'availability_type_id', 'condition' => '=', 'value' => 1],
['field' => 'date', 'condition' => '=', 'value' => $day]
],
];
$getPropertyRoomAndRoomRateAvailability = $this->propertyRoomAvailabilityService->select($requestParam);
if ($getPropertyRoomAndRoomRateAvailability['status'] != 'success') {
throw new ApiErrorException('getPropertyRoomAndRoomRateAvailability Empty');
}
foreach ($getPropertyRoomAndRoomRateAvailability['data'] as $roomAvailability) {
$roomAvailabilityUpdated = $roomAvailability['availability'] <= 0 ? 1 : ($roomAvailability['availability'] + 1);
$this->propertyRoomAvailabilityService->update($roomAvailability['id'], ['availability' => $roomAvailabilityUpdated]);
}
}
/* ROOM AVAILABILITY */
}
}
$bookingCode = is_null($bookingCode) ? 'ENW' . $param['booking']['search_key'] : $bookingCode;
$reservationConfirmParam = $channelService->reservationConfirmParam($param['channel_manager']['property_id'], $param['channel_manager']['booking_id'], $bookingCode, $param);
$reservationConfirm = $channelService->reservationConfirm($reservationConfirmParam);
if (!$reservationConfirm['status']) {
throw new ApiErrorException($reservationConfirm['message']);
}
$notificationCancelToPropertyUser = [
'booking_id' => $param['booking']['id'],
];
$this->mailer->onQueue('cancelBookingMail', new CancelBookingMail($notificationCancelToPropertyUser));
$response['status'] = true;
$response['data'] = $param;
} 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']) {
//PUSH CHANNEL MANAGER QUEUE
$channelManagerPropertyMappingCriteria = [
'criteria' =>
[
['field' => 'property_id', 'condition' => '=', 'value' => $bookingDetail['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) {
if(in_array($channelPropertyData['channel_manager_id'],[11,13])) {
continue;
}
$channelManagerBookingCreateParam = [
'property_id' => $bookingDetail['data']['property_id'],
'booking_id' => $bookingDetail['data']['id'],
'channel_manager_id' => $channelPropertyData['channel_manager_id'],
'type' => 'Cancel',
];
$channelManagerBookingCreate = $this->channelManagerBookingService->create($channelManagerBookingCreateParam);
}
}
//PUSH CHANNEL MANAGER QUEUE
DB::commit();
} else {
DB::rollBack();
}
return $response;
}
public function handle()
{
try {
$this->info(date('Y-m-d H:i:s') . ' : Start');
$channelManagerCriteria =
[
'criteria' =>
[
['field' => 'status', 'condition' => '=', 'value' => 1],
],
'orderBy' => [
['field' => 'id', 'value' => 'ASC']
]
];
$channelManager = $this->channelManagerService->select($channelManagerCriteria);
$channelManagerList = [];
if ($channelManager['status'] == 'success' && !empty($channelManager['data'])) {
$channelManagerList = $channelManager['data'];
}
//CHANNEL MANAGER
foreach ($channelManagerList as $channelKey => $channel) {
$this->info(date('Y-m-d H:i:s') . ' : Channel Start: ' . $channel['name']);
if (!class_exists("App\Core\Service\ChannelManager\\{$channel['name']}")) {
$this->error(date('Y-m-d H:i:s') . ' : Channel: ' . $channel['name'] . ' Class does not exist!');
continue;
}
$channelService = App::make("App\Core\Service\ChannelManager\\{$channel['name']}");
$channelManagerPropertyMappingCriteria = [
'criteria' =>
[
['field' => 'status', 'condition' => '=', 'value' => 1],
['field' => 'channel_manager_id', 'condition' => '=', 'value' => $channel['id']],
['field' => 'channel_manager_property_id', 'condition' => '!=', 'value' => null],
],
'with' => ['channelManagerRoomRate.propertyRoomRateMapping', 'property'],
'orderBy' => [
['field' => 'property_id', 'value' => 'ASC']
]
];
//TODO: Channex limited hotels
if ($channel['id'] == 2) {
$channexPullReservationPropertyIds = [71,313, /*538, 541, 545, 546, 548, 549, 550,*/ 672, 712, 785, 808, 790, 755, 901, 952, 912, 848, 1098, 1103, 1035];
$channelManagerPropertyMappingCriteria['whereIn'][] = ["field" => "property_id", "value" => $channexPullReservationPropertyIds];
}
$channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria);
//Eğer kanala ait bir otel yok ise devam et
if ($channelManagerPropertyMapping['status'] != 'success' || empty($channelManagerPropertyMapping['data'])) {
continue;
}
if ($channelManagerPropertyMapping['status'] == 'success') {
//CHANNEL MANAGER PROPERTY
foreach ($channelManagerPropertyMapping['data'] as $propertyMapping) {
//Property
if (!in_array($propertyMapping['property']['id'],[623])) {
//continue;
}
$this->info(date('Y-m-d H:i:s') . ' : Property: ' . $propertyMapping['property']['id'] . ' - ' . $propertyMapping['property']['name']);
$reservationListParam = $channelService->reservationListParam($propertyMapping['channel_manager_property_id']);
$reservationList = $channelService->reservationList($reservationListParam);
//Eğer kanaldaki otele ait bir rezervasyon yok ise devam et
if (!$reservationList['status']) {
continue;
}
//CHANNEL MANAGER PROPERTY Reservation
foreach ($reservationList['data'] as $reservationKey => $reservation) {
$reservationPullFormatted = $channelService->reservationPullFormattedData($propertyMapping['property_id'], $propertyMapping['channel_manager_property_id'], $reservation);
if (!$reservationPullFormatted['status']) {
//Burada bi hata var demektir, mail atılsın ama sonraki işleme devam edilsin.
//$logMessage
$mailParams = [
'title' => $channel['name'] . ' - ReservationPullService Error - reservationPullFormatted',
'logMessage' => '<pre>' . print_r($reservationPullFormatted, true) . '</pre>'
];
$this->mailer->onQueue('logMail', new LogMail($mailParams));
//$logMessage
$this->error(date('Y-m-d H:i:s') . ' : Property: ' . $propertyMapping['property']['id'] . ' - ' . $propertyMapping['property']['name'].' Error: reservationPullFormattedData');
continue;
}
//TODO: Eğer burada gelen kanal extranetwork ise alınmış gibi yapılıp diğer işleme geçilmeli
if (in_array($reservationPullFormatted['data']['channel_manager']['sub_channel'], ['ExtranetWork'])) {
$reservationConfirmParam = $channelService->reservationConfirmParam($reservationPullFormatted['data']['channel_manager']['property_id'], $reservationPullFormatted['data']['channel_manager']['booking_id'], 'ENW' . $reservationPullFormatted['data']['channel_manager']['booking_id'], $reservationPullFormatted['data']);
$reservationConfirm = $channelService->reservationConfirm($reservationConfirmParam);
if (!$reservationConfirm['status']) {
throw new ApiErrorException($reservationConfirm['message']);
}
continue;
}
$reservationPull = ['status' => false, 'message' => ''];
if ($reservationPullFormatted['type'] == 'createBooking') {
$reservationPull = $this->createBooking($channel['name'], $reservationPullFormatted['data']);
} elseif ($reservationPullFormatted['type'] == 'modifiedBooking') {
//If the modified reservation is not found, first create a reservation.
$bookingDetailParam = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => $reservationPullFormatted['data']['booking']['property_id']],
['field' => 'search_key', 'condition' => '=', 'value' => $reservationPullFormatted['data']['booking']['search_key']],
],
'firstRow' => true
];
$bookingDetail = $this->bookingService->select($bookingDetailParam);
if (empty($bookingDetail['data'])) {
$reservationPull = $this->createBooking($channel['name'], $reservationPullFormatted['data']);
} else {
$reservationPull = $this->modifiedBooking($channel['name'], $reservationPullFormatted['data']);
}
} elseif ($reservationPullFormatted['type'] == 'cancelBooking') {
$reservationPull = $this->cancelBooking($channel['name'], $reservationPullFormatted['data']);
}
if ($reservationPull['status']) {
$this->info(date('Y-m-d H:i:s') . ' : Success ' . $reservationPullFormatted['type'] . ': ' . $reservationPull['data']['booking']['booking_code']);
} else {
//$logMessage
$mailParams = [
'title' => $channel['name'] . ' - ReservationPullService Error - Booking',
'logMessage' => '<pre>' . print_r(array_merge($reservationPullFormatted, $reservationPull), true) . '</pre>'
];
$this->mailer->onQueue('logMail', new LogMail($mailParams));
//$logMessage
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $reservationPull['message']);
}
}
}
}
$this->info(PHP_EOL);
}
//dd($channelManagerList);
$this->info(date('Y-m-d H:i:s') . ' : Finished');
} catch (ApiErrorException $e) {
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage());
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message);
}
}
}

View File

@@ -0,0 +1,150 @@
<?php
namespace App\Console\Commands\ChannelManager;
use App\Core\Mail\LogMail;
use App\Core\Service\ChannelManager\Reseliva;
use App\Core\Service\ChannelManagerBookingService;
use App\Exceptions\ApiErrorException;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Log;
use Exception;
class ReservationPushService extends Command
{
protected $signature = 'cron:reservation-push-service';
protected $description = '';
protected $channelService;
protected $channelManagerBookingService;
public function __construct(
Mailer $mailer,
Reseliva $channelService,
ChannelManagerBookingService $channelManagerBookingService
)
{
parent::__construct();
$this->mailer = $mailer;
$this->channelService = $channelService;
$this->channelManagerBookingService = $channelManagerBookingService;
}
public function handle()
{
$this->info(date('Y-m-d H:i:s') . ' : Start');
$pendingBookingCriteria = [
'criteria' =>
[
//['field' => 'id', 'condition' => '=', 'value' => 22461],#21390
['field' => 'is_pushed', 'condition' => '=', 'value' => null],
['field' => 'status', 'condition' => '=', 'value' => 1],
],
'with' => [
'channelManager',
'bookingDetail.bookingContact', 'bookingDetail.bookingChannel',
'bookingDetail.bookingPayment', 'bookingDetail.bookingPaymentType',
'bookingDetail.bookingStatus', 'bookingDetail.bookingRoom.roomPax.paxCountry'
],
'orderBy' => [
['field' => 'id', 'value' => 'ASC']
],
'take' => 100
];
$pendingBooking = $this->channelManagerBookingService->select($pendingBookingCriteria);
if ($pendingBooking['status'] == 'success') {
$pendingBooking = $pendingBooking['data'];
foreach ($pendingBooking as $booking) {
try {
$this->info(date('Y-m-d H:i:s') . ' : Booking ID: ' . $booking['booking_id']);
$channelService = App::make("App\Core\Service\ChannelManager\\{$booking['channel_manager']['name']}");
$this->info(date('Y-m-d H:i:s') . ' : Channel: ' . $booking['channel_manager']['name']);
if ($booking['channel_manager_id'] == 10) {
//After 3 minutes, the faulty operation is set to status 2 for Hyperguest.
if (Carbon::createFromTimestamp($booking['created_at'])->diffInMinutes(Carbon::now()) > 3) {
$this->channelManagerBookingService->update($booking['id'], ['status' => 2]);
$this->error(date('Y-m-d H:i:s') . ' : Channel: ' . $booking['channel_manager']['name']);
continue;
}
}
//After 30 minutes, the faulty operation is set to status 2.
if (Carbon::createFromTimestamp($booking['created_at'])->diffInMinutes(Carbon::now()) > 30) {
$this->channelManagerBookingService->update($booking['id'], ['status' => 2]);
}
$requestPostReservationPushParam = $channelService->requestPostReservationPushParam($booking['property_id'], $booking['booking_id'], $booking['type'], $booking);
if (empty($requestPostReservationPushParam)) {
throw new ApiErrorException('requestPostReservationPushParam Error');
}
$this->info(date('Y-m-d H:i:s') . ' : Booking ID: ' . $booking['booking_id'] . ' Push');
$this->channelManagerBookingService->update($booking['id'], ['request' => $requestPostReservationPushParam]);
$requestPostReservationPush = $channelService->requestPostReservationPush($requestPostReservationPushParam);
if ($requestPostReservationPush['status']) {
$this->info(date('Y-m-d H:i:s') . ' : Booking ID: ' . $booking['booking_id'] . ' Success');
$this->channelManagerBookingService->update($booking['id'], ['is_pushed' => 1, 'status' => 1, 'response' => $requestPostReservationPush['response']]);
} else {
//$logMessage
$mailParams = [
'title' => 'ReservationPushService Error - ChannelManagerName: ' . $booking['channel_manager']['name'],
'logMessage' => '<pre>' . print_r(array_merge($booking, $requestPostReservationPush), true) . '</pre>'
];
$this->mailer->onQueue('logMail', new LogMail($mailParams));
//$logMessage
$this->error(date('Y-m-d H:i:s') . ' : Booking ID: ' . $booking['booking_id'] . ' Failed');
$this->channelManagerBookingService->update($booking['id'], ['response' => $requestPostReservationPush['message']]);
}
} catch (ApiErrorException $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage());
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message);
}
}
}
$this->info(date('Y-m-d H:i:s') . ' : Finished');
}
}

View File

@@ -0,0 +1,262 @@
<?php
namespace App\Console\Commands\ChannelManager;
use App\Core\Mail\LogMail;
use App\Core\Service\ChannelManager\Reseliva;
use App\Core\Service\ChannelManagerPropertyMappingService;
use App\Core\Service\ChannelManagerService;
use App\Core\Service\PropertyRoomAvailabilityQueueService;
use App\Exceptions\ApiErrorException;
use App\Models\PropertyRoomAvailabilityQueue;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Log;
class RoomAvailabilityPushService extends Command
{
protected $signature = 'cron:roomavailability-push-service';
protected $description = '';
protected $mailer;
protected $channelService;
protected $channelManagerService;
protected $propertyRoomAvailabilityQueueService;
public function __construct(
Mailer $mailer,
ChannelManagerService $channelManagerService,
PropertyRoomAvailabilityQueueService $propertyRoomAvailabilityQueueService,
ChannelManagerPropertyMappingService $channelManagerPropertyMappingService
)
{
parent::__construct();
$this->mailer = $mailer;
$this->channelManagerService = $channelManagerService;
$this->propertyRoomAvailabilityQueueService = $propertyRoomAvailabilityQueueService;
$this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService;
}
public function handle()
{
try {
$this->info(date('Y-m-d H:i:s') . ' : Start');
//Queue Check
$this->info(date('Y-m-d H:i:s') . ' : Queue Check');
$roomAvailabilityQueueCountCriteria = ['criteria' => [['field' => 'status', 'condition' => '=', 'value' => 1]], 'count' => true];
$roomAvailabilityQueueCount = $this->propertyRoomAvailabilityQueueService->select($roomAvailabilityQueueCountCriteria);
if ($roomAvailabilityQueueCount['status'] == 'success') {
$roomAvailabilityQueueCount = $roomAvailabilityQueueCount['data'];
if ($roomAvailabilityQueueCount > 2000) {
$roomAvailabilityQueueCountGroupByProperty = PropertyRoomAvailabilityQueue::selectRaw('property_id, COUNT(*) as total')
->groupBy('property_id')
->orderByDesc('total')
->first();
$roomAvailabilityQueueCountGroupByProperty = $roomAvailabilityQueueCountGroupByProperty ? $roomAvailabilityQueueCountGroupByProperty->toArray() : null;
if ($roomAvailabilityQueueCountGroupByProperty) {
if ($roomAvailabilityQueueCountGroupByProperty['total'] > 1000) {
PropertyRoomAvailabilityQueue::where('property_id', $roomAvailabilityQueueCountGroupByProperty['property_id'])->delete();
}
}
}
if ($roomAvailabilityQueueCount > 1000) {
$this->error(date('Y-m-d H:i:s') . ' : Queue Alarm: ' . $roomAvailabilityQueueCount);
//Clear Test Property Data
PropertyRoomAvailabilityQueue::where('property_id', 1)->delete();
//$logMessage
$mailParams = [
'title' => 'RoomAvailabilityPushService Error - Queue Error',
'logMessage' => 'Queue: ' . $roomAvailabilityQueueCount
];
$this->mailer->onQueue('logMail', new LogMail($mailParams));
//$logMessage
}
}
//Queue Check
$channelManagerCriteria =
[
'criteria' =>
[
['field' => 'status', 'condition' => '=', 'value' => 1],
],
/*'whereIn' =>
[
['field' => 'id', "value" => [7]]
],*/
'orderBy' => [
['field' => 'id', 'value' => 'ASC']
]
];
$channelManager = $this->channelManagerService->select($channelManagerCriteria);
$channelManagerList = [];
if ($channelManager['status'] == 'success' && !empty($channelManager['data'])) {
$channelManagerList = $channelManager['data'];
}
$roomAvailabilityQueueCriteria =
[
'criteria' =>
[
['field' => 'status', 'condition' => '=', 'value' => 1],
],
'with' => ['property'/*, 'propertyChannelManager.channelManagerRoomRate.propertyRoomRateMapping'*/],
'orderBy' => [
['field' => 'id', 'value' => 'ASC']
],
'take' => 500
];
$roomAvailabilityQueue = $this->propertyRoomAvailabilityQueueService->select($roomAvailabilityQueueCriteria);
if ($roomAvailabilityQueue['status'] == 'success' && !empty($roomAvailabilityQueue['data'])) {
foreach ($roomAvailabilityQueue['data'] as $data) {
$roomAvailabilityQueueData[$data['property_id']][] = $data;
}
$channelManagerPushedIdsList = [];
$channelManagerNoneMappingIdsList = [];
//PROPERTY
foreach ($roomAvailabilityQueueData as $roomAvailabilityQueuePropertyId => $roomAvailabilityQueueProperty) {
//CHANNEL MANAGER
$channelManagerCheckList = [];
foreach ($channelManagerList as $channelKey => $channel) {
if (in_array($channel['id'], [7, 10, 13])) {
continue;
}
$this->info(date('Y-m-d H:i:s') . ' : Channel Start: ' . $channel['name']);
if (!class_exists("App\Core\Service\ChannelManager\\{$channel['name']}")) {
$this->error(date('Y-m-d H:i:s') . ' : Channel: ' . $channel['name'] . ' Class does not exist!');
continue;
}
$channelService = App::make("App\Core\Service\ChannelManager\\{$channel['name']}");
$channelManagerPropertyMappingCriteria = [
'criteria' =>
[
['field' => 'status', 'condition' => '=', 'value' => 1],
['field' => 'property_id', 'condition' => '=', 'value' => $roomAvailabilityQueuePropertyId],
['field' => 'channel_manager_id', 'condition' => '=', 'value' => $channel['id']],
['field' => 'channel_manager_property_id', 'condition' => '!=', 'value' => null],
],
'firstRow' => true,
];
$channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria);
if ($channelManagerPropertyMapping['status'] != 'success' || ($channelManagerPropertyMapping['status'] == 'success' && empty($channelManagerPropertyMapping['data']))) {
$this->info(date('Y-m-d H:i:s') . ' : Channel: ' . $channel['name'] . ' PropertyID: ' . $roomAvailabilityQueuePropertyId . ' : PASS');
continue;
}
$channelManagerCheckList[$channel['id']] = true;
$roomAvailabilityPush = $channelService->roomAvailabilityPush($roomAvailabilityQueuePropertyId, $roomAvailabilityQueueProperty);
if ($roomAvailabilityPush['status']) {
$channelManagerPushedIdsList[$channel['id']] = $roomAvailabilityPush['data']['channelManagerPushedIds'];
$channelManagerNoneMappingIdsList[$channel['id']] = $roomAvailabilityPush['data']['channelManagerNoneMappingIds'];
$this->info(date('Y-m-d H:i:s') . ' : Success: ' . $channel['name']);
} else {
$channelManagerCheckList[$channel['id']] = false;
//$logMessage
$mailParams = [
'title' => $channel['name'] . ' - RoomAvailabilityPushService Error - inventoryRoomRateUpdate Error',
'logMessage' => '<pre>' . print_r($roomAvailabilityPush, true) . '</pre>'
];
$this->mailer->onQueue('logMail', new LogMail($mailParams));
//$logMessage
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $channel['name'] . ' - ' . $roomAvailabilityPush['message']);
}
$this->info(date('Y-m-d H:i:s') . ' : Channel Finished: ' . $channel['name']);
}
if (in_array(false, $channelManagerCheckList)) {
$this->error(date('Y-m-d H:i:s') . ' : Error Break: ' . var_export($channelManagerCheckList));
continue;
}
if (count($channelManagerPushedIdsList) > 1) {
$channelManagerPushedIdIntersect = call_user_func_array('array_intersect', $channelManagerPushedIdsList);
if (!empty($channelManagerPushedIdIntersect)) {
$this->propertyRoomAvailabilityQueueService->delete($channelManagerPushedIdIntersect);
$this->info(date('Y-m-d H:i:s') . ' : channelManagerPushedIdsList Deleted: ' . var_dump($channelManagerPushedIdIntersect));
}
} elseif (!empty($channelManagerPushedIdsList)) {
$this->propertyRoomAvailabilityQueueService->delete(reset($channelManagerPushedIdsList));
$this->info(date('Y-m-d H:i:s') . ' : channelManagerPushedIdsList Deleted: ' . var_dump($channelManagerPushedIdsList));
}
if (empty($channelManagerNoneMappingIdsList)) {
$this->info(date('Y-m-d H:i:s') . ' : channelManagerNoneMappingIdsList Empty');
continue;
}
$channelManagerNoneMappingIdsListMerge = call_user_func_array('array_merge', $channelManagerNoneMappingIdsList);
if (!empty($channelManagerNoneMappingIdsListMerge)) {
$this->propertyRoomAvailabilityQueueService->delete($channelManagerNoneMappingIdsListMerge);
$this->info(date('Y-m-d H:i:s') . ' : channelManagerNoneMappingIdsListMerge Deleted: ' . var_dump($channelManagerNoneMappingIdsListMerge));
}
}
}
$this->info(date('Y-m-d H:i:s') . ' : Finished');
} catch (ApiErrorException $e) {
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage());
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message);
}
}
}

View File

@@ -0,0 +1,255 @@
<?php
namespace App\Console\Commands\ChannelManager;
use App\Core\Mail\LogMail;
use App\Core\Service\ChannelManager\Reseliva;
use App\Core\Service\ChannelManagerPropertyMappingService;
use App\Core\Service\ChannelManagerService;
use App\Core\Service\PropertyRoomAvailabilityQueueService;
use App\Core\Service\PropertyRoomRatePriceQueueService;
use App\Exceptions\ApiErrorException;
use App\Models\PropertyRoomRatePriceQueue;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Log;
class RoomRatePushService extends Command
{
protected $signature = 'cron:roomrate-push-service';
protected $description = '';
protected $mailer;
protected $channelService;
protected $propertyRoomRatePriceQueueService;
protected $channelManagerService;
protected $propertyRoomAvailabilityQueueService;
public function __construct(
Mailer $mailer,
PropertyRoomRatePriceQueueService $propertyRoomRatePriceQueueService,
ChannelManagerService $channelManagerService,
PropertyRoomAvailabilityQueueService $propertyRoomAvailabilityQueueService,
ChannelManagerPropertyMappingService $channelManagerPropertyMappingService
)
{
parent::__construct();
$this->mailer = $mailer;
$this->propertyRoomRatePriceQueueService = $propertyRoomRatePriceQueueService;
$this->channelManagerService = $channelManagerService;
$this->propertyRoomAvailabilityQueueService = $propertyRoomAvailabilityQueueService;
$this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService;
}
public function handle()
{
//$request = $this->channelService->productList(14480);
try {
$this->info(date('Y-m-d H:i:s') . ' : Start');
//Queue Check
$this->info(date('Y-m-d H:i:s') . ' : Queue Check');
$roomRatePriceQueueCountCriteria = ['criteria' => [['field' => 'status', 'condition' => '=', 'value' => 1]],'count' => true];
$roomRatePriceQueueCount = $this->propertyRoomRatePriceQueueService->select($roomRatePriceQueueCountCriteria);
if($roomRatePriceQueueCount['status'] == 'success') {
$roomRatePriceQueueCount = $roomRatePriceQueueCount['data'];
if($roomRatePriceQueueCount > 1000) {
$this->error(date('Y-m-d H:i:s') . ' : Queue Alarm: '. $roomRatePriceQueueCount);
//Clear Test Property Data
PropertyRoomRatePriceQueue::where('property_id',1)->delete();
//$logMessage
$mailParams = [
'title' => 'RoomRatePushService Error - Queue Error',
'logMessage' => 'Queue: '.$roomRatePriceQueueCount
];
$this->mailer->onQueue('logMail', new LogMail($mailParams));
//$logMessage
}
}
//Queue Check
$channelManagerCriteria =
[
'criteria' =>
[
['field' => 'status', 'condition' => '=', 'value' => 1],
],
/*'whereIn' =>
[
['field' => 'id', "value" => [7]]
],*/
'orderBy' => [
['field' => 'id', 'value' => 'ASC']
]
];
$channelManager = $this->channelManagerService->select($channelManagerCriteria);
$channelManagerList = [];
if ($channelManager['status'] == 'success' && !empty($channelManager['data'])) {
$channelManagerList = $channelManager['data'];
}
$roomRatePriceQueueCriteria =
[
'criteria' =>
[
['field' => 'status', 'condition' => '=', 'value' => 1],
],
'with' => ['property'/*, 'propertyChannelManager.channelManagerRoomRate'*/],
'orderBy' => [
['field' => 'id', 'value' => 'ASC']
],
'take' => 500
];
$roomRatePriceQueue = $this->propertyRoomRatePriceQueueService->select($roomRatePriceQueueCriteria);
if ($roomRatePriceQueue['status'] == 'success' && !empty($roomRatePriceQueue['data'])) {
foreach ($roomRatePriceQueue['data'] as $data) {
$roomRatePriceQueueData[$data['property_id']][] = $data;
}
$channelManagerPushedIdsList = [];
$channelManagerNoneMappingIdsList = [];
//PROPERTY
foreach ($roomRatePriceQueueData as $roomRatePriceQueuePropertyId => $roomRatePriceQueueProperty) {
//CHANNEL MANAGER
$channelManagerCheckList = [];
foreach ($channelManagerList as $channelKey => $channel) {
if(in_array($channel['id'],[7,10, 13])) {
continue;
}
$this->info(date('Y-m-d H:i:s') . ' : Channel Start: ' . $channel['name']);
if(!class_exists("App\Core\Service\ChannelManager\\{$channel['name']}")) {
$this->error(date('Y-m-d H:i:s') . ' : Channel: ' . $channel['name'].' Class does not exist!');
continue;
}
$channelService = App::make("App\Core\Service\ChannelManager\\{$channel['name']}");
$channelManagerPropertyMappingCriteria = [
'criteria' =>
[
['field' => 'status', 'condition' => '=', 'value' => 1],
['field' => 'property_id', 'condition' => '=', 'value' => $roomRatePriceQueuePropertyId],
['field' => 'channel_manager_id', 'condition' => '=', 'value' => $channel['id']],
['field' => 'channel_manager_property_id', 'condition' => '!=', 'value' => null],
],
'firstRow' => true,
];
$channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria);
if ($channelManagerPropertyMapping['status'] != 'success' || ($channelManagerPropertyMapping['status'] == 'success' && empty($channelManagerPropertyMapping['data']))) {
$this->info(date('Y-m-d H:i:s') . ' : Channel: ' . $channel['name'] . ' PropertyID: ' . $roomRatePriceQueuePropertyId . ' : PASS');
continue;
}
$channelManagerCheckList[$channel['id']] = true;
$roomRatePricePush = $channelService->roomRatePricePush($roomRatePriceQueuePropertyId, $roomRatePriceQueueProperty);
if ($roomRatePricePush['status']) {
if (!empty($roomRatePricePush['data']['channelManagerPushedIds']) || !empty($roomRatePricePush['data']['channelManagerNoneMappingIds'])) {
$channelManagerPushedIdsList[$channel['id']] = $roomRatePricePush['data']['channelManagerPushedIds'];
$channelManagerNoneMappingIdsList[$channel['id']] = $roomRatePricePush['data']['channelManagerNoneMappingIds'];
}
$this->info(date('Y-m-d H:i:s') . ' : Channel Success: ' . $channel['name']);
} else {
$channelManagerCheckList[$channel['id']] = false;
//$logMessage
$mailParams = [
'title' => $channel['name'] . ' - RoomRatePushService Error - InventoryRoomRateUpdate Error',
'logMessage' => '<pre>' . print_r($roomRatePricePush, true) . '</pre>'
];
$this->mailer->onQueue('logMail', new LogMail($mailParams));
//$logMessage
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $channel['name'] . ' - ' . $roomRatePricePush['message']);
}
$this->info(date('Y-m-d H:i:s') . ' : Channel Finished: ' . $channel['name']);
}
/*foreach ($channelManagerPushedIdsList as $key => $channelManagerPushedIds) {
if(empty($channelManagerPushedIds)) {
unset($channelManagerPushedIdsList[$key]);
}
}*/
if (in_array(false, $channelManagerCheckList)) {
$this->error(date('Y-m-d H:i:s') . ' : Error Break: ' . var_export($channelManagerCheckList));
continue;
}
if (count($channelManagerPushedIdsList) > 1) {
$channelManagerPushedIdIntersect = call_user_func_array('array_intersect', $channelManagerPushedIdsList);
if (!empty($channelManagerPushedIdIntersect)) {
$this->propertyRoomRatePriceQueueService->delete($channelManagerPushedIdIntersect);
$this->info(date('Y-m-d H:i:s') . ' : $channelManagerPushedIdsList Deleted: ' . var_export($channelManagerPushedIdIntersect));
}
} elseif (!empty($channelManagerPushedIdsList)) {
$this->propertyRoomRatePriceQueueService->delete(reset($channelManagerPushedIdsList));
$this->info(date('Y-m-d H:i:s') . ' : $channelManagerPushedIdsList Deleted: ' . var_export($channelManagerPushedIdsList));
}
if (!empty($channelManagerNoneMappingIdsList)) {
$channelManagerNoneMappingIdsListMerge = call_user_func_array('array_merge', $channelManagerNoneMappingIdsList);
if (!empty($channelManagerNoneMappingIdsListMerge)) {
$this->propertyRoomRatePriceQueueService->delete($channelManagerNoneMappingIdsListMerge);
$this->info(date('Y-m-d H:i:s') . ' : $channelManagerNoneMappingIdsListMerge Deleted: ' . var_dump($channelManagerNoneMappingIdsListMerge));
}
}
}
}
$this->info(date('Y-m-d H:i:s') . ' : Finished');
} catch (ApiErrorException $e) {
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage());
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message);
}
}
}

View File

@@ -0,0 +1,497 @@
<?php
namespace App\Console\Commands\ChannelManager;
use App\Core\Mail\LogMail;
use App\Core\Service\ChannelManager\Reseliva;
use App\Core\Service\ChannelManagerLogService;
use App\Core\Service\ChannelManagerPropertyMappingService;
use App\Core\Service\ChannelManagerService;
use App\Core\Service\PropertyChannelMappingService;
use App\Core\Service\PropertyRoomAvailabilityQueueService;
use App\Core\Service\PropertyRoomAvailabilityService;
use App\Core\Service\PropertyRoomRateChannelMappingService;
use App\Core\Service\PropertyRoomRatePriceService;
use App\Core\Service\PropertyRoomService;
use App\Exceptions\ApiErrorException;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class ReselivaAvailRateUpdateService extends Command
{
protected $signature = 'cron:reseliva-availrateupdate-service';
protected $description = '';
protected $mailer;
public function __construct(
Mailer $mailer,
PropertyRoomService $propertyRoomService,
PropertyRoomRatePriceService $propertyRoomRatePriceService,
ChannelManagerLogService $channelManagerLogService,
ChannelManagerPropertyMappingService $channelManagerPropertyMappingService,
PropertyRoomRateChannelMappingService $propertyRoomRateChannelMappingService,
PropertyChannelMappingService $propertyChannelMappingService,
PropertyRoomAvailabilityService $propertyRoomAvailabilityService
)
{
parent::__construct();
$this->mailer = $mailer;
$this->propertyRoomService = $propertyRoomService;
$this->propertyRoomRatePriceService = $propertyRoomRatePriceService;
$this->channelManagerLogService = $channelManagerLogService;
$this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService;
$this->propertyRoomRateChannelMappingService = $propertyRoomRateChannelMappingService;
$this->propertyChannelMappingService = $propertyChannelMappingService;
$this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService;
}
public function propertyChannelMapping($propertyId, $channelId)
{
$response = ['status' => false, 'message' => ''];
try {
$propertyChannelMappingCriteria = [
'criteria' => [
['field' => 'channel_id', 'condition' => '=', 'value' => $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, $channelId)
{
$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' => [
'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');
}
$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, $channelId)
{
$response = ['status' => false, 'message' => ''];
try {
$requestParam =
[
'criteria' =>
[
['field' => 'status', 'condition' => '=', 'value' => 1],
['field' => 'property_id', 'condition' => '=', 'value' => $propertyId],
['field' => 'channel_manager_id', 'condition' => '=', 'value' => $channelId],
],
'firstRow' => true
];
$channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($requestParam);
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 handle()
{
$this->info(date('Y-m-d H:i:s') . ' : Start');
$channelId = 1;
$channelManagerId = 1;
$channelManagerLogCriteria = [
'criteria' => [
['field' => 'id', 'condition' => '=', 'value' => 32670],
['field' => 'service', 'condition' => '=', 'value' => 'AvailRateUpdate'],
['field' => 'status', 'condition' => '=', 'value' => null],
],
'orderBy' => [
['field' => 'id', 'value' => 'ASC']
]
];
$channelManagerLog = $this->channelManagerLogService->select($channelManagerLogCriteria);
if ($channelManagerLog['status'] && !empty($channelManagerLog['data'])) {
foreach ($channelManagerLog['data'] as $logData) {
$response = ['status' => false, 'message' => ''];
$payloadXML = simplexml_load_string($logData['request']);
$payloadParam = json_decode(json_encode($payloadXML), 1);
try {
$propertyId = $payloadParam['Hotel']['@attributes']['id'];
$channelManagerPropertyCheck = $this->channelManagerPropertyCheck($propertyId, $channelId);
if (!$channelManagerPropertyCheck['status']) {
throw new ApiErrorException($channelManagerPropertyCheck['message']);
}
$channelPropertyRoomRate = $this->channelPropertyRoomRate($propertyId, $channelId);
if (!$channelPropertyRoomRate['status']) {
throw new ApiErrorException($channelPropertyRoomRate['message']);
}
$channelPropertyRoomRate = $channelPropertyRoomRate['data'];
$channelPropertyRoomRateCollect = collect($channelPropertyRoomRate);
$propertyChannelMapping = $this->propertyChannelMapping($propertyId, $channelId);
if (!$propertyChannelMapping['status']) {
throw new ApiErrorException($propertyChannelMapping['message']);
}
$propertyChannelMapping = $propertyChannelMapping['data'];
$availRateUpdates = singleElementXMLArray($payloadParam['AvailRateUpdate']);
DB::beginTransaction();
foreach ($availRateUpdates as $availRateUpdate) {
$dateRange = [];
$dateRange['startDate'] = $availRateUpdate['DateRange']['@attributes']['from'];
$dateRange['finishDate'] = $availRateUpdate['DateRange']['@attributes']['to'];
if (Carbon::parse($dateRange['startDate'])->isBefore(Carbon::now()->toDateString()) || Carbon::parse($dateRange['finishDate'])->isBefore(Carbon::now()->toDateString())) {
throw new ApiErrorException('Dates to be updated cannot be earlier than today');
}
$roomTypes = singleElementXMLArray($availRateUpdate['RoomType']);
$this->info(date('Y-m-d H:i:s') . ' : ' . $dateRange['startDate'] . ' - ' . $dateRange['finishDate']);
foreach ($roomTypes as $roomType) {
$roomId = $roomType['@attributes']['id'];
$roomCheck = $channelPropertyRoomRateCollect->where('property_room_rate_mapping.room_id', $roomId)->isEmpty();
if ($roomCheck) {
throw new ApiErrorException('Tanımlı ya da aktif olmayan oda');
}
$totalInventoryAvailable = null;
if (isset($roomType['Inventory']['@attributes']['totalInventoryAvailable'])) {
$totalInventoryAvailable = $roomType['Inventory']['@attributes']['totalInventoryAvailable'];
}
$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' => $dateRange['startDate'],
'end_date' => $dateRange['finishDate'],
'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']);
}
$this->info(date('Y-m-d H:i:s') . ' : Update Type: ' . $requestParams['update_type']);
}
if (isset($roomType['RatePlan'])) {
$ratePlans = singleElementXMLArray($roomType['RatePlan']);
foreach ($ratePlans as $ratePlan) {
$roomRateMappingId = $ratePlan['@attributes']['id'];
$isCloseRoomRateMappingSale = null;
if (isset($ratePlan['@attributes']['closed'])) {
$isCloseRoomRateMappingSale = $ratePlan['@attributes']['closed'] == 'true' ? true : false;
}
$channelRoomRateMappingCheck = $channelPropertyRoomRateCollect->where('room_rate_mapping_id', $roomRateMappingId)->isEmpty();
if ($channelRoomRateMappingCheck) {
throw new ApiErrorException('Tanımlı ya da aktif olmayan oda konaklama');
}
$roomRates = [
'room_id' => $roomId,
'room_rate_mapping_id' => [
$roomRateMappingId
]
];
$paramsListChannel = [];
$paramsListChannel[] = 1;
//CONNECTED CHANNEL RATE UPDATE
$propertyChannelMappingConnectedCriteria = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => $requestParamBase['property_id']],
['field' => 'connected_channel_id', 'condition' => '=', 'value' => $requestParamBase['channel_id']],
['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
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($ratePlan['Rate'])) {
$currency = $ratePlan['Rate']['@attributes']['currency'];
$currencyCheck = ($currency == $propertyChannelMapping['currency_code']) ? true : false;
if (!$currencyCheck) {
throw new ApiErrorException('Kanal döviz kuru ile eşleşmeyen döviz kuru, kanal döviz kuru: ' . $propertyChannelMapping['currency_code']);
}
$channelRoomRateMapping = $channelPropertyRoomRateCollect->where('room_rate_mapping_id', $roomRateMappingId)->first();
$amountPerDay = $ratePlan['Rate']['PerDay']['@attributes']['rate'];
$requestParams = [];
$requestParams = $requestParamBase;
$requestParams['update_type'] = 'rate';
$requestParams['value'] = $amountPerDay;
$requestParams['room_rates'] = [$roomRates];
$requestParams['channel_id'] = $paramChannelId;
$propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams);
if ($propertyRoomRateMapping['status'] != 'success') {
throw new ApiErrorException($propertyRoomRateMapping['message']);
}
$this->info(date('Y-m-d H:i:s') .
' : Update Type: ' .$requestParams['update_type'].
' : Channel ID: '. $requestParams['channel_id'].
' : Room ID: '. $roomRates['room_id']
);
}
//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;
$propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams);
if ($propertyRoomRateMapping['status'] != 'success') {
throw new ApiErrorException($propertyRoomRateMapping['message']);
}
$this->info(date('Y-m-d H:i:s') . ' : Update Type: ' . $requestParams['update_type']);
}
//Kısıtlamalar var ise min los
if (isset($ratePlan['Restrictions'])) {
//Minimum Konaklama Gün Sayısı
if (isset($ratePlan['Restrictions']['@attributes']['minLOS'])) {
$minStay = $ratePlan['Restrictions']['@attributes']['minLOS'];
$requestParams = [];
$requestParams = $requestParamBase;
$requestParams['update_type'] = 'min_stay';
$requestParams['value'] = $minStay;
$requestParams['room_rates'] = [$roomRates];
$requestParams['channel_id'] = $paramChannelId;
$propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams);
if ($propertyRoomRateMapping['status'] != 'success') {
throw new ApiErrorException($propertyRoomRateMapping['message']);
}
$this->info(date('Y-m-d H:i:s') . ' : Update Type: ' . $requestParams['update_type']);
}
}
}
}
}
}
}
$response['status'] = true;
$updateDataLog = [
'response' => json_encode($response),
'status' => 1
];
$channelManagerLog = $this->channelManagerLogService->update($logData['id'], $updateDataLog);
DB::commit();
} 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();
}
//TODO: mail
if (!$response['status']) {
DB::rollBack();
}
}
}
$this->info(date('Y-m-d H:i:s') . ' : Finished');
}
}

View File

@@ -0,0 +1,784 @@
<?php
namespace App\Console\Commands\ChannelManager;
use App\Core\Mail\CancelBookingMail;
use App\Core\Mail\LogMail;
use App\Core\Mail\ModifiedBookingMail;
use App\Core\Service\BookingContactService;
use App\Core\Service\BookingPaymentService;
use App\Core\Service\BookingRoomService;
use App\Core\Service\BookingService;
use App\Core\Service\ChannelManager\Reseliva;
use App\Core\Service\ChannelManagerMappingService;
use App\Core\Service\ChannelManagerPropertyMappingService;
use App\Core\Service\ChannelManagerPropertyRateMappingService;
use App\Core\Service\NewBookingMailService;
use App\Core\Service\PropertyRoomAvailabilityService;
use App\Exceptions\ApiErrorException;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class ReservationPullService extends Command
{
protected $signature = 'cron:reservation-pull-service';
protected $description = '';
protected $mailer;
protected $channelService;
protected $channelManagerPropertyMappingService;
protected $bookingService;
protected $propertyRoomAvailabilityService;
protected $newBookingMailService;
public function __construct(
Mailer $mailer,
Reseliva $channelService,
ChannelManagerMappingService $channelManagerMappingService,
ChannelManagerPropertyMappingService $channelManagerPropertyMappingService,
BookingService $bookingService,
BookingContactService $bookingContactService,
BookingRoomService $bookingRoomService,
BookingPaymentService $bookingPaymentService,
PropertyRoomAvailabilityService $propertyRoomAvailabilityService,
NewBookingMailService $newBookingMailService
)
{
parent::__construct();
$this->mailer = $mailer;
$this->channelService = $channelService;
$this->channelManagerMappingService = $channelManagerMappingService;
$this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService;
$this->bookingService = $bookingService;
$this->bookingContactService = $bookingContactService;
$this->bookingRoomService = $bookingRoomService;
$this->bookingPaymentService = $bookingPaymentService;
$this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService;
$this->newBookingMailService = $newBookingMailService;
}
public function reservationListParam($channelManagerPropertyId)
{
$userId = Config::get('app.channelManager.reseliva.userId');
$userPSW = Config::get('app.channelManager.reseliva.userPassword');
$requestParam = new \SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><request></request>');
$Authentication = $requestParam->addChild('Authentication');
$Authentication->addChild('UserID', $userId);
$Authentication->addChild('UserPSW', $userPSW);
$Authentication->addChild('PropertyID', $channelManagerPropertyId);
return $requestParam->asXML();
}
public function reservationConfirmParam($propertyId, $channelManagerBookingId, $bookingCode)
{
$userId = Config::get('app.channelManager.reseliva.userId');
$userPSW = Config::get('app.channelManager.reseliva.userPassword');
$requestParam = new \SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><request></request>');
$Authentication = $requestParam->addChild('Authentication');
$Authentication->addChild('UserID', $userId);
$Authentication->addChild('UserPSW', $userPSW);
$Authentication->addChild('PropertyID', $propertyId);
$reservations = $requestParam->addChild('reservations');
$reservation = $reservations->addChild('reservation');
$reservation->addAttribute('reseliva_id', $channelManagerBookingId);
$reservation->addAttribute('pms_id', $bookingCode);
return $requestParam->asXML();
}
public function getDateByDay($dates = [])
{
$dateByDay = [];
$diffInDays = Carbon::parse($dates['checkIn'])->floatDiffInDays(Carbon::parse($dates['checkOut']));
for ($i = 0; $i < $diffInDays; $i++) {
$dateByDay[] = Carbon::parse($dates['checkIn'])->addDay($i)->format('Y-m-d');
}
return $dateByDay;
}
public function createBooking($param)
{
$response = ['status' => false, 'message' => ''];
DB::beginTransaction();
try {
$bookingCode = getCodeGenerate('BKG');
$bookingStatus = 1;
$roomRequest = [];
foreach ($param['room'] as $room) {
$roomRequest[] = [
'adults' => $room['totalpax'],
'children' => $room['totalchd'],
'age' => []
];
}
if (empty(fillOnUndefined($param, 'reservno_ota'))) {
$param['reservno_ota'] = null;
}
$bookingCreateParam = [
'property_id' => $param['property']['id'],
'channel_id' => $param['property']['channel_id'],
'booking_code' => $bookingCode,
'channel_booking_code' => fillOnUndefined($param, 'reservno_ota'),
'search_key' => $param['reservno'],
'checkin_date' => $param['checkinFormatted'],
'checkout_date' => $param['checkoutFormatted'],
'rooms' => json_encode($roomRequest),
'payment_type_code' => 'CHN',
'room_amount' => $param['paymenttotal'],
'addon_amount' => 0,
'discount_amount' => 0,
'total' => $param['paymenttotal'],
'currency_code' => $param['paymentcurr'],
'channel_token' => null,
'booking_engine_token' => null,
'reservation_time' => $param['restimeUnixFormatted'],
'status' => $param['status'] == 'A' ? 1 : 0
];
$bookingCreate = $this->bookingService->create($bookingCreateParam);
//$bookingCreate['status'] = 'success';
//$bookingCreate['data']['id'] = 52;
if ($bookingCreate['status'] != 'success') {
throw new ApiErrorException(lang('Booking could not be made, Reservation: ' . $param['reservno']));
}
//INSERT CONTACT DATA
$bookingContactCreateParam = [
'booking_id' => $bookingCreate['data']['id'],
'name' => $param['firstname'],
'surname' => !empty($param['lastname']) ? $param['lastname'] : null,
'phone_code' => null,
'phone_number' => $param['tel'],
'email' => $param['email'],
'note' => !empty($param['note']) ? $param['note'] : null,
'language_code' => fillOnUndefined($param, 'language', 'en'),
'status' => 1
];
$bookingContactCreate = $this->bookingContactService->create($bookingContactCreateParam);
//$bookingContactCreate['status'] = 'success';
if ($bookingContactCreate['status'] != 'success') {
throw new ApiErrorException(lang('Booking Contact could not be made'));
}
//INSERT ROOM DATA
foreach ($param['room'] as $roomOrder => $room) {
$bookingRoomCreateParam = [
'booking_id' => $bookingCreate['data']['id'],
'room_order_number' => ($roomOrder + 1),
'occupancy_code' => str_repeat('A', $room['totalpax']) . str_repeat('C', $room['totalchd']),
'checkin_date' => $param['checkinFormatted'], //$room['checkin'],
'checkout_date' => $param['checkoutFormatted'],//$room['checkout'],
'rate_key' => null,
'rate_key_code' => null,
'availability_id' => 1,
'availability_code' => 'ROM',
'room_id' => $room['property']['room_id'],
'room_name' => $room['roomtype'],
'room_rate_mapping_id' => $room['property']['room_rate_mapping_id'],
'room_rate_name' => $room['ratename'],
'cancellation_policy' => null,
'payment_type_code' => 'CHN',
'rate_detail' => json_encode($room),
'total' => $room['total_amount'],
'currency_code' => $param['paymentcurr'],
'status' => $param['status'] == 'A' ? 1 : 0
];
$bookingRoomCreate = $this->bookingRoomService->create($bookingRoomCreateParam);
//$bookingRoomCreate['status'] = 'success';
if ($bookingRoomCreate['status'] != 'success') {
throw new ApiErrorException(lang('Booking Room could not be made'));
}
/* ROOM AVAILABILITY */
$dateByDay = [];
$dateByDay = $this->getDateByDay(['checkIn' => $room['checkin'], 'checkOut' => $room['checkout']]);
foreach ($dateByDay as $day) {
$requestParam = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => $param['property']['id']],
['field' => 'property_room_id', 'condition' => '=', 'value' => $room['property']['room_id']],
['field' => 'availability_type_id', 'condition' => '=', 'value' => 1],
['field' => 'date', 'condition' => '=', 'value' => $day]
],
];
$getPropertyRoomAndRoomRateAvailability = $this->propertyRoomAvailabilityService->select($requestParam);
if ($getPropertyRoomAndRoomRateAvailability['status'] != 'success') {
throw new ApiErrorException('getPropertyRoomAndRoomRateAvailability Empty');
}
foreach ($getPropertyRoomAndRoomRateAvailability['data'] as $roomAvailability) {
$roomAvailabilityUpdated = $roomAvailability['availability'] <= 0 ? 0 : ($roomAvailability['availability'] - 1);
$this->propertyRoomAvailabilityService->update($roomAvailability['id'], ['availability' => $roomAvailabilityUpdated]);
}
}
/* ROOM AVAILABILITY */
}
//INSERT PAYMENT DATA
$bookingPaymentCreateParam = [
'booking_id' => $bookingCreate['data']['id'],
'payment_code' => (isset($param['cc_token']) && !empty($param['cc_token'])) ? fillOnUndefined($param, 'cc_token') : null,
'payment_type_code' => 'CHN',
'total' => $param['paymenttotal'],
'currency_code' => $param['paymentcurr'],
'status' => 2
];
$bookingPaymentCreate = $this->bookingPaymentService->create($bookingPaymentCreateParam);
//$bookingContactCreate['status'] = 'success';
if ($bookingPaymentCreate['status'] != 'success') {
throw new ApiErrorException(lang('Booking Payment could not be made'));
}
//INSERT PAYMENT DATA
//INSERT CHANNEL PAYMENT DATA
if (isset($param['cc_token']) && !empty($param['cc_token'])) {
$bookingPaymentDataCreateParam = [
'booking_id' => $bookingCreate['data']['id'],
'type' => 'ch',
'data' => md5($param['reservno'].$param['channelManagerPropertyId'].$param['cc_token'])
];
$bookingPaymentDataCreate = $this->bookingPaymentService->createPaymentData($bookingPaymentDataCreateParam);
if ($bookingPaymentDataCreate['status'] != 'success') {
throw new ApiErrorException(lang('Booking Payment could not be made'));
}
}
//INSERT CHANNEL PAYMENT DATA
//$param['reservno'] = '27145472222';
$reservationConfirmParam = $this->reservationConfirmParam($param['channelManagerPropertyId'], $param['reservno'], $bookingCode);
$reservationConfirm = $this->channelService->reservationConfirm($reservationConfirmParam);
if (!$reservationConfirm['status']) {
throw new ApiErrorException($reservationConfirm['message']);
}
DB::commit();
$mailParams = ['booking_id' => $bookingCreate['data']['id']];
$this->newBookingMailService->process($mailParams);
$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();
}
if (!$response['status']) {
DB::rollBack();
}
return $response;
}
public function cancelBooking($param)
{
$response = ['status' => false, 'message' => ''];
DB::beginTransaction();
try {
$bookingCode = null;
$bookingDetailParam = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => $param['property']['id']],
['field' => 'search_key', 'condition' => '=', 'value' => $param['reservno']]
],
'with' => ['bookingRoom'],
'firstRow' => true
];
$bookingDetail = $this->bookingService->select($bookingDetailParam);
if ($bookingDetail['status'] != 'success') {
throw new ApiErrorException(lang('Booking could not be found, Reservation: ' . $param['reservno']));
}
if (!empty($bookingDetail['data'])) {
$bookingCode = $bookingDetail['data']['booking_code'];
$this->bookingService->update($bookingDetail['data']['id'], ['status' => 0]);
foreach ($bookingDetail['data']['booking_room'] as $roomOrder => $room) {
$bookingRoomCreate = $this->bookingRoomService->update($room['id'], ['status' => 0]);
/* ROOM AVAILABILITY */
$dateByDay = [];
$dateByDay = $this->getDateByDay(['checkIn' => $room['checkin_date'], 'checkOut' => $room['checkout_date']]);
foreach ($dateByDay as $day) {
$requestParam = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => $param['property']['id']],
['field' => 'property_room_id', 'condition' => '=', 'value' => $room['room_id']],
['field' => 'availability_type_id', 'condition' => '=', 'value' => 1],
['field' => 'date', 'condition' => '=', 'value' => $day]
],
];
$getPropertyRoomAndRoomRateAvailability = $this->propertyRoomAvailabilityService->select($requestParam);
if ($getPropertyRoomAndRoomRateAvailability['status'] != 'success') {
throw new ApiErrorException('getPropertyRoomAndRoomRateAvailability Empty');
}
foreach ($getPropertyRoomAndRoomRateAvailability['data'] as $roomAvailability) {
$roomAvailabilityUpdated = $roomAvailability['availability'] <= 0 ? 1 : ($roomAvailability['availability'] + 1);
$this->propertyRoomAvailabilityService->update($roomAvailability['id'], ['availability' => $roomAvailabilityUpdated]);
}
}
/* ROOM AVAILABILITY */
}
}
$response['status'] = true;
$bookingCode = is_null($bookingCode) ? 'ENW' . $param['reservno'] : $bookingCode;
$reservationConfirmParam = $this->reservationConfirmParam($param['channelManagerPropertyId'], $param['reservno'], $bookingCode);
$reservationConfirm = $this->channelService->reservationConfirm($reservationConfirmParam);
if (!$reservationConfirm['status']) {
throw new ApiErrorException($reservationConfirm['message']);
}
$notificationCancelToPropertyUser = [
'channel' => $param['otaname'],
'channelBookingCode' => $param['reservno_ota'],
'propertyChannelManager' => $param['otaname'],//$channelManagerMapping['property_channel_manager']['name'],
'nameSurname' => $param['firstname'] . ' ' . $param['lastname'],
'propertyId' => $param['property']['id'],
];
$this->mailer->onQueue('cancelBookingMail', new CancelBookingMail($notificationCancelToPropertyUser));
} 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']) {
DB::commit();
} else {
DB::rollBack();
}
return $response;
}
public function modifiedBooking($param)
{
$response = ['status' => false, 'message' => ''];
DB::beginTransaction();
try {
$bookingCode = null;
$bookingDetailParam = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => $param['property']['id']],
['field' => 'search_key', 'condition' => '=', 'value' => $param['reservno']]
],
'with' => ['bookingRoom', 'bookingContact'],
'firstRow' => true
];
$bookingDetail = $this->bookingService->select($bookingDetailParam);
if ($bookingDetail['status'] != 'success') {
throw new ApiErrorException(lang('Booking could not be found, Reservation: ' . $param['reservno']));
}
if (!empty($bookingDetail['data'])) {
$bookingCode = $bookingDetail['data']['booking_code'];
$bookingUpdateParam = [
'channel_booking_code' => fillOnUndefined($param, 'reservno_ota'),
'search_key' => $param['reservno'],
'checkin_date' => $param['checkinFormatted'],
'checkout_date' => $param['checkoutFormatted'],
'payment_type_code' => 'CHN',
'total' => $param['paymenttotal'],
'currency_code' => $param['paymentcurr'],
];
$bookingUpdate = $this->bookingService->update($bookingDetail['data']['id'], $bookingUpdateParam);
$bookingContactUpdateParam = [
'name' => $param['firstname'],
'surname' => $param['lastname'],
'phone_code' => null,
'phone_number' => $param['tel'],
'email' => $param['email'],
'note' => !empty($param['note']) ? $param['note'] : null,
'language_code' => fillOnUndefined($param, 'language', 'en')
];
$bookingContactUpdate = $this->bookingContactService->update($bookingDetail['data']['booking_contact']['id'], $bookingContactUpdateParam);
foreach ($bookingDetail['data']['booking_room'] as $roomOrder => $room) {
foreach ($param['room'] as $roomOrderChannel => $roomChannel) {
if ($roomOrder == $roomOrderChannel) {
$bookingRoomUpdateParam = [
'occupancy_code' => str_repeat('A', $roomChannel['totalpax']) . str_repeat('C', $roomChannel['totalchd']),
'checkin_date' => $roomChannel['checkin'],
'checkout_date' => $roomChannel['checkout'],
'room_id' => $roomChannel['property']['room_id'],
'room_name' => $roomChannel['roomtype'],
'room_rate_mapping_id' => $roomChannel['property']['room_rate_mapping_id'],
'room_rate_name' => $roomChannel['ratename'],
'rate_detail' => json_encode($roomChannel),
'total' => $roomChannel['total_amount'],
'currency_code' => $param['paymentcurr'],
];
$bookingRoomUpdate = $this->bookingRoomService->update($room['id'], $bookingRoomUpdateParam);
}
}
}
}
$response['status'] = true;
$bookingCode = is_null($bookingCode) ? 'ENW' . $param['reservno'] : $bookingCode;
$reservationConfirmParam = $this->reservationConfirmParam($param['channelManagerPropertyId'], $param['reservno'], $bookingCode);
$reservationConfirm = $this->channelService->reservationConfirm($reservationConfirmParam);
if (!$reservationConfirm['status']) {
throw new ApiErrorException($reservationConfirm['message']);
}
$notificationModifiedToPropertyUser = [
'channel' => $param['otaname'],
'channelBookingCode' => $param['reservno_ota'],
'propertyChannelManager' => $param['otaname'],//$channelManagerMapping['property_channel_manager']['name'],
'nameSurname' => $param['firstname'] . ' ' . $param['lastname'],
'propertyId' => $param['property']['id'],
];
$this->mailer->onQueue('modifiedBookingMail', new ModifiedBookingMail($notificationModifiedToPropertyUser));
} 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']) {
DB::commit();
} else {
DB::rollBack();
}
return $response;
}
public function handle()
{
//$request = $this->channelService->productList(14480);
try {
/*
1. Reseliva mapping olan oteller çekilecek
2. Her otel için foreach ile reservaion servisi çağrılacak
3. Gelen bilgiler enw ye işlenecek, sonra da confirmcheck yapılacak
* */
$this->info(date('Y-m-d H:i:s') . ' : Start');
$channelManagerMappingCriteria =
[
'criteria' =>
[
['field' => 'status', 'condition' => '=', 'value' => 1],
],
'with' => ['propertyChannelManager'],
'orderBy' => [
['field' => 'id', 'value' => 'ASC']
]
];
$channelManagerMappingData = $this->channelManagerMappingService->select($channelManagerMappingCriteria);
$channelManagerMappingCollect = collect($channelManagerMappingData['data']);
$channelManagerPropertyMappingCriteria = [
'criteria' =>
[
['field' => 'status', 'condition' => '=', 'value' => 1],
['field' => 'channel_manager_id', 'condition' => '=', 'value' => 1],
['field' => 'channel_manager_property_id', 'condition' => '!=', 'value' => null],
//['field' => 'property_id', 'condition' => '=', 'value' => 326],//TODO: Delete
],
'with' => ['channelManagerRoomRate.propertyRoomRateMapping'],
'orderBy' => [
['field' => 'id', 'value' => 'ASC']
]
];
$channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria);
if ($channelManagerPropertyMapping['status'] == 'success') {
foreach ($channelManagerPropertyMapping['data'] as $propertyMapping) {
$channelManagerRoomRateCollect = collect($propertyMapping['channel_manager_room_rate']);
$reservationListParam = $this->reservationListParam($propertyMapping['channel_manager_property_id']);
$reservationList = $this->channelService->reservationList($reservationListParam);
if (!$reservationList['status']) {
//$logMessage
$mailParams = [
'title' => 'ReservationPullService Error - ReservationList Error',
'logMessage' => '<pre>' . $reservationListParam . '</pre>'
];
$this->mailer->onQueue('logMail', new LogMail($mailParams));
//$logMessage
throw new ApiErrorException('ReservationList Error: ' . $reservationList['message']);
}
foreach ($reservationList['data'] as $reservationKey => $reservation) {
//Check Channel Manager Mapping
$channelManagerMapping = $channelManagerMappingCollect->where('channel_manager_channel_id', $reservation['otaname'])->first();
//Eğer ExtranetWork ise içeri almadan onayla
if ($reservation['otaname'] == 'ExtranetWork') {
$reservationConfirmParam = $this->reservationConfirmParam($propertyMapping['channel_manager_property_id'], $reservation['reservno'], 'ENWRES' . $reservation['reservno']);
//$reservationConfirm = $this->channelService->reservationConfirm($reservationConfirmParam);
$reservationConfirm['status'] = true;
if (!$reservationConfirm['status']) {
throw new ApiErrorException($reservationConfirm['message']);
}
continue;
}
if (empty($channelManagerMapping)) {
//Eğer mapping yapılmış kanal bulunamamış ise rezervasyonu içeri alamazsın
//$logMessage
$mailParams = [
'title' => 'ReservationPullService Error - Channel Manager Mapping',
'logMessage' => '<pre>' . print_r(array_merge($propertyMapping, $reservation), true) . '</pre>'
];
$this->mailer->onQueue('logMail', new LogMail($mailParams));
//$logMessage
unset($reservationList['data'][$reservationKey]);
continue;
}
$reservationList['data'][$reservationKey]['property']['id'] = $propertyMapping['property_id'];
$reservationList['data'][$reservationKey]['property']['channel_id'] = $channelManagerMapping['property_channel_id'];
foreach ($reservation['room'] as $roomKey => $room) {
//Check Room Rate Mapping
$channelManagerRoomRate = $channelManagerRoomRateCollect->where('channel_manager_room_id', $room['roomid'])->where('channel_manager_room_rate_id', $room['rateid'])->first();
if (empty($channelManagerRoomRate)) {
$channelManagerRoomRate = $channelManagerRoomRateCollect->where('channel_manager_room_id', $room['roomid'])->first();
}
$reservationList['data'][$reservationKey]['room'][$roomKey]['property']['room_id'] = null;
$reservationList['data'][$reservationKey]['room'][$roomKey]['property']['room_rate_id'] = null;
$reservationList['data'][$reservationKey]['room'][$roomKey]['property']['room_rate_mapping_id'] = null;
$reservationList['data'][$reservationKey]['channelManagerPropertyId'] = $propertyMapping['channel_manager_property_id'];
if (empty($channelManagerRoomRate)) {
//Eğer mapping yapılmış oda bulunamamış ise rezervasyonu içeri alamazsın
//$logMessage
$mailParams = [
'title' => 'ReservationPullService Error - Channel Manager Room Rate Mapping',
'logMessage' => '<pre>' . print_r(array_merge($propertyMapping, $reservation), true) . '</pre>'
];
$this->mailer->onQueue('logMail', new LogMail($mailParams));
//$logMessage
unset($reservationList['data'][$reservationKey]);
$this->error(date('Y-m-d H:i:s') . ' : Error: RoomRate Mapping Reservation: ' . $reservation['reservno']);
//Eşleşmeyen ve iptal edilen işlemin otele bildirilmesi.
if ($reservation['status'] == 'C') {
$notificationCancelToPropertyUser = [
'channel' => $reservation['otaname'],
'channelBookingCode' => $reservation['reservno_ota'],
'propertyChannelManager' => $channelManagerMapping['property_channel_manager']['name'],
'nameSurname' => $reservation['firstname'] . ' ' . $reservation['lastname'],
'propertyId' => $propertyMapping['property_id'],
];
$this->mailer->onQueue('cancelBookingMail', new CancelBookingMail($notificationCancelToPropertyUser));
$reservationConfirmParam = $this->reservationConfirmParam($propertyMapping['channel_manager_property_id'], $reservation['reservno'], 'ENWRES' . $reservation['reservno']);
$reservationConfirm = $this->channelService->reservationConfirm($reservationConfirmParam);
if (!$reservationConfirm['status']) {
throw new ApiErrorException($reservationConfirm['message']);
}
}
} else {
$reservationList['data'][$reservationKey]['room'][$roomKey]['property']['room_id'] = $channelManagerRoomRate['property_room_rate_mapping']['room_id'];
$reservationList['data'][$reservationKey]['room'][$roomKey]['property']['room_rate_id'] = $channelManagerRoomRate['property_room_rate_mapping']['room_rate_id'];
$reservationList['data'][$reservationKey]['room'][$roomKey]['property']['room_rate_mapping_id'] = $channelManagerRoomRate['property_room_rate_mapping']['id'];
}
}
}
foreach ($reservationList['data'] as $reservationKey => $reservation) {
//Eğer ExtranetWork ise içeri almadan onayla
if ($reservation['otaname'] == 'ExtranetWork') {
$reservationConfirmParam = $this->reservationConfirmParam($propertyMapping['channel_manager_property_id'], $reservation['reservno'], 'ENWRES' . $reservation['reservno']);
$reservationConfirm = $this->channelService->reservationConfirm($reservationConfirmParam);
if (!$reservationConfirm['status']) {
throw new ApiErrorException($reservationConfirm['message']);
}
continue;
}
$booking = ['status' => false, 'message' => ''];
if ($reservation['status'] == 'A') {
$booking = $this->createBooking($reservation);
} elseif ($reservation['status'] == 'C') {
$booking = $this->cancelBooking($reservation);
} elseif ($reservation['status'] == 'M') {
$booking = $this->modifiedBooking($reservation);
}
//M Modified kayıt bul güncelle ve sonra mail atılacak cancel ile aynı mail yapısı kullanılacak
if ($booking['status']) {
$this->info(date('Y-m-d H:i:s') . ' : Success: ' . $reservation['reservno']);
} else {
//$logMessage
$mailParams = [
'title' => 'ReservationPullService Error - Booking',
'logMessage' => '<pre>' . print_r(array_merge($booking, $reservation), true) . '</pre>'
];
$this->mailer->onQueue('logMail', new LogMail($mailParams));
//$logMessage
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $booking['message']);
}
}
}
}
$this->info(date('Y-m-d H:i:s') . ' : Finished');
} catch (ApiErrorException $e) {
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage());
} catch
(Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message);
}
}
}

View File

@@ -0,0 +1,281 @@
<?php
namespace App\Console\Commands\ChannelManager;
use App\Core\Mail\LogMail;
use App\Core\Service\ChannelManager\Reseliva;
use App\Core\Service\ChannelManagerBookingService;
use App\Exceptions\ApiErrorException;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Log;
class ReservationPushService extends Command
{
protected $signature = 'cron:reservation-push-service';
protected $description = '';
protected $channelService;
protected $channelManagerBookingService;
protected $typeMapping;
public function __construct(
Mailer $mailer,
Reseliva $channelService,
ChannelManagerBookingService $channelManagerBookingService
)
{
parent::__construct();
$this->mailer = $mailer;
$this->channelService = $channelService;
$this->channelManagerBookingService = $channelManagerBookingService;
$this->typeMapping = [
'Booking' => 'Book',
'Modify' => 'Modify',
'Cancel' => 'Cancel'
];
}
public function handle()
{
try {
$this->info(date('Y-m-d H:i:s') . ' : Start');
$pendingBookingCriteria = [
'criteria' =>
[
['field' => 'channel_manager_id', 'condition' => '=', 'value' => 1],
['field' => 'is_pushed', 'condition' => '=', 'value' => null],
['field' => 'status', 'condition' => '=', 'value' => 1],
],
'with' => ['bookingDetail.bookingContact', 'bookingDetail.bookingChannel', 'bookingDetail.bookingPayment', 'bookingDetail.bookingPaymentType', 'bookingDetail.bookingStatus', 'bookingDetail.bookingRoom.roomPax.paxCountry'],
'orderBy' => [
['field' => 'id', 'value' => 'ASC']
],
'take' => 100
];
$pendingBooking = $this->channelManagerBookingService->select($pendingBookingCriteria);
if ($pendingBooking['status'] == 'success') {
$pendingBooking = $pendingBooking['data'];
foreach ($pendingBooking as $booking) {
$bookingDetail = $booking['booking_detail'];
$type = $this->typeMapping[$booking['type']];
$serviceRequestName = 'BookingRetrieval';
$xmlResponse = new \SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><' . $serviceRequestName . 'RS></' . $serviceRequestName . 'RS>');
if (in_array($bookingDetail['status'], [0, 3])) {
$Bookings = $xmlResponse->addChild('Bookings');
$Booking = $Bookings->addChild('Booking');
if(Carbon::createFromTimestamp($booking['booking_detail']['created_at'])->lessThan(Carbon::parse('2022-04-01'))) {
$Booking->addAttribute('id', $bookingDetail['id']);
} else {
$Booking->addAttribute('id', $bookingDetail['booking_code']);
}
$Booking->addAttribute('type', 'Cancel');
$Booking->addAttribute('cancelDateTime', Carbon::createFromTimestamp($bookingDetail['updated_at'])->toISOString());
$Hotel = $Booking->addChild('Hotel');
$Hotel->addAttribute('id', $bookingDetail['property_id']);
foreach ($bookingDetail['booking_room'] as $room) {
$RoomStay = $Booking->addChild('RoomStay');
$RoomStay->addAttribute('roomTypeID', $room['room_id']);
$RoomStay->addAttribute('ratePlanID', $room['room_rate_mapping_id']);
$StayDate = $RoomStay->addChild('StayDate');
$StayDate->addAttribute('arrival', $room['checkin_date']);
$StayDate->addAttribute('departure', $room['checkout_date']);
}
} else {
$Bookings = $xmlResponse->addChild('Bookings');
$Booking = $Bookings->addChild('Booking');
if(Carbon::createFromTimestamp($booking['booking_detail']['created_at'])->lessThan(Carbon::parse('2022-04-01'))) {
$Booking->addAttribute('id', $bookingDetail['id']);
} else {
$Booking->addAttribute('id', $bookingDetail['booking_code']);
}
//Book ve Modify Aynı olacak, Cancel
if ($type == 'Book') {
$Booking->addAttribute('type', 'Book');
$Booking->addAttribute('createDateTime', Carbon::createFromTimestamp($bookingDetail['created_at'])->toISOString());
}
if ($type == 'Modify') {
$Booking->addAttribute('type', 'Modify');
$Booking->addAttribute('modifyDateTime', Carbon::createFromTimestamp($bookingDetail['updated_at'])->toISOString());
}
$Hotel = $Booking->addChild('Hotel');
$Hotel->addAttribute('id', $bookingDetail['property_id']);
foreach ($bookingDetail['booking_room'] as $room) {
$RoomStay = $Booking->addChild('RoomStay');
$RoomStay->addAttribute('roomTypeID', $room['room_id']);
$RoomStay->addAttribute('ratePlanID', $room['room_rate_mapping_id']);
$StayDate = $RoomStay->addChild('StayDate');
$StayDate->addAttribute('arrival', $room['checkin_date']);
$StayDate->addAttribute('departure', $room['checkout_date']);
$roomPaxCollect = collect($room['room_pax']);
$GuestCount = $RoomStay->addChild('GuestCount');
$GuestCount->addAttribute('adult', $roomPaxCollect->where('type', 'ADT')->count());
$diffInDays = Carbon::parse($room['checkin_date'])->diffInDays(Carbon::parse($room['checkout_date']));
//dd($room['total'], $diffInDays, $room);
$PerDayRates = $RoomStay->addChild('PerDayRates');
$PerDayRates->addAttribute('currency', $room['currency_code']);
$baseRateDaily = moneyDoubleFormatDecimal($room['total'] / $diffInDays);
$currentDate = $room['checkin_date'];
for ($i = 0; $i < $diffInDays; $i++) {
$PerDayRate = $PerDayRates->addChild('PerDayRate');
$PerDayRate->addAttribute('stayDate', $currentDate);
$PerDayRate->addAttribute('baseRate', $baseRateDaily);
$PerDayRate->addAttribute('hotelServiceFees', 0);
$currentDate = Carbon::parse($currentDate)->addDay()->toDateString();
}
$Total = $RoomStay->addChild('Total');
$Total->addAttribute('amountAfterTaxes', $room['total']);
$Total->addAttribute('amountOfTaxes', 0);
$Total->addAttribute('currency', $room['currency_code']);
$roomNotes['cancellationPolicy'] = 'Cancellation Policy: Refundable';
$cancellationPolicy = json_decode($room['cancellation_policy'],1);
if(!empty($cancellationPolicy) && is_array($cancellationPolicy)) {
if(isset($cancellationPolicy['isNonRefundable']) && $cancellationPolicy['isNonRefundable']) {
$roomNotes['cancellationPolicy'] = 'Cancellation Policy: NonRefundable';
}
}
$roomNotes['payment'] = 'Payment: '.$bookingDetail['booking_payment_type']['name'];
$RoomStay->addChild('RoomNotes', implode('. ',$roomNotes));
}
$PrimaryGuest = $Booking->addChild('PrimaryGuest');
$Name = $PrimaryGuest->addChild('Name');
$Name->addAttribute('givenName', $bookingDetail['booking_contact']['name']);
$Name->addAttribute('surname', $bookingDetail['booking_contact']['surname']);
$Phone = $PrimaryGuest->addChild('Phone');
$Phone->addAttribute('countryCode', $bookingDetail['booking_contact']['phone_code']);
//$Phone->addAttribute('cityAreaCode');
$Phone->addAttribute('number', $bookingDetail['booking_contact']['phone_number']);
$PrimaryGuest->addChild('Email', $bookingDetail['booking_contact']['email']);
$Total = $Booking->addChild('Total');
$Total->addAttribute('amountAfterTaxes', $bookingDetail['total']);
$Total->addAttribute('amountOfTaxes', 0);
$Total->addAttribute('currency', $bookingDetail['currency_code']);
$Booking->addChild('SpecialRequest');
$Booking->addChild('BookingNotes', $bookingDetail['booking_contact']['note']);
}
$this->info(date('Y-m-d H:i:s') . ' : Booking Id: '. $booking['booking_id']. ' Push');
$xmlPayload = $xmlResponse->asXML();
$this->channelManagerBookingService->update($booking['id'], ['request' => $xmlPayload]);
$requestPostReservationPush = $this->channelService->requestPostReservationPush($xmlPayload);
$this->channelManagerBookingService->update($booking['id'], ['response' => $requestPostReservationPush['data']['xmlBase']]);
if ($requestPostReservationPush['status']) {
if($requestPostReservationPush['data']['Status'] == 'success') {
$this->info(date('Y-m-d H:i:s') . ' : Booking Id: '. $booking['booking_id']. ' Success');
$this->channelManagerBookingService->update($booking['id'], ['is_pushed' => 1]);
} else {
//$logMessage
$mailParams = [
'title' => 'ReservationPushService Error - requestPostReservationPush Error',
'logMessage' => '<pre>' . print_r(array_merge($booking, $requestPostReservationPush), true) . '</pre>'
];
$this->mailer->onQueue('logMail', new LogMail($mailParams));
//$logMessage
}
} else {
//$logMessage
$mailParams = [
'title' => 'ReservationPushService Error - requestPostReservationPush Error',
'logMessage' => '<pre>' . print_r(array_merge($booking, $requestPostReservationPush), true) . '</pre>'
];
$this->mailer->onQueue('logMail', new LogMail($mailParams));
//$logMessage
$this->info(date('Y-m-d H:i:s') . ' : Booking Id: '. $booking['booking_id']. ' Failed');
}
}
}
$this->info(date('Y-m-d H:i:s') . ' : Finished');
} catch (ApiErrorException $e) {
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage());
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message);
}
}
}

Binary file not shown.

View File

@@ -0,0 +1,188 @@
<?php
namespace App\Console\Commands\CurrencyRates;
use App\Core\Repository\CurrencyRates\CurrencyRatesRepository;
use App\Core\Service\CurrencyService;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
class CurrencyRatesService extends Command
{
protected $signature = 'cron:currency-rates';
protected $description = '';
protected $serviceUrl;
private $currencyRatesRepository;
private $currencyService;
public function __construct(
CurrencyRatesRepository $currencyRatesRepository,
CurrencyService $currencyService
)
{
parent::__construct();
$this->currencyRatesRepository = $currencyRatesRepository;
$this->serviceUrl = 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml';
$this->currencyService = $currencyService;
}
public function handle()
{
$currencyList = $this->currencyService->getCurrencyList();
if (!$currencyList['status']) {
$this->error(date('Y-m-d H:i:s') . ' : CurrencyList alınamadı.');
}
$availableCurrencies = [];
foreach ($currencyList['data'] as $currency) {
$availableCurrencies[] = $currency['code'];
}
$availableCurrency = $availableCurrencies;
$this->restClient = new Client(['allow_redirects' => false]);
$request = $this->restClient->GET($this->serviceUrl);
$requestResponse = $request->getBody();
$currencyRatesData = json_decode(json_encode(simplexml_load_string($requestResponse)), 1);
if (empty($currencyRatesData)) {
$this->error(date('Y-m-d H:i:s') . ' : CurrencyRatesData alınamadı.');
return false;
}
//Georgia GEL
$tbcBankApiUrl = 'https://nbg.gov.ge/gw/api/ct/monetarypolicy/currencies/en/json/';
$requestTbcBank = $this->restClient->GET($tbcBankApiUrl);
$requestResponseTbcBank = $requestTbcBank->getBody()->getContents();
$currencyRatesDataTbcBank = json_decode($requestResponseTbcBank, 1);
if (empty($currencyRatesDataTbcBank)) {
$this->error(date('Y-m-d H:i:s') . ' : GEL CurrencyRatesData alınamadı.');
}
$currencyRatesDataTbcBank = reset($currencyRatesDataTbcBank);
$currencyRatesDataTbcBank = collect($currencyRatesDataTbcBank['currencies'])->where('code','EUR')->first();
$currencyRatesData['Cube']['Cube']['Cube'][] = [
'@attributes' => [
'currency' => 'GEL',
'rate' => $currencyRatesDataTbcBank['rate']
]
];
//Georgia GEL
//Morocco MAD
$euroApiUrl = 'https://www.floatrates.com/daily/eur.xml';
$requestEuroApiUrl = $this->restClient->GET($euroApiUrl);
$responseEuroApi = $requestEuroApiUrl->getBody();
$currencyRatesDataEuroApi = json_decode(json_encode(simplexml_load_string($responseEuroApi)), 1);
if (empty($currencyRatesDataEuroApi)) {
$this->error(date('Y-m-d H:i:s') . ' : EUR CurrencyRatesData alınamadı.');
}
$currencyRatesDataEuroApiSelected = collect($currencyRatesDataEuroApi['item'])->where('targetCurrency','MAD')->first();
$currencyRatesData['Cube']['Cube']['Cube'][] = [
'@attributes' => [
'currency' => 'MAD',
'rate' => (float)number_format($currencyRatesDataEuroApiSelected['exchangeRate'],4)
]
];
//Morocco MAD
$currencyRatesDataEuroApiSelected = collect($currencyRatesDataEuroApi['item'])->where('targetCurrency','AZN')->first();
$currencyRatesData['Cube']['Cube']['Cube'][] = [
'@attributes' => [
'currency' => 'AZN',
'rate' => (float)number_format($currencyRatesDataEuroApiSelected['exchangeRate'],4)
]
];
//Azerbaijani AZN
$date = $currencyRatesData['Cube']['Cube']['@attributes']['time'];
$currencyRatesCriteria = [
'criteria' => [
['field' => 'date', 'condition' => '=', 'value' => $date],
],
'count' => true,
];
$currencyRateCount = $this->currencyRatesRepository->findByCriteria($currencyRatesCriteria);
if ($currencyRateCount > 0) {
$this->error(date('Y-m-d H:i:s') . ' : ' . $date . ' tarihi için döviz bilgisi güncel.');
return false;
}
$euroParity[] = [
'currency_code' => 'EUR',
'exc_currency_code' => 'EUR',
'rate' => 1
];
foreach ($currencyRatesData['Cube']['Cube']['Cube'] as $perEuroParity) {
if (in_array($perEuroParity['@attributes']['currency'], $availableCurrency)) {
$euroParity[] = [
'currency_code' => 'EUR',
'exc_currency_code' => $perEuroParity['@attributes']['currency'],
'rate' => floatval($perEuroParity['@attributes']['rate']),
];
}
}
$exchangeParity = [];
foreach ($euroParity as $perParity) {
foreach ($euroParity as $perParityExchange) {
$exchangeParity[$perParity['exc_currency_code'] . $perParityExchange['exc_currency_code']] = [
'currency_code' => $perParity['exc_currency_code'],
'exc_currency_code' => $perParityExchange['exc_currency_code'],
'rate' => $perParityExchange['rate'] / $perParity['rate']
];
$exchangeParity[$perParityExchange['exc_currency_code'] . $perParity['exc_currency_code']] = [
'currency_code' => $perParityExchange['exc_currency_code'],
'exc_currency_code' => $perParity['exc_currency_code'],
'rate' => $perParity['rate'] / $perParityExchange['rate']
];
}
}
ksort($exchangeParity);
foreach ($exchangeParity as $perExchangeParity) {
$data[] = [
'date' => $date,
'currency_code' => $perExchangeParity['currency_code'],
'exc_currency_code' => $perExchangeParity['exc_currency_code'],
'rate' => $perExchangeParity['rate'],
'created_at' => Carbon::now()->timestamp
];
}
$currencyRateUpdate = $this->currencyRatesRepository->insert($data);
if ($currencyRateUpdate['status'] == 'success') {
$this->info(date('Y-m-d H:i:s') . ' : ' . $date . ' tarihi için ' . count($exchangeParity) . ' adet döviz bilgisi güncellendi.');
}
}
}

View File

@@ -0,0 +1,149 @@
<?php
namespace App\Console\Commands\Data;
use App\Exceptions\ApiErrorException;
use App\Models\PropertyWeb;
use App\Models\PropertyWebWeather;
use App\Models\vwActiveProperty;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
class DashboardCacheService extends Command
{
protected $signature = 'cron:dashboard-cache';
protected $description = '';
public function __construct(
Client $restClient
)
{
parent::__construct();
$this->restClient = $restClient;
}
public function handle()
{
try {
$this->info(date('Y-m-d H:i:s') . ' : START');
$bookingService = App::make("App\Core\Service\BookingService");
$propertyWebController = App::make("App\Http\Controllers\V1\PropertyWebController");
$vwActiveProperty = vwActiveProperty::where('commission', '>', 1)->orderBy('id')->get()->toArray();
//$dashboardCountablePlaceCacheKey
$this->info(date('Y-m-d H:i:s') . ' : $dashboardCountablePlaceCacheKey');
foreach ($vwActiveProperty as $property) {
//$dashboardCountablePlaceCacheKey
$dashboardCountablePlaceCacheKey = md5('dashboardCountablePlace-' . $property['id']);
try {
$this->line(date('Y-m-d H:i:s') . ' : ' . $property['id'] . ' - ' . $property['name']);
$propertyWeb = PropertyWeb::where('property_id', $property['id'])->where('status', 1)->orderByDesc('id')->first();
$propertyWeb = $propertyWeb ? $propertyWeb->toArray() : null;
if (empty($propertyWeb)) {
throw new Exception('Empty Web ID');
}
$dashboardCountablePlaceParam = ['property_id' => $property['id']];
$dashboardCountablePlace = $propertyWebController->dashboardCountablePlace($dashboardCountablePlaceParam, $propertyWeb['id']);
if ($dashboardCountablePlace['status']) {
Cache::put($dashboardCountablePlaceCacheKey, $dashboardCountablePlace, 24 * 60 * 60);//1 Day
}
} catch (Exception $e) {
$this->error(date('Y-m-d H:i:s') . ' : ' . $e->getMessage());
}
}
//$getBookingDetailedListCacheKey
$this->info(date('Y-m-d H:i:s') . ' : GetBookingDetailedListCacheKey');
foreach ($vwActiveProperty as $property) {
$getBookingDetailedListCacheKey = md5('getBookingDetailedList-' . $property['id']);
try {
$this->line(date('Y-m-d H:i:s') . ' : ' . $property['id'] . ' - ' . $property['name']);
$getBookingDetailedListParam = ['property_id' => $property['id'], 'channel_id' => 1];
$getBookingDetailedList = $bookingService->getBookingDetailedList($getBookingDetailedListParam);
if ($getBookingDetailedList['status'] == 'success') {
$bookings = collect($getBookingDetailedList['data']);
$channelBookings = $bookings->where('channel_id', '=', 1);
$getBookingEngineBookings = $channelBookings->all();
$paxCountArray = $channelBookings->where('status', '=', 1)->map(function ($booking) {
$roomPaxCount = collect($booking['booking_room'])->map(function ($room) {
return collect($room['room_pax'])->count();
})->values()->first();
return [
'booking_id' => $booking['id'],
'room_pax_count' => $roomPaxCount,
];
})->values()->all();
$totalPaxCount = collect($paxCountArray)->sum('room_pax_count');
$allBookingCount = $channelBookings->count();
$preBookingCount = $channelBookings->where('status', '=', 2)->count();
$successBookingCount = $channelBookings->where('status', '=', 1)->count();
$conversionRate = $allBookingCount > 0 ? ($successBookingCount * 100) / $allBookingCount : 0;
$responseData['all_booking_count'] = $allBookingCount;
$responseData['success_booking_count'] = $successBookingCount;
$responseData['pre_booking_count'] = $preBookingCount;
$responseData['conversion_rate'] = number_format($conversionRate, 2);
$responseData['total_pax_count'] = $totalPaxCount;
Cache::put($getBookingDetailedListCacheKey, $responseData, 24 * 60 * 60);//1 Day
}
} catch (Exception $e) {
$this->error(date('Y-m-d H:i:s') . ' : ' . $e->getMessage());
}
//$getBookingDetailedListCacheKey
}
$this->info(date('Y-m-d H:i:s') . ' : FINISHED');
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message);
}
}
}

View File

@@ -0,0 +1,128 @@
<?php
namespace App\Console\Commands\Data;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Exception;
use Illuminate\Support\Facades\Log;
use Google\Cloud\Vision\V1\ImageAnnotatorClient;
class HotelBedsList extends Command
{
protected $signature = 'cron:hotelbeds-list';
protected $description = '';
public function __construct()
{
parent::__construct();
}
public function handle()
{
try {
$hotelList = [];
$this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' START');
$baseUrl = 'https://api.hotelbeds.com';
$apiKey = 'ddaa6y6zpf6sy8fne4n2zj7q';
$secret = 'wc87VEfTSD';
$countryCode = 'TR';
$language = 'TUR';
$destinationCode = 'AYT';
$fields = ['code', 'name', 'email', 'countryCode', 'destinationCode', 'city','phones'];
$chunk = 500;
$from = 1;
$to = $chunk;
$isContinue = true;
while ($isContinue) {
$xSignature = hash("sha256", $apiKey . $secret . time());
$urlGenerate = $baseUrl . '/hotel-content-api/1.0/hotels?fields=' . implode(',', $fields) . '&countryCode=' . $countryCode . '&language=' . $language . '&from=' . $from . '&to=' . $to.'&destinationCode='.$destinationCode;
$this->restClient = new Client(['allow_redirects' => false]);
$request = $this->restClient->GET($urlGenerate, [
'headers' => [
'content-type' => 'application/json',
'Api-key' => $apiKey,
'X-Signature' => $xSignature,
],
'body' => null,
]);
Log::debug($xSignature);
$requestResponse = $request->getBody();
$requestResponse = json_decode($requestResponse, 1);
$this->info(date('Y-m-d H:i:s') . ' : ' . $urlGenerate);
$from += $chunk;
$to = $from + $chunk - 1;
if (empty($requestResponse['hotels'])) {
$isContinue = false;
}
foreach ($requestResponse['hotels'] as $hotel) {
if(!isset($hotel['email'])) {
continue;
}
$email = mb_strtolower($hotel['email']);
$hotelList[$email] = [
'code' => $hotel['code'],
'content' => (string)uCase($hotel['name']['content']),
'countryCode' => $hotel['countryCode'],
'email' => $email
];
foreach ($hotel['phones'] as $phone) {
if(in_array($phone['phoneType'], ['PHONEHOTEL','PHONEMANAGEMENT'])) {
$hotelList[$email]['phone'] = $phone['phoneNumber'];
break;
}
}
}
}
// Open a file in write mode ('w')
$fileName = $countryCode.(!empty($destinationCode) ? '-'.$destinationCode : '');
$fp = fopen(resource_path().'/data/'.$fileName.'.csv', 'w');
// Loop through file pointer and a line
foreach ($hotelList as $hotel) {
fputcsv($fp, $hotel);
}
fclose($fp);
$this->info(date('Y-m-d H:i:s') . ' : Total: ' . count($hotelList).' / '. $requestResponse['total']);
$this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' FINISHED');
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message);
}
}
}

View File

@@ -0,0 +1,130 @@
<?php
namespace App\Console\Commands\Data;
use App\Models\PropertyWeb;
use App\Models\PropertyWebWeather;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Exception;
use Illuminate\Support\Facades\Log;
class WeatherService extends Command
{
protected $signature = 'cron:weather';
protected $description = '';
public function __construct(
Client $restClient
)
{
parent::__construct();
$this->restClient = $restClient;
}
public function handle()
{
try {
$date = date('Y-m-d');
$this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' START');
$baseUrl = 'https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline';
$apiKey = 'GQG8FVH2C7ZZYZXS6PECE2QFX';
$this->restClient = new Client(['http_errors' => false]);
$propertyWeb = PropertyWeb::where('status', 1)
->where('weather_active', 1)->with('property.propertyContact')
//->where('property_id',1231)//TODO:Del
->get()->toArray();
foreach ($propertyWeb as $property) {
$propertyWebWeatherId = null;
$propertyWebWeather = PropertyWebWeather::where('property_id', $property['property']['id'])->first();
if ($propertyWebWeather) {
$propertyWebWeatherId = $propertyWebWeather['id'];
}
$latitude = $property['property']['property_contact']['latitude'];
$longitude = $property['property']['property_contact']['longitude'];
if (!empty($latitude) && !empty($longitude)) {
$requestUrl = $baseUrl . '/' . $latitude . ',' . $longitude . '/' . $date . '?key=' . $apiKey . '&include=days&unitGroup=metric&elements=tempmax,tempmin,temp,conditions,icon';
$requestWeather = $this->restClient->request('GET', $requestUrl);
$getResponseBody = $requestWeather->getBody();
$getResponse = $getResponseBody ? json_decode($getResponseBody, 1) : [];
$propertyWebWeatherParam = [
'property_id' => $property['property']['id'],
'date' => $date,
'temp' => $getResponse['days'][0]['tempmax'],
'conditions' => $getResponse['days'][0]['conditions'],
'icon' => $getResponse['days'][0]['icon'],
'response' => json_encode($getResponse),
'created_by' => 1,
'updated_by' => 1,
];
if (empty($propertyWebWeatherId)) {
$locationUrl = 'https://geocode.maps.co/reverse?lat=' . $latitude . '&lon=' . $longitude . '&api_key=6683d9ee52e5d111344805khdf0451c';
$requestLocation = $this->restClient->request('GET', $locationUrl);
$getResponseBodyLocation = $requestLocation->getBody();
$getResponseLocation = $getResponseBodyLocation ? json_decode($getResponseBodyLocation, 1) : [];
if ($getResponseLocation) {
$location = null;
if(isset($getResponseLocation['address']['province'])) {
$location = $getResponseLocation['address']['province'];
}elseif(isset($getResponseLocation['address']['town'])) {
$location = $getResponseLocation['address']['town'];
}elseif(isset($getResponseLocation['address']['city'])) {
$location = $getResponseLocation['address']['city'];
}
$propertyWebWeatherParam['location'] = $location;
$propertyWebWeatherParam['address'] = json_encode($getResponseLocation);
}
PropertyWebWeather::create($propertyWebWeatherParam);
$this->info(date('Y-m-d H:i:s') . ' : ' . $propertyWebWeatherParam['property_id'] . ' - ' . $propertyWebWeatherParam['date'] . ' : ' . $propertyWebWeatherParam['conditions']. ' : ' . $propertyWebWeatherParam['temp']);
} else {
PropertyWebWeather::where('id', $propertyWebWeatherId)->update($propertyWebWeatherParam);
$this->line(date('Y-m-d H:i:s') . ' : ' . $propertyWebWeatherParam['property_id'] . ' - ' . $propertyWebWeatherParam['date'] . ' : ' . $propertyWebWeatherParam['conditions']. ' : ' . $propertyWebWeatherParam['temp']);
}
}
}
$this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' FINISHED');
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message);
}
}
}

View File

@@ -0,0 +1,140 @@
<?php
namespace App\Console\Commands\Google;
use App\Models\PropertyWeb;
use App\Models\PropertyWebComponentMapping;
use App\Models\PropertyWebReview;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Exception;
use Illuminate\Support\Facades\Log;
use Google\Cloud\Vision\V1\ImageAnnotatorClient;
class GoogleReview extends Command
{
protected $signature = 'cron:google-review {--property_id=}';
protected $description = '';
public function __construct(
Client $restClient
)
{
parent::__construct();
$this->restClient = $restClient;
}
public function handle()
{
try {
$this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' START');
$baseUrl = 'https://maps.googleapis.com/maps/api/place/details/json';
$apiKey = 'AIzaSyAPsKZ_XasAieKEhbmpOLUpArY2u2UcXuk';
$availableRating = [4,5];
$this->restClient = new Client(['http_errors' => false]);
if (!is_null($this->option('property_id'))) {
$propertyWebComponentMapping = PropertyWebComponentMapping::where('status', 1)->where('component_id', 3)->where('property_id', $this->option('property_id'))->get()->toArray();
} else {
$propertyWebComponentMapping = PropertyWebComponentMapping::where('status', 1)->where('component_id', 3)->get()->toArray();
}
foreach ($propertyWebComponentMapping as $propertyWebComponent) {
if (!isset($propertyWebComponent['parameterArray']['placeId'])) {
continue;
}
$googlePlaceId = trim($propertyWebComponent['parameterArray']['placeId']);
Log::debug('google-review: '.$googlePlaceId);
$params = [
'query' => [
'place_id' => $googlePlaceId,
'key' => $apiKey,
'fields' => 'name,rating,reviews',
'reviews_sort' => 'newest',
'reviews_no_translations' => true,
//'language' => 'tr'
]
];
$requestReview = $this->restClient->request('GET', $baseUrl, $params);
$getResponseBody = $requestReview->getBody();
$getResponse = $getResponseBody ? json_decode($getResponseBody, 1) : [];
$reviews = [];
if(isset($getResponse['result']['reviews'])) {
$reviews = collect($getResponse['result']['reviews'])->sortBy('time')->toArray();
}
foreach ($reviews as $review) {
if(!in_array(fillOnUndefined($review, 'rating'),$availableRating)) {
continue;
}
try {
$code = md5($propertyWebComponent['property_id'].'-'.$review['author_name'] . '-' . $review['time']);
$propertyWebReviewCheck = PropertyWebReview::where('code', $code)->first();
if ($propertyWebReviewCheck) {
$this->error(date('Y-m-d H:i:s') . ' : ' . $propertyWebComponent['property_id'] . ' - ' . $review['author_name'] . ' : ' . $review['rating']);
continue;
}
$propertyWebWeatherParam = [
'property_id' => $propertyWebComponent['property_id'],
'channel' => 'google',
'code' => $code,
'language_code' => fillOnUndefined($review, 'language') ? substr($review['language'],0,2) : null,
'author' => $review['author_name'],
'profile_photo' => fillOnUndefined($review, 'profile_photo_url'),
'rating' => fillOnUndefined($review, 'rating'),
'review' => fillOnUndefined($review, 'text'),
'time' => fillOnUndefined($review, 'time'),
'status' => 1,
'created_by' => 1,
'updated_by' => 1,
];
$propertyWebReviewCreate = PropertyWebReview::create($propertyWebWeatherParam);
$this->info(date('Y-m-d H:i:s') . ' : ' . $propertyWebComponent['property_id'] . ' - ' . $review['author_name'] . ' : ' . $review['rating']);
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message);
}
}
$this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' FINISHED');
}
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message);
}
}
}

View File

@@ -0,0 +1,107 @@
<?php
namespace App\Console\Commands\Google;
use App\Models\Property;
use App\Models\PropertyWeb;
use App\Models\PropertyWebComponentMapping;
use App\Models\PropertyWebReview;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Exception;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Log;
use Google\Cloud\Vision\V1\ImageAnnotatorClient;
class GoogleStaticMap extends Command
{
protected $signature = 'cron:google-static-map {--property_id=}';
protected $description = '';
public function __construct(
Client $restClient
)
{
parent::__construct();
$this->restClient = $restClient;
}
public function handle()
{
try {
$this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' START');
$baseUrl = 'https://maps.googleapis.com/maps/api/staticmap';
$apiKey = 'AIzaSyAPsKZ_XasAieKEhbmpOLUpArY2u2UcXuk';
$imageSizes = [];
$imageSizes[] = ['name' => 'square','size' => '250x250'];
$imageSizes[] = ['name' => 'rectangle','size' => '1000x200'];
$this->restClient = new Client(['http_errors' => false]);
if (!is_null($this->option('property_id'))) {
$propertyList = Property::where('status', 1)->where('id', $this->option('property_id'))->with('propertyContact')->get()->toArray();
} else {
$propertyList = Property::where('status', 1)->where('commission','>=', 1)->with('propertyContact')->get()->toArray();
}
foreach ($propertyList as $property) {
if (!isset($property['property_contact'])) {
continue;
}
$folderPath = Config::get('app.fileSystemDriver') . '/property-map/' . $property['id'];
if(!is_dir($folderPath)) {
mkdir($folderPath);
}
foreach ($imageSizes as $imageSize) {
$imageName = 'map-'.$property['id'].'-'.$imageSize['name'].'.png';
$imagePath = Config::get('app.fileSystemDriver') . '/property-map/' . $property['id'] . '/'.$imageName;
if(is_file($imagePath)) {
$this->line(date('Y-m-d H:i:s') . ' : ' . $imageName);
continue;
}
$params = [
'center' => $property['property_contact']['latitude'] . ',' . $property['property_contact']['longitude'],
'size' => $imageSize['size'], //300x300 1000x200
'zoom' => 18,
'format' => 'png',
'scale' => 2,
'markers' => 'color:red|' . $property['property_contact']['latitude'] . ',' . $property['property_contact']['longitude'],
'key' => $apiKey,
'language' => 'en'
];
$imageUrl = $baseUrl . '?' . http_build_query($params, '', '&');
$imageSave = file_put_contents($imagePath, file_get_contents($imageUrl));
$this->info(date('Y-m-d H:i:s') . ' : ' . $imageName);
}
}
$this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' FINISHED');
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message);
}
}
}

View File

@@ -0,0 +1,72 @@
<?php
namespace App\Console\Commands\Google;
use Illuminate\Console\Command;
use Exception;
use Illuminate\Support\Facades\Log;
use Google\Cloud\Vision\V1\ImageAnnotatorClient;
class GoogleVisioLabel extends Command
{
protected $signature = 'cron:google-visio-label';
protected $description = '';
public function __construct(
)
{
parent::__construct();
}
public function handle()
{
try {
$this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' START');
$googleVisionAuthentication = base_path().'/resources/data/google-vision-authentication.json';
putenv('GOOGLE_APPLICATION_CREDENTIALS='.$googleVisionAuthentication);
$imageAnnotator = new ImageAnnotatorClient();
$fileName = 'https://image.rezervasyon.com/hotel/301356/lavin-otel-10-9566879.jpg';
$fileName = 'https://image.rezervasyon.com/hotel/301356/lavin-otel-10-9566886.jpg';
$fileName = 'https://image.rezervasyon.com/hotel/301356/lavin-otel-10-9566881.jpg';
$fileName = 'https://image.rezervasyon.com/hotel/301356/lavin-otel-10-9566878.jpg';
$image = file_get_contents($fileName);
$response = $imageAnnotator->labelDetection($image);
$labels = $response->getLabelAnnotations();
$labelList = [];
if ($labels) {
foreach ($labels as $label) {
$labelList[] = [
'description' => $label->getDescription(),
'score' => $label->getScore(),
'topicality' => $label->getTopicality(),
];
}
} else {
echo('No label found' . PHP_EOL);
}
$imageAnnotator->close();
print_r($labelList);
$this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' FINISHED');
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message);
}
}
}

View File

@@ -0,0 +1,122 @@
<?php
namespace App\Console\Commands\Jobs;
use App\Core\Service\BookingService;
use App\Exceptions\ApiErrorException;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Exception;
class BookingCommissionService extends Command
{
protected $signature = 'cron:commission-service';
protected $description = '';
private $bookingService;
public function __construct(
BookingService $bookingService
)
{
parent::__construct();
$this->bookingService = $bookingService;
}
public function handle()
{
$this->info(date('Y-m-d H:i:s') . ' START');
try {
$bookingListParam = [
'criteria' => [
//['field' => 'id', 'condition' => '=', 'value' => 600],
//['field' => 'property_id', 'condition' => '=', 'value' => 313],
['field' => 'commission', 'condition' => '=', 'value' => null],
['field' => 'commission_rate', 'condition' => '=', 'value' => null]
],
'with' => ['bookingChannel.propertyChannelCategory', 'bookingProperty'],
"take" => 10000,
"orderBy" => [
["field" => "id", "value" => "ASC"]
],
];
$bookingList = $this->bookingService->select($bookingListParam);
if ($bookingList['status'] != 'success' || ($bookingList['status'] == 'success' && empty($bookingList['data']))) {
throw new ApiErrorException('Property list not found!');
}
foreach ($bookingList['data'] as $booking) {
$commission = null;
$commissionRate = null;
//$booking['booking_property']['commission'] = 15;//TOOD: DEL
switch ($booking['booking_channel']['channel_category_id']) {
case "3" :
if (fillOnUndefined($booking['booking_property'], 'commission') && $booking['booking_property']['commission'] > 0) {
$commissionRate = $booking['booking_property']['commission'];
$commission = moneyDoubleFormatDecimal($booking['booking_property']['commission'] * $booking['total'] / 100);
}
break;
case "2" :
if (fillOnUndefined($booking['booking_property'], 'commission_offline') && $booking['booking_property']['commission_offline'] > 0) {
$commissionRate = $booking['booking_property']['commission_offline'];
$commission = moneyDoubleFormatDecimal($booking['booking_property']['commission_offline'] * $booking['total'] / 100);
}
break;
case "4" :
if (fillOnUndefined($booking['booking_property'], 'commission_channel') && $booking['booking_property']['commission_channel'] > 0) {
$commissionRate = $booking['booking_property']['commission_channel'];
$commission = moneyDoubleFormatDecimal($booking['booking_property']['commission_channel'] * $booking['total'] / 100);
}
break;
case "7" :
if (fillOnUndefined($booking['booking_property'], 'commission_wholesaler') && $booking['booking_property']['commission_wholesaler'] > 0) {
$commissionRate = $booking['booking_property']['commission_wholesaler'];
$commission = moneyDoubleFormatDecimal($booking['booking_property']['commission_wholesaler'] * $booking['total'] / 100);
}
break;
}
if (!empty($commission) && !empty($commissionRate)) {
$this->bookingService->update($booking['id'], ['commission' => $commission, 'commission_rate' => $commissionRate]);
$this->info(date('Y-m-d H:i:s') . ' Property: ' . $booking['booking_property']['name'] . ' Code: ' . $booking['booking_code'] . ' Commission: ' . $commission . ' Commission Rate: ' . $commissionRate);
} else {
$this->bookingService->update($booking['id'], ['commission' => 0, 'commission_rate' => 0]);
$this->error(date('Y-m-d H:i:s') . ' Property: ' . $booking['booking_property']['name'] . ' Code: ' . $booking['booking_code'] . ' Commission: ' . $commission . ' Commission Rate: ' . $commissionRate);
}
//sleep(1);
}
} catch (ApiErrorException | Exception $e) {
$this->error(date('Y-m-d H:i:s') . ' ERROR:' . $e->getMessage());
}
$this->info(date('Y-m-d H:i:s') . ' FINISHED');
}
}

View File

@@ -0,0 +1,194 @@
<?php
namespace App\Console\Commands\Jobs;
use App\Core\Mail\BookingEngineSearchReportMail;
use App\Core\Service\PropertyService;
use App\Exceptions\ApiErrorException;
use App\Models\Country;
use App\Models\Language;
use App\Models\vwBookingEngineSearch;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class BookingEngineSearchReportService extends Command
{
protected $signature = 'cron:bookingengine-search-report-mail';
protected $description = '';
private $propertyService;
public function __construct(
Mailer $mailer,
PropertyService $propertyService
)
{
parent::__construct();
$this->mailer = $mailer;
$this->propertyService = $propertyService;
}
public function handle()
{
$this->info(date('Y-m-d H:i:s') . ' START');
$reportPropertyList = [506, 529, 1606];
//506 Green Nature Diamond Hotel
//529 Green Nature Resort & Spa Otel
//1606 Green Nature Sarıgerme
$propertyListCriteria = [
'criteria' =>
[
['field' => 'status', 'condition' => '=', 'value' => 1],
],
'with' => ['propertyBrand', 'propertyUser.user'],
'orderBy' => [
['field' => 'id', 'value' => 'ASC']
],
'whereIn' =>
[
['field' => 'id', 'value' => $reportPropertyList]
]
];
$propertyListData = $this->propertyService->select($propertyListCriteria);
$propertyList = [];
if ($propertyListData['status'] == 'success' && !empty($propertyListData['data'])) {
$propertyList = $propertyListData['data'];
}
$reportData = [];
$reportDate = Carbon::now()->subDay()->toDateString();
//$reportDate = '2023-02-28';
$reportDateFormatted = Carbon::parse($reportDate)->format('d.m.Y');
$countryList = Country::all()->toArray();
$languageList = Language::all()->toArray();
$this->info(date('Y-m-d H:i:s') . ' Date: ' . $reportDate);
foreach ($propertyList as $property) {
$reportData = [];
$reportData['propertyId'] = $property['id'];
$reportData['propertyName'] = $property['name'];
$reportData['propertyCountry'] = $property['country'];
$reportData['logo'] = $property['property_brand']['logoUrl'];
$reportData['date'] = $reportDateFormatted;
$reportData['propertyUserEmail'] = collect($property['property_user'])->where('user.email','<>', null)->pluck('user.email')->toArray();
$searchData = vwBookingEngineSearch::where('property_id', $property['id'])
->where('date', $reportDate)
->get()->toArray();
$this->info(date('Y-m-d H:i:s') . ' Property: ' . $reportData['propertyName']);
if (!empty($searchData)) {
$reportData['transaction']['search'] = collect($searchData)->count();
$reportData['transaction']['roomFound'] = collect($searchData)->where('status', 1)->count();
$reportData['transaction']['roomNotFound'] = collect($searchData)->where('status', 0)->count();
$reportData['transaction']['preBooking'] = collect($searchData)->where('status', 2)->count();
$reportData['transaction']['booking'] = collect($searchData)->where('status', 3)->count();
$countryCodes = collect($searchData)->groupBy('country_code')->keys()->toArray();
foreach ($countryCodes as $countryCode) {
$countryText = $countryCode;
$countryTextCheck = collect($countryList)->where('country_code', mb_strtoupper($countryCode))->first();
if (!empty($countryTextCheck)) {
$countryText = $countryTextCheck['name'];
}
$reportData['country'][$countryCode]['text'] = $countryText;
$reportData['country'][$countryCode]['search'] = collect($searchData)->where('country_code', $countryCode)->count();
$reportData['country'][$countryCode]['roomFound'] = collect($searchData)->where('country_code', $countryCode)->where('status', 1)->count();
$reportData['country'][$countryCode]['roomNotFound'] = collect($searchData)->where('country_code', $countryCode)->where('status', 0)->count();
$reportData['country'][$countryCode]['preBooking'] = collect($searchData)->where('country_code', $countryCode)->where('status', 2)->count();
$reportData['country'][$countryCode]['booking'] = collect($searchData)->where('country_code', $countryCode)->where('status', 3)->count();
}
$reportData['country'] = collect($reportData['country'])->sortByDesc('search')->toArray();
$languageCodes = collect($searchData)->groupBy('language_code')->keys()->toArray();
foreach ($languageCodes as $languageCode) {
$languageText = $languageCode;
$languageTextCheck = collect($languageList)->where('code', $languageCode)->first();
if (!empty($languageTextCheck)) {
$languageText = $languageTextCheck['name'];
}
$reportData['language'][$languageCode]['text'] = $languageText;
$reportData['language'][$languageCode]['search'] = collect($searchData)->where('language_code', $languageCode)->count();
$reportData['language'][$languageCode]['roomFound'] = collect($searchData)->where('language_code', $languageCode)->where('status', 1)->count();
$reportData['language'][$languageCode]['roomNotFound'] = collect($searchData)->where('language_code', $languageCode)->where('status', 0)->count();
$reportData['language'][$languageCode]['preBooking'] = collect($searchData)->where('language_code', $languageCode)->where('status', 2)->count();
$reportData['language'][$languageCode]['booking'] = collect($searchData)->where('language_code', $languageCode)->where('status', 3)->count();
}
$reportData['language'] = collect($reportData['language'])->sortByDesc('search')->toArray();
$occupancyCodes = collect($searchData)->groupBy('pax')->keys()->toArray();
foreach ($occupancyCodes as $occupancyCode) {
$reportData['occupancy'][$occupancyCode]['text'] = occupancyCodeFormatted($occupancyCode);
$reportData['occupancy'][$occupancyCode]['count'] = collect($searchData)->where('pax', $occupancyCode)->count();
}
$reportData['occupancy'] = collect($reportData['occupancy'])->sortByDesc('count')->toArray();
//Daily Intensity
$dailyIntensity = [];
foreach ($searchData as $data) {
$checkInDate = $data['checkin_date'];
$checkOutDate = $data['checkout_date'];
$dateDiff = Carbon::parse($data['checkout_date'])->diffInDays(Carbon::parse($data['checkin_date']));
for ($i = 0; $i < $dateDiff; $i++) {
$date = Carbon::parse($checkInDate)->addDays($i)->toDateString();
if (!isset($dailyIntensity[$date])) {
$dailyIntensity[$date]['text'] = Carbon::parse($date)->format('d.m.Y');
$dailyIntensity[$date]['search'] = 0;
$dailyIntensity[$date]['roomFound'] = 0;
$dailyIntensity[$date]['roomNotFound'] = 0;
$dailyIntensity[$date]['preBooking'] = 0;
$dailyIntensity[$date]['booking'] = 0;
}
$dailyIntensity[$date]['search']++;
$dailyIntensity[$date]['roomFound'] += $data['status'] == 1 ? 1 : 0;
$dailyIntensity[$date]['roomNotFound'] += $data['status'] == 0 ? 1 : 0;
$dailyIntensity[$date]['preBooking'] += $data['status'] == 2 ? 1 : 0;
$dailyIntensity[$date]['booking'] += $data['status'] == 3 ? 1 : 0;
}
}
ksort($dailyIntensity);
$reportData['dailyIntensity'] = $dailyIntensity;
//Daily Intensity
}
if (!empty($searchData)) {
$this->mailer->onQueue('bookingEngineSearchReportMail', new BookingEngineSearchReportMail($reportData));
$this->info(date('Y-m-d H:i:s') . ' Property: ' . $reportData['propertyName'] . ' - SENT MAIL');
}
}
$this->info(date('Y-m-d H:i:s') . ' FINISHED');
}
}

View File

@@ -0,0 +1,92 @@
<?php
namespace App\Console\Commands\Jobs;
use App\Models\Property;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Exception;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Artisan;
class DataFetch extends Command
{
protected $signature = 'cron:data-fetch';
public function __construct()
{
parent::__construct();
}
public function handle()
{
$propertyList = Property::whereIn('status', [1, 3])
->where('commission', '>', 1)
//->where('id', 1456)
->with('propertyContractUser')
->with('propertyExecutive.executiveType')
->with('propertyContact')
->with('propertyAdditionalInfos.propertyAdditionalInfoKey')
->with('propertyType')
->with('propertyStatus')
->get();
$propertyList = $propertyList ? $propertyList->toArray() : null;
$propertyListToExcel = [];
foreach ($propertyList as $property) {
$numberOfRooms = collect($property['property_additional_infos'])->where('additional_info_key_id',3)->first();
$numberOfRooms = $numberOfRooms['value'];
$propertyListToExcel[] = [
'contract_user' => $property['property_contract_user']['nameSurname'],
'executive_name_surname' => reset($property['property_executive'])['name_surname'],
'name' => $property['name'],
'phone' => $property['property_contact']['view_full_phone'],
'email' => $property['property_contact']['email'],
'executive_position' => reset($property['property_executive'])['executive_type']['name'],
'executive_phone' => reset($property['property_executive'])['view_full_phone'],
'executive_email' => reset($property['property_executive'])['email'],
'web' => $property['property_contact']['web'],
'address' => $property['property_contact']['address'],
'location' => null, //Bölge
'number_of_rooms' => $numberOfRooms,
'category' => $property['property_type']['name'],
'property_pms' => null,
'property_cm' => null,
'commission' => $property['commission'],
'commission_period' => $property['invoice_type'],
'contract_start' => Carbon::createFromTimestamp($property['created_at'])->format('d.m.Y'),
'contract_finish' => null,
'content' => null,
'dns' => null,
'ssl' => null,
'cm' => null,
'third_party' => null,
'golive' => Carbon::createFromTimestamp($property['created_at'])->format('d.m.Y'),
'training' => null,
'panel' => null,
'official_name' => $property['official_name'],
'tax_office' => $property['tax_office'],
'tax_number' => $property['tax_number'],
'tax_address' => $property['property_contact']['address'],
'status' => $property['property_status']['name'],
'id' => $property['id'],
];
}
$f = fopen("C:\www\api.extranetwork.com\storage/tmp.csv", "w");
foreach ($propertyListToExcel as $property) {
fputcsv($f, $property);
}
}
}

View File

@@ -0,0 +1,97 @@
<?php
namespace App\Console\Commands\Jobs;
use App\Core\Service\JobsService;
use Illuminate\Console\Command;
use Exception;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Artisan;
class MailJobs extends Command
{
/*
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'cron:mail-jobs';
/**
* The console command description.
*
* @var string
*/
protected $mailJobs =
[
"default",
"userCreateMail",
"UserForgotPassword",
"slackLog",
"newBookingMail",
"contactFormMail",
"manualPaymentMail",
"logMail",
"inventoryActionMail",
"bookingTicketMail",
"enwContactFormMail",
"trialFirstMail",
"trialSecondMail",
"cancelBookingMail",
"modifiedBookingMail",
"inventoryPdfLinkMail",
"dailyReportMail",
"bookingPaymentDataCode",
"bookingPropertyAddonUpdateMail",
"offerAcceptMail",
"offerPreConfirmCustomerMail",
"offerPreConfirmPropertyMail",
"bookingEngineSearchReportMail",
"channelManagerNotificationMail",
"bookingInvoiceUpdateMail",
"offerSendMail",
"dailyReportSalesMail",
"affiliateRequestMail",
"propertyProductOfferMail"
];
protected $description = 'Calls All Mail Jobs';
private $jobsService;
public function __construct(JobsService $jobsService)
{
parent::__construct();
$this->jobsService = $jobsService;
}
public function handle()
{
$mailJobsCriteria =
[
"whereIn" =>
[
["field" => "queue", "value" => $this->mailJobs]
],
"orderBy" =>
[
["field" => "id", "value" => "ASC"]
],
"take" => 20
];
$mailJobs = $this->jobsService->getJobsList($mailJobsCriteria, ["queue"]);
foreach ($mailJobs as $perJob) {
try {
Artisan::call("queue:work --queue=" . $perJob["queue"]." --tries=5");
} catch (Exception $e) {
$message = "Mail Job Fail --- Failed Mail : " . $perJob . " ErrorDetail : " . $e->getLine() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
continue;
}
sleep(1);
}
}
}

View File

@@ -0,0 +1,252 @@
<?php
namespace App\Console\Commands\Jobs;
use App\Exceptions\ApiErrorException;
use App\Models\ChannelManagerPropertyMapping;
use App\Models\CurrencyRates;
use App\Models\PropertyPriceComparison;
use App\Models\PropertyRoomRatePrice;
use App\Models\vwActiveProperty;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Exception;
class PriceComparisonService extends Command
{
protected $signature = 'cron:price-comparison-service';
protected $description = '';
private $bookingService;
public function __construct()
{
parent::__construct();
}
public function handle()
{
//$today = '2025-06-05';
$today = Carbon::now()->toDateString();
$today = Carbon::parse($today)->startOfWeek(Carbon::MONDAY);
$year = Carbon::parse($today)->format('Y');
$week = Carbon::parse($today)->isoWeek();
$daysCount = [1, 15, 45, 90];
$exchangeCurrency = 'EUR';
//'BookingEngine'
$comparisonChannels = ['Agoda.com', 'etstur.com', 'Booking.com'];
$exchangeRateUSD = CurrencyRates::where('currency_code', 'USD')->where('exc_currency_code', $exchangeCurrency)->orderBy('date', 'DESC')->first()->toArray();
$exchangeRateUSD = $exchangeRateUSD['rate'];
$competitorPriceAnalysisController = App::make('App\Http\Controllers\V1\CompetitorPriceAnalysisController');
$this->info(date('Y-m-d H:i:s') . ' START');
$queryWeekPrices = [];
$queryWeekPricesDaily = [];
$queryKeyHash = md5($year . '-' . $week);
$propertyList = vwActiveProperty::where('commission', '>', 1)
//->whereIn('id', [1433,1441,1551,1574])
->get()->toArray();
foreach ($propertyList as $property) {
try {
$channelManagerProperty = ChannelManagerPropertyMapping::where('channel_manager_id', 12)
->where('property_id', $property['id'])->first();
$channelManagerProperty = $channelManagerProperty ? $channelManagerProperty->toArray() : null;
$channelManagerPropertyId = $channelManagerProperty ? $channelManagerProperty['channel_manager_property_id'] : null;
$this->info(date('Y-m-d H:i:s') . ' ' . $property['id'] . ' - ' . $property['name']);
if (empty($channelManagerPropertyId)) {
$this->error(date('Y-m-d H:i:s') . ' ' . $property['name'] . ': channelManagerPropertyId!');
continue;
}
foreach ($daysCount as $day) {
//Booking Engine
$queryDate = Carbon::parse($today)->addDays($day)->toDateString();
//FIRST Trigger
$paramCompetitorPrice = ['date' => $queryDate, 'competitor_property_key' => $channelManagerPropertyId, 'currency' => $exchangeCurrency,];
$getPropertyCompetitorPrice = $competitorPriceAnalysisController->getPropertyCompetitorPrice($paramCompetitorPrice);
$this->info(date('Y-m-d H:i:s') . ' ' . $property['id'] . ' - ' . $queryDate);
sleep(1);
$bestPriceOfDay = 0;
$queryWeekPrices[$queryKeyHash][$property['id']]['BookingEngine'][$day] = [
'channel' => 'BookingEngine',
'date' => $queryDate,
'amount' => null,
'currency' => null
];
$propertyPrices = PropertyRoomRatePrice::where('property_id', $property['id'])
->where('channel_id', 5)
->where('stop_sell', 0)
->where('status', 1)
->where('amount', '<>', 0)
->where('amount', '<>', null)
->where('date', $queryDate)
->with('roomRateMapping.propertyRoomRate')
->get();
$propertyPrices = $propertyPrices ? $propertyPrices->toArray() : null;
if (empty($propertyPrices)) {
//continue;
}
$bestPrice = collect($propertyPrices)
->where('room_rate_mapping.property_room_rate.name', 'Best Available Rate')
->sortBy('amount')->first();
if (empty($bestPrice)) {
//continue;
} else {
if ($bestPrice['currency'] != $exchangeCurrency) {
$exchangeRate = CurrencyRates::where('currency_code', $bestPrice['currency'])
->where('exc_currency_code', $exchangeCurrency)
->orderBy('date', 'DESC')->first()->toArray();
$exchangeRate = $exchangeRate['rate'];
$bestPrice['amount'] = $bestPrice['amount'] * $exchangeRate;
}
$bestPrice['amount'] = moneyDoubleFormatDecimal($bestPrice['amount']);
$queryWeekPrices[$queryKeyHash][$property['id']]['BookingEngine'][$day] = [
'channel' => 'BookingEngine',
'date' => $queryDate,
'amount' => $bestPrice['amount'],
'currency' => $exchangeCurrency,
];
$queryWeekPricesDaily[$queryKeyHash][$property['id']][$day] = $bestPrice['amount'];
}
//Booking Engine
//OTHER Channels
$paramCompetitorPrice = ['date' => $queryDate, 'competitor_property_key' => $channelManagerPropertyId, 'currency' => $exchangeCurrency];
$getPropertyCompetitorPrice = $competitorPriceAnalysisController->getPropertyCompetitorPrice($paramCompetitorPrice);
foreach ($comparisonChannels as $comparisonChannel) {
$queryWeekPrices[$queryKeyHash][$property['id']][$comparisonChannel][$day] = [
'channel' => $comparisonChannel,
'date' => $queryDate,
'amount' => null,
'currency' => null
];
if(!isset($queryWeekPricesDaily[$queryKeyHash][$property['id']][$day])) {
$queryWeekPricesDaily[$queryKeyHash][$property['id']][$day] = $queryWeekPrices[$queryKeyHash][$property['id']][$comparisonChannel][$day]['amount'];
}
if ($getPropertyCompetitorPrice['status'] && !empty($getPropertyCompetitorPrice['data']['all'])) {
$getPropertyCompetitorPriceChannel = $getPropertyCompetitorPrice['data']['all'];
$getPropertyCompetitorPriceChannelCheck = collect($getPropertyCompetitorPriceChannel)->where('provider', $comparisonChannel)->first();
if ($getPropertyCompetitorPriceChannelCheck) {
$queryWeekPrices[$queryKeyHash][$property['id']][$comparisonChannel][$day]['amount'] = moneyDoubleFormatDecimal($getPropertyCompetitorPriceChannelCheck['amount'] * $exchangeRateUSD);
$queryWeekPrices[$queryKeyHash][$property['id']][$comparisonChannel][$day]['currency'] = 'EUR';
//BestPriceCheck
if(empty($queryWeekPricesDaily[$queryKeyHash][$property['id']][$day])) {
$queryWeekPricesDaily[$queryKeyHash][$property['id']][$day] = $queryWeekPrices[$queryKeyHash][$property['id']][$comparisonChannel][$day]['amount'];
}elseif ($queryWeekPrices[$queryKeyHash][$property['id']][$comparisonChannel][$day]['amount'] < $queryWeekPricesDaily[$queryKeyHash][$property['id']][$day]) {
$queryWeekPricesDaily[$queryKeyHash][$property['id']][$day] = $queryWeekPrices[$queryKeyHash][$property['id']][$comparisonChannel][$day]['amount'];
}
}
}
}
}
//dd($queryWeekPrices[$queryKeyHash][$property['id']],$queryWeekPricesDaily[$queryKeyHash][$property['id']]);
foreach ($queryWeekPrices[$queryKeyHash][$property['id']] as $channelKey => $channelDays) {
foreach ($channelDays as $channelDayKey => $channelDay) {
//dd($channelDay,$queryWeekPricesDaily[$queryKeyHash][$property['id']][$channelDayKey]);
if ($queryWeekPricesDaily[$queryKeyHash][$property['id']][$channelDayKey] == $channelDay['amount'] && !is_null($channelDay['amount'])) {
$queryWeekPrices[$queryKeyHash][$property['id']][$channelKey][$channelDayKey]['bestPrice'] = true;
} else {
$queryWeekPrices[$queryKeyHash][$property['id']][$channelKey][$channelDayKey]['bestPrice'] = false;
}
}
}
$this->info(date('Y-m-d H:i:s') . ' ' . $property['id'] . ' - ' . $property['name'] . ' OK!');
$propertyComparisonPrice = [
'property_id' => $property['id'],
'week_key' => $queryKeyHash,
'year' => $year,
'week' => $week,
'date' => $today,
'data' => json_encode($queryWeekPrices[$queryKeyHash][$property['id']]),
'status' => 1,
'created_at' => Carbon::now()->unix(),
'updated_at' => Carbon::now()->unix(),
];
$propertyPriceComparisonCheck = PropertyPriceComparison::where('week_key', $queryKeyHash)->where('property_id', $property['id'])->first();
if ($propertyPriceComparisonCheck) {
$propertyPriceComparisonCheck = $propertyPriceComparisonCheck->toArray();
$propertyPriceComparison = PropertyPriceComparison::where('id', $propertyPriceComparisonCheck['id'])->update($propertyComparisonPrice);
} else {
$propertyPriceComparison = PropertyPriceComparison::insert($propertyComparisonPrice);
}
unset($queryWeekPrices[$queryKeyHash]);
} catch (ApiErrorException|Exception $e) {
$this->error(date('Y-m-d H:i:s') . ' ERROR: L: ' . $e->getLine() . ' - ' . $e->getMessage());
}
}
$this->info(date('Y-m-d H:i:s') . ' FINISHED');
}
}

View File

@@ -0,0 +1,113 @@
<?php
namespace App\Console\Commands\Jobs;
use App\Core\Mail\PropertyCatalogMail;
use App\Core\Service\PropertyService;
use App\Exceptions\ApiErrorException;
use App\Models\Country;
use App\Models\Language;
use App\Models\vwBookingEngineSearch;
use Barryvdh\DomPDF\PDF;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
class PropertyCatalogService extends Command
{
protected $signature = 'cron:property-catalog-service {property_id} {language} {--email=}';
protected $description = '';
private $propertyService;
public function __construct(
PDF $pdf,
Mailer $mailer,
PropertyService $propertyService
)
{
parent::__construct();
$this->pdf = $pdf;
$this->mailer = $mailer;
$this->propertyService = $propertyService;
}
public function handle()
{
$this->info(date('Y-m-d H:i:s') . ' START');
$pdfDataRequest = [
'property_id' => $this->argument('property_id'),
'locale' => $this->argument('language')
];
$pdfContentService = App::make('App\Core\Service\PdfContentService');
$factSheetDataResponse = $pdfContentService->factSheetData($pdfDataRequest);
if ($factSheetDataResponse['status'] != 'success') {
throw new Exception($factSheetDataResponse['message']);
}
$pageContent = $factSheetDataResponse['data'];
$pdfLanguage = $pdfDataRequest['locale'];
$this->info(date('Y-m-d H:i:s') . ' PDF');
app('translator')->setLocale($pdfLanguage);
$pdfService = $this->pdf->loadView('pdf.propertyCatalog', compact('pageContent'), [], 'UTF8');
$pdfService->setOptions([
'dpi' => 100,
'isHtml5ParserEnabled' => true,
'isRemoteEnabled' => true,
'chroot', base_path(),
'enable_html5_parser' => true,
'enable_css_float' => true
]);
$hotelName = Str::slug($pageContent['name'], '_', 'en') . '_' . $pdfLanguage;
$pathStorage = Config::get('app.fileSystemDriver') . '/property-catalog/' . $hotelName . '.pdf';
file_put_contents($pathStorage, $pdfService->output());
if ($this->option('email')) {
$this->info(date('Y-m-d H:i:s') . ' E-Mail');
$languageDetail = Language::where('code', $pdfLanguage)->first();
$languageDetail = $languageDetail ? $languageDetail->toArray() : null;
$mailParams = [
'email' => $this->option('email'),
'catalogUrl' => Config::get('app.imageUrl') . '/property-catalog/' . $hotelName . '.pdf',
'propertyName' => $pageContent['name'],
'language' => $pdfLanguage,
'languageText' => __($languageDetail['language_key'],[],'tr'),
'pathStorage' => $pathStorage
];
$this->mailer->send('emails.propertyCatalogMail', ['mailParams' => $mailParams], function ($message) use ($mailParams) {
$message->to($mailParams['email'], 'Extranetwork Property Katalog')
->bcc(Config::get('app.logMailAddress'))
->subject($mailParams['propertyName'] . ' Catalog - ' . $mailParams['languageText'])
//->attach($mailParams['pathStorage'])
->from(Config::get('app.mailSenderAddress'), 'Extranetwork');
});
}
$this->info(date('Y-m-d H:i:s') . ' FINISHED');
}
}

View File

@@ -0,0 +1,117 @@
<?php
namespace App\Console\Commands\Jobs;
use App\Exceptions\ApiErrorException;
use App\Models\ChannelManagerPropertyMapping;
use App\Models\CurrencyRates;
use App\Models\Property;
use App\Models\PropertyPriceComparison;
use App\Models\PropertyRoomRatePrice;
use App\Models\vwActiveProperty;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Exception;
class PropertyInvoiceService extends Command
{
protected $signature = 'cron:property-invoice-service';
protected $description = '';
private $propertyInvoiceService;
public function __construct()
{
parent::__construct();
}
public function handle()
{
$propertyInvoiceService = App::make('App\Core\Service\PropertyInvoiceService');
//BULK
/*$firstAllOfYear = '2022-01-01';
$lastAllOfYear = '2025-10-01';
$startDayOfYear = Carbon::parse($firstAllOfYear)->firstOfMonth()->toDateString();
$lastDayOfYear = Carbon::parse($lastAllOfYear)->firstOfMonth()->toDateString();
$diffInPeriod = Carbon::parse($startDayOfYear)->diffInMonths(Carbon::parse($lastDayOfYear));
$periodList = [];
for ($i = 0; $i < $diffInPeriod; $i++) {
$periodList[] = Carbon::parse($firstAllOfYear)->addMonths($i)->format('Y-m');
}*/
//$periodList[] = '2025-09';
//BULK
//$invoiceWithPeriod = $propertyInvoiceService->invoiceWithPeriod(623, '2025-10');
//dd($invoiceWithPeriod);
//$periodList = ['2025-09'];
//$lastOfMonth = '2025-10-30';
//$dayOfMonth = '2025-10-30';
//$lastOfMonth = Carbon::now()->lastOfMonth()->format('Y-m-d');
//$dayOfMonth = Carbon::now()->format('Y-m-d');
//if ($lastOfMonth != $dayOfMonth) {
//$this->alert(date('Y-m-d H:i:s') . ' : ' . $lastOfMonth . ' - ' . $dayOfMonth);
//return false;
//}
//$period = Carbon::parse($dayOfMonth)->lastOfMonth()->format('Y-m');
//$periodList = [$period];
$year = Carbon::now()->year;
$currentMonth = Carbon::now()->month;
$periodList = [];
for ($month = $currentMonth; $month <= 12; $month++) {
$periodList[] = Carbon::create($year, $month, 1)->format('Y-m');
}
$this->info(date('Y-m-d H:i:s') . ' START');
$propertyList = Property::where('commission', '>', 1)
->whereIn('status', [1,3])
//->whereIn('id', [1810])
->get()->toArray();
foreach ($periodList as $period) {
$this->alert('PERIOD: ' . $period);
foreach ($propertyList as $property) {
try {
$invoiceWithPeriod = $propertyInvoiceService->invoiceWithPeriod($property['id'], $period);
if ($invoiceWithPeriod['status'] == 'success') {
$this->info(date('Y-m-d H:i:s') . ': ' . $period . ' ' . $property['id'] . ' - ' . $property['name'] . ' : ' . $period . ' - ' . $invoiceWithPeriod['data']['total'] . ' ' . $invoiceWithPeriod['data']['currency']);
} else {
$this->error(date('Y-m-d H:i:s') . ': ' . $period . ' ' . $property['id'] . ' - ' . $invoiceWithPeriod['message']);
}
} catch (ApiErrorException | Exception $e) {
$this->error(date('Y-m-d H:i:s') . ' ERROR: L: ' . $e->getLine() . ' - ' . $e->getMessage() . ' - ' . $property['id'] . ' - ' . $property['name']);
}
}
}
$this->info(date('Y-m-d H:i:s') . ' FINISHED');
}
}

View File

@@ -0,0 +1,124 @@
<?php
namespace App\Console\Commands\Jobs;
use App\Exceptions\ApiErrorException;
use App\Models\ChannelManagerPropertyMapping;
use App\Models\CurrencyRates;
use App\Models\Property;
use App\Models\PropertyPriceComparison;
use App\Models\PropertyRoomRatePrice;
use App\Models\vwActiveProperty;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Exception;
class PropertySummaryService extends Command
{
protected $signature = 'cron:property-summary-service';
protected $description = '';
private $propertySummaryService;
public function __construct()
{
parent::__construct();
}
public function handle()
{
$propertySummaryService = App::make('App\Core\Service\PropertySummaryService');
//BULK
/*$firstAllOfYear = '2022-01-01';
$lastAllOfYear = '2027-01-01';
$startDayOfYear = Carbon::parse($firstAllOfYear)->firstOfMonth()->toDateString();
$lastDayOfYear = Carbon::parse($lastAllOfYear)->firstOfMonth()->toDateString();
$diffInPeriod = Carbon::parse($startDayOfYear)->diffInMonths(Carbon::parse($lastDayOfYear));
$periodList = [];
for ($i = 0; $i < $diffInPeriod; $i++) {
$periodList[] = Carbon::parse($firstAllOfYear)->addMonths($i)->format('Y-m');
}*/
//$periodList[] = '2025-09';
//BULK
//$invoiceWithPeriod = $propertyInvoiceService->invoiceWithPeriod(623, '2025-10');
//dd($invoiceWithPeriod);
//$periodList = ['2025-09'];
//$lastOfMonth = '2025-10-30';
//$dayOfMonth = '2025-10-30';
//$lastOfMonth = Carbon::now()->lastOfMonth()->format('Y-m-d');
//$dayOfMonth = Carbon::now()->format('Y-m-d');
//if ($lastOfMonth != $dayOfMonth) {
//$this->alert(date('Y-m-d H:i:s') . ' : ' . $lastOfMonth . ' - ' . $dayOfMonth);
//return false;
//}
//$period = Carbon::parse($dayOfMonth)->lastOfMonth()->format('Y-m');
//$periodList = [$period];
$year = Carbon::now()->year;
$currentMonth = Carbon::now()->month;
$periodList = [];
for ($month = $currentMonth; $month <= 12; $month++) {
$periodList[] = Carbon::create($year, $month, 1)->format('Y-m');
}
//$periodList = ['2025-03'];
$this->info(date('Y-m-d H:i:s') . ' START');
$propertyList = Property::where('commission', '>', 1)
->where('status', 1)
//->whereIn('id', [71])
->get()->toArray();
$types[1] = 'Checkout';
$types[2] = 'Transaction';
foreach ($periodList as $period) {
$this->alert('PERIOD: ' . $period);
foreach ($propertyList as $property) {
try {
foreach ($types as $typeCode => $type) {
$invoiceWithPeriod = $propertySummaryService->summaryWithPeriod($property['id'], $period, $typeCode);
if ($invoiceWithPeriod['status'] == 'success') {
$this->info(date('Y-m-d H:i:s') . ': ' . $period . ' ' . $property['id'] . ' - ' . $property['name'] . ' : ' . $type . ' : ' . $period . ' - ' . $invoiceWithPeriod['data']['total'] . ' ' . $invoiceWithPeriod['data']['currency']);
} else {
$this->error(date('Y-m-d H:i:s') . ': ' . $period . ' ' . $property['id'] . ' - ' . $invoiceWithPeriod['message']);
}
}
} catch (ApiErrorException | Exception $e) {
$this->error(date('Y-m-d H:i:s') . ' ERROR: L: ' . $e->getLine() . ' - ' . $e->getMessage() . ' - ' . $property['id'] . ' - ' . $property['name']);
}
}
}
$this->info(date('Y-m-d H:i:s') . ' FINISHED');
}
}

View File

@@ -0,0 +1,386 @@
<?php
namespace App\Console\Commands\Jobs;
use App\Core\Mail\DailyReportMail;
use App\Core\Mail\TrialFirstMail;
use App\Core\Mail\TrialSecondMail;
use App\Core\Service\CurrencyService;
use App\Core\Service\PropertyService;
use App\Exceptions\ApiErrorException;
use App\Models\PropertyInvoice;
use App\Models\vwActiveProperty;
use App\Models\vwBookingSummary;
use App\Models\vwBookingSummaryAll;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class SummaryReportMail extends Command
{
protected $signature = 'cron:summary-report-mail';
protected $description = '';
private $propertyService;
public function __construct(
Mailer $mailer,
PropertyService $propertyService,
CurrencyService $currencyService
)
{
parent::__construct();
$this->mailer = $mailer;
$this->propertyService = $propertyService;
$this->currencyService = $currencyService;
}
public function handle()
{
$this->info(date('Y-m-d H:i:s') . ' START');
$today = Carbon::now()->subDay()->toDateString();
$report['daily']['data'] = [];
$report['daily']['title'] = 'Daily Report';
$report['daily']['period'] = Carbon::parse($today)->format('d.m.Y');
$daily = vwBookingSummaryAll::where('time', '>', Carbon::parse($today)->toDateString())
->where('time', '<', Carbon::parse($today)->addDay()->toDateString())
->where('commission', '>', 0)
->get()->toArray();
if ($daily) {
$dataCollect = collect($daily);
$dataCollect = $dataCollect->filter(function ($item) {
if ($item['property_id'] == 362) {
//Exclude Commission - Barın Hotel, 34 Hotelbeds, 103 World2Meet
if (!in_array($item['channel_id'], [34, 103])) {
return $item;
}
} else if ($item['property_id'] == 712) {
//Exclude Commission - G Hotels Skopje
if (!in_array($item['id'], [18122, 18091, 18090, 18089, 18088, 18087, 18086])) {
return $item;
}
} else {
return $item;
}
});
$dataCollectGroup = $dataCollect->groupBy('currency_code')->toArray();
foreach ($dataCollectGroup as $currencyCode => $currencyGroup) {
$report['daily']['data'][$currencyCode]['count'] = count($currencyGroup);
$report['daily']['data'][$currencyCode]['total'] = array_sum(pickItemFromArray('total', $currencyGroup));
$report['daily']['data'][$currencyCode]['commission'] = array_sum(pickItemFromArray('commission', $currencyGroup));
}
$report['daily']['summary'] = ['count' => 0, 'total' => 0, 'commission' => 0];
foreach ($report['daily']['data'] as $currentCurrency => $dailyData) {
$lastExchangeRate = $this->currencyService->lastExchangeRate($currentCurrency, 'EUR');
$report['daily']['summary']['count'] += $dailyData['count'];
$report['daily']['summary']['total'] += $dailyData['total'] * $lastExchangeRate['data'];
$report['daily']['summary']['commission'] += $dailyData['commission'] * $lastExchangeRate['data'];
}
}
$report['monthly']['data'] = [];
$report['monthly']['title'] = 'Monthly Report';
$report['monthly']['period'] = Carbon::parse($today)->firstOfMonth()->format('m.Y');
$monthly = vwBookingSummaryAll::where('time', '>', Carbon::parse($today)->firstOfMonth()->toDateString())
->where('time', '<', Carbon::parse($today)->addMonth()->firstOfMonth()->toDateString())
->where('commission', '>', 0)
->get()->toArray();
if ($monthly) {
$dataCollect = collect($monthly);
$dataCollect = $dataCollect->filter(function ($item) {
if ($item['property_id'] == 362) {
//Exclude Commission - Barın Hotel, 34 Hotelbeds, 103 World2Meet
if (!in_array($item['channel_id'], [34, 103])) {
return $item;
}
} else if ($item['property_id'] == 712) {
//Exclude Commission - G Hotels Skopje
if (!in_array($item['id'], [18122, 18091, 18090, 18089, 18088, 18087, 18086])) {
return $item;
}
} else {
return $item;
}
});
$dataCollectGroup = $dataCollect->groupBy('currency_code')->toArray();
foreach ($dataCollectGroup as $currencyCode => $currencyGroup) {
$report['monthly']['data'][$currencyCode]['count'] = count($currencyGroup);
$report['monthly']['data'][$currencyCode]['total'] = array_sum(pickItemFromArray('total', $currencyGroup));
$report['monthly']['data'][$currencyCode]['commission'] = array_sum(pickItemFromArray('commission', $currencyGroup));
}
$report['monthly']['summary'] = ['count' => 0, 'total' => 0, 'commission' => 0];
foreach ($report['monthly']['data'] as $currentCurrency => $dailyData) {
$lastExchangeRate = $this->currencyService->lastExchangeRate($currentCurrency, 'EUR');
$report['monthly']['summary']['count'] += $dailyData['count'];
$report['monthly']['summary']['total'] += $dailyData['total'] * $lastExchangeRate['data'];
$report['monthly']['summary']['commission'] += $dailyData['commission'] * $lastExchangeRate['data'];
}
//summaryCheckout
$monthlyCheckout = vwBookingSummaryAll::where('checkout_period', Carbon::parse($today)->firstOfMonth()->format('Y-m'))
->where('commission', '>', 0)
->get()->toArray();
$dataCollect = collect($monthlyCheckout);
$dataCollect = $dataCollect->filter(function ($item) {
if ($item['property_id'] == 362) {
//Exclude Commission - Barın Hotel, 34 Hotelbeds, 103 World2Meet
if (!in_array($item['channel_id'], [34, 103])) {
return $item;
}
} else if ($item['property_id'] == 712) {
//Exclude Commission - G Hotels Skopje
if (!in_array($item['id'], [18122, 18091, 18090, 18089, 18088, 18087, 18086])) {
return $item;
}
} else {
return $item;
}
});
$dataCollectGroup = $dataCollect->groupBy('currency_code')->toArray();
foreach ($dataCollectGroup as $currencyCode => $currencyGroup) {
$report['monthly']['summaryCheckoutData'][$currencyCode]['count'] = count($currencyGroup);
$report['monthly']['summaryCheckoutData'][$currencyCode]['total'] = array_sum(pickItemFromArray('total', $currencyGroup));
$report['monthly']['summaryCheckoutData'][$currencyCode]['commission'] = array_sum(pickItemFromArray('commission', $currencyGroup));
}
$report['monthly']['summaryCheckout'] = ['count' => 0, 'total' => 0, 'commission' => 0];
foreach ($report['monthly']['summaryCheckoutData'] as $currentCurrency => $dailyData) {
$lastExchangeRate = $this->currencyService->lastExchangeRate($currentCurrency, 'EUR');
$report['monthly']['summaryCheckout']['count'] += $dailyData['count'];
$report['monthly']['summaryCheckout']['total'] += $dailyData['total'] * $lastExchangeRate['data'];
$report['monthly']['summaryCheckout']['commission'] += $dailyData['commission'] * $lastExchangeRate['data'];
}
$monthlySummary = [];
$annuallyMonths = [];
for ($i = 0; $i < 12; $i++) {
$annuallyMonths[] = Carbon::parse($today)->firstOfYear()->addMonths($i)->format('Y-m');
}
$vwBookingSummaryTransaction = vwBookingSummaryAll::whereIn('transaction_period',$annuallyMonths)
->where('commission', '>', 0)
->get()->toArray();
$vwBookingSummaryCheckout = vwBookingSummaryAll::whereIn('checkout_period',$annuallyMonths)
->where('commission', '>', 0)
->get()->toArray();
$vwBookingSummaryTransactionGrouped = collect($vwBookingSummaryTransaction)->groupBy('transaction_period')->toArray();
$vwBookingSummaryCheckoutGrouped = collect($vwBookingSummaryCheckout)->groupBy('checkout_period')->toArray();
$monthlySummary['month'] = [];
foreach ($annuallyMonths as $annuallyMonth) {
//$annuallyMonth = Carbon::parse($annuallyMonth)->format('Y-m');
$monthlySummary['month'][$annuallyMonth] = $annuallyMonth;
$monthlySummary['transaction'][$annuallyMonth]['count'] = 0;
$monthlySummary['transaction'][$annuallyMonth]['total'] = 0;
$monthlySummary['transaction'][$annuallyMonth]['commission'] = 0;
if(isset($vwBookingSummaryTransactionGrouped[$annuallyMonth])) {
$dataCollectGroupCurrency = collect($vwBookingSummaryTransactionGrouped[$annuallyMonth])->groupBy('currency_code')->toArray();
foreach ($dataCollectGroupCurrency as $currencyCode => $currencyGroup) {
$lastExchangeRate = $this->currencyService->lastExchangeRate($currencyCode, 'EUR');
$monthlySummary['transaction'][$annuallyMonth]['count'] += collect($currencyGroup)->count();
$monthlySummary['transaction'][$annuallyMonth]['total'] += collect($currencyGroup)->sum('total') * $lastExchangeRate['data'];
$monthlySummary['transaction'][$annuallyMonth]['commission'] += collect($currencyGroup)->sum('commission') * $lastExchangeRate['data'];
}
}
$monthlySummary['checkout'][$annuallyMonth]['count'] = 0;
$monthlySummary['checkout'][$annuallyMonth]['total'] = 0;
$monthlySummary['checkout'][$annuallyMonth]['commission'] = 0;
if(isset($vwBookingSummaryCheckoutGrouped[$annuallyMonth])) {
$dataCollectGroupCurrency = collect($vwBookingSummaryCheckoutGrouped[$annuallyMonth])->groupBy('currency_code')->toArray();
foreach ($dataCollectGroupCurrency as $currencyCode => $currencyGroup) {
$lastExchangeRate = $this->currencyService->lastExchangeRate($currencyCode, 'EUR');
$monthlySummary['checkout'][$annuallyMonth]['count'] += collect($currencyGroup)->count();
$monthlySummary['checkout'][$annuallyMonth]['total'] += collect($currencyGroup)->sum('total') * $lastExchangeRate['data'];
$monthlySummary['checkout'][$annuallyMonth]['commission'] += collect($currencyGroup)->sum('commission') * $lastExchangeRate['data'];
}
}
}
$report['monthlySummary'] = $monthlySummary;
}
$report['annually']['data'] = [];
$report['annually']['title'] = 'Annually Report';
$report['annually']['period'] = Carbon::parse($today)->firstOfYear()->format('Y');
$annually = vwBookingSummaryAll::where('time', '>', Carbon::parse($today)->firstOfYear()->toDateString())
->where('time', '<', Carbon::parse($today)->addYear()->firstOfYear()->toDateString())
->where('commission', '>', 0)
->get()->toArray();
if ($annually) {
$dataCollect = collect($annually);
$dataCollect = $dataCollect->filter(function ($item) {
if ($item['property_id'] == 362) {
//Exclude Commission - Barın Hotel, 34 Hotelbeds, 103 World2Meet
if (!in_array($item['channel_id'], [34, 103])) {
return $item;
}
} else if ($item['property_id'] == 712) {
//Exclude Commission - G Hotels Skopje
if (!in_array($item['id'], [18122, 18091, 18090, 18089, 18088, 18087, 18086])) {
return $item;
}
} else {
return $item;
}
});
$dataCollectGroup = $dataCollect->groupBy('currency_code')->toArray();
foreach ($dataCollectGroup as $currencyCode => $currencyGroup) {
$report['annually']['data'][$currencyCode]['count'] = count($currencyGroup);
$report['annually']['data'][$currencyCode]['total'] = array_sum(pickItemFromArray('total', $currencyGroup));
$report['annually']['data'][$currencyCode]['commission'] = array_sum(pickItemFromArray('commission', $currencyGroup));
}
$report['annually']['summary'] = ['count' => 0, 'total' => 0, 'commission' => 0];
foreach ($report['annually']['data'] as $currentCurrency => $dailyData) {
$lastExchangeRate = $this->currencyService->lastExchangeRate($currentCurrency, 'EUR');
$report['annually']['summary']['count'] += $dailyData['count'];
$report['annually']['summary']['total'] += $dailyData['total'] * $lastExchangeRate['data'];
$report['annually']['summary']['commission'] += $dailyData['commission'] * $lastExchangeRate['data'];
}
//summaryCheckout Annually
$annuallyCheckout = vwBookingSummaryAll::where('checkout_date', '>=', Carbon::parse($today)->firstOfYear()->format('Y-m-d'))
->where('checkout_date', '<=', Carbon::parse($today)->endOfYear()->format('Y-m-d'))
->where('commission', '>', 0)
->get()->toArray();
$dataCollect = collect($annuallyCheckout);
$dataCollect = $dataCollect->filter(function ($item) {
if ($item['property_id'] == 362) {
//Exclude Commission - Barın Hotel, 34 Hotelbeds, 103 World2Meet
if (!in_array($item['channel_id'], [34, 103])) {
return $item;
}
} else if ($item['property_id'] == 712) {
//Exclude Commission - G Hotels Skopje
if (!in_array($item['id'], [18122, 18091, 18090, 18089, 18088, 18087, 18086])) {
return $item;
}
} else {
return $item;
}
});
$dataCollectGroup = $dataCollect->groupBy('currency_code')->toArray();
foreach ($dataCollectGroup as $currencyCode => $currencyGroup) {
$report['annually']['summaryCheckoutData'][$currencyCode]['count'] = count($currencyGroup);
$report['annually']['summaryCheckoutData'][$currencyCode]['total'] = array_sum(pickItemFromArray('total', $currencyGroup));
$report['annually']['summaryCheckoutData'][$currencyCode]['commission'] = array_sum(pickItemFromArray('commission', $currencyGroup));
}
$report['annually']['summaryCheckout'] = ['count' => 0, 'total' => 0, 'commission' => 0];
foreach ($report['annually']['summaryCheckoutData'] as $currentCurrency => $dailyData) {
$lastExchangeRate = $this->currencyService->lastExchangeRate($currentCurrency, 'EUR');
$report['annually']['summaryCheckout']['count'] += $dailyData['count'];
$report['annually']['summaryCheckout']['total'] += $dailyData['total'] * $lastExchangeRate['data'];
$report['annually']['summaryCheckout']['commission'] += $dailyData['commission'] * $lastExchangeRate['data'];
}
}
//Hotel LIST
$vwActivePropertySummary = [];
$vwActiveProperty = vwActiveProperty::where('commission', '>', 1)->orderByDesc('id')->get()->toArray();
$vwActivePropertySummary['count'] = count($vwActiveProperty);
$vwActivePropertySummary['groupByMonth'] = collect($vwActiveProperty)->sortByDesc('month')->groupBy('month')->toArray();
$vwActivePropertySummary['lastMonth'] = collect($vwActivePropertySummary['groupByMonth'])->take(12)->toArray();
if ($vwActivePropertySummary['lastMonth']) {
foreach ($vwActivePropertySummary['lastMonth'] as $lastMonthKey => $lastMonth) {
$vwActivePropertySummary['lastMonth'][$lastMonthKey] = collect($vwActivePropertySummary['lastMonth'][$lastMonthKey])->sortByDesc('id')->toArray();
if ($vwActivePropertySummary['lastMonth'][$lastMonthKey]) {
$vwActivePropertySummary['lastMonth'][$lastMonthKey] = array_values($vwActivePropertySummary['lastMonth'][$lastMonthKey]);
}
}
}
//Hotel LIST
$report['activeProperty'] = $vwActivePropertySummary;
//Comparative Summary Data
//Carbon::setLocale('tr');
for ($month = 1; $month <= 12; $month++) {
$months[$month] = Carbon::create(null, $month, 1)->translatedFormat('F');
}
$report['comparative']['monthList'] = $months;
$currentYear = Carbon::parse($today)->firstOfYear()->format('Y');
$lastYear = Carbon::parse($today)->subYear()->firstOfYear()->format('Y');
$report['comparative']['yearList'][] = $lastYear;
$report['comparative']['yearList'][] = $currentYear;
$periodList = [];
foreach ([$currentYear,$lastYear] as $periodYear) {
for ($month = 1; $month <= 12; $month++) {
$periodList[] = $periodYear . '-' . str_pad((integer)$month, 2, '0', STR_PAD_LEFT);
}
}
$propertyInvoice = PropertyInvoice::where('status',1)->whereIn('period', $periodList);
$propertyInvoice = $propertyInvoice ? $propertyInvoice->get()->toArray() : [];
foreach ($propertyInvoice as $invoice) {
$periodYear = Carbon::parse($invoice['period'])->format('Y');
$periodMonth = (int)Carbon::parse($invoice['period'])->format('m');
if(!isset($report['comparative']['data'][$periodYear][$periodMonth])) {
$report['comparative']['data'][$periodYear][$periodMonth] = 0;
}
$report['comparative']['data'][$periodYear][$periodMonth]+=$invoice['total'];
}
$comparativeDiff = [];
foreach ($months as $monthKey => $month) {
$comparativeDiff[$monthKey]['amount'] = $report['comparative']['data'][$currentYear][$monthKey] - $report['comparative']['data'][$lastYear][$monthKey];
}
$report['comparative']['diff'] = $comparativeDiff;
//Comparative Summary Data
//$json = json_encode($report, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
//file_put_contents(resource_path('data/data.json'), $json);
//die();
$this->mailer->onQueue('dailyReportMail', new DailyReportMail($report));
$this->info(date('Y-m-d H:i:s') . ' FINISHED');
}
}

View File

@@ -0,0 +1,310 @@
<?php
namespace App\Console\Commands\Jobs;
use App\Core\Mail\DailyReportMail;
use App\Core\Mail\DailyReportMailSales;
use App\Core\Mail\TrialFirstMail;
use App\Core\Mail\TrialSecondMail;
use App\Core\Service\CurrencyService;
use App\Core\Service\PropertyService;
use App\Core\Service\UserService;
use App\Exceptions\ApiErrorException;
use App\Models\vwActiveProperty;
use App\Models\vwBookingSummary;
use App\Models\vwBookingSummaryAll;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class SummaryReportMailSales extends Command
{
protected $signature = 'cron:summary-report-mail-sales';
protected $description = '';
private $propertyService;
public function __construct(
Mailer $mailer,
PropertyService $propertyService,
CurrencyService $currencyService,
UserService $userService
)
{
parent::__construct();
$this->mailer = $mailer;
$this->propertyService = $propertyService;
$this->currencyService = $currencyService;
$this->userService = $userService;
}
public function reportCalculate($userId, $contractUserProperty, $type)
{
$today = Carbon::now()->subDay()->toDateString();
$report = ['data' => null, 'summary' => null];
switch ($type) {
case 'daily':
$vwBookingSummaryAll = vwBookingSummaryAll::where('time', '>', Carbon::parse($today)->toDateString())
->where('time', '<', Carbon::parse($today)->addDay()->toDateString())
->where('commission', '>', 0)
->where('contract_user_id', $userId)
->whereIn('property_id', $contractUserProperty)
->get()->toArray();
break;
case 'monthly':
$monthlySummary = [];
$annuallyMonths = [];
for ($i = 0; $i < 12; $i++) {
$annuallyMonths[] = Carbon::parse($today)->firstOfYear()->addMonths($i)->format('Y-m');
}
$vwBookingSummaryAll = vwBookingSummaryAll::whereIn('transaction_period', [Carbon::parse($today)->firstOfMonth()->format('Y-m')])
->where('commission', '>', 0)
->where('contract_user_id', $userId)
->whereIn('property_id', $contractUserProperty)
->get()->toArray();
$vwBookingSummaryTransaction = vwBookingSummaryAll::whereIn('transaction_period', $annuallyMonths)
->where('commission', '>', 0)
->where('contract_user_id', $userId)
->whereIn('property_id', $contractUserProperty)
->get()->toArray();
$vwBookingSummaryCheckout = vwBookingSummaryAll::whereIn('checkout_period', $annuallyMonths)
->where('commission', '>', 0)
->where('contract_user_id', $userId)
->whereIn('property_id', $contractUserProperty)
->get()->toArray();
$vwBookingSummaryTransactionGrouped = collect($vwBookingSummaryTransaction)->groupBy('transaction_period')->toArray();
$vwBookingSummaryCheckoutGrouped = collect($vwBookingSummaryCheckout)->groupBy('checkout_period')->toArray();
$monthlySummary['month'] = [];
foreach ($annuallyMonths as $annuallyMonth) {
$annuallyMonth = Carbon::parse($annuallyMonth)->format('Y-m');
$monthlySummary['month'][$annuallyMonth] = $annuallyMonth;
$monthlySummary['transaction'][$annuallyMonth]['count'] = 0;
$monthlySummary['transaction'][$annuallyMonth]['total'] = 0;
$monthlySummary['transaction'][$annuallyMonth]['commission'] = 0;
if(isset($vwBookingSummaryTransactionGrouped[$annuallyMonth])) {
$dataCollectGroupCurrency = collect($vwBookingSummaryTransactionGrouped[$annuallyMonth])->groupBy('currency_code')->toArray();
foreach ($dataCollectGroupCurrency as $currencyCode => $currencyGroup) {
$lastExchangeRate = $this->currencyService->lastExchangeRate($currencyCode, 'EUR');
$monthlySummary['transaction'][$annuallyMonth]['count'] += collect($currencyGroup)->count();
$monthlySummary['transaction'][$annuallyMonth]['total'] += collect($currencyGroup)->sum('total') * $lastExchangeRate['data'];
$monthlySummary['transaction'][$annuallyMonth]['commission'] += collect($currencyGroup)->sum('commission') * $lastExchangeRate['data'];
}
}
$monthlySummary['checkout'][$annuallyMonth]['count'] = 0;
$monthlySummary['checkout'][$annuallyMonth]['total'] = 0;
$monthlySummary['checkout'][$annuallyMonth]['commission'] = 0;
if(isset($vwBookingSummaryCheckoutGrouped[$annuallyMonth])) {
$dataCollectGroupCurrency = collect($vwBookingSummaryCheckoutGrouped[$annuallyMonth])->groupBy('currency_code')->toArray();
foreach ($dataCollectGroupCurrency as $currencyCode => $currencyGroup) {
$lastExchangeRate = $this->currencyService->lastExchangeRate($currencyCode, 'EUR');
$monthlySummary['checkout'][$annuallyMonth]['count'] += collect($currencyGroup)->count();
$monthlySummary['checkout'][$annuallyMonth]['total'] += collect($currencyGroup)->sum('total') * $lastExchangeRate['data'];
$monthlySummary['checkout'][$annuallyMonth]['commission'] += collect($currencyGroup)->sum('commission') * $lastExchangeRate['data'];
}
}
}
$report['monthlySummary'] = $monthlySummary;
break;
case 'annually':
$vwBookingSummaryAll = vwBookingSummaryAll::where('time', '>', Carbon::parse($today)->firstOfYear()->toDateString())
->where('time', '<', Carbon::parse($today)->addYear()->firstOfYear()->toDateString())
->where('commission', '>', 0)
->where('contract_user_id', $userId)
->whereIn('property_id', $contractUserProperty)
->get()->toArray();
break;
}
if ($vwBookingSummaryAll) {
$dataCollect = collect($vwBookingSummaryAll);
$dataCollectGroup = $dataCollect->groupBy('property_id')->toArray();
foreach ($dataCollectGroup as $propertyId => $propertyList) {
$property = reset($propertyList);
$report['data'][$propertyId]['id'] = $property['property_id'];
$report['data'][$propertyId]['name'] = $property['property_name'];
$report['data'][$propertyId]['count'] = 0;
$report['data'][$propertyId]['total'] = 0;
$report['data'][$propertyId]['commission'] = 0;
$dataCollectGroupCurrency = collect($propertyList)->groupBy('currency_code')->toArray();
foreach ($dataCollectGroupCurrency as $currencyCode => $currencyGroup) {
$lastExchangeRate = $this->currencyService->lastExchangeRate($currencyCode, 'EUR');
$count = collect($currencyGroup)->count();
$total = collect($currencyGroup)->sum('total');
$commission = collect($currencyGroup)->sum('commission');
$report['data'][$propertyId]['count'] += $count;
$report['data'][$propertyId]['total'] += $total * $lastExchangeRate['data'];
$report['data'][$propertyId]['commission'] += $commission * $lastExchangeRate['data'];
}
}
$report['data'] = collect($report['data'])->sortByDesc('commission')->toArray();
$report['summary']['count'] = collect($report['data'])->sum('count');
$report['summary']['total'] = collect($report['data'])->sum('total');
$report['summary']['commission'] = collect($report['data'])->sum('commission');
}
return $report;
}
public function handle()
{
$this->info(date('Y-m-d H:i:s') . ' START');
$today = Carbon::now()->subDay()->toDateString();
$userListIds = [904, 941, 1485];//41, 22, 883
$userListCriteria = [
'criteria' => [
['field' => 'status', 'condition' => '=', 'value' => 1],
],
'whereIn' => [
['field' => 'id', 'value' => $userListIds]
],
'orderBy' => [
['field' => 'id', 'value' => 'ASC']
]
];
$userList = $this->userService->select($userListCriteria);
foreach ($userList['data'] as $user) {
$contractUserProperty = vwActiveProperty::where('contract_user_id', $user['id'])
//->where('month', '>', '2024-10')
->get()->toArray();
$contractUserProperty = $contractUserProperty ? pickItemFromArray('id',$contractUserProperty) : [];
$this->info(date('Y-m-d H:i:s') . ' : '.$user['nameSurname']);
$report['name'] = $user['nameSurname'];
$report['email'] = $user['email'];
//DAILY
$report['daily']['data'] = [];
$report['daily']['title'] = 'Daily Report';
$report['daily']['type'] = 'daily';
$report['daily']['period'] = Carbon::parse($today)->format('d.m.Y');
$reportCalculate = $this->reportCalculate($user['id'], $contractUserProperty, $report['daily']['type']);
$report['daily']['data'] = $reportCalculate['data'];
$report['daily']['summary'] = $reportCalculate['summary'];
//MONTHLY
$report['monthly']['data'] = [];
$report['monthly']['title'] = 'Monthly Report';
$report['monthly']['type'] = 'monthly';
$report['monthly']['period'] = Carbon::parse($today)->firstOfMonth()->format('m.Y');
$reportCalculate = $this->reportCalculate($user['id'], $contractUserProperty, $report['monthly']['type']);
$report['monthly']['data'] = $reportCalculate['data'];
$report['monthly']['summary'] = $reportCalculate['summary'];
$report['monthlySummary'] = $reportCalculate['monthlySummary'];
//ANNUALLY
$report['annually']['data'] = [];
$report['annually']['title'] = 'Annually Report';
$report['annually']['type'] = 'annually';
$report['annually']['period'] = Carbon::parse($today)->firstOfYear()->format('Y');
$reportCalculate = $this->reportCalculate($user['id'], $contractUserProperty, $report['annually']['type']);
$report['annually']['data'] = $reportCalculate['data'];
$report['annually']['summary'] = $reportCalculate['summary'];
$report['activeProperty'] = vwActiveProperty::where('commission', '>', 1)
->where('contract_user_id', $user['id'])
->whereIn('id', $contractUserProperty)
->orderByDesc('id')
->get()->toArray();
//Property Price Comparison
$priceComparisonLink = null;
$todayComparison = Carbon::now()->toDateString();
$firstDayOfWeek = Carbon::parse($todayComparison)->startOfWeek(Carbon::MONDAY);
//$firstDayOfWeek = Carbon::parse($today)->startOfWeek(Carbon::MONDAY)->toDateString();
//if(Carbon::now()->toDateString() == $firstDayOfWeek) {
$year = Carbon::parse($firstDayOfWeek)->format('Y');
$week = Carbon::parse($firstDayOfWeek)->isoWeek();
$queryKeyHash = md5($year . '-' . $week);
$priceComparisonLink = config('app.url').'/property-comparison/'.$queryKeyHash.'/'.$user['id'];
//}
$report['priceComparisonLink'] = $priceComparisonLink;
//Property Price Comparison
$this->mailer->onQueue('dailyReportSalesMail', new DailyReportMailSales($report));
}
//Hotel LIST
/*$vwActivePropertySummary = [];
$vwActiveProperty = vwActiveProperty::where('commission', '>', 1)->get()->toArray();
$vwActivePropertySummary['count'] = count($vwActiveProperty);
$vwActivePropertySummary['groupByMonth'] = collect($vwActiveProperty)->sortByDesc('month')->groupBy('month')->toArray();
$vwActivePropertySummary['lastMonth'] = collect($vwActivePropertySummary['groupByMonth'])->take(3)->toArray();
//Hotel LIST
$report['activeProperty'] = $vwActivePropertySummary;*/
$this->info(date('Y-m-d H:i:s') . ' FINISHED');
}
}

View File

@@ -0,0 +1,239 @@
<?php
namespace App\Console\Commands\PropertyReviewService;
use App\Exceptions\ApiErrorException;
use App\Models\PropertyReview;
use App\Models\PropertyReviewCategory;
use App\Models\PropertyReviewCategoryMapping;
use App\Models\PropertyReviewKeywordMapping;
use Carbon\Carbon;
use Google\Protobuf\Api;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Http\Request;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Exception;
class PropertyReviewAnalyzeService extends Command
{
protected $signature = 'cron:property-review-analyze-service {review_id}';
protected $description = '';
public function __construct()
{
parent::__construct();
$this->restClient = new Client(['http_errors' => false]);
}
protected function requestService($params = [])
{
$response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
try {
$client = new \GuzzleHttp\Client([
'max' => 5,
'strict' => false,
'referer' => false,
'protocols' => ['https'],
'timeout' => 30,
'headers' => [
'Authorization' => 'Bearer ' . config('app.openAISecretKey'),
'Content-Type' => 'application/json',
'Cache-Control' => 'no-cache',
'Connection' => 'keep-alive',
'Accept-Encoding' => 'gzip'
]
]
);
$result = $client->post('https://api.openai.com/v1/chat/completions', [
'body' => json_encode($params['query'])
]);
$result = $result->getBody()->getContents();
$result = json_decode($result, 1);
$choiceMessage = reset($result['choices']);
if (isset($choiceMessage['message']['content'])) {
$choiceMessage = json_decode($choiceMessage['message']['content'], 1);
$data = $choiceMessage;
}
$response = [
'status' => true,
'data' => $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 $response;
}
public function handle()
{
$this->info(date('Y-m-d H:i:s') . ' START');
//420
$propertyReview = PropertyReview::where('id', $this->argument('review_id'))
->with('channel')
->with('property')
->first();
$propertyReview = $propertyReview ? $propertyReview->toArray() : null;
if (!$propertyReview) {
Log::error('Property Review: ' . $propertyReview['property']['name'] . ' - ' . $propertyReview['channel']['name']);
return false;
}
$propertyReviewCategory = PropertyReviewCategory::where('status', 1)->select(['id', 'name'])->get()->toArray();
$propertyReviewCategoryText = implode(', ', collect($propertyReviewCategory)->pluck('name')->toArray());
$params['query'] = [
'model' => 'gpt-4o',
'response_format' => [
'type' => 'json_object'
],
'messages' => [
[
'role' => 'system',
'content' => 'Sen bir otel gelir yönetimi uzmanısın ve otellere yapılan yorumları değerlendiriyosun. Cevaplar SADECE JSON formatında. Yorumu genel olarak değerlendirip, misafir gibi düşünüp 0: olumsuz,1: olumlu olacak şekilde sentiment alanında işaretleyelim. Gelen yorumları \"' . $propertyReviewCategoryText . '\" kategorilerine göre categories alanında işaretleyip gruplayalım. Her bir gruplanan kategori için de 0: olumsuz,1: olumlu olacak şekilde işaretleyelim, ilgisiz kategorileri eklemeyelim. keywords alanında bu yorum ile ilgili kilit kelimeleri, ileride kelime bulutu yapmak için ingilizce çıkaralım,kelimeler otel ve otelcilik ile ilgili olsun, kelimeler normal metin şeklinde, aralıkları boşluklu ve sadece ilk harfleri büyük olsun, bu kelimeler için de 0: olumsuz,1: olumlu olacak şekilde işaretleyelim. Yorumu da language parametresi altında 2 haneli ISO koduna göre verelim.'
],
[
'role' => 'user',
'content' => $propertyReview['review']
]
]
];
$propertyReviewAnalyze = $this->requestService($params);
//$propertyReviewAnalyze = json_decode('{"status":true,"data":{"sentiment":0,"categories":{"Location":0,"Breakfast":0,"Service":1,"Cleanliness":1,"Room Facilities":0},"keywords":{"Location":0,"Breakfast":0,"Service Quality":1,"Cleaning":1,"Room Amenities":0}}}', 1);
if ($propertyReviewAnalyze['status']) {
DB::beginTransaction();
$transactionSave = false;
try {
$this->info(date('Y-m-d H:i:s') . ': Property Review: ' . $propertyReview['property']['name'] . ' - ' . $propertyReview['channel']['name']);
PropertyReview::where('id', $propertyReview['id'])->update(['sentiment' => $propertyReviewAnalyze['data']['sentiment'], 'language' => $propertyReviewAnalyze['data']['language']]);
//PropertyReviewCategoryMapping
$this->info(date('Y-m-d H:i:s') . ': Property Review Category Mapping: ' . $propertyReview['property']['name'] . ' - ' . $propertyReview['channel']['name']);
$bulkReviewCategoryMapping = [];
PropertyReviewCategoryMapping::where('review_id', $propertyReview['id'])->delete();
foreach ($propertyReviewAnalyze['data']['categories'] as $category => $categorySentiment) {
$categorySelected = collect($propertyReviewCategory)->where('name', $category)->first();
if (isset($categorySelected['id'])) {
$bulkReviewCategoryMapping[] = [
'review_id' => $propertyReview['id'],
'property_id' => $propertyReview['property_id'],
'channel_id' => $propertyReview['channel_id'],
'category_id' => $categorySelected['id'],
'sentiment' => $categorySentiment,
'review_date' => $propertyReview['review_date'],
'status' => 1,
'created_at' => time(),
'updated_at' => time(),
];
}
}
if (!empty($bulkReviewCategoryMapping)) {
PropertyReviewCategoryMapping::insert($bulkReviewCategoryMapping);
}
//PropertyReviewCategoryMapping
//PropertyReviewKeywordMapping
if (is_array($propertyReviewAnalyze['data']['keywords'])) {
$this->info(date('Y-m-d H:i:s') . ': Property Review Keyword Mapping: ' . $propertyReview['property']['name'] . ' - ' . $propertyReview['channel']['name']);
$bulkReviewKeywordMapping = [];
PropertyReviewKeywordMapping::where('review_id', $propertyReview['id'])->delete();
foreach ($propertyReviewAnalyze['data']['keywords'] as $keyword => $keywordSentiment) {
$bulkReviewKeywordMapping[] = [
'review_id' => $propertyReview['id'],
'property_id' => $propertyReview['property_id'],
'channel_id' => $propertyReview['channel_id'],
'keyword' => $keyword,
'sentiment' => $keywordSentiment,
'review_date' => $propertyReview['review_date'],
'status' => 1,
'created_at' => time(),
'updated_at' => time(),
];
}
if (!empty($bulkReviewKeywordMapping)) {
PropertyReviewKeywordMapping::insert($bulkReviewKeywordMapping);
}
}
//PropertyReviewKeywordMapping
//throw new Exception('Booking Room could not be made');
$transactionSave = true;
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$transactionSave = false;
}
if ($transactionSave) {
DB::commit();
} else {
DB::rollBack();
}
}
$this->info(date('Y-m-d H:i:s') . ' FINISHED');
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace App\Console\Commands\PropertyReviewService;
use App\Exceptions\ApiErrorException;
use App\Jobs\PropertyReviewServiceJob;
use App\Models\PropertyReviewChannelMapping;
use Carbon\Carbon;
use Google\Protobuf\Api;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Exception;
class PropertyReviewScheduleService extends Command
{
protected $signature = 'cron:property-review-schedule-service';
protected $description = '';
public function __construct()
{
parent::__construct();
}
public function handle()
{
$this->info(date('Y-m-d H:i:s') . ' START');
$propertyReviewChannelMapping = PropertyReviewChannelMapping::where('status', 1)
->with('channel')
->with('property')
->get();
$propertyReviewChannelMapping = $propertyReviewChannelMapping ? $propertyReviewChannelMapping->toArray() : null;
foreach ($propertyReviewChannelMapping as $propertyReview) {
if (Carbon::createFromTimestamp($propertyReview['created_at'])->dayName != Carbon::now()->dayName) {
continue;
}
$this->info(date('Y-m-d H:i:s') . ' Property Review: ' . $propertyReview['property']['name'] . ' - ' . $propertyReview['channel']['name']);
dispatch(new PropertyReviewServiceJob($propertyReview['property_id'], $propertyReview['channel_id']));
}
$this->info(date('Y-m-d H:i:s') . ' FINISHED');
}
}

View File

@@ -0,0 +1,738 @@
<?php
namespace App\Console\Commands\PropertyReviewService;
use App\Exceptions\ApiErrorException;
use App\Jobs\PropertyReviewAnalyzeServiceJob;
use App\Jobs\PropertyReviewServiceJob;
use App\Models\PropertyReview;
use App\Models\PropertyReviewChannelMapping;
use Carbon\Carbon;
use Google\Protobuf\Api;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Exception;
class PropertyReviewService extends Command
{
protected $signature = 'cron:property-review-service {property_id} {channel_id}';
protected $description = '';
protected $maxPageSize = 10;
protected $xApiKey = 'sk_live_995958e62147c2ae81f6be573daa7c0d0bcedf550ff5dae52315bd05f1272803';
public function __construct()
{
parent::__construct();
$this->restClient = new Client(['http_errors' => false]);
}
protected function requestService($params)
{
try {
$requestUrl = $params['requestUrl'];
$requestParams['headers']['x-api-key'] = $this->xApiKey;
$requestParams['headers']['Content-Type'] = 'application/json';
unset($params['requestUrl']);
$requestParams['query'] = $params;
$result = $this->restClient->request('GET', $requestUrl, $requestParams);
$getResponseBody = $result->getBody()->getContents();
$getResponseData = $getResponseBody ? json_decode($getResponseBody, 1) : [];
//$getResponseData = json_decode(file_get_contents(storage_path() . '/response.json'), 1);
//$getResponseData = json_decode(file_get_contents(storage_path() . '/google.json'), 1);
//$getResponseData = json_decode(file_get_contents(storage_path() . '/Tripadvisor.json'), 1);
//$getResponseData = json_decode(file_get_contents(storage_path() . '/Tripadvisor.json'), 1);
if (isset($getResponseData['error'])) {
throw new ApiErrorException($getResponseData['detail']);
}
$response['status'] = true;
$response['data'] = $getResponseData;
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::debug($message);
$response['message'] = $e->getMessage();
dd($response);
}
return $response;
}
public function handle()
{
$this->info(date('Y-m-d H:i:s') . ' START');
$propertyReviewChannelMapping = PropertyReviewChannelMapping::where('property_id', $this->argument('property_id'))
->where('channel_id', $this->argument('channel_id'))
->with('channel')
->with('property')
->first();
$propertyReviewChannelMapping = $propertyReviewChannelMapping ? $propertyReviewChannelMapping->toArray() : null;
Log::debug('Property Review: ' . $propertyReviewChannelMapping['property']['name'] . ' - ' . $propertyReviewChannelMapping['channel']['name']);
switch ($propertyReviewChannelMapping['channel_id']) {
//BookingCom
case '1':
$this->info(date('Y-m-d H:i:s') . ' START : ' . $propertyReviewChannelMapping['property']['name'] . ' - ' . $propertyReviewChannelMapping['channel']['name']);
$maxPageSize = 1;
if ($propertyReviewChannelMapping['fetch_status'] == 3) {
$maxPageSize = $this->maxPageSize;
PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 2]);
}
for ($i = 0; $i < $maxPageSize; $i++) {
$requestParams = [
'requestUrl' => 'https://api.stayapi.com/v1/booking/hotel/reviews',
'hotel_id' => $propertyReviewChannelMapping['parameterArray']['hotelId'],
'sort' => 'newest',
'per_page' => 20,
'page' => ($i + 1)
];
$requestReview = $this->requestService($requestParams);
//$bulkReview = [];
if ($requestReview['status']) {
foreach ($requestReview['data']['data']['reviews'] as $review) {
try {
if (empty($review['review']['positive']) && empty($review['review']['negative'])) {
continue;
}
$bulkReview = [
'property_id' => $propertyReviewChannelMapping['property_id'],
'channel_id' => $propertyReviewChannelMapping['channel_id'],
'channel_review_id' => $review['id'],
'author' => $review['guest']['name'],
'title' => fillOnUndefined($review['review'], 'title'),
'review' => $review['review']['positive'] . ' ' . $review['review']['negative'],
'review_date' => Carbon::parse($review['reviewed_date'])->toDateTimeString(),
'rating' => $review['score'],
'top_rating' => 10,
'score' => number_format($review['score'] / 10 * 100, 2),
'language' => $review['review']['language'],
'detail' => json_encode($review),
'status' => 1,
'created_at' => time(),
'updated_at' => time(),
];
$propertyReviewCheck = PropertyReview::where('property_id', $bulkReview['property_id'])
->where('channel_id', $bulkReview['channel_id'])
->where('channel_review_id', $bulkReview['channel_review_id'])
->first();
if (!$propertyReviewCheck) {
$propertyReviewCreate = PropertyReview::create($bulkReview);
dispatch(new PropertyReviewAnalyzeServiceJob($propertyReviewCreate['id']));
$this->info(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']);
} else {
$this->error(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']);
}
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
//dd($message);
}
}
}
}
PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 1]);
break;
//Google
case '2':
$this->info(date('Y-m-d H:i:s') . ' START : ' . $propertyReviewChannelMapping['property']['name'] . ' - ' . $propertyReviewChannelMapping['channel']['name']);
$maxPageSize = 1;
if ($propertyReviewChannelMapping['fetch_status'] == 3) {
PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 2]);
}
for ($i = 0; $i < $maxPageSize; $i++) {
$requestParams = [
'requestUrl' => 'https://api.stayapi.com/v1/google_reviews/reviews-paginated',
'data_id' => $propertyReviewChannelMapping['parameterArray']['dataId'],
'sort_by' => 'newest',
'pages' => 10
];
$requestReview = $this->requestService($requestParams);
if ($requestReview['status']) {
foreach ($requestReview['data']['reviews'] as $review) {
if (empty($review['text'])) {
continue;
}
try {
$bulkReview = [
'property_id' => $propertyReviewChannelMapping['property_id'],
'channel_id' => $propertyReviewChannelMapping['channel_id'],
'channel_review_id' => $review['review_id'],
'author' => $review['reviewer']['name'],
'title' => null,
'review' => $review['text'],
'review_date' => Carbon::parse($review['iso_date'])->toDateTimeString(),
'rating' => $review['rating'],
'top_rating' => 5,
'score' => number_format($review['rating'] / 5 * 100, 2),
'language' => null,
'detail' => json_encode($review),
'status' => 1,
'created_at' => time(),
'updated_at' => time(),
];
$propertyReviewCheck = PropertyReview::where('property_id', $bulkReview['property_id'])
->where('channel_id', $bulkReview['channel_id'])
->where('channel_review_id', $bulkReview['channel_review_id'])
->first();
if (!$propertyReviewCheck) {
$propertyReviewCreate = PropertyReview::create($bulkReview);
dispatch(new PropertyReviewAnalyzeServiceJob($propertyReviewCreate['id']));
$this->info(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']);
} else {
$this->error(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']);
}
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
//dd($message);
}
}
}
}
PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 1]);
break;
//Tripadvisor
case '3':
$this->info(date('Y-m-d H:i:s') . ' START : ' . $propertyReviewChannelMapping['property']['name'] . ' - ' . $propertyReviewChannelMapping['channel']['name']);
$maxPageSize = 1;
if ($propertyReviewChannelMapping['fetch_status'] == 3) {
$maxPageSize = $this->maxPageSize;
PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 2]);
}
for ($i = 0; $i < $maxPageSize; $i++) {
$requestParams = [
'requestUrl' => 'https://api.stayapi.com/v1/tripadvisor/hotel/reviews/' . $propertyReviewChannelMapping['parameterArray']['hotelId'],
'per_page' => 20,
'page' => ($i + 1)
];
$requestReview = $this->requestService($requestParams);
if ($requestReview['status']) {
foreach ($requestReview['data']['reviews'] as $review) {
if (!fillOnUndefined($review, 'text')) {
continue;
}
try {
$bulkReview = [
'property_id' => $propertyReviewChannelMapping['property_id'],
'channel_id' => $propertyReviewChannelMapping['channel_id'],
'channel_review_id' => $review['id'],
'author' => $review['user']['display_name'],
'title' => fillOnUndefined($review, 'title'),
'review' => fillOnUndefined($review, 'text'),
'review_date' => Carbon::parse($review['created_date'])->toDateTimeString(),
'rating' => $review['rating'],
'top_rating' => 5,
'score' => number_format($review['rating'] / 5 * 100, 2),
'language' => fillOnUndefined($review, 'language'),
'detail' => json_encode($review),
'status' => 1,
'created_at' => time(),
'updated_at' => time(),
];
$propertyReviewCheck = PropertyReview::where('property_id', $bulkReview['property_id'])
->where('channel_id', $bulkReview['channel_id'])
->where('channel_review_id', $bulkReview['channel_review_id'])
->first();
if (!$propertyReviewCheck) {
$propertyReviewCreate = PropertyReview::create($bulkReview);
dispatch(new PropertyReviewAnalyzeServiceJob($propertyReviewCreate['id']));
$this->info(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']);
} else {
$this->error(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']);
}
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
//dd($message);
}
}
}
}
PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 1]);
break;
//Agoda
case '4':
$this->info(date('Y-m-d H:i:s') . ' START : ' . $propertyReviewChannelMapping['property']['name'] . ' - ' . $propertyReviewChannelMapping['channel']['name']);
$maxPageSize = 1;
if ($propertyReviewChannelMapping['fetch_status'] == 3) {
$maxPageSize = $this->maxPageSize;
PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 2]);
}
for ($i = 0; $i < $maxPageSize; $i++) {
$requestParams = [
'requestUrl' => 'https://api.stayapi.com/v1/agoda/hotel/reviews/' . $propertyReviewChannelMapping['parameterArray']['hotelId'],
'page' => ($i + 1)
];
$requestReview = $this->requestService($requestParams);
if ($requestReview['status']) {
foreach ($requestReview['data']['reviews'] as $review) {
if (!fillOnUndefined($review, 'comment')) {
continue;
}
try {
$bulkReview = [
'property_id' => $propertyReviewChannelMapping['property_id'],
'channel_id' => $propertyReviewChannelMapping['channel_id'],
'channel_review_id' => $review['review_id'],
'author' => null,
'title' => fillOnUndefined($review, 'title'),
'review' => fillOnUndefined($review, 'comment'),
'review_date' => Carbon::parse($review['date'])->toDateTimeString(),
'rating' => $review['rating'],
'top_rating' => 10,
'score' => number_format($review['rating'] / 10 * 100, 2),
'language' => fillOnUndefined($review, 'language'),
'detail' => json_encode($review),
'status' => 1,
'created_at' => time(),
'updated_at' => time(),
];
$propertyReviewCheck = PropertyReview::where('property_id', $bulkReview['property_id'])
->where('channel_id', $bulkReview['channel_id'])
->where('channel_review_id', $bulkReview['channel_review_id'])
->first();
if (!$propertyReviewCheck) {
$propertyReviewCreate = PropertyReview::create($bulkReview);
dispatch(new PropertyReviewAnalyzeServiceJob($propertyReviewCreate['id']));
$this->info(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']);
} else {
$this->error(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']);
}
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
//dd($message);
}
}
}
}
PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 1]);
break;
//Trip.com
case '5':
$this->info(date('Y-m-d H:i:s') . ' START : ' . $propertyReviewChannelMapping['property']['name'] . ' - ' . $propertyReviewChannelMapping['channel']['name']);
$maxPageSize = 1;
if ($propertyReviewChannelMapping['fetch_status'] == 3) {
$maxPageSize = $this->maxPageSize;
PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 2]);
}
for ($i = 0; $i < $maxPageSize; $i++) {
$requestParams = [
'requestUrl' => 'https://api.stayapi.com/v1/tripcom/hotel/reviews/' . $propertyReviewChannelMapping['parameterArray']['hotelId'],
'page' => ($i + 1),
'page_size' => 50
];
$requestReview = $this->requestService($requestParams);
if ($requestReview['status']) {
foreach ($requestReview['data']['data']['reviews'] as $review) {
if (!fillOnUndefined($review, 'text')) {
continue;
}
/* if ($review['source'] != 1) {
continue;
}*/
try {
$bulkReview = [
'property_id' => $propertyReviewChannelMapping['property_id'],
'channel_id' => $propertyReviewChannelMapping['channel_id'],
'channel_review_id' => $review['id'],
'author' => isset($review['reviewer_name']) ? $review['reviewer_name'] : null,
'title' => fillOnUndefined($review, 'title'),
'review' => fillOnUndefined($review, 'text'),
'review_date' => Carbon::parse($review['date'])->toDateTimeString(),
'rating' => $review['rating'],
'top_rating' => 10,
'score' => number_format($review['rating'] / 10 * 100, 2),
'language' => fillOnUndefined($review, 'language'),
'detail' => json_encode($review),
'status' => 1,
'created_at' => time(),
'updated_at' => time(),
];
$propertyReviewCheck = PropertyReview::where('property_id', $bulkReview['property_id'])
->where('channel_id', $bulkReview['channel_id'])
->where('channel_review_id', $bulkReview['channel_review_id'])
->first();
if (!$propertyReviewCheck) {
$propertyReviewCreate = PropertyReview::create($bulkReview);
dispatch(new PropertyReviewAnalyzeServiceJob($propertyReviewCreate['id']));
$this->info(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']);
} else {
$this->error(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']);
}
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
//dd($message);
}
}
}
}
PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 1]);
break;
//Expedia.com
case '6':
$this->info(date('Y-m-d H:i:s') . ' START : ' . $propertyReviewChannelMapping['property']['name'] . ' - ' . $propertyReviewChannelMapping['channel']['name']);
$maxPageSize = 1;
if ($propertyReviewChannelMapping['fetch_status'] == 3) {
$maxPageSize = $this->maxPageSize;
PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 2]);
}
for ($i = 0; $i < $maxPageSize; $i++) {
$requestParams = [
'requestUrl' => 'https://api.stayapi.com/v1/expedia/hotel/reviews',
'property_id' => $propertyReviewChannelMapping['parameterArray']['hotelId'],
'page' => $i,
'page_size' => 5
];
$requestReview = $this->requestService($requestParams);
if ($requestReview['status']) {
foreach ($requestReview['data']['reviews'] as $review) {
if (!fillOnUndefined($review, 'text')) {
continue;
}
try {
preg_match('/(\d+)\s*\/\s*(\d+)/', $review['rating'], $matches);
$bulkReview = [
'property_id' => $propertyReviewChannelMapping['property_id'],
'channel_id' => $propertyReviewChannelMapping['channel_id'],
'channel_review_id' => $review['id'],
'author' => isset($review['reviewer_name']) ? $review['reviewer_name'] : null,
'title' => fillOnUndefined($review, 'title'),
'review' => fillOnUndefined($review, 'text'),
'review_date' => Carbon::parse($review['review_date'])->toDateTimeString(),
'rating' => (int)$matches[1],
'top_rating' => 10,
'score' => number_format((int)$matches[1] / 10 * 100, 2),
'language' => fillOnUndefined($review, 'language'),
'detail' => json_encode($review),
'status' => 1,
'created_at' => time(),
'updated_at' => time(),
];
$propertyReviewCheck = PropertyReview::where('property_id', $bulkReview['property_id'])
->where('channel_id', $bulkReview['channel_id'])
->where('channel_review_id', $bulkReview['channel_review_id'])
->first();
if (!$propertyReviewCheck) {
$propertyReviewCreate = PropertyReview::create($bulkReview);
dispatch(new PropertyReviewAnalyzeServiceJob($propertyReviewCreate['id']));
$this->info(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']);
} else {
$this->error(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']);
}
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
//dd($message);
}
}
}
}
PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 1]);
break;
//HolidayCheck
case '7':
$this->info(date('Y-m-d H:i:s') . ' START : ' . $propertyReviewChannelMapping['property']['name'] . ' - ' . $propertyReviewChannelMapping['channel']['name']);
$maxPageSize = 1;
if ($propertyReviewChannelMapping['fetch_status'] == 3) {
$maxPageSize = $this->maxPageSize;
PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 2]);
}
for ($i = 0; $i < $maxPageSize; $i++) {
$hotelId = $propertyReviewChannelMapping['parameterArray']['hotelId'];
$limit = 10;
$offset = $i * $limit;
$requestParams = [
'requestUrl' => "https://www.holidaycheck.de/api/hotel-reviews;filter=hotel.id:{$hotelId};limit={$limit};offset={$offset};select=id,user,title,texts,textAdvice,hotel,travelDate,recommendation,ratings,ranking,proofedReservation,ownerComment,additional,entryDate;sort=entryDate:desc",
];
$requestReview = $this->requestService($requestParams);
if ($requestReview['status']) {
$reviews = isset($requestReview['data']['data']['items']) ? $requestReview['data']['data']['items'] : [];
foreach ($reviews as $review) {
$reviewText = fillOnUndefined($review, 'textAdvice');
if (empty($reviewText)) {
$reviewText = fillOnUndefined($review, 'texts.GENERAL');
}
if (empty($reviewText)) {
continue;
}
try {
$rating = fillOnUndefined($review, 'ratings.GENERAL.GENERAL');
$author = fillOnUndefined($review, 'user.firstName');
if (empty($author)) {
$author = fillOnUndefined($review, 'user.name');
}
$bulkReview = [
'property_id' => $propertyReviewChannelMapping['property_id'],
'channel_id' => $propertyReviewChannelMapping['channel_id'],
'channel_review_id' => fillOnUndefined($review, 'id'),
'author' => $author,
'title' => fillOnUndefined($review, 'title'),
'review' => $reviewText,
'review_date' => Carbon::createFromTimestampMs(fillOnUndefined($review, 'entryDate'))->toDateTimeString(),
'rating' => $rating,
'top_rating' => 6,
'score' => number_format($rating / 6 * 100, 2),
'language' => fillOnUndefined($review, 'originalLocale'),
'detail' => json_encode($review),
'status' => 1,
'created_at' => time(),
'updated_at' => time(),
];
$propertyReviewCheck = PropertyReview::where('property_id', $bulkReview['property_id'])
->where('channel_id', $bulkReview['channel_id'])
->where('channel_review_id', $bulkReview['channel_review_id'])
->first();
if (!$propertyReviewCheck) {
$propertyReviewCreate = PropertyReview::create($bulkReview);
dispatch(new PropertyReviewAnalyzeServiceJob($propertyReviewCreate['id']));
$this->info(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']);
} else {
$this->error(date('Y-m-d H:i:s') . ' - ' . $bulkReview['channel_review_id']);
}
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
//dd($message);
}
}
}
}
PropertyReviewChannelMapping::where('id', $propertyReviewChannelMapping['id'])->update(['fetch_status' => 1]);
break;
}
$this->info(date('Y-m-d H:i:s') . ' FINISHED');
}
}

View File

@@ -0,0 +1,125 @@
<?php
namespace App\Console\Commands\PropertyTrialCheck;
use App\Core\Service\PropertyProductMappingService;
use App\Core\Service\PropertyService;
use App\Exceptions\ApiErrorException;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class PropertyTrialCheck extends Command
{
protected $signature = 'cron:property-trial-check';
protected $description = '';
private $propertyService;
public function __construct(
PropertyService $propertyService,
PropertyProductMappingService $productMappingService
)
{
parent::__construct();
$this->propertyService = $propertyService;
$this->productMappingService = $productMappingService;
}
public function handle()
{
$response = ['status' => false, 'message' => ''];
$propertySelectCriteria = [
'criteria' => [
//['field' => 'id', 'condition' => '=', 'value' => 1],
['field' => 'status', 'condition' => '=', 'value' => 1],
['field' => 'commission', 'condition' => '=', 'value' => null],
['field' => 'created_at', 'condition' => '>', 'value' => Carbon::parse('2021-10-01')->timestamp],
],
'with' => ['propertyProductMapping'],
'orderBy' => [
["field" => "id", "value" => "ASC"]
],
'take' => 100
];
$propertyData = $this->propertyService->select($propertySelectCriteria);
if ($propertyData['status'] == 'success') {
foreach ($propertyData['data'] as $property) {
if (empty($property['property_product_mapping'])) {
continue;
}
$expireDay = Carbon::now()->diff(Carbon::createFromTimestamp($property['created_at']))->days;
$this->info(date('Y-m-d H:i:s') . ' Property: ' . $property['id'] . ' - ' . $property['name'] . ' - ' . $expireDay. ' Day');
if (in_array($expireDay, [30])) {
DB::beginTransaction();
try {
$this->info(date('Y-m-d H:i:s') . ' : Property: ' . $property['id'] . ' - ' . $property['name']);
//Product remove from property
foreach ($property['property_product_mapping'] as $productMapping) {
$this->productMappingService->update($productMapping['id'], ['status' => 0]);
}
//Trial period status
$propertyData = $this->propertyService->update($property['id'], ['status' => 2]);
//Burada otel user larına mail atılabilir, trial süresi biti diye
$response['status'] = true;
} catch (ApiErrorException $e) {
$response['message'] = implode(', ', $e->getMessageArr());
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
}
if ($response['status']) {
DB::commit();
} else {
DB::rollBack();
}
}
//Expiration Check
//Product remove from property via expiration date
foreach ($property['property_product_mapping'] as $productMapping) {
if($productMapping['status'] == 1 && !is_null($productMapping['expiration_date'])) {
if(Carbon::now()->greaterThanOrEqualTo(Carbon::parse($productMapping['expiration_date']))) {
$this->productMappingService->update($productMapping['id'], ['status' => 3]);}
}
}
}
}
}
}

View File

@@ -0,0 +1,83 @@
<?php
namespace App\Console\Commands\PropertyTrialCheck;
use App\Core\Mail\TrialFirstMail;
use App\Core\Mail\TrialSecondMail;
use App\Core\Service\PropertyService;
use App\Exceptions\ApiErrorException;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class PropertyTrialMail extends Command
{
protected $signature = 'cron:property-trial-mail';
protected $description = '';
private $propertyService;
public function __construct(
Mailer $mailer,
PropertyService $propertyService
)
{
parent::__construct();
$this->mailer = $mailer;
$this->propertyService = $propertyService;
}
public function handle()
{
$this->info(date('Y-m-d H:i:s') . ' START');
$propertySelectCriteria = [
'criteria' => [
['field' => 'status', 'condition' => '=', 'value' => 1],
['field' => 'commission', 'condition' => '=', 'value' => null],
],
'orderBy' => [
["field" => "id", "value" => "ASC"]
],
];
$propertyData = $this->propertyService->select($propertySelectCriteria);
if ($propertyData['status'] == 'success') {
foreach ($propertyData['data'] as $property) {
$createDate = Carbon::createFromTimestamp($property['created_at'])->toDateTimeString();
$expireDay = Carbon::now()->diff(Carbon::createFromTimestamp($property['created_at']))->days;
if (in_array($expireDay, [4, 10])) {
if ($expireDay == 4) {
$this->mailer->onQueue('trialFirstMail', new TrialFirstMail(['propertyId' => $property['id']]));
$this->info(date('Y-m-d H:i:s') . ' SENT Day 4: ' . $property['id'] . ' - ' . $property['name'] . ' - ' . $createDate);
}
if ($expireDay == 10) {
$this->mailer->onQueue('trialSecondMail', new TrialSecondMail(['propertyId' => $property['id']]));
$this->info(date('Y-m-d H:i:s') . ' SENT Day 10: ' . $property['id'] . ' - ' . $property['name'] . ' - ' . $createDate);
}
}
}
}
$this->info(date('Y-m-d H:i:s') . ' FINISHED');
}
}

View File

@@ -0,0 +1,57 @@
<?php
namespace App\Console\Commands\PropertyWebCheckDns;
use App\Core\Service\PropertyWebService;
use App\Exceptions\ApiErrorException;
use Illuminate\Console\Command;
use Exception;
use Illuminate\Support\Facades\Log;
class PropertyWebCheckDns extends Command
{
protected $signature = 'cron:property-web-check-dns'; // read table name column, update table key column
protected $description = '';
private $propertyWebService;
public function __construct(
PropertyWebService $propertyWebService
)
{
$this->propertyWebService = $propertyWebService;
parent::__construct();
}
public function handle()
{
try {
$this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' Check DNS Status start');
$process = $this->propertyWebService->checkDnsStatus();
if($process['status'] != 'success'){
throw new Exception($process['message']) ;
}
$this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' Check DNS Status finished');
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message);
}
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace App\Console\Commands\PropertyWebMenuMapping;
use App\Core\Service\PropertyWebService;
use App\Exceptions\ApiErrorException;
use App\Models\PropertyWeb;
use App\Models\PropertyWebMenu;
use App\Models\PropertyWebMenuMapping;
use Illuminate\Console\Command;
use Exception;
use Illuminate\Support\Facades\Log;
class PropertyWebMenuMappingConsole extends Command
{
protected $signature = 'cron:property-web-menu-mapping';
protected $description = '';
public function __construct(){
parent::__construct();
}
public function handle()
{
try {
$this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' Start');
$webMenus = PropertyWebMenu::all();
$webs = PropertyWeb::all();
$datas = [];
foreach ($webs as $key => $web){
foreach ($webMenus as $key1 => $menu){
$datas[$key][$key1]['property_id'] = $web->property_id;
$datas[$key][$key1]['property_web_id'] = $web->id;
$datas[$key][$key1]['property_web_menu_id'] = $menu->id;
$datas[$key][$key1]['order_number'] = $menu->order_number;
$datas[$key][$key1]['status'] = 1;
$datas[$key][$key1]['created_by'] = 1;
$datas[$key][$key1]['updated_by'] = 1;
$datas[$key][$key1]['created_at'] = 1;
$datas[$key][$key1]['updated_at'] = 1;
}
}
PropertyWebMenuMapping::insert(collect($datas)->flatten(1)->toArray());
$this->info(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' Finished');
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$this->error(date('Y-m-d H:i:s') . ' : ' . date('Y-m-d') . ' ERROR: ' . $message);
}
}
}

161
app/Console/Kernel.php Normal file
View File

@@ -0,0 +1,161 @@
<?php
namespace App\Console;
use App\Console\Commands\ApplicationLanguageFiles\ApplicationLanguageFiles;
use App\Console\Commands\ApplicationLanguageFiles\ApplicationLanguageBaseData;
use App\Console\Commands\ApplicationLanguageFiles\ApplicationFillTableLanguageKey;
use App\Console\Commands\ChannelManager\BestAvailableRateSyncService;
use App\Console\Commands\ChannelManager\MetaCancellationService;
use App\Console\Commands\ChannelManager\PropertyBookingSyncService;
use App\Console\Commands\ChannelManager\PropertyChannelSyncService;
use App\Console\Commands\ChannelManager\PropertyMetaRoomRatePriceService;
use App\Console\Commands\ChannelManager\PropertyMetaRoomRatePushService;
use App\Console\Commands\ChannelManager\PropertyMetaRoomRateService;
use App\Console\Commands\ChannelManager\RemovePaymentTokenService;
use App\Console\Commands\ChannelManager\ReselivaAvailRateUpdateService;
use App\Console\Commands\ChannelManager\ReservationPushService;
use App\Console\Commands\ChannelManager\ReservationPullService;
use App\Console\Commands\ChannelManager\RoomAvailabilityPushService;
use App\Console\Commands\CurrencyRates\CurrencyRatesService;
use App\Console\Commands\ChannelManager\RoomRatePushService;
use App\Console\Commands\Data\DashboardCacheService;
use App\Console\Commands\Data\HotelBedsList;
use App\Console\Commands\Data\WeatherService;
use App\Console\Commands\Google\GoogleReview;
use App\Console\Commands\Google\GoogleStaticMap;
use App\Console\Commands\Jobs\BookingCommissionService;
use App\Console\Commands\Jobs\BookingEngineSearchReportService;
use App\Console\Commands\Jobs\DataFetch;
use App\Console\Commands\Jobs\PriceComparisonService;
use App\Console\Commands\Jobs\PropertyCatalogService;
use App\Console\Commands\Jobs\PropertyInvoiceService;
use App\Console\Commands\Jobs\PropertySummaryService;
use App\Console\Commands\PropertyReviewService\PropertyReviewAnalyzeService;
use App\Console\Commands\PropertyReviewService\PropertyReviewScheduleService;
use App\Console\Commands\PropertyReviewService\PropertyReviewService;
use App\Console\Commands\Jobs\SummaryReportMail;
use App\Console\Commands\Jobs\SummaryReportMailSales;
use App\Console\Commands\PropertyTrialCheck\PropertyTrialCheck;
use App\Console\Commands\PropertyTrialCheck\PropertyTrialMail;
use App\Console\Commands\PropertyWebCheckDns\PropertyWebCheckDns;
use App\Console\Commands\Google\GoogleVisioLabel;
use App\Console\Commands\Jobs\MailJobs;
use App\Console\Commands\PropertyWebMenuMapping\PropertyWebMenuMappingConsole;
use Illuminate\Console\Scheduling\Schedule;
use Laravel\Lumen\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
GoogleVisioLabel::class,
MailJobs::class,
ApplicationLanguageFiles::class,
ApplicationLanguageBaseData::class,
ApplicationFillTableLanguageKey::class,
PropertyWebCheckDns::class,
CurrencyRatesService::class,
PropertyWebMenuMappingConsole::class,
RoomRatePushService::class,
RoomAvailabilityPushService::class,
ReservationPullService::class,
PropertyTrialCheck::class,
PropertyTrialMail::class,
HotelBedsList::class,
ReservationPushService::class,
SummaryReportMail::class,
PropertyChannelSyncService::class,
PropertyBookingSyncService::class,
BestAvailableRateSyncService::class,
RemovePaymentTokenService::class,
BookingEngineSearchReportService::class,
PropertyMetaRoomRateService::class,
PropertyMetaRoomRatePriceService::class,
PropertyMetaRoomRatePushService::class,
WeatherService::class,
BookingCommissionService::class,
DashboardCacheService::class,
GoogleReview::class,
SummaryReportMailSales::class,
GoogleStaticMap::class,
PriceComparisonService::class,
PropertyCatalogService::class,
PropertyInvoiceService::class,
PropertyReviewService::class,
PropertyReviewScheduleService::class,
PropertyReviewAnalyzeService::class,
DataFetch::class,
MetaCancellationService::class,
PropertySummaryService::class
//ReselivaAvailRateUpdateService::class
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
/*$schedule->command('cron:mail-jobs')
->withoutOverlapping()
->everyMinute()
->sendOutputTo(storage_path() . '/logs/cron-mail-jobs.log');*/
$schedule->command('cron:mail-jobs')->everyMinute();
$schedule->command('cron:currency-rates')
->withoutOverlapping()
->twiceDaily(2, 14)
//->everyMinute()
//->emailOutputTo('byumak@rezervasyon.com')
->sendOutputTo(storage_path() . '/logs/cron-currency-rates.log');
$schedule->command('cron:roomrate-push-service')->everyMinute();
$schedule->command('cron:roomavailability-push-service')->everyMinute();
$schedule->command('cron:reservation-pull-service')->everyMinute();
$schedule->command('cron:reservation-push-service')->everyMinute();
$schedule->command('cron:property-trial-check')->withoutOverlapping()->twiceDaily(9, 15);
$schedule->command('cron:property-trial-mail')->withoutOverlapping()->dailyAt('10:00');
//$schedule->command('queue:work')->everyMinute()->withoutOverlapping();
$schedule->command('queue:restart')->hourly()->withoutOverlapping();
$schedule->command('cron:summary-report-mail')->dailyAt('00:05');
$schedule->command('cron:summary-report-mail-sales')->dailyAt('09:00');
$schedule->command('cron:remove-payment-token-service')->withoutOverlapping()->dailyAt('02:00');
$schedule->command('cron:bookingengine-search-report-mail')->withoutOverlapping()->dailyAt('09:00');
$schedule->command('cron:propertymeta-roomrate-service')->withoutOverlapping()->dailyAt('03:00');
$schedule->command('cron:propertymeta-roomrateprice-service')->withoutOverlapping()->dailyAt('05:00');
$schedule->command('cron:propertymeta-roomratepush-service')->withoutOverlapping()->dailyAt('07:00');
//$schedule->command('cron:bar-sync-service')->withoutOverlapping()->cron('0 */2 * * *');
$schedule->command('cron:bar-sync-service')->cron('0 */2 * * *');
$schedule->command('cron:price-comparison-service')->withoutOverlapping()->weekly()->mondays()->at('02:00');
$schedule->command('cron:commission-service')->everyTenMinutes();
$schedule->command('cron:weather')->withoutOverlapping()->twiceDaily(2, 14);
$schedule->command('cron:dashboard-cache')->withoutOverlapping()->dailyAt('03:00');
$schedule->command('cron:google-static-map')->withoutOverlapping()->dailyAt('04:00');
$schedule->command('cron:google-review')->withoutOverlapping()->weekly()->mondays()->at('14:00');
$schedule->command('cron:property-invoice-service')->withoutOverlapping()->dailyAt('04:00');
$schedule->command('cron:property-summary-service')->withoutOverlapping()->dailyAt('04:30');
$schedule->command('cron:property-review-schedule-service')->withoutOverlapping()->dailyAt('05:00');
$schedule->command('cron:meta-cancellation-service')->withoutOverlapping()->dailyAt('05:30');
}
}