Grouping data inside foreach in blade in laravel - php

I am trying to group a product name in may table. I found a suggestion to put a ->groupBy in my controller but when I am doing it my relation to other model is broken. what is the bets approach to achieve my what I want?
here's my code in my view blade.
<table class="table table-striped m-b-none" data-ride="datatables" id="table">
<thead>
<tr>
<th width="">Product Code</th>
<th width="">Product Name</th>
<th width="">In</th>
<th width="">Out</th>
<th width="">Total Stocks</th>
<th width="">Note</th>
</tr>
</thead>
<tbody>
#foreach( $warehouse1stocks as $warehouse1stock )
#php
$totalStocks = $warehouse1stock->stock_in_qty - $warehouse1stock->stock_out_qty;
$stockWarning = $warehouse1stock->product->wh1_limit_warning;
#endphp
<tr>
<td>{{$warehouse1stock->orderItem->product_code}}</td>
<td>{{$warehouse1stock->orderItem->product_name}}</td>
<td>{{$warehouse1stock->stock_in_qty}}</td>
<td>{{$warehouse1stock->stock_out_qty}}</td>
#if($totalStocks <= $stockWarning||$totalStocks==$stockWarning) <td>{{$totalStocks}} <i data-toggle="tooltip" data-placement="top" title="below stock limit, {{$stockWarning}}" class="fas fa-exclamation-circle text-danger"></i></td>
#else
<td>{{$totalStocks}}</td>
#endif
<td>{{$warehouse1stock->delivery_note}}</td>
</tr>
#endforeach
</tbody>
</table>
here's the screenshot of the view table
My index function in my controller
public function index()
{
$warehouse1stocks = Warehouse1stocks::all();
// dd($warehouse1stock->companies->comp_name);
return view('warehouse1.index', compact('warehouse1stocks', $warehouse1stocks));
}
what I'm trying to achieve is to group the product code and sum its 'in'. How
can i do that? thank you so much in advance!
UPDATE
this is additional information regarding with my inquiry.
The column product name and product code from my output table is from eloquent eloquent orderItems
class Orderitems extends Model
{
protected $table = 'order_items';
protected $fillable = [
'product_id',
'order_id',
'product_name',
'product_code',
'cost',
'rate',
'quantity',
'total_cost',
];
}
Progress Update
#apokrypus, Here's the error after applying your suggestion.
here's the updated code
$warehouse1stocks = Warehouse1stocks::select(
'order_item_id',
Warehouse1stocks::raw('SUM(stock_in_qty) as stock_in_qty'),
Warehouse1stocks::raw('SUM(stock_out_qty) as stock_out_qty')
)->groupBy('order_item_id')->get();
// dd($warehouse1stocks);
return view('warehouse1.index', compact('warehouse1stocks', $warehouse1stocks));
Here's the screenshot

Assuming you want to sum both in and out then you can do:
public function index()
{
$warehouse1stocks = Warehouse1stocks::select(
'order_item_id',
\DB::raw('SUM(stock_in_qty) as stock_in_qty'),
\DB::raw('SUM(stock_out_qty) as stock_out_qty')
)->groupBy('order_item_id')
->get()
// dd($warehouse1stock->companies->comp_name);
return view('warehouse1.index', compact('warehouse1stocks', $warehouse1stocks));
}
This should (ideally) not require you to make any view changes.
However if your delivery note is different on each row you might consider not including it in the result since you won't be able to show it when grouping multiple rows.

Related

How can I fix it to show the total number of posts by user in the result list?

