Skip to content

Instantly share code, notes, and snippets.

@xProgrammer-007
Created September 5, 2018 20:19
Show Gist options
  • Save xProgrammer-007/3793963ff04a9e90b204044a852f5dff to your computer and use it in GitHub Desktop.
Save xProgrammer-007/3793963ff04a9e90b204044a852f5dff to your computer and use it in GitHub Desktop.
Symfony hotel pricing calculator
<?php
/*
http://localhost:8000/checkout?name=&contact=&check-in-date=2018-09-03&check-out-date=2018-09-07&rooms=01&adults=01&hotel_id=1&kids=01
Use the above parameters for example
*/
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Validator\Constraints\DateTime;
use App\Entity\Hotel;
use App\Entity\Season;
use Symfony\Component\Form\Extension\Core\Type\DateIntervalType;
//use Symfony\Component\Validator\Constraints\Date;
class CheckoutPageController extends AbstractController{
/**
* @Route("/checkout", name="checkout_page")
*/
public function index(Request $request){
$userTotalRate = 0;
$name= $request->query->get('name');
$contact=$request->query->get('contact');
$check_in_date=$request->query->get('check-in-date');
$check_out_date=$request->query->get('check-out-date');
$rooms=$request->query->get('rooms');
$adults=$request->query->get('adults');
$kids=$request->query->get('kids');
$hotel_id= $request->query->get('hotel_id');
$startDate = date_create($check_in_date);
$endDate= date_create($check_out_date);
$noOfDays= date_diff($startDate,$endDate);
$noOfnights= $noOfDays->days;
$hotel=$this->getDoctrine()->getRepository(Hotel::class)->find($hotel_id);
$checkInMonth = date_parse_from_format("Y-m-d", $check_in_date);
$checkInMonth = $checkInMonth["month"];
$checkOutMonth = date_parse_from_format("Y-m-d", $check_in_date);
$checkOutMonth = $checkOutMonth["month"];
if($checkOutMonth > $checkInMonth){
//Checkout is in another month ;
//implement algorithm respectively
}else{
//checkout is in the same month.
$season=$this->getDoctrine()->getRepository(Season::class)->findOneBy(['monthInteger' => 9]);
$hasSeason = $season->getHasSeason();
$seasonStartDate = $season->getStartSeasonDate()->format('y-m-d');
$seasonEndDate = $season->getEndSeasondate()->format('y-m-d');
if($hasSeason){ //means that the specific months is on season period
$offSeasonRate = $hotel->getOffSeasonRate(); // Get Offseason Rate from hotel Entity
$seasonRate = $hotel->getSeasonRate(); // Get season Rate from hotel Entity
/*
Now because there is a chance of season dates lying in user check in and check out dates.
So we first convert the check_in_date and check_out_date to timestamps , meanwhile also subtracting a day from check_out_date.
As because hotel rates are calculated in terms of nights not days .
*/
$startTime = strtotime($check_in_date);
$endTime = strtotime('-1 day' , strtotime($check_out_date));
$userTotalRate = 0; // initialize it to zero
/*
Now we loop from begin timestamp to endtimestamp incrementing the counter by a day ,
i.e 86400 in milliseconds. Timestamps are in milliseconds .Now make a check if the date itself lies in between the season range using check_in_range function.
If it lies then use SeasonRate else use Offseason rate and add it to $userTotalRate .
*/
for( $i = $startTime; $i <= $endTime; $i = $i + 86400){
if(self::check_in_range($seasonStartDate, $seasonEndDate, date('y-m-d', $i ))){
// echo $seasonStartDate. '/' . $seasonEndDate . '/' . date('y-m-d', $i );
$userTotalRate = $userTotalRate + $seasonRate;
// echo 'season\r\n';
}else{
// echo 'offseason\r\n';
$userTotalRate = $userTotalRate + $offSeasonRate;
}
}
}else {
//means that the specific months has no season period
$userTotalRate = 1;
$perNightRate = $hotel->getOffSeasonRate();
$userTotalRate = $perNightRate * $noOfnights;
}
}
return new Response($userTotalRate);
// return $this->render('checkout_page/index.html.twig', [
// 'controller_name' => 'CheckoutPageController',
// ]);
}
function check_in_range($start_date, $end_date, $date_from_user){
// Convert to timestamp
$start_ts = strtotime($start_date);
$end_ts = strtotime($end_date);
$user_ts = strtotime($date_from_user);
// Check that user date is between start & end
return (($user_ts >= $start_ts) && ($user_ts <= $end_ts));
}
}
@xProgrammer-007
Copy link
Author

This is just a practice and needs other requirements to work properly so kindly ignore if you looking for a generic algorithm . 😢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment