Laravel eloquent build query - php

I want to write a query using the Laravel Eloquent structure. I want to query these values ​​after entering the min and max values. I have a product table. Column product table with discount (%) and price. I want to get min and max value according to the discounted value of the product.
I want this to be based on the query including the discount.
$products->where('price', '<=', $max)
->where('price', '>=', $min)
->orderByDesc('id')
->paginate(9);
Product migration:
Schema::create('products', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('upper_category_id')->index();
$table->unsignedBigInteger('category_id')->index();
$table->unsignedBigInteger('user_id')->index();
$table->string('name');
$table->longText('text');
$table->float('price')->index();
$table->integer('stock');
$table->float('discount');
$table->timestamps();
});
Thank you very much in advance.

If I correctly understood your question, you can try do it this way:
$products->where(DB::raw('price - price * discount'), '<=', $max)
->where(DB::raw('price - price * discount'), '>=', $min)
->orderByDesc('id')
->paginate(9);
https://laravel.com/docs/5.8/queries#raw-expressions

Related

Laravel - Eloquent - How to sum related data and query agaist it?

I'm looking for help with database queries, not collection solution
I have the following models:
User
Order
Product
User hasMany orders, and orders belongsToMany products
I'm in a place where I would need to query users and select all sold products, meaning the sum of all products quantities that are attached to the orders.
quantity value is stored in the order_product pivot table.
Table name: users, orders, products & order_product
Ideally, I would like to make queries like: select all users that have sold at least 100 products, for example.
DB::raw() & selectRaw is most likely the way to go, I think(?), but I'm not sure about the syntax and how to actually make the query, with and without where clause.
Thanks a lot in advance, this has bothered me for a while
Database Schemas
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
});
Schema::create('orders', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id')->index();
});
Schema::create('order_product', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('order_id')->index();
$table->unsignedBigInteger('product_id')->index();
$table->integer('quantity')->unsigned()->default(1);
});
Schema::create('products', function (Blueprint $table) {
$table->bigIncrements('id');
});
UPDATE
This far I have come:
\App\User::addSelect([
'sold_products_count' => \App\Order::whereColumn('user_id', 'users.id')
->join('order_product', 'orders.id', '=', 'order_product.order_id')
->select(DB::raw('sum(order_product.quantity) as qty')),
])->where('users.sold_products_count', '>=', 100);
HOWEVER, the last statement where('users.sold_products_count', '>=', 100) throws error, cuz there's no sold_products_count column.
So I think I'm on the right track, but how I can use the new sum column in where clause?
Can I use addSelect, or do I have to use something else?
Finally, I solved this
Here's the answer:
\App\User::addSelect([
'sold_products_count' => \App\Order::whereColumn('user_id', 'users.id')
->join('order_product', 'orders.id', '=', 'order_product.order_id')
->select(DB::raw('sum(order_product.quantity) as qty')),
])->having('sold_products_count', '>=', 100);
The idea is to first count the sum via addSelect and then we can query against the value using having, neat
DB::table('users')
->join('orders', 'orders.user_id', '=', 'users.id')
->join('order_product', 'orders.id', '=', 'order_product.order_id')
->select('users.*', DB::raw('sum(order_product.quantity) as qty'))
->having('qty', '>=', 100)
->get();

Laravel using Sum and Groupby

I would like to fetch sum of quantity in each month, so that I can display on bar chart quantities against month
This is what I thought but didn't workout
$data1 = Borrow::groupBy(function($d) {
return Carbon::parse($d->created_at)->format('m')->sum('quantity');
})->get();
My table structure
Schema::create('borrows', function (Blueprint $table) {
$table->increments('id');
$table->integer('member_id');
$table->integer('book_id');
$table->integer('quantity');
$table->integer('status')->default(0);
$table->timestamps();
});
that a collection group by not an eloquent groupby
if you want to do it with eloquent, gotta:
$data1 = Borrow::selectRaw('SUM(quantity) as qt, MONTH(created_at) as borrowMonth')
->groupBy('borrowMonth')->get();
if you want to do it with the collection groupBy method, you should first do the get, then the groupBy.
As in, though im not sure what you're trying to accomplish with what you do inside the callback..
$data1 = Borrow::get()->groupBy(function($d) {
return Carbon::parse($d->created_at)->format('m')->sum('quantity');
});
try this query , you will get month wise count :
use DB;
$month_wise_count=DB::table("borrows")
->select(DB::raw('CONCAT(MONTHNAME(created_at), "-", YEAR(created_at)) AS month_year'),
DB::raw("MONTH(created_at) as month , YEAR(created_at) as year"),
DB::raw("(COUNT(*)) as total_records"),
DB::row("(SUM('quantity') as total_value"))
->orderBy(DB::raw("MONTH(created_at),YEAR(created_at)"))
->groupBy(DB::raw("MONTH(created_at),YEAR(created_at)"))
->get();

