Laravel eloquent where TIMESTAMP time is specific hour - laravel

I want to check after my orWhereColumn if planned_completion_date time is at 09:00. planned_completion_date is of timestamp datatype. How can I check this? This is how my query looks like:
$portings = Porting::with('items')
->where('status', AbstractPorting::STATUS_ACCEPTED)
->where(function ($q) {
$q->where('planned_completion_date', '<=', date("Y-m-d H:i:s", time()));
$q->orWhereColumn('planned_completion_date', '<', 'first_possible_date');
})->get();

You can try this :
$portings = Porting::with('items')
->where('status', AbstractPorting::STATUS_ACCEPTED)
->where(function ($q) {
$q->where('planned_completion_date', '<=', date("Y-m-d H:i:s", time()));
$q->orWhereColumn('planned_completion_date', '<', 'first_possible_date');
$q->where(DB::raw("DATE_FORMAT(planned_completion_date, '%H:%i')"), '=', '09:00');
})->get();

Related

Custom validation rule , check if date range is already taken or not

I have to manage the reservation for the rental of a house, when I make a new reservation the start date and the end date should be free.
For example, if I make a reservation for a client from September 23 to September 28, I cannot create another reservation over this date.
I would need an eloquent query that could check that started_at and ends_at (of the form) are not included between the already existing dates
I think I found a solution :
$bookings = DB::table('bookings')
->where(function ($q) use ($start, $end) {
$q->where('started_at', '>=', $start)
->where('started_at', '<=', $end);
})
->orWhere(function ($q) use ($start, $end) {
$q->where('ends_at', '>=', $start)
->where('ends_at', '<=', $end);
})
->orWhere(function ($q) use ($start, $end) {
$q->where('started_at', '<', $start)
->where('ends_at', '>', $end);
})
->count();

How to optimize this eloquent query? (check that a date range is not already taken)

Here is my Eloquent query, which allows to check if a date is already occupied or not, according to a "started_at" and an "ends_at".
$bookings = Booking::where(function ($q) use ($start, $end) {
$q->orWhere('started_at', '>=', $start)
->where('started_at', '<=', $end)
->where('status', '!==', Booking::STATUS_CANCELED);
})
->orWhere(function ($q) use ($start, $end) {
$q->where('ends_at', '>=', $start)
->where('ends_at', '<=', $end)
->where('status', '!==', Booking::STATUS_CANCELED);
})
->orWhere(function ($q) use ($start, $end) {
$q->where('started_at', '<', $start)
->where('ends_at', '>', $end)
->where('status', '!==', Booking::STATUS_CANCELED);
})->get();
The query works, but I think it's a bit long, it can probably be shortened.
Especially for the where that checks that the status is not "cancelled".
Thanks in advance
your query could look like that :
$bookings = Booking::where('status', '!==', Booking::STATUS_CANCELED)
->where(function ($q) use ($start, $end) {
$q->where('started_at', '<=', $end)
->orWhere('started_at', '>=', $start);
})
->orWhere(function ($q) use ($start, $end) {
$q->where('ends_at', '>=', $start)
->where('ends_at', '<=', $end);
})->orWhere(function ($q) use ($start, $end) {
$q->where('started_at', '<', $start)
->where('ends_at', '>', $end);
})->get();
Haven't tested this out, but something like this should work:
$bookings = Booking::where('status', '!=', Booking::STATUS_CANCELED)
->where(function ($query) use ($start, $end) {
$query->whereBetween('started_at', [$start, $end])
->orWhereBetween('ends_at', [$start, $end])
->orWhere(function ($query) use ($start, $end) {
$query->where('started_at', '<', $start)
->where('ends_at', '>', $end);
});
});

How I can ignore current row id one time only

