Laravel Multiple Count in 1 Query and display it on my views using #foreach? - laravel-4

Sorry im new to this framework, Im planning to improve my code it is hassle to declare tons of variable just to get the count of the values. help me guys see my code.
$broken = LiipRepairMaintenanceItem::join('liip_psrm_components', 'liip_psrm_components.psrm_components_id', '=', 'liip_psrm_items.id')
->where('liip_psrm_items.psrm_items_id', '=', $psrm_maintenance->id)
->whereIn('liip_psrm_components.problem_code', [1])
->count();
$broken_negligence = LiipRepairMaintenanceItem::join('liip_psrm_components', 'liip_psrm_components.psrm_components_id', '=', 'liip_psrm_items.id')
->where('liip_psrm_items.psrm_items_id', '=', $psrm_maintenance->id)
->whereIn('liip_psrm_components.problem_code', [2])
->count();
$drop = LiipRepairMaintenanceItem::join('liip_psrm_components', 'liip_psrm_components.psrm_components_id', '=', 'liip_psrm_items.id')
->where('liip_psrm_items.psrm_items_id', '=', $psrm_maintenance->id)
->whereIn('liip_psrm_components.problem_code', [3])
->count();
$sliced_by_Forklift = LiipRepairMaintenanceItem::join('liip_psrm_components', 'liip_psrm_components.psrm_components_id', '=', 'liip_psrm_items.id')
->where('liip_psrm_items.psrm_items_id', '=', $psrm_maintenance->id)
->whereIn('liip_psrm_components.problem_code', [4])
->count();
switch ($status) {
case 'getApprove':
// Title
$title = Lang::get('liipPsrmMaintenance::repairMaintenance/title.repair_maintenance_approve');
//Show the page
return View::make('liipPsrmMaintenance::view.approve', compact('broken', 'broken_negligence', 'drop', 'sliced_by_Forklift '));
break;
}
views
<div class="col-md-4">
<form role="form">
<!-- Broken/Cracked -->
<div class="form-group">
<label>B -Broken/Cracked</label>
<p class="form-control-static">{{{ $broken }}}</p>
</div>
<!-- ./ Broken/Cracked -->
<!-- Broken/Cracked -->
<div class="form-group">
<label>B -Broken/Cracked due to negligence</label>
<p class="form-control-static">{{{ $broken_negligence }}}</p>
</div>
<!-- ./ Broken/Cracked -->
<!-- Dry rot -->
<div class="form-group">
<label>DR -Dry rot</label>
<p class="form-control-static">{{{ $sliced_by_Forklift }}}</p>
</div>
<!-- ./ Dry rot -->
<!-- dropped -->
<div class="form-group">
<label>D -dropped</label>
<p class="form-control-static">{{{ $drop }}}</p>
</div>
<!-- ./ dropped -->
</form>
</div>
is it possible to compress it in 1 query for more proccessing speed then i will call it on my views using #foreach($broken->broken_negligence as $broken). im suffering from slow code proccessing because of this, help me guys. Thank you

You may use a single query with conditional aggregation:
$result = LiipRepairMaintenanceItem::join('liip_psrm_components', 'liip_psrm_components.psrm_components_id', '=', 'liip_psrm_items.id')
->select(DB::raw("COUNT(CASE WHEN liip_psrm_components.problem_code IN (".[1]." THEN 1 END) AS broken" .
"COUNT(CASE WHEN liip_psrm_components.problem_code IN (".[2]." THEN 1 END) AS broken_negligence" .
"COUNT(CASE WHEN liip_psrm_components.problem_code IN (".[3]." THEN 1 END) AS drop" .
"COUNT(CASE WHEN liip_psrm_components.problem_code IN (".[4]." THEN 1 END) AS sliced_by_Forklift"))
->where('liip_psrm_items.psrm_items_id', '=', $psrm_maintenance->id);
Note that the above code might be vulnerable to SQL injection, if the arrays ([1], [2], etc.) are not sterilized.
This answer corresponds to the following raw MySQL query:
SELECT
COUNT(CASE WHEN t2.problem_code IN [1] THEN 1 END) AS broken,
COUNT(CASE WHEN t2.problem_code IN [2] THEN 1 END) AS broken_negligence,
COUNT(CASE WHEN t2.problem_code IN [3] THEN 1 END) AS drop,
COUNT(CASE WHEN t2.problem_code IN [4] THEN 1 END) AS sliced_by_Forklift
FROM liip_psrm_items t1
INNER JOIN liip_psrm_components t2
ON t1.id = t2.psrm_components_id
WHERE
t1.psrm_items_id = <some value>;

