253 lines
11 KiB
PHP
253 lines
11 KiB
PHP
<?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');
|
|
|
|
|
|
}
|
|
}
|