I'm stuck in a problem, I have these 3 models: Order, OrderItem and Product, each Order has many Order Items, and each Order Item has one Prduct but a Product can be ordered several times.
Product has a supplier ID column (each supplier has many Products).
So here are the relationships:
Model: Order:
public function items(){
return $this->hasMany('App\Models\OrderItem','id','order_id');
}
Model OrderItem
public function order(){
return $this->belongsTo('App\Models\Order','order_id','id');
}
public function product(){
return $this->belongsTo('App\Models\Product','item_id','id');
}
Model Product
public function orders()
{
return $this->hasMany('App\Models\OrderItem','item_id','id');
}
What I want is that given a supplier_id, I need to filter Products for that supplier_id, and get the Order Items for that supplier_id and then group them by created date which is only available in the Order Model and not Order Items.
In other words, I want to get all Orders of a given supplier (through the supplier_id column in products) grouped by their creation date but there is no direct relation from Orders to Products I have to get Order Items to get to Products (Orders > Order Items > Products).
I thought about doing the following:
Product::with("orders")->where("supplier_id","=",$supplier_id)->join("orders","orders.id","=","products.orders")
The problem is that products.orders is a relationship (between Product and Order Item) and not a column.
You can do it using DB interface or if you'd like continue using Models you need to use multiple pluck.
You can do something like this:
Product::with(['orders','orders.order'])->where('supplier_id', $supplier_id)->get()->pluck("orders")->flatten()->pluck('order');
Use following snippet:
Product::select(DB::Raw('DATE(created_at) as cr'), ...)->where('supplier_id', $supplier_id)->with('orders.order')->groupBy('supplier_id')->get();
After that, you can loop on the result and group them by date:
$result->groupBy('cr')
Related
So i have 2 tables. Orders and OrderItems. Relationship is each Order can have many OrderItems (orderitem is just a product).
OrderItem Table
id INT PRIMARY KEY
name TEXT
quantity INT
pack_value INT
order_id INT FOREIGN KEY REFERENCES ORDER_ID ON ORDERS TABLE
product_id INT FOREIGN KEY REFERENCES PRODUCT_ID ON PRODUCTS TABLE
Orders Table
order_id INT PRIMARY KEY
status TEXT
user_id INT FOREIGN KEY REFERENCES USER_ID ON USERS TABLE
An order can have the same OrderItem twice or only once. For example like below, 3 items but 2 products:
OrderItem(id=1, product_id=100, name="Pizza", quantity=2, pack_value=10, order_id=7)
OrderItem(id=2, product_id=100, name="Pizza", quantity=10, pack_value=1, order_id=7)
OrderItem(id=3, product_id=555, name="Olives", quantity=5, pack_value=1, order_id=7)
So above there is 2 entries for Pizza and this is the result i get. However i want it to only show 1 entry for Pizza because its the same item. Below is what i want to see:
OrderItem(product_id=100, name="Pizza", quantity=30, pack_value=1, order_id=7)
OrderItem(product_id=555, name="Olives", quantity=5, pack_value=1, order_id=7)
So essentially, if the item only exists once, then do nothing to it. If it exists twice, then make the pack_value=1 and the quantity is the sum of the individual quantity*pack_value. So in example above quantity becomes (2*10 + 10*1 = 30).
The controller method is like below, and so here is where I want to do this:
public function showOrderDetails(Order $order){
return view('orders.show', compact('order'));
}
Also the Order and OrderItem models has the method for the relationships. For example, in the Order Model i have:
public function orderItems(){
return $this->hasMany(OrderItem::class, 'order_id');
}
Thanks, and if you need any extra info i can provide.
SELECT name,
SUM(quantity * pack_value) AS quantity,
1 AS pack_value,
order_id
FROM order_items
GROUP BY name,
order_id;
fiddle
Merge another tables to this code using it as subquery, or add them into FROM clause (adjusting its output list and grouping expression) if needed.
I have 2 tables Bag(cart) and products. I am saving quantity added by user in bad table and sale_price in products table. I need to get sum of bag.quantity * products.sale_price for each item. I am using query builder to get sum. How can i get that
I am able to use join to get list of all attributes
$items = DB::table('bag')->where('bag.user_id' , $user_id)->where('bag.order_id', 0)->join('products','products.id','=','bag.product_id')->get();
api link:
https://apptest.factory2homes.com/api/get-bag-products/3
I need to multiply quantity and sale_price for each unique product_id and then take total sum of it
you can use selectRaw to do such thing:
$items = DB::table('bag')->where('bag.user_id' , $user_id)
->where('bag.order_id', 0)
->join('products','products.id','=','bag.product_id')
->selectRaw('*, (bag.quantity * products.sale_price) as totalPrice')
->get();
and to get sum of all, you can use sum:
$sum=$items->sum('totalPrice');
I have the following table structure
tables
tbl_items
id
sub_category_id //foreign key
table subcategories
tbl_subcategories
id
category_id
name
table categories
tbl_categories
id
name
As you can see from the above the sub_category_id is a foreign key in products table which relates to the id in the subcategories table. the subcategories table have a category_id which is a foreign key from the categories table
Now i wanted to fetch all items belonging to a certain category.
so i have tried
$categories = Categories::where('id',7)->first();
//from categories get subcategoryid
$allsubcategories = Subcategories::where('category_id',$categories->id)->pluck('id')
$allitems = Items::where('status',1)->wherein('sub_category_id',$allsubcategories)
The above works. but is there a neater way to do this?
define a hasManyThrough relationship in the Category model to the Item model.
// on the Category Model
public function items() {
return $this->hasManyThrough(Items::class, Subcategories::class);
}
then you can access all the items belongs to a particular category
// On your Controller
$category = Categories::where('id',7)->first();
$items = $category->items
official documentation - https://laravel.com/docs/5.7/eloquent-relationships#has-many-through
Well you could probably try using Nested Eager Loading, which should be a little more efficent:
//Assuming the relationships are named subCategories() on Categories model & items() on Subcategories model
$cat = Categories::where('id', 7)
->with('subCategories.items')
->get()
->first();
That should load the category w/ all the subCategories and all the items within each subCategories with the least amount of queries.
I have 3 tables, Order, Products, Order_Products. I need get all field from order and products, thats ok using hasManyThrough(). But i need 1 more field from Order_products. How can i get this field ?
public function products()
{
//in order model
return $this->hasManyThrough('App\Models\Product','App\Models\OrderProduct','order_id','id','id','product_id');
}
using sql i need query like
SELECT
products.*, order_products.order_id, order_products.count as order_count
FROM
products
INNER JOIN order_products ON order_products.product_id = products.id
WHERE
order_products.order_id = 2
You can access intermediate table fields by using pivot attribute on model.
Lets say you have product, Then you can access count field of orders_products
$product->pivot->count;
I'm new on Laravel & Eloquent. I have Users, Products and Votes tables on my DB. Users can vote (0 to 5) on products, so it is a "many to many" relationship, with the Votes table acting like a pivot:
Users: id, name, email, password
Products: id, name, model, brand
Votes: user_id, product_id, vote
I mapped this schema like this:
// User model:
public function product_votes()
{
return $this->belongsToMany('App\Product', 'votes')->withPivot('vote');
}
// Product model:
public function product_votes()
{
return $this->belongsToMany('App\User', 'votes')->withPivot('vote');
}
So John can vote 5 on product X and 0 on product Y. Bob can vote 2 on product X, 3 on product Y, and so on...
I'm trying to query all products, with the sum of votes of each one of them. Something like:
SELECT p.*, (SUM(v.vote) / COUNT(*)) as votes FROM products p INNER JOIN votes v on v.product_id = p.id GROUP BY p.id
How can I do that with QueryBuilder? My mapping is right?
The following will do the trick:
Product::select('products.*', DB::raw('SUM(vote)/COUNT(*) as votes'))
->join('votes', 'votes.product_id', '=', 'products.id')
->groupBy('products.id')
->get();
You can see the query that will be run by calling toSql() instead of get().