Getting latest products base on their category in laravel

I try to get my latest products of each category in separate panel in my index page,
for this matter there are 3 tables involved products admin_designs and categories
Logic
In my admin_designs table i will select categories and base on my selected category there will add new panel to my index page including last 10 products in that category.
So far I can get my categories products in index page in separate
panels BUT not as I wish.
Problems
I'm not able to get categories title
I only get 1 product as result however I limited results for 10
I want to get title value from admin_designs table instead of category title if is provided only but i can't find it in my query.
codes
controller
public function welcome() {
//rest of the codes....
//dynamic categories
$category = DB::table('admin_designs')
->join('categories', 'categories.id', '=', 'admin_designs.category_id')
->join('products', function ($join) {
$join->on('admin_designs.category_id', '=', 'products.category_id');
})
->groupby('categories.id')
->take(10)
->get();
return view('welcome', compact('category'));
}
my blade code
#foreach($category as $ki)
// title of panel
cat id: {{$ki->category_id}} //return category id from products table (the best i could get instead of category title!)
//panel data
{{$ki->title}} // product title
#endforeach
NOTE: as you see in my controller i have ->take(10) but my result only get 1 (I have enough products in each category so is not about that i don't have data)
Screenshot
this is actual results
UPDATE
categories schema I need title from this table.
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('title')->unique();
$table->string('image');
$table->string('imageAlt')->nullable();
$table->string('slug');
$table->text('meta_description')->nullable();
$table->text('meta_tags')->nullable();
$table->integer('status_id')->unsigned();
$table->timestamps();
});
Schema::table('categories', function (Blueprint $table) {
$table->foreign('status_id')->references('id')->on('statuses');
});
Admin_designs schema I need title from this table
Schema::create('admin_designs', function (Blueprint $table) {
$table->increments('id');
$table->integer('category_id')->unsigned();
$table->integer('status_id')->unsigned();
$table->string('title')->nullable();
$table->timestamps();
});
Schema::table('admin_designs', function($table) {
$table->foreign('category_id')->references('id')->on('categories');
$table->foreign('status_id')->references('id')->on('statuses');
});
products schema I need everything from this table
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->string('title')->unique();
$table->string('slug');
$table->string('imageOne');
$table->string('imageTwo')->nullable();
$table->text('short_description');
$table->longText('description');
$table->string('price');
$table->text('meta_description')->nullable();
$table->text('meta_tags')->nullable();
$table->string('arrivalDays');
$table->string('height')->nullable();
$table->string('weight')->nullable();
$table->string('lenght')->nullable();
$table->string('width')->nullable();
$table->string('sku');
$table->string('stock');
$table->integer('status_id')->unsigned();
$table->integer('brand_id')->unsigned();
$table->integer('category_id')->unsigned();
$table->integer('subcategory_id')->unsigned();
$table->timestamps();
});
Schema::table('products', function (Blueprint $table) {
$table->foreign('status_id')->references('id')->on('statuses');
$table->foreign('brand_id')->references('id')->on('brands');
$table->foreign('category_id')->references('id')->on('categories');
$table->foreign('subcategory_id')->references('id')->on('subcategories');
});
Relations
category.php
public function products(){
return $this->hasMany(Product::class);
}
public function admin_designs(){
return $this->hasMany(AdminDesign::class);
}
admindesign.php
public function category(){
return $this->belongsTo(Category::class, 'category_id');
}
product.php
public function category(){
return $this->belongsTo(Category::class);
}
UPDATE 2
I decided to remove my admin_designs table and instead I added a column to my categories table and local scope to my category model. Now when I set my new column value to 1 that category products will show in homepage.
here is the query of that:
$categories = Category::with('products')->OfListed()->get();
ISSUE:
I need this query to get only last 10 products of my category and not more than that. How can I add that condition to it?

Laravel Sub queries in select using query builder

