Files
api-extranetwork/app/Console/Commands/ChannelManager/PropertyMetaRoomRatePushService.php
ExtraNetwork e5c4b6aa13 first commit
2026-05-12 17:04:54 +03:00

310 lines
14 KiB
PHP

<?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');
}
}