Laravel : how to avoid time overlapping? - php

I have building a laravel controller where I'm trying to avoid time overlapping. But I'm facing problem with my query as I couldn't run the query properly in my controller:
public function postAllocateRoom(Request $request)
{
$classRoom = new ClassRoom();
$classRoom->department_id=$request->Input(['department_id']);
$classRoom->room_id=$request->Input(['room_id']);
$classRoom->course_id=$request->Input(['course_id']);
$classRoom->day_id=$request->Input(['day_id']);
$classRoom->start=Carbon::parse(str_replace(array('am', 'pm'), ':00', $request->input('start')));
$classRoom->end=Carbon::parse(str_replace(array('am', 'pm'), ':00', $request->input('end')));
$day = $classRoom->day_id;
$startTime=$classRoom->start;
$endTime=$classRoom->end;
$result=DB::select( DB::raw("SELECT * FROM `allocate_rooms`
WHERE start='$startTime' AND end='$endTime' AND day_id='day'"));
if (sizeof($result)>0) {
flash()->error('Class Room Already Taken.');
return redirect('allocateRoomPage');
}
else {
$classRoom->save();
flash()->success('Successfully allocated room.');
return redirect('allocateRoomPage');
}
}
Here in my controller's query first I will check whether the day_id has given as input is match with database with that day_id and then it will check with the time, if it matches the result will be more than one, so it can't let user to save the input otherwise if the query failed, it will let user to save the data.
I'm facing problem with the query. If any one help to find out the solution.

First of all, I suggest you to perform some validations on your inputs before creating the model instance.
Then, I don't understand why you sometimes use $request->Input(['input_name']) and sometimes $request->input('input_name'), it's better to use the second syntax.
I edited your code, please test it, it should work.
public function postAllocateRoom(Request $request)
{
// SOME VALIDATION HERE BEFORE GO ON, PLEASE
$startTime = Carbon::parse(str_replace(array('am', 'pm'), ':00', $request->input('start')));
$endTime = Carbon::parse(str_replace(array('am', 'pm'), ':00', $request->input('end')));
$dayId = $request->input('day_id');
$timeExists = AllocateRooms::where('day_id', $dayId)
->where('start', $startTime)
->where('end', $endTime)
->exists(); //use allocate_rooms table model (I don't know if it is ClassRomm)
if($timeExists){
reuturn redirect('allocateRoomPage')->withErrors(['time' => 'Class Room Already Taken']);
}
$classRoom = new ClassRoom();
$classRoom->department_id=$request->input('department_id');
$classRoom->room_id=$request->input('room_id');
$classRoom->course_id=$request->input('course_id');
$classRoom->day_id=$dayId;
$classRoom->start=$startTime;
$classRoom->end=$endTime;
$classRoom->save();
$request->session()->flash('success', 'Successfully allocated room');
return redirect('allocateRoomPage');
}

Related

I need to show all user's data with how many days ago they inserted it into the database?

I am trying to get a Date Count using Carbon. Like 20 days ago created.
I want to send data in JSON format API.
I want to send it from the controller. Here is my Controller Code.
use Carbon\Carbon;
public function index()
{
$now = Carbon::now();
$users = User::all('first_name', 'last_name', 'profile_img', 'created_at');
$date = $users->created_at->diffInDays($now);
return response()->json(['data' => $users , 'date' => $date]);
}
But I get the error from the postman
Without the Date count, I can get all data without any error. So My problem is in here just. Please inform me where is I am wrong. Thank You
first of all, you're trying to get data from a collection of objects. it might be pluck or you may use a for each loop here to modify your data. like as -
$date = array();
foreach($users as $user){
$date[] = $user->created_at->diffInDays($now); // or $user->created_at->diffForHumans();
}
for API you may use resource or Laravel Repository Pattern.
I have done it using model accessor laravel. In User Model I am creating a function
public function getCreatedAtAttribute($created_at)
{
return Carbon::parse($created_at)->diffInDays(now());
}
and In Controller, I have used this code.
public function index()
{
$users = User::all('first_name', 'last_name', 'profile_img', 'created_at');
return response()->json(['data' => $users], 200);
}
And now IT sends a fine result
Thank's all.
you can also format date in different format like this via model accessor
protected function serializeDate(DateTimeInterface $date)
{
return $date->format('Y-m-d H:i:s');
}

Improve performance of multiple row insertions in Laravel

I have a controller API method where I insert many rows (around 4000 - 8000), before inserting a new row I also check if a venue with the same ame was added already in the zone sothat's another Elouent call, my issue is I usually get timeout errors becuase the row inserting takes too much, I use set_time_limit(0) but this seems too hacky.
I think the key is the validation check I do before inserting a new row.
//Check if there is a venue with same name and in the same zone already added
$alreadyAdded = Venue::where('name', $venue['name'])->whereHas('address', function ($query) use ($address){
$query->where('provinceOrState' , $address['provinceOrState']);
})->orWhere('venueId',$venue['venueId'])->first();
Is there a way I can improve the performance of this method ? This is my complete method call:
public function uploadIntoDatabase(Request $request)
{
set_time_limit(0);
$count = 0;
foreach($request->input('venuesToUpload') as $index => $venue)
{
//Check if there is a venue with same name and in the same zone already added
$alreadyAdded = Venue::where('name', $venue['name'])->whereHas('address', function ($query) use ($address){
$query->where('provinceOrState' , $address['provinceOrState']);
})->orWhere('venueId',$venue['venueId'])->first();
if(!$alreadyAdded)
{
$newVenue = new Venue();
$newVenue->name = $venue['name'];
$newVenue->save();
$count++;
}
}
return response()->json([
'message' => $count.' new venues uploaded to database',
]);
}
use only one request to add the venues
$newVenues = [];
$count = 0;
foreach($request->input('venuesToUpload') as $index => $venue) {
//Check if there is a venue with same name and in the same zone already added
$alreadyAdded = Venue::where('name', $venue['name'])->whereHas('address', function ($query) use ($address){
$query->where('provinceOrState' , $address['provinceOrState']);
})->orWhere('venueId',$venue['venueId'])->count();
if(!$alreadyAdded) {
$newVenues [] = ['name' => $venur['name'];
}
}
if ($newVenues) {
$count = count($newVenues);
Venue::insert($newVenues);
}
As for the verification part, change the first to count cause you dont need to recover the data, just the information that it exists. And since you're verifying with both name and id, you can do some custom query that verifies all values in one query using a static table made from the request inputs and joining on the existing venues table where venues.id = null.

Laravel - Call to a member function provides_service() on null

I have the following error in my code which I'm having trouble figuring out. I would appreciate if anyone could help. What I am trying to do is add validation to the working hours that have been input by an employee. In my create appointment form I have input the following details;
however the following error is returned;
Call to a member function provides_service() on null
in AppointmentsController.php (line 63)
I'm not sure why this is occurring as the data exists in my db;
AppointmentsController - store method
public function store(StoreAppointmentsRequest $request)
$employee = \App\Employee::find($request->employee_id);
$working_hours = \App\WorkingHour::where('employee_id', $request->employee_id)->whereDay('date', '=', date("d", strtotime($request->date)))->whereTime('start_time', '<=', date("H:i", strtotime("".$request->starting_hour.":".$request->starting_minute.":00")))->whereTime('finish_time', '>=', date("H:i", strtotime("".$request->finish_hour.":".$request->finish_minute.":00")))->get();
if($employee->provides_service($request->service_id))
return redirect()->back()->withErrors("This employee doesn't provide your selected service")->withInput();
if($working_hours->isEmpty())
return redirect()->back()->withErrors("This employee isn't working at your selected time")->withInput();
$appointment = new Appointment;
$appointment->client_id = $request->client_id;
$appointment->employee_id = $request->employee_id;
$appointment->start_time = "".$request->date." ".$request->starting_hour .":".$request->starting_minute.":00";
$appointment->finish_time = "".$request->date." ".$request->finish_hour .":".$request->finish_minute.":00";
$appointment->comments = $request->comments;
$appointment->save();
return redirect()->route('admin.appointments.index');
}

If to compare two dates using Carbon on Laravel, a date from a table and a now() instance

I'm trying to display some items from a table and I'm ordering by the time they begin, I only want to show the next three items starting from now(). Here is my controller function:
Probably the whole thing is completely wrong, but still, any help will be greatly appreciated.
public function next(Request $request)
{
$eventos = Event::orderBy('start','asc');
$eventTime = Carbon::createFromDate($eventos->start);
$mytime = Carbon::now();
if($eventTime > $mytime){
$eventos = paginate(3);
return view('evento.next',compact('eventos'));
}
}
public function next(Request $request)
{
$eventos=Event::where('start','>=',Carbon::now()) // select all recodrs where start Time more than now date
->orderBy('start','asc') // order all records by asc
->take(3) // take first 3 record
->get(); // now get the result
return view('evento.next',compact('eventos'));
}

Laravel Query: BadMethodCallException in Builder.php line 2258:

I have building a laravel application where in a controller I'm checking with time overlapping problem.
The Logic I have used is in my controller's query first I will check whether the day_id has given as input is match with database with that day_id and then it will check with the time, if it matches so it can't let user to save the input otherwise if the query failed, it will let user to save the data.
public function postAllocateRoom(Request $request)
{
$startTime = Carbon::parse(str_replace(array('am', 'pm'), ':00', $request->input('start')));
$endTime = Carbon::parse(str_replace(array('am', 'pm'), ':00', $request->input('end')));
$dayId = $request->input('day_id');
$timeExists = ClassRoom::where('day_id', $dayId)
->andWhere('start', $startTime)
->andWhere('end', $endTime)
->exists();
if($timeExists){
return redirect('allocateRoomPage')->withErrors(['time' => 'Class Room Already Taken']);
}
$classRoom = new ClassRoom();
$classRoom->department_id=$request->input('department_id');
$classRoom->room_id=$request->input('room_id');
$classRoom->course_id=$request->input('course_id');
$classRoom->day_id=$dayId;
$classRoom->start=$startTime;
$classRoom->end=$endTime;
$classRoom->save();
$request->session()->flash('success', 'Successfully allocated room');
return redirect('allocateRoomPage');
}
But After I run the program I'm seeing the following Error:
BadMethodCallException in Builder.php line 2258: Call to undefined
method Illuminate\Database\Query\Builder::andWhere()
If anyone find the problem please help me to find the solution.
Simply use
$timeExists = ClassRoom::where('day_id', $dayId)
->Where('start', $startTime)
->Where('end', $endTime)
->exists();
as there is no andWhere method in laravel
There is no andWhere method.
Simple where(<...>)->where(<...>) acts like where <...> and where <...>.

Categories