Laravel groupBy multiple relations - laravel

i have the follow relations
Order -> orderItems (hasnmany)-> product (hasOne) -> product_category (hasOne)
I would like get all orders groupBy category product id. But i need help because my query is not working well.
My query:
$items = Order::orderBy("id", "desc")
->with("orderItems.product.product_category")
->get();
$groupByCategory = $items
->groupBy("orderItems.product.product_category.id");
Can you help me please?

You are not starting from the right Object.
Dealing with Eloquent, always start as you want your tree to look like ;
in your case :
Category->product->order, so your query would look like this :
$categories = Category::with([
'products.orderItems' => function($query){
$query->orderBy('id', 'desc');
}])->get();
Then :
foreach($categories as $category){
// $category->name
foreach($category->products as $product){
// $product->name
foreach($product->orderItems as $item){
// $item->name
}
}
}

Related

How many products do I have Laravel

I have a table whit some products and I try to do that if I add more products than I have in my inventory it has to show me an alert.
I did it but its not working, In products i have the sku and reference.In inventories i have all the products that i have.
Controller:
foreach ($request->dataTable as $dataTable) {
$productId = DB::table('products')
->where('sku', $dataTable[2])
->whereNull('deleted_at')
->select('id', 'reference')
->first();
$inventoryId = DB::table('inventories')
->where('product_id', $productId->id)
->whereNull('deleted_at')
->whereNull('sale_id')
->select('id')
->first();
if ($inventoryId == null) {
return response()->json([
'type' => 'error',
'msg' => 'No existe suficiente stock para realizar la venta del producto con referencia: ' . $productId->reference . '. Solo hay ' . $productId->references->count(),
]);
}
}
Product Model:
public function references()
{
return $this->hasOne('App\Models\Inventory');
}
Products
id
reference
sku
1
BCR2214
0108888893016580
2
BCR2219
0108888893016580
Inventories
ID
product_id
1
1
2
1
3
2
If I add a product_id = 1 three times it has to show me the alert and says "The product 1 only has 2 in stock in inventory"
But I add two products and says: "error", msg: "Undefined property: stdClass::$references"}
You're not able to access eloquent relationships on the DB facade.
If you wanted to access the references relationship you'd need to change
$productId = DB::table('products')
->where('sku', $dataTable[2])
->whereNull('deleted_at')
->select('id', 'reference')
->first();
into an eloquent model lookup, something like
$productId = App\Models\Products::where('sku', $dataTable[2])
->whereNull('deleted_at')
->select('id', 'reference')
->first();
As a separate note and to help with performance, I'd also suggest eager loading the inventories relationship. Without knowing much about your DB design, something like the below should get you started
// Product model
public function inventories()
{
return $this->belongsTo('App\Models\Inventory');
}
Then you could adjust the top eloquent query to be something like
$productId = App\Models\Products::where('sku', $dataTable[2])
->whereNull('deleted_at')
->doesntHave('inventories')
->select('id', 'reference')
->first();
Be sure to checkout Laravel eloquent relationships for more information specific to your situation

Laravel Sorting (orderBy or sortBy) is no working to sort database results

I am using Laravel 6.x and have been trying to sort orders ascendingly by the time they were created. This is what I tried. I tried changing the positions of orderBy and sortBy, but it didn't change anything.
public function index()
{
$orders = Order::select("*", DB::raw("count(*) as order_count"))
->groupBy(DB::raw("coupon"))->sortBy('created_at', 'desc')
->get();
return view('admin.order.index', compact('orders'));
}
So can you please tell me why this code is not sorting properly? Thank you for your support!
sortBy is used by collection, for a query, you have to use a orderBy :
public function index()
{
$orders = Order::orderByDesc('created_at')
->get();
return view('admin.order.index', compact('orders'));
}
you can also use latest()
public function index()
{
$orders = Order::latest()
->get();
return view('admin.order.index', compact('orders'));
}
You can't use a count a groupBy here, or you would get a single line.
Provide more information about what you are trying to do (Do you want to have the number of order per coupon ?
Edited :
To get your order groupby coupon :
$coupons = Coupon::with(['order' => function($query){
$query->latest();
})->withCount('order')->get();
then you can use it :
#foreach($coupons as $coupon)
Number of Order : {{ $coupon->order_count }}
<br>
Orders :
#foreach($coupon->orders as $order)
{{ $order->[...] }}
#endforeach
#endforeach

how to group by item many to many query builder laravel

I have comics and categories related many to many through pivot tables. I use join and groupBy caterories.id but it doesn't group categories same comics id.
If I do not use the group
$result = DB::table('comics')
->select('comics.name','categories.title')
->join('category_comic', 'comics.id', '=', 'category_comic.comic_id')
->join('categories', 'category_comic.category_id', '=', 'categories.id')
->get();
I want each comic group category
(source: uphinh.org)
First of all
try tou use Laravel Eloquent Relationship and its really cool and very easy to use
In Eloquent Method
In Comics Model
add relationship function
public function cat(){
return $this->hasOne(ComicCategory::class,'id','comic_id'); //ComicCategory::class is your category_comic model
}
Then you just need you Comic Model to get a group of your category com
$result = Comic::with('cat')->get(); //Commic is your model
In query Builder, you need to group manual using foreach
$result = DB::table('comics')
->select('comics.name','categories.title')
->join('category_comic', 'comics.id', '=', 'category_comic.comic_id')
->join('categories', 'category_comic.category_id', '=', 'categories.id')
->get();
$result = json_decode(json_encode($result), TRUE);
$new_result = [];
foreach($result as $row){
$arr[$row['id']]['name'] = $row['name'];
$arr[$row['id']]['cat'][] = $row['title'];
}
and finally rearange the key
$new_result = array_values($new_result );
PS : thats array method, i never group using object method

how to make join in laravel ? get only some columns of another table

I am working on admin panel ... where i get all products from database and show in table ... the problem is i want to get each product categorey from "category" table and get stock of each product from "products attribute" table ... i am create a join but this join collapse product id , name stock or prize from another table... Thanks.
public function viewProducts(Request $request){
$products = Product::get();
$products = Product::join('categories','categories.id','products.category_id')
->join('products_attributes','products_attributes.product_id',
'products.id')
->get();
$products = json_decode(json_encode($products));
//echo "<pre>"; print_r($products); die;
return view('admin.products.view_products')->with(compact('products'));
}
$products = Product::join('categories','categories.id','products.category_id')
->join('products_attributes','products_attributes.product_id','products.id')
->get(['categories.category_name as category_name', 'products_attributes.stock as product_stock', 'products.*']);
Try this:
Product::join('categories','categories.id','products.category_id')
->join('products_attributes','products_attributes.product_id','products.id')
->select(['categories.category_name as category_name', 'products_attributes.stock as product_stock', 'products.*'])
->get()->toArray();

Laravel filtering one to many relations

I have Product and Category models tied one to many.How to filter Products by category? In template i have
{{ $category->name }}
How to write function to filter Products with Category?
public function productsByCategory($category_id){
$products = Product:: ????
return view("layouts._productsByCategory", compact("products"));
Answer is
$products = Product::where('category_id', $category_id)->get();
You can use:
$products = Product::where('category_id', $category_id)->get();
or
$products = Product::whereHas('category', function($q) use ($category_id) {
$q->where('id', $category_id);
});
assuming you set category relationship in Product model.
You might find it easier to go via the category:
public function productsByCategory($category_id){
return view("layouts._productsByCategory", [
'products' => Category::with('products')->find($category_id)->products
]);
}

Resources