how to get order item sales report in laravel? - php

I'm trying to get last month order items report. Here is my table structure
orders
id - integer
amount- double
order_items (pivot table)
id - integer
order_id - foreign
item_id - foreign
quantity
price
Here is my Item model
public function orders()
{
return $this->belongsToMany(Order::class, 'order_items', 'item_id', 'order_id')
->withPivot('quantity', 'price');
}
Here is my Order model
public function items()
{
return $this->belongsToMany(Item::class, 'order_items', 'order_id', 'item_id')
->withPivot('quantity', 'price')
->withTimestamps();
}
Here is my controller where I got last month's all orders
$orders = Order::with('items')
->whereMonth('created_at', '=', Carbon::now()->subMonth()->month)
->get();
After foreach loop in blade,
#foreach ($orders as $order)
<ul>
#foreach($order->items as $item)
<li>
{{ $item->name }}, {{ $item->pivot->quantity }}, {{ $item->pivot->price }}
</li>
#endforeach
</ul>
<hr>
#endforeach
I'm getting data like this
Item Name Quantity Price
Item A 20 600
Item A 15 400
Item A 5 200
Item B 5 100
Item B 5 100
But I don't want to show same item in this row, I want to show like this
Item Name Quantity Price
Item A 40 1200
Item B 10 200
How to sum quantity and price if item is same?

I think this could solve your problem:
$orders = Order::with('items')
->whereMonth('created_at', '=', Carbon::now()->subMonth()->month)
->get();
$orders->transform(function($order){
$itemsArray = [];
$order['items'] = $order['items']->groupBy('name')->map(function ($item) use ($itemsArray){
array_push($itemsArray, [
'name' => $item[0]['name'],
'qty' => $item->sum('qty'),
'price' => $item->sum('price')
]);
return $itemsArray[0];
})->values();
return $order;
});

Related

Why is my order_id in my pivot table not being updated but everything else is?

I have two models, a marketsegment model and a product model, both have a many to many relation with eachother.
Example in MarketSegment.php:
public function products()
{
return $this->belongsToMany(Product::class);
}
Now I post the following array to a function that updates the pivot table:
products[]:
6
products[]:
11
I want to update market_segment_product to contain all products belonging to a market segment and add the sort order of them for the column order_id. As the order_id I want to use the keys of the above array, so the full data example would be:
market_segment_id - 7
product_id - 6
order_id - 0
market_segment_id - 7
product_id - 11
order_id - 1
I have the following function to update the pivot table:
public function updateProducts(Request $request, $id)
{
$marketSegment = MarketSegment::find($id);
$products = $request->input('products');
$order = [];
$i = 0;
foreach ($products as $id) {
$order[$id] = $i;
$i++;
}
$data = [];
foreach ($products as $id) {
$data[$id] = ['order_id' => $order[$id]];
}
$marketSegment->products()->sync($products, $data);
return [
'error' => false,
'message' => 'Producten gewijzigd'
];
}
But this updates everything except the order_id which stays 0 for all rows. Why doesn't it update the order_id ? I am using laravel 6.

get order products categories in laravel

I have four tables
Order, Category, Product, Order_Product
each product belongs to a category
each order has many products
i save the order products in order_product table,
now in orderResource i want to have number of order->products in each category
so OrderResource should have
data
[
{
category_name: 'something',
productsCount: 3,
},
{
category_name: 'somethingelse',
productsCount: 2
}
]
how to do so ?
So you want to get products from an order, and group the products by category and count the number of products in a category.
$orders = Order::with(['products' => function($query) {
$query->groupBy('category_id')
->select(DB::raw('count(*) AS productsCount'), 'category_id')
->with('category');
}])
->get();
foreach($orders as $order) {
foreach($order->products as $product) {
$product->productsCount;
$product->category->name;
}
}

Laravel Query Relationship in 3 tables using eloquent

Help me again,
I have 3 tables
Product Table
id
product_name
Productquantity Table
id
prod_id -> product table id
price
Purchaserecord
id
prodquantityid -> productquantity table id
quantity
amount
How can I make to display the name of the product in my view? I have this on my Purchaserecord model
public function productquantity()
{
return $this->belongsTO('App\Productquantity', 'prodquantityid', 'id');
}
and in my view
#foreach($dataPurchaseRecord as $Record)
<tr>
<td>{{$Record->productquantity->prod_id}}</td>
<td>{{$Record->quantity}}</td>
<td>{{$Record->price}}</td>
</tr>
#endforeach
I just want to know how to display the product name instead of the productid {{$Record->productquantity->prod_id}}
Thank you
In your controller, try this:
function viewPurchases(Request $request)
{
//Perform your query, and end on ->get() to retreive iterable collection.
$dataPurchaseRecord = Purchaserecord
::with('productquantity')
->where('id', '<', 10)
->get();
//load your view, and pass the collection to your view.
//compact('dataPurchaseRecord') basically results in a key value array like so:
//['dataPurchaseRecord' => $dataPurchaseRecord]
return view('your_viewname', compact('dataPurchaseRecord'));
}
Hope it helps :)