Related

Laravel - How to only enable Add Button based on condition

I have a Laravel-8 project with this model:
protected $fillable = [
'id',
'employee_id',
'leave_status',
'commencement_date',
'resumption_date',
'created_at'
];
protected $dates = [
'commencement_date',
'resumption_date',
'created_at',
'updated_at',
];
View:
<div class="panel-heading clearfix">
<div class="container-fluid">
#if ($currentstatus)
<div style="margin-bottom: 10px;" class="row">
<div class="col-lg-12">
<a class="btn btn-info" href="{{ route(" service.leave_requests.create ") }}">
Add
</a>
</div>
</div>
#endif
</div>
</div>
I want the Add button to only be visible when:
leave_status is 0 for the last record (order by created_at)
or
leave_status is 4 and resumption_date is greater than or equal to today's date (order by created_at) for the last record.
or
leave_status is 3 (order by created_at) for the last record.
I tried the code below, but it's not working.
$userID = Auth::user()->id;
$currentstatus = HrLeaveRequest::select('leave_status')->where('employee_id', $userID)->whereIn('leave_status', [0, 3, 4])->orderBy('created_at', 'DESC')->first();
Note: If the last record is previous year, it should automatically make the button visible. But for the current year, it should apply any of the conditions for the rules.
How do I achieve this?
Thanks
Try this:
// This gets last requests this year
$request = HrLeaveRequest::whereEmployeeId($userID)->whereYear('created_at', date('Y'))->whereIn('leave_status', [0,3,4])->latest()->first();
// OR you might remove the whereYear query to check with conditions
If(date('Y', strtotime($request->created_at)) < date('Y')) {
// This checks if the year is the previous year
}
$currentstatus = HrLeaveRequest::where(['employee_id', '==' $userID], ['resumption_date', '>=', date('d-m-Y')])->whereIn('leave_status', [0, 3, 4])->latest()->first();

Laravel soft delete: model::onlyTrashed() returns all

When I try to view only soft deleted records in Laravel the onlyTrashed returns all records.
As you will see I also have a searchform which complifies things a bit. And I think the searchform is the reason this doesn't work but I don't understand why excactly.
Controller:
public function toTrashbin(Request $request) {
$search = '%' . $request->input('search') . '%';
$students = Student::onlyTrashed()
->where('first_name', 'like', $search)
->orWhere('last_name', 'like', $search)
->orWhere('rnumber', 'like', $search)
->paginate(15)
->appends(['search'=> $request->input('search')]);
return view('admin.students.students_trashbin')->with('students', $students);;
}
View:
{{--searchform--}}
<form method="get" action="/students/trashbin" id="searchForm">
<div class="row">
<div class="col-sm-6 mb-2">
<input type="text" class="form-control" name="search" id="search"
value="{{request()->search}}" placeholder="Search by name or R-number">
</div>
<div class="col-sm-2 mb-2">
<button type="submit" class="btn btn-success btn-block">Search</button>
</div>
</div>
</form>
<hr>
#if (count($students) > 0)
{{--table--}}
<table class="table">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">R-number</th>
<th scope="col">Deleted at</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
#foreach ($students as $student)
<tr>
<td>{{$student->first_name}} {{$student->last_name}}</td>
<td>{{$student->rnumber}}</td>
<td>{{$student->deleted_at}}</td>
<td>
restore
</td>
</tr>
#endforeach
</tbody>
</table>
{{$students->links()}} {{--pagination--}}
#else
<p>No students found using your searchquery.</p>
#endif
Somehow the view displays all students, both soft deleted and not soft deleted ones.
However: It works perfectly if I remove the 3 "where"s in the controller. But then I can't use search obviously. Does anyone know how I can make this work with search?
Thanks.
Fixed it by changing the controller to this:
public function toTrashbin(Request $request) {
$search = '%' . $request->input('search') . '%';
$conditions = [
['first_name', 'like', $search, 'or'],
['last_name', 'like', $search, 'or'],
['rnumber', 'like', $search, 'or'],
];
$students = Student::onlyTrashed()
->where($conditions)
->paginate(15)
->appends(['search'=> $request->input('search')]);
return view('admin.students.students_trashbin')->with('students', $students);;
}
Honestly still not sure what was wrong with my original controller so if anyone knows the cause, please let me know. But hey, at least I got it to work.
On your first try, Laravel did something like this:
select * from `students` where `students`.`deletedAt` is not null and `last_name` like 'test' or `last_name` like 'test';
On your second approach, the query was mounted like this:
select * from `students` where `students`.`deletedAt` is not null and (`last_name` like 'test' or `last_name` like 'test');
Be extra careful when using "OR" on SQL because it can mess up your results and "ignore" some conditions.
You can control your parentheses doing somethin like this:
$search = '%' . $request->input('search') . '%';
$query = Student::onlyTrashed();
$query->where('votes', '>', 100)
->orWhere(function($query) use ($search) {
$query->where('name', $search)
->where('votes', '>', 50);
});
$query->paginate(15);
Extra information on Closures here: https://laravel.com/docs/7.x/queries#where-clauses
Have a good day!