I want to get this query using query builder:
SELECT *,
( SELECT sum(vendor_quantity)
from inventory
WHERE product_id = products.id
) as qty from products
I'm stuck with this part
(SELECT sum(vendor_quantity) from inventory where product_id = products.id)
I can do it using raw query but I want to know if there is a way to do it in query builder.
My Table Schema for products:
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->string('product_type',50);
$table->string('product_name',255);
$table->string('internal_reference',255);
$table->string('barcode',255);
$table->decimal('sale_price', 10, 2);
$table->decimal('cost', 10, 2);
$table->decimal('weight', 10, 2);
$table->decimal('volume', 10, 2);
$table->integer('added_by')->unsigned();
$table->timestamps();
});
// Foreign Keys
Schema::table('products', function(Blueprint $table) {
$table->foreign('added_by')->references('id')->on('users');
});
Stocks Table:
Schema::create('stocks', function (Blueprint $table) {
$table->increments('id');
$table->integer('product_id')->unsigned();
$table->integer('vendor')->unsigned();
$table->string('vendor_product_code',255);
$table->string('vendor_product_name',255);
$table->integer('vendor_quantity');
$table->decimal('vendor_price', 10, 2);
$table->date('vendor_produce');
$table->date('vendor_expiry');
$table->integer('added_by')->unsigned();
$table->timestamps();
});
// Foreign Keys
Schema::table('stocks', function(Blueprint $table) {
$table->foreign('product_id')->references('id')->on('products');
$table->foreign('vendor')->references('id')->on('customers');
$table->foreign('added_by')->references('id')->on('users');
});
can you just add what exactly do you need as output? Like what do you plan to throw at your view so I can give you the eloquent setup. From the migration above it looks like you're missing some tables like "inventory".
In any way - you first need to setup eloquent relationships between your models. For the two above, something like this:
class Stock extends Model{
public function product(){
return $this->belongsTo(Product::class);
}
}
and
class Product extends Model{
public function stock(){
return $this->hasMany(Stock::class);
}
}
Now, that sum of yours has me confused a bit... since vendor_quantity is a column in your stocks table... Do you need to get all the products and the corresponding foreign key values from the stocks table and then sum all the values in the vendor_quantity? If that's the case do something like this:
$products = Products::with('stock')->get();
This will return the eloquent collection with all your products AND foreign key values from the stock table. Since you have the values from the related table you can just iterate through each of those an add it to a variable or just append it to the initial object for passing to your view. For example
$products = Product::with('stock')->get();
foreach ($products as $key => $product){
$vendorQuantitySum = $product->stock->sum('vendor_quantity');
$products[$key]->vendorQuantity = $vendorQuantitySum;
}
Now, when you pass $products to your view, you can easily get the sum in your view like so:
{{ $product->vendorQuantity }}
I just tested it on my Laravel install and it seems to work :)

represent my sql query in laravel Eloquent

I have an application tha i want it to make bookings but i'am having trouble making my Eloquent query
I have two modals "Booking.php" and "Room.php" my bookings migrations table is as follows
Schema::create('bookings', function(Blueprint $table)
{
$table->increments('id');
$table->string('name');
$table->integer('phone');
$table->integer('time_in');
$table->integer('room_id');
$table->integer('time_out');
$table->string('days');
$table->string('type');
$table->integer('expiry_status'); /*expiry status 0->expired 1->not expired*/
$table->timestamps();
});
and my rooms migrations table is as follows
Schema::create('rooms', function(Blueprint $table)
{
$table->increments('id');
$table->integer('room_no');
$table->integer('price');
$table->timestamps();
});
in my view i have got inputs for satrt of reservation(time_in) and end of reservation(time_out) now if there is a reservation that does not end before or start after the reservation we want, the room is considered busy therefore i do not want to show that room show those rooms for my reservation dates.
My problem is I want to know the rooms available between my reservation dates,Can someone help me to write the eloquent to get the available rooms from the above table structures. I'm using mysql as the database engine. Thanks in advance.
I found this query to be useful but how to i implement it in the form of Eloquent model
SELECT r.id
FROM rooms r
WHERE r.room_id NOT IN (
SELECT b.room_id FROM bookings b
WHERE NOT (b.time_out < '2012-09-14T18:00'
OR
b.time_in > '2012-09-21T09:00'))
ORDER BY r.room_id;
You can create subselects and advanced where conditions in Laravel Eloquent.
This script worked for me. I tried to build it for your schema.
DB::table('rooms')
->whereNotIn('room_id', function($query)
{
$query->select('room_id')
->from(with(new Booking)->getTable())
->where(function($query)
{
$query->where('time_out', '<', '2012-09-14T18:00')
->orWhere('time_in', '>', '2012-09-21T09:00');
});
})
->orderBy('room_id')
->get();
https://gist.github.com/DengoPHP/d3e95441a7b9e27299b7

Categories