found error in laravel 5.4,Property [categories] does not exist on this collection instance

I am trying to display the product listing on listing page of the product. Each product has category.My table structure
categories
id name description
1 Cat1 Category 1
2 Cat2 Category 2
This is the category table having id name and description
products
id name description category_id
1 pro1 product 1 1
2 pro2 product 2 2
This is the product table having category_id.
Product Model
public function categories() {
return $this->belongsTo("App\Category");
}
This is the product model where the products are belongs to category
Category Model
public function products() {
return $this->hasMany("App\Product");
}
This is the Category model where the Category has many product
Now in the product controller on listing function I want the list of product with category name
public function index()
{
$product = Product::with('categories')->get();
print_r($product->categories);die;
return view('product.index')->with("list",$product);
}
I want my Output should be
products
id name description category name
1 pro1 product 1 cat1
2 pro2 product 2 cat2
I found this error "Property [categories] does not exist on this collection instance."
When you run:
$product = Product::with('categories')->get();
you are not getting single products but all products so it should be rather renamed to:
$products = Product::with('categories')->get();
Further, looking at your database structure, each product belongs to single category so in Product model you should rename
public function categories()
{
return $this->belongsTo("App\Category");
}
to
public function category()
{
return $this->belongsTo("App\Category");
}
If you do this change, you should then again change
$products = Product::with('categories')->get();
to
$products = Product::with('category')->get();
Going back to your controller assuming all your products have set category, you can display it like this:
foreach ($products as $product)
{
echo $product->id.' '.$product->name.' '.$product->description.' '.$product->category->name;
}
You can obviously do the same later in Blade view like so:
#foreach ($list as $product)
{{ $product->id }} {{$product->name}} {{ $product->description }} {{ $product->category->name }}
#endforeach
I have changed in ProductController which is my product controllers function
public function index()
{
$products = Product::with('category')->get();
return view('product.index')->with("list",$products);
}
Also changed in Product Model
public function category() {
return $this->belongsTo("App\Category");
}
After these changes I got my expected result.

Laravel 4.2 n+1 without eager loading

I have a table with products
products
------------------------------------------------
id product_code purchase_type quantity
1 106 new 1
2 107 renew 3
and a pricelist for products
price_list
----------------------------------------------------------------------
id product_code purchase_type minimum maximum unit_price
1 106 new 1 25 20
2 106 new 26 50 16
3 106 new 51 100 14
When I display the products on a page, I need to display the price with the formula
getPrice(product_code, purchase_type, quantity) for every product
Using
foreach(Product::all() as $product){
{{ $product->product_code }}
{{ $product->purchase_type }}
{{ $product->quantity }}
{{ PriceList::getPrice($product->product_code, $product->purchase_type, $product->quantity) }} - this one is the n+1 problem
}
PriceList::getPrice() is something like:
public static function getPrice($productCode, $purchaseType, $quantity){
return PriceList::where('product_code', $productCode)
->where('purchase_type', $purchaseType)
->where('minimum', '>=', $quantity)
->where('maximum', '<=', $quantity)
->get()->first()->unit_price;
}
I can't seem to find a more efficient way.
And when I display over 1000 products, then it gets really slow.
I can't seem to find a way to use eager loading.
It is not a good idea to call model from inside loop to get data.
Instead of doing that, follow below way.
You should define relationship between Product and PriceList tables.
In Model Product.php
public function price_list(){
return $this->hasMany('PriceList','product_code');
}
In Model PriceList.php
public function product(){
return $this->belongsTo('Product','product_code');
}
In Controller File
$products = Product::with('price_list')->get();
return View::make('your_view')->with('products', $products);
In View File (file must have extention .blade.php to use below syntax)
#foreach($products as $product)
{{ $product }}
#endforeach
Note:- Print $products in controller to check results.
I found a way with mysql,
SELECT
`products`.`id` AS `product_id`,
`products`.`product_code` AS `product_product_code`,
`products`.`purchase_type` AS `product_purchase_type`,
`products`.`quantity` AS `product_quantity`,
`price_list`.`product_code` AS `price_list_product_code`,
`price_list`.`purchase_type` AS `price_list_purchase_type`,
`price_list`.`minimum` AS `price_list_minimum`,
`price_list`.`maximum` AS `price_list_maximum`,
`price_list`.`unit_price` AS `price_list_unit_price`
FROM
`products`
LEFT JOIN `price_list` ON `products`.`product_code` = `price_list`.`product_code`
AND `products`.`purchase_type` = price_list.purchase_type
AND `products`.`quantity` >= price_list.minimum
AND `products`.`quantity` <= price_list.maximum
ORDER BY
`products`.`id` ASC
http://sqlfiddle.com/#!9/5d6ac/2

Categories