How many products do I have Laravel - 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

Related

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();

Check if related model have entry in another related model

i have following models and there relation
Models
User
Product
Orders
OrderProduct
ProductReviews
Relations
User hasMany Orders
Orders hasMany OrderProdut
User hasMany ProductReview
Product hasMany ProductReview
ProductReview belongsTo User
Inside the product page all the reviews for that product is listed with the user details who made the review.
I want to check if review in list has made a purchase of the reviewed product.
So far i have done this with php loops and eager loading. Is there a better way to do this
$product = Product::with([
'reviews'=>function($q) {
$q->where('status', 1);
},
'reviews.user'
])->first();
if($product){
$product->load(['reviews.user.orders.orderProducts' => function($q) use($product){
$q->where('product_id',$product->id);
}]);
}
foreach ($product->reviews as $review){
$review->purchased_from_microless = false;
foreach ($review->user->orders as $order) {
if($order->orderProducts->count()){
$review->purchased_from_microless = true;
break;
}
}
}
It is possible to inline the query to check if reviewed product was purchased:
$product = Product::with([
'reviews' => function($q) {
$q->where('status', 1);
},
'reviews.user.orders'
])->first();
$reviews = $product
->reviews
->map(function ($value, $key) {
$wasPurchased = $review->user->orders->orderProduct()->where('product_id', $product->id)->count() > 0;
$review['purchased_from_microless'] = $wasPurchased;
return $review;
})->all();
Where, the reviews collection is looped through with a check to see if the review's user's orders has an product which has the id of the product in question.
Return true if the count is greater than one.

How do i query the database to grab each user post and count the number of post from the user?

I am trying to make a datatable, but I am having trouble querying the database. What I want to do is select one instance of each user on the datatable and I want to grab a count of all the products created by that user.
Products Table
id user_id title
1 2 tv
2 2 car
3 2 book
4 3 glasses
So user(2) has 3 products
So user(3) has 1 products
Here is the code I been working on
$users = DB::table('users')
->join('products', 'users.id', '=', 'products.user_id')
->select('users.*', 'products.id', 'url')
->groupBy('products.id', 'url')
->get();
You need to select the user details, together with a count of the products, grouped by the user id, as follows:
$users = DB::table('users')
->selectRaw('users.*, COUNT(products.id) AS products')
->join('products', 'users.id', '=', 'products.user_id')
->groupBy('users.id')
->get();
You can do this really simply with eloquent
Say you have your User model and Product model.
In your database structure, for your products table, you need to include a column called user_id as an integer data type.
Then You declare this relationship on the user model
public function products()
{
return $this->hasMany(Product::class);
}
then the inverse of the relation on the product's model
public function user()
{
return $this->belongsTo(User::class);
}
Now you can simply do the following
//This returns all users with products (eager loading pointes out by fubar)
$users = User::with('products')->get();
//Now you could pass $users to your view and loop through like so
#foreach($users as $user)
<li>{{ $user->name }} has {{ $user->products->count() }} </li>
#endforeach
for a specific user, you can simply
$user = User::find($id);
$userProductCount = $user->products->count();
eloquent really does make everything so clean and beautiful

Laravel 5.5 - How to fetch related products in many to many relation

I am developing a e-commerce website.
I have 3 tables
1.prodcts table
2.conditions table
3.condition_product table
A product can have many conditions.
particular condition belongs to many products.
Now I have a product which belongs to 3 conditions.
I want to get all related products which belongs to these 3 conditions.
How can i achieve this?
product.php
public function conditions(){
return $this->belongsToMany(Condition::class)->withTimestamps();
}
condition.php
public function products(){
return $this->belongsToMany(Product::class)->withTimestamps();
}
This is my code:
public function productDetails(Product $product)
{
$a = $product->id;
$relatedProducts = Product::whereHas('conditions.products', function($q) use($a) {
$q->where('id', $a);
})
->get();
return view('pages/product', compact('product','relatedProducts'));
}
But I am getting error.
Use the whereHas() method with nested relationships:
Product::whereHas('conditions.products', function($q) use($productId) {
$q->where('id', $productId);
})
->get();
This will give you products that have conditions of a specified product.
Alternatively, you could do this:
$conditionIds = Product::find($productId)->conditions->pluck('id');
$products = Product::whereHas('conditions', function($q) use($conditionIds) {
$q->whereIn('id', $conditionIds);
})
->get();
A good practice is to always specify witch table the 'id' field is referencing too, because if not, it could both reference the 'conditions' table or the 'products' table 'id' field :
$relatedProducts = Product::whereHas('conditions.products', function($q) use($a) {
$q->where('products.id', $a);
})
->get();
You could see this answer about SQL ambiguous column name.