As a premise, the membership bulletin board is functioning, and the total of keywords such as "delicious" and "bad" in the posted content of the logged-in user can be acquired and displayed with the following code. Would you please teach me where to modify to list the total number of keywords posted by all authenticated users?
Web.php:
Route::get('/myfood', 'HomeController#myfood')->name('home.myfood');
Route::get('/foods', 'HomeController#foods')->name('home.foods');
Controller:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\Post;
use App\Models\Comment;
use Auth;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Facades\DB;
class HomeController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function myfood()
{
$user = auth()->user()->id;
$myusers=User::where('id', $user)->get();
$PostsOisiCount = Post::where('user_id', $user)->where(function($query) {$query->where('body', 'like', '%delicious%')
->orWhere('body', 'like', '%bad%');})->count();
$PostsCount = Post::where('user_id', $user)->count();
return view('myfood', compact('user', 'myusers', 'PostsOisiCount', 'PostsCount'));
}
public function foods()
{
$users = User::all();
$PostsOisiCount = Post::where('body', 'like', '%delicious%')
->orWhere('body', 'like', '%bad%')
->count();
$PostsCount = Post::count();
return view('foods', compact('users', 'PostsOisiCount', 'PostsCount'));
}
}
myfoodBlade:
<table>
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Results</th>
</tr>
</thead>
<tbody>
#foreach($myusers as $myuser)
<tr>
<th>{{$myuser->id}}</th>
<td>{{$myuser->name}}</td>
<td>
($PostsOisiCount / $PostsCount ) * 100
</td>
</tr>
#endforeach
</tbody>
</table>
foodsBlade:
<table>
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Results</th>
</tr>
</thead>
<tbody>
#foreach($users as $user)
<tr>
<th>{{$user->id}}</th>
<td>{{$user->name}}</td>
<td>
($PostsOisiCount / $PostsCount ) * 100
</td>
</tr>
#endforeach
</tbody>
</table>
I will try to help you but first lets make your code more performant:
When you want to do a count on a Model, you don't need to do ->get()->count() as that is getting the data from the database (->get()) and that could be HUGE, even running out of memory, and then counting the array values (->count()). Instead of doing that, you can directly count on the database and the database will always do this way faster than any language. So your could would be: $total = Model::conditions()->count(), $total will directly have a positive (or 0) integer number, and that's it!
Your code should be like:
$users = User::all();
$PostsOisiCount = Post::where('user_id', $users)->where('body', 'like', '%delicious%')->orWhere('body', 'like', '%bad%')->count();
$PostsCount = Post::where('user_id', $users)->count();
Have in mind that you are not currently getting the Logged in User's data, but EVERYONE data, because you are doing User::all(), so you will get all IDs that are not soft deleted. Instead of doing that, you can still get everything by removing where('user_id', $users):
$PostsOisiCount = Post::where('body', 'like', '%delicious%')->orWhere('body', 'like', '%bad%')->count();
$PostsCount = Post::count();
To be able to just get data from authenticated Users, that is absolutely way more complex than it seems and it depends a lot on your Authentication "driver"... Where are you storing or tracking sessions? If they are logged in, what should you read? So this is very dependant on your authentication implementation.

give approve and reject function to the button and display it in user's dashboard in Laravel

I want to give function to both approve and reject button that is in admin dashboard and display the result in user's dashboard.
here is my admin view
dashboard.php.blade
<div class="card-body">
<div class="table-responsive">
<table class="table">
<thead class=" text-primary">
<th>ID</th>
<th>Name</th>
<th>Leave Type</th>
<th>Leave Start date</th>
<th>Leave End date</th>
<th>Remark</th>
<th>Approve</th>
<th>Decline</th>
</thead>
<tbody>
#foreach ($leaves as $leave)
<tr>
<td>{{$leave->id}}</td>
<td>{{$leave->applied_by->name}}</td>
<td>{{$leave->type->type}}</td>
<td>{{$leave->start}}</td>
<td>{{$leave->end}}</td>
<td>{{$leave->remarks}}</td>
<td>
Approve
</td>
<td>
Decline
AdminLeaveController.php .. Do not have any method yet
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Leave;
use App\Models\LeaveType;
use App\User;
class AdminLeave extends Controller
{
public function leaveapproval()
{
$leaves = Leave::with('type', 'applied_by')->get();
return view ('admin.dashboard',compact ('leaves'));
}
}
The easiest way to do this would be to create two new routes, one for approving, and the other one for declining.
Route::post('/approve/{id}', 'AdminLeaveController#approve')->name('admin.approve')
Route::post('/decline/{id}', 'AdminLeaveController#decline')->name('admin.decline')
Now, when you have those routes, you can add them to your buttons:
Approve //pass the id here
Decline //pass the id here as well
After that, you could add a boolean column to your leaves table, something like status, where 0 would be declined, and 1 would be approved.
All that is left to do, is to create two new methods in your AdminLeaveController:
public function approve($id){
$leave = App\Models\Leave::findOrFail($id);
$leave->status = 1; //Approved
$leave->save();
return redirect()->back(); //Redirect user somewhere
}
public function decline($id){
$leave = App\Models\Leave::findOrFail($id);
$leave->status = 0; //Declined
$leave->save();
return redirect()->back(); //Redirect user somewhere
}
Note: code is not tested, let me know if you have any errors.
You just have to pass 0 for 'Approve' and 1 for 'Decline'. In url then you need one more method in controller which change state of the column you have saved in database.
Don't forget to put csrf token.
As i am seeing this is simple thing you should try at your own also.

Laravel 6 - View the data of the comparison statement in if condition