I have custom query where ignored current row id:
$relatedVacancies = \App\Vacancy::whereHas('skills', function ($q) use ($vacancy) {
return $q->whereIn('skill_id', $vacancy->skills->pluck('skill_id'));
})->where('id', '!=', $vacancy->id)
->orWhere('employment', $vacancy->employment)->where('id', '!=', $vacancy->id)
->orWhere('title', 'like', '%'.$vacancy->title.'%')->where('id', '!=', $vacancy->id)
->get();
How I can use this condition one time only:
->where('id', '!=', $vacancy->id)
If you are trying to select based on three conditions:
->where([
('id', '!=', $vacancy->id),
('employment', '=', $vacancy->employment),
('title', 'like', '%'.$vacancy->title.'%'),
])->get();
Try this (based on https://laravel.com/docs/5.7/queries#parameter-grouping):
$relatedVacancies = \App\Vacancy::where('id', '!=', $vacancy->id)
->whereHas('skills', function ($q) use ($vacancy) {
return $q->whereIn('skill_id', $vacancy->skills->pluck('skill_id'));
})
->where(function ($query) {
$query->where('employment', $vacancy->employment)
->orWhere('title', 'like', '%'.$vacancy->title.'%');
})
->get();
Also check for this answer: https://stackoverflow.com/a/23009807/5458355

Why won't my Laravel collection filter correctly by date?

I have
$dt = Carbon::now();
$b4 = Carbon::now()->addWeeks(12);
Event::orderBy('date', 'desc')
->where('date', '<', $b4)
->where('ends', '>=', $dt)
->orWhere('date', '>=', $dt)
->take(3)
->get();
All filters work except the first where. I tried it following the orWhere first, no dice. It displays items with the date in August 2018. Help?
I think you need to group your where queries ie.
$dt = Carbon::now();
$b4 = Carbon::now()->addWeeks(12);
Event::orderBy('date', 'desc')
->where(function ($query) use ($dt, $b4) {
$query->where('date', '<', $b4->format('Y-m-d'))
->where('ends', '>=', $dt->format('Y-m-d'));
})
->orWhere('date', '>=', $dt->format('Y-m-d'))
->take(3)
->get();
https://laravel.com/docs/5.5/queries#parameter-grouping

Laravel 4 advanced wheres

I have my query working perfectly in mySQL, however am struggling to use the advanced wheres inside the laravel query builder.
Can anyone assist in converting this at all?
So far I have:
LARAVEL
$start_request = '2014-12-18 09:00';
$end_request = '2014-12-18 10:00';
$events= DB::table('events')
->where('hotel_id', 4)
->orWhere(function($query)
{
$query->where($start_request, '<=', 'start_time')
->where($end_request, '>', 'start_time');
})
->orWhere(function($query)
{
$query->where($start_request, '>=', 'start_time')
->where($end_request, '<', 'end_time');
})
->get();
mySQL
SELECT id, title, description, start_time, end_time FROM events where hotel_id = 4 and (('2014-12-18 09:00' <= start_time and '2014-12-18 10:00' > start_time)
or ('2014-12-18 09:00' >= start_time and '2014-12-18 10:00' < end_time));
Can you try this?
$start_request = '2014-12-18 09:00';
$end_request = '2014-12-18 10:00';
$events= DB::table('events')
->where('hotel_id', 4)
->where(function($query) use($start_request, $end_request) {
$query->where(function($subquery) use($start_request, $end_request){
$subquery->where('start_time', '>=', $start_request)
->where('start_time', '<', $end_request);
});
$query->orWhere(function($subquery1) use($start_request, $end_request) {
$subquery1->where('start_time', '<=', $start_request)
->where('end_time', '>', $end_request);
});
})
->get();
Something like this should do the job:
$start_request = '2014-12-18 09:00';
$end_request = '2014-12-18 10:00';
$events = DB::table('events')
->where('hotel_id', 4)
->where(function ($q) use ($start_request, $end_request) {
$q->where(function ($query) use ($start_request, $end_request) {
$query->where($start_request, '<=', 'start_time')
->where($end_request, '>', 'start_time');
})
->orWhere(function ($query) use ($start_request, $end_request) {
$query->where($start_request, '>=', 'start_time')
->where($end_request, '<', 'end_time');
});
})
->select('id', 'title', 'description', 'start_time', 'end_time')
->get();

Resources