![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/job-board.corals.io/Corals/modules/Reservation/Classes/ |
<?php namespace Corals\Modules\Reservation\Classes; use Carbon\Carbon; use Corals\Modules\Reservation\Models\LineItem; use Corals\Modules\Reservation\Models\Reservation; use Corals\Modules\Reservation\Models\Service; class RatesCalculator { /** * @param LineItem $lineItem * @param $parameters * @return array|\Illuminate\Database\Eloquent\HigherOrderBuilderProxy|mixed */ public function getLineItemRateValue(LineItem $lineItem, $parameters) { if ($rateValue = data_get($parameters, ['rate_value'])) { return $rateValue; } $reservation = null; if ($reservationId = data_get($parameters, 'reservation_id')) { $reservation = Reservation::find($reservationId); } $rateQuery = $lineItem->rates(); $endsAt = data_get($parameters, 'endsAt'); $startsAt = data_get($parameters, 'startsAt'); $this->applyStartEndRateQuery($rateQuery, $startsAt, $reservation); $this->applyMinMaxPeriodRateQuery($rateQuery, $startsAt, $endsAt, $reservation); $this->applyUserClassificationRateQuery($rateQuery, $reservation); $rateValue = $rateQuery->select('res_rates.rate_value')->first(); if ($rateValue) { //return found rate value return $rateValue->rate_value; } //return line item base value return $lineItem->rate_value; } /** * @param Service $service * @param $parameters * @param null $only * @return array */ public function getServiceLineItems(Service $service, $parameters, $only = null) { $lineItems = []; $mainLineItem = $service->mainLineItem()->first(); $lineItems[] = $this->getLineItemAsArray($mainLineItem, $parameters, [ 'deletable' => false, 'is_main_line_item' => true ]); foreach ($service->optionalLineItems as $lineItem) { $lineItemCode = $lineItem->code; if (is_array($only) && !in_array($lineItemCode, $only)) continue; $lineItems[] = $this->getLineItemAsArray($lineItem, $parameters,[ 'is_main_line_item' => false ]); } return $lineItems; } /** * @param LineItem $lineItem * @param $parameters * @param array $extras * @return array */ public function getLineItemAsArray(LineItem $lineItem, $parameters, $extras = []): array { return array_merge([ 'id' => $lineItem->id, 'code' => $lineItem->code, 'rate_value' => $this->getLineItemRateValue($lineItem, $parameters), 'name' => $lineItem->name, 'notes' => '', 'deletable' => true, 'description' => $lineItem->description ], $extras); } /** * @param Reservation $reservation * @param $lineItems */ public function calculateLineItemValues(Reservation $reservation, $lineItems) { $reservation->lineItemValues()->delete(); $periodInMinutes = $reservation->period_in_minutes; $lineItemValues = []; $service = $reservation->service; $mainLineItemId = $service->mainLineItem()->first()->id; foreach ($lineItems as $lineItemArray) { $lineItemObject = LineItem::where('code', data_get($lineItemArray, 'code'))->firstOrFail(); $rateValue = data_get($lineItemArray, 'rate_value'); //if there's not rate_value get default rate_value if (!$rateValue) { $rateValue = $this->getLineItemRateValue($lineItemObject, [ 'startsAt' => $reservation->starts_at, 'endsAt' => $reservation->ends_at, 'reservation_id' => $reservation->id ]); } $period = $lineItemObject->getPeriodDependsOnRateType($periodInMinutes); $qty = data_get($lineItemArray, 'quantity', 1); $lineItemValues[] = [ 'line_item_id' => $lineItemObject->id, 'properties' => [ 'main_line_item' => $mainLineItemId == $lineItemObject->id, 'quantity' => $qty ], 'rate_value' => $rateValue, 'value' => ($period && $period > 0 ? $period * $rateValue : $rateValue) * $qty, 'notes' => data_get($lineItemArray, 'notes'), ]; } $reservation->lineItemValues()->createMany($lineItemValues); } /** * @param $rateQuery * @param $startsAt * @param $reservation */ protected function applyStartEndRateQuery($rateQuery, $startsAt, $reservation): void { if (!$startsAt) { return; } $startsAt = Carbon::parse($startsAt); $rateQuery->where(function ($query) use ($startsAt) { $query->where(function ($query) use ($startsAt) { $query->where('res_rates.start_date', '<=', $startsAt->toDateString()) ->where('res_rates.end_date', '>=', $startsAt->toDateString()); })->orWhere(function ($query) { $query->whereNull('res_rates.start_date') ->whereNull('res_rates.end_date'); }); }); } /** * @param $rateQuery * @param $reservation */ protected function applyUserClassificationRateQuery($rateQuery, $reservation): void { $classification = optional($reservation, function ($reservation) { return optional($reservation->owner)->classification; }); $rateQuery->when($classification, function ($query, $userClassification) { $query->where('res_rates.classification', $userClassification) ->orWhereNull('res_rates.classification'); }); } /** * @param $rateQuery * @param $startsAt * @param $endsAt * @param $reservation */ protected function applyMinMaxPeriodRateQuery($rateQuery, $startsAt, $endsAt, $reservation): void { if (!$startsAt || !$endsAt) { return; } $endsAt = Carbon::parse($endsAt); $startsAt = Carbon::parse($startsAt); $period = $startsAt->diffInMinutes($endsAt); $rateQuery->where(function ($query) use ($period) { $query->where(function ($query) use ($period) { $query->where('res_rates.min_period_in_minutes', '<=', $period); $query->where('res_rates.max_period_in_minutes', '>=', $period); })->orWhere(function ($query) { $query->where(function ($query) { $query->WhereNull('res_rates.min_period_in_minutes') ->WhereNull('res_rates.max_period_in_minutes'); })->orWhere(function ($query) { $query->Where('res_rates.min_period_in_minutes', '=', 0) ->Where('res_rates.max_period_in_minutes', '=', 0); }); }); }); } }