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');
}
Related
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');
}
I have the following tables (with only relevant fields):
devices
id
name
created_at
updated_at
device_reports
id
device_id
location
created_at
updated_at
I have a report with a number of filters on it that is already working, so I want to stick with the eloquent way of doing things. Here is Controller function:
public function devices(Request $request)
{
$devicesQuery = Device::with(['latestReport']);
if ($request->ajax())
{
if($request->input('start') && $request->input('start')!='')
{
$start_date = date('Y-m-d', strtotime($request->input('start')));
$end_date = date('Y-m-d', strtotime($request->input('end')));
$devicesQuery = $devicesQuery->lastReportBetween($start_date,$end_date);
}
$devices = $devicesQuery->paginate(10);
return Response::json(View::make('devices/table', array('devices' => $devices))->render());
}
}
The model's latestReport is defined as:
public function latestReport()
{
return $this->hasOne('App\Models\DeviceReport')->latest();
}
The model's function lastReportBetween is defined as:
public function scopeLastReportBetween($query, $start, $end)
{
$query = $query->join('device_reports AS dr', 'dr.device_id', '=', 'devices.id');
$query = $query->where('dr.id', '=', DB::raw('(SELECT max(dr2.id) FROM device_reports AS dr2 WHERE dr2.device_id = devices.id)'));
$query = $query->where(DB::raw("(IFNULL(dr.gps_time, dr.created_at))"), '>=', DB::raw("STR_TO_DATE('".$start."', '%Y-%m-%d')"));
$query = $query->where(DB::raw("(IFNULL(dr.gps_time, dr.created_at))"), '<=', DB::raw("STR_TO_DATE('".$end."', '%Y-%m-%d')"));
return $query;
}
When running the above with a start/end date selected, I get the correct records returned, but I don't get anything returned in "latestReport", but when I run the page without the date filters in place, it correctly returns the device information and the most recent report record in the latestReport class variable.
Can anyone help me understand how to change this code such that I do get the latestReport back when I also call the lastReportBetween function?
I figured out my problem. I should have been using "whereHas()" instead of manual joins and whatnot.
public function scopeLastReportBetween($query, $start, $end)
{
return $query->whereHas('latestReport', function($reportsQuery) use ($start, $end)
{
$reportsQuery->whereBetween('created_at', [$start, $end])
->where('device_reports.id', '=', DB::raw('(SELECT max(dr2.id) FROM device_reports AS dr2 WHERE dr2.device_id = device_reports.device_id)'));
});
}
im using laravel eloquent to update a record in a database table. Im passing in a parameter of 52 which is the id of the record I want to update (primary key).
I am printing the query to check which record its finding and its printing the record with the id of 13 and then when i check the table, id 13 has been updated.
protected $connection = 'sqlsrv';
protected $table = 'todo';
public $timestamps = false;
public static function complete($todoId, $userId)
{
$now = new DateTime();
$query = Self::join('todoTypes', 'todo.typeId', 'todoTypes.id')
->where('todoTypes.canComplete', 1)
->whereNull('todo.completedDate')
->find(52);
$query->where(function ($query) use ($now)
{
$query->whereNull('cancelDate')
->orWhere('cancelDate', '>', $now);
});
if ($query)
{
$query->completedDate = $now;
$query->save();
}
}
How about trying like this?
The query after using find did not make any sense since find returns the first object not a query builder instance.
public static function complete($todoId, $userId)
{
$now = new DateTime();
$object = Self::join('todoTypes', 'todo.typeId', 'todoTypes.id')
->where('todoTypes.canComplete', 1)
->whereNull('todo.completedDate')
->where(function ($query) use ($now) {
$query->whereNull('cancelDate')
->orWhere('cancelDate', '>', $now);
})->find(52);
if ($object) {
$object->completedDate = $now;
$object->save();
}
}
I have managed to fix this by just adding a select at the start
select('todo.id', 'todo.completedDate')
It seems it was getting the right row, but displaying the id as something else.
When I took out the join and the joins where clause, it worked. I suspect it was using the id of the joint row from the todoTypes table as that was 13.
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 <...>.
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');
}