Result will display two times in blade file in laravel 5.7

I am creating task in which i want to display notification based on notification_status & order_status .
From controller only three record is obtained but in blade file the loop repeat, two record two times.
As expected output, i want to display only first three record but it repeat again second & third record. How can remove this confusion?
controller:
public function get_notification()
{
$userId=Session::get('userid');
$data = DB::select('Select orders.product_id,subcategory.image,GROUP_CONCAT(subcategory.name_of_subcategory) as subcategory,orders.grand_total,orders.deliver_date,orders.order_status,orders.notification_status,orders.orders_id,orders.payment_status,orders.orders_date from orders inner join product_details on FIND_IN_SET(product_details.product_id,orders.product_id) > 0 inner join subcategory on product_details.sub_id=subcategory.sub_id where orders.user_id=? GROUP BY orders.product_id,orders.deliver_date,orders.order_status,orders.orders_id,orders.notification_status,orders.orders_date,orders.payment_status,orders.orders_subtotal,subcategory.image,orders.grand_total',[$userId]);
return view('notification')->with('data',$data);
}
blade:
#foreach($data as $notification)
<div class="card-body noti-card" id="noti-card">
<div class="row mt-2">
<div class="col-sm-2">
<div>
<span><img src="{{asset('images/subcategory/'.$notification->image)}}" class="img-fluid" height="100" width="100"></span><br>
</div>
</div>
<div class="col-sm-8">
<div>
<span>
<?php
if($notification->notification_status == 1 && $notification->order_status ==1){
echo "<b>Order Placed</b><br>";
echo "Your order for ".$notification->subcategory." with order ID ODI".$notification->orders_id." amounting to Rs.".$notification->grand_total." has been received.";
}
if($notification->notification_status == 2 && $notification->order_status == 2)
{
echo "<b>Order Cancelled</b><br>";
echo "Your order for".$notification->subcategory." with order ID ODI".$notification->orders_id." is successfully cancelled.";
}
if($notification->notification_status == 3 && $notification->order_status == 3)
{
echo "<b>Product Packed</b><br>";
echo "Your package containing ".$notification->subcategory." has been packed by seller and will be shipped soon.";
}
if($notification->notification_status == 4 && $notification->order_status == 4)
{
echo "<b>Product Shipped</b><br>";
echo "Your package containing ".$notification->subcategory." has been shipped by seller and will be delivered soon.";
}
if($notification->notification_status == 5 && $notification->order_status == 5){
echo "<b>Out for Delivery</b><br>";
echo "Your package containing ".$notification->subcategory." from Aarch Ayurved will be delivered today";
}
if($notification->notification_status == 6 && $notification->order_status == 6){
echo "<b>Product Delivered</b><br>";
echo "Your package containing ".$notification->subcategory." has been delivered. Thanks for shopping!";
}
?>
</span>
</div>
<div>
<span class="noti-date"><?php
$timestamp = strtotime("$notification->orders_date");
$formattedDate = date('F d, Y', $timestamp);
echo $formattedDate;
?></span>
</div>
</div>
</div>
</div>
#endforeach
</div>
</div>
</div>
</div>
#endsection
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
<script type="text/javascript">
function loadlink(){
$('#noti-card').load('/notification #noti-card');
console.log('TESTING!!!!');
}
loadlink();
setInterval(function(){
loadlink()
}, 1000);
</script>
output:
The duplication is most likely coming from the query. Can youuse the Laravel helper methods dump() or dd() the results right after running the query to confirm? e.g. dd($data) immediately after the query would allow you to see the results the query returns and verify if they match expectations or not.
I believe the issue might be in the join to product_details. What is the intent of using FIND_IN_SET()?
The query would be much easier to read and understand if it where broken onto multiple lines. It might be easier to troubleshoot if you switch to using query builder, which would look something like this:
$data = DB::table('orders')
->select([
'orders.deliver_date',
'orders.grand_total',
'orders.notification_status',
'orders.order_status',
'orders.orders_date',
'orders.orders_date',
'orders.orders_id',
'orders.payment_status',
'orders.product_id',
'subcategory.image',
DB::raw('GROUP_CONCAT(subcategory.name_of_subcategory) as subcategory'),
])
->join('product_details', 'orders.product_id', '=', 'product_details.product_id')
->join('subcategory', 'product_details.sub_id', '=', 'subcategory.sub_id')
->where('orders.user_id', '=', $userId)
->groupBy(
'orders.product_id',
'orders.deliver_date',
'orders.order_status',
'orders.orders_id',
'orders.notification_status',
'orders.orders_date',
'orders.payment_status',
'orders.orders_subtotal',
'subcategory.image',
'orders.grand_total'
)
->get();

