%PDF- %PDF-
Direktori : /var/www/html/rental/app/Http/Controllers/ |
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); } }