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