Laravel: Filtering results based on input from multiple checkboxes

Struggling to figure out how to filter data in view using checkboxes. If only one location is selected, then it's straightforward. But what if multiple locations are selected? Is this a #foreach?
My view
<form method="post" action="filter">
{{ csrf_field() }}
<input type="checkbox" name="locationfilter[]" value="Chicago">Chicago</label>
<input type="checkbox" name="locationfilter[]" value="New York">New York</label>
<button type="submit" class="btn btn-primary"> Submit </button>
My controller
$lofilter = implode(", ", $request->get('locationfilter'));
$mypostings = Postings::where('location', 'LIKE', '%'. $lofilter .'%')->get();
You can use whereIn() function to get values from given array,
users = DB::table('users')->whereIn('id', [1, 2, 3])->get();
if you want to use LIKE operator try like this,
$checkbox = []; //assume this array as selected checkboxes
DB::query()
->Where(function ($query) use($checkbox) {
for ($i = 0; $i < count($checkbox ); $i++){
$query->orwhere('location', 'like', '%' . $checkbox [$i] .'%');
}
})->get();

Laravel 4 search - in view, show value submitted in form

Below is the beginnings of filter form I have built. It works ok but what I'd like to do is retrieve in my view, the values entered for. So, in this example I'd like to display "you searched by 'the keyword user entered'", and also display this within the keyword text field. This will be the same principle when I add select lists.
If the user wishes to change filter settings, or paginate through the results, the values are always stored.
My question is how to do this. I'm quite sure it's possible in laravel but only know how to do this in PHP
FORM
<div class="row">
{{ Form::open(array('url'=>'events/search', 'class'=>'form-search', 'role'=>'form')) }}
<div class="col-lg-6">
<div class="input-group">
{{ Form::text('search', '', array('class'=>'form-control', 'placeholder'=>'Search by keyword.'))}}
<span class="input-group-btn">
{{ Form::submit('Search', array('class'=>'btn btn-default'))}}
</span>
</div>
</div>
{{ Form::close() }}
</div>
SEARCH CONTROLLER
public function postSearch() {
$search = Input::get('search');
$events = DB::table('events')
->where(function($query) use ($search)
{
$query->where('title', 'LIKE', '%' . $search . '%')
->where('date','>=', DB::raw('CURDATE()'));
})
->orderBy('date', 'DESC')
->get();
$this->layout->content = View::make('events.results',
array(
'events' => $events
)
);
}
VIEW
#foreach($events as $event)
<div class="col-md-9">You search for ''</div>
{{-- filter form will again display here --}}
<h2>{{ HTML::link("events/$event->id/", "$event->title") }}</h2>
#endforeach
Controller:
public function postSearch() {
$search = Input::get('search');
$events = DB::table('events')
->where(function($query) use ($search)
{
$query->where('title', 'LIKE', '%' . $search . '%')
->where('date','>=', DB::raw('CURDATE()'));
})
->orderBy('date', 'DESC')
->get();
$this->layout->content = View::make('events.results',
array(
'events' => $events,
'search' => $search <-------- pass the search parameter to view
)
);
}
View:
#if(!empty($search))
<div class="col-md-9">You search for {{$search}}</div>
#endif
#foreach($events as $event)
{{-- filter form will again display here --}}
<h2>{{ HTML::link("events/$event->id/", "$event->title") }}</h2>
#endforeach
Two issues:
Generally search forms are GET and not POST. (easier to bookmark, give the links elsewhere)
put the search term outside the loop.

Resources