The title might sound confusing but this what I want to achieve in displaying the data.
I have a table tbl_employee which has a supervisor_id. The structure would be
senior manager
manager
team leader
I am using this syntax
<table class="table table-bordered table-dark">
<tr>
<th>#</th>
<th>Department Name</th>
<th>Supervisor ID</th></th>
<th>Action</th>
</tr>
#foreach($getEmployee as $id => $employee)
#if(Auth::user()->id == $employee->supervisor_id)
<tr>
<td>{{++$id}}</td>
<td>{{$employee->first_name}}</td>
<td>{{$employee->supervisor_id}}</td>
</tr>
#endif
#endforeach
</table>
Controller
public function create() {
$getEmployee = EmployeeModel::all();
$getDepartment = DepartmentModel::pluck('department_name', 'id');
$getSupervisor = EmployeeModel::select
(DB::raw("CONCAT(last_name,', ',first_name,' ',middle_name,' ',COALESCE(extension_name,'')) AS full_name"),'id')
->pluck('full_name', 'id');
$getHR = EmployeeModel::select
(DB::raw("CONCAT(last_name,', ',first_name,' ',middle_name,' ',COALESCE(extension_name,'')) AS full_name"),'id')
->where('position_id', 1)
->pluck('full_name', 'id');
return view('EmployeeView.add', compact('getDepartment', 'getSupervisor', 'getHR', 'getEmployee'));
}
I logged-in a senior manager account and I was able to see managers who has a supervisor_id of the senior manager. Now I also wanted to see team leaders who has a supervisor_id of a manager under the senior manager. I am quite confused on how to do a query.

Laravel orderby with relationship

i'm trying to sort the student list by each level with using relationship method with OrderBy function but unfortunately i can't make it work any idea whats missing on my code?
Note:
every-time i remove the orderby my code will work but students level are not arrange accordingly
Controller:
$students=Student::with('level')->where(['status' => 'ENROLLED'])->get()->orderBy('level_name','asc');
View
<table>
<tr>
<th>Name</th>
<th>Level</th>
</tr>
#foreach($students as $std)
<tr>
<td>
{{$std->student_name}}
</td>
<td>
#foreach($std->level as $lv)
{{$lv->level_name}}
#endforeach
</td>
</tr>
#endforeach
</table>
You can't order by a relationship because under the hood laravel makes two seperate queries under the hood.
You can instead use a join, something like this (beware I guessed your table names, so you may have to update them).
$users = Student::join('levels', 'students.level_id', '=', 'levels.id')
->orderBy('levels. level_name', 'asc')->select('students.*')->paginate(10);
Try this:
Controller:
$students = Student::with(['level' => function (Builder $query) {
$query->orderBy('level_name', 'asc');
}])->where(['status' => 'ENROLLED'])->get();
In addition you can add orderBy() to relation method.
Student Model:
public function level()
{
return $this->relationMethod(Level::class)->orderBy('level_name', 'asc');
}
Try this
$students=Student::with('level')->where(['status' => 'ENROLLED'])->orderBy('level_name','asc')->get();

How to use pagination along with laravel eloquent find method in laravel 5.4

I am trying to implement pagination in laravel and got following error
Undefined property: Illuminate\Pagination\LengthAwarePaginator::$name
Here is my controller function
public function showTags($id)
{
$tag = Tag::find($id)->paginate(5);
// when lazy loading
$tag->load(['posts' => function ($q) {
$q->orderBy('id', 'desc');
}]);
return view('blog.showtags')->withTag($tag);
}
Here is the Tag Model
class Tag extends Model
{
public function posts()
{
return $this->belongsToMany('App\Post');
}
}
The Tag and Post model has belongsToMany Relationship so there are many posts under the specific tag and my aim is to iterate all posts under the specific tags descending order of post and also to implement pagination in that page.
Here is the code for showtags view
<table class="table">
<thead>
<tr>
<th>#</th>
<th>Title</th>
<th>Tags</th>
</tr>
</thead>
<tbody>
<?php $count = 1; ?>
#foreach($tag->posts as $post)
<tr>
<th>{{ $count++ }}</th>
<th>{{ $post->title }}</th>
<th>#foreach($post->tags as $tag)
<span class="label label-default">{{ $tag->name }}</span>
#endforeach
</th>
</tr>
#endforeach
</tbody>
</table>
//Here is the code i used for pagination in view
<div class="text-center">
{!! $tag->posts->links() !!}
</div>
If anybody know how to do this please respond. Thanks in advance.
I solve the problem by using a simple trick. My aim was to paginate all posts under the same tags just like you guys can see in StackOverflow.
The modified controller function is
public function showTags($id)
{
$tag = Tag::find($id);
// when lazy loading
$tag->load(['posts' => function ($q) {
$q->orderBy('id', 'desc')->paginate(10);
}]);
return view('blog.showtags')->withTag($tag);
}
As you guys see that I move the paginate() function from find to load function which I use before for sorting post by descending order.
Now in view instead of using traditional method {!! $tag->links() !!} for making link of pagination
I use {!! $tag->paginate(10) !!}
With this line $tag = Tag::find($id)->paginate(5); You should get only one tag(or null if tag with your id dose not exist), and after that you want paginate it. If you want paginate your tags get all tags and after that paginate it Tag::paginate(5)

Categories