Laravel Eloquent nested query

I was working with Laravel and got stuck in a situation. I have following models:
Category
Product
CategoryProduct
CategoryProduct holds the information about which product belongs to which category (a product may belong to multiple categories).
Now, when I want to load all products belonging to a particular category, I need to run query on Product and CategoryProduct which is where I'm stuck.
I gave it the following try but was unsuccessful:
$products = Product::where('status', '=', 'active')
->where('category_id', '=', $category_id)
->take($count)
->skip($skip)
->get();
Obviously, it will say that category_id is not a column.
Here is my DB & Model structure:
categories table
id,
name,
etc.
products table
id,
name,
sku,
etc.
category_products table
id,
product_id, ( Foreign key to Product.id )
category_id, ( Foreign key to Category.id )
etc.
Product model
class Product extends Eloquent {
protected $table = 'products';
protected $hidden = array();
public static $rules = array('name' => 'required|min:3');
}
Category model
class Category extends Eloquent {
protected $table = 'categories';
public static $rules = array('name' => 'required|min:3');
}
CategoryProduct model
<?php
class CategoryProduct extends Eloquent {
protected $table = 'category_products';
public function product()
{
return $this->belongsTo('Product');
}
public function category()
{
return $this->belongsTo('Category');
}
}
Update
A new question on this
I'm trying to display products. If category is not passed (value is -1), then I will show all products, otherwise I will show products from the passed category.
Now, when I show all products, those products may already exist in a category. I want to display ticked checkbox for products that are already in a category. I'm doing something like this:
if($category_id==-1)
$products = Product::where('status', '=', 'active')->take($count)->skip($skip)->get();
else{
$products = Product::whereHas('categories', function($q) use ($category_id)
{
$q->where('category_id', $category_id);
})->where('status', 'active')
->take($count)
->skip($skip)
->get();
}
The table category_products have product_id, category_id as columns.
Now, the query:
$products = Product::where('status', '=', 'active')->take($count)->skip($skip)->get();
will pick products only from products table. If I check each product for its existence in category_products, then there will be too many database queries for large number of products.
Any idea, how to achieve this. I hope I was able to clear my situation. Thanks
The CategoryProduct model should not be necessary unless you have additional fields besides product_id and category_id which point to other relationships.
What is necessary are the methods for setting up the relationship on the Category and Product models.
In Category, add the relationship function...
public function products()
{
return $this->belongsToMany('Product', 'category_products');
}
In your Product model, do the same for categories.
public function categories()
{
return $this->belongsToMany('Category', 'category_products');
}
Then you can query for your active products that belong to that category using your relationship method and whereHas()
$products = Product::whereHas('categories', function($q) use ($category_id)
{
$q->where('id', $category_id);
})->where('status', 'active')
->take($count)
->skip($skip)
->get();
You don't need a model for a pivot table in Many-to-Many relationships. Look at this section of the Eloquent documentation for further explanation.
You still need to create a migration to set up the pivot table (or do it manually if you don't use migrations), but not a model. Instead, create a function for Category to designate the relationship:
public function products()
{
return $this->belongsToMany('App\Product', 'category_products');
// - You might need to adjust the namespace of App\Product
// - category_products refers to the pivot table name
}
Likewise, Product needs a similar public function.
Then you're able to do it the other way around, by finding the category and then listing all its related products:
$products = Category::find($category_id)
->products()
->where('status', 'active')
->take($count)
->skip($skip)
->get();
This question could also be relevant to yours.

Resources