How to sum field base on status field with eloquent laravel (with) - php

I have case sum of data
actual result: return 0
Expected result not return 0.
I have table like
Transaction
id
user_id
amount_load
status
1f
3edf
100000
1
Log Transaction
id
trx_id
amount_pay
status
32f
1f
10000
1
23d
1f
50000
1
12e
1f
1000
3
info about status:
ID
Meaning
0
not paid
1
paid not full
2
paided
3
refunded
My code on controller
$data = Transaction::select('user_id')->groupBy(‘user_id’)
->with([LogTransaction => function ($query) {
$query->sumRefund();
}]);
Model Transaction.php
public function scopeSelectDefault($q) {
return $q->selectRaw(‘id, user_id, amount_load, status’);
}
//RELATION
public function logTransaction()
{
return $this->hasMany('App\Models\LogTransaction', 'trx_id', 'id');
}
Model LogTransaction.php
public function scopeSumRefund($q) {
return $q->selectRaw(‘coalesce(SUM(amount_pay) FILTER (WHERE status = '3'),0) AS total_refund’);
}
// RELATION
public function transaction($query, $order)
{
return $this->belongsTo('App\Models\Transaction', 'id');
}
expected result: total_refund on relation resulting 1000 base status = 3
other information:
laravel ^6.0
postgres 12.0
please help

Firstly you can use the Laravel custom attribute option and you can define it in your Transactions Model like so
public function getTotalRefundAttribute() {
return $this->logTransaction ? $this->logTransaction->where('status', 3)->sum('amount_pay') : null;
}
And now when you get any Transaction instance it will have an extra attribute called total_refund where you can see the total amount. But make sure you actually have eloquent relations setup between Transaction and LogTransactions models

Related

How to loop through children and grandchildren in laravel

I'm trying to find a way to do \App\Goal::find(1)->children and get returned all children, and childrens children.
With the database pasted below I want
\App\Goal::find(1)->children
to return
2, 4 and 5. Currently I can only do \App\Goal::find(1)->goals, which returns only 2 and 4
I have a database like this:
id user_id goal_id objective
1 1 NULL Get rich
2 1 1 Save $5
3 1 NULL Learn to cook
4 1 1 Save $10,000
5 1 4 Buy stocks
6 1 5 Buy 5x Intel
7 1 5 Buy 5x AMD
How would you go about creating the children() function in the Goal model?
Please ask if any important info is missing from this
Edit:
Goal.php:
public function user()
{
return $this->belongsToUser(User::class);
}
public function goals()
{
return $this->hasMany(Goal::class, 'goal_id')
}
When I run \App\Goals::find(1)->goals in the GoalController it returns the children of itself (with id 2 and 4 from the example db table), but not its grandchildren...
ID 5 from the example table has a parent of id 4, which itself has a parent id of 1.
So how could I get \App\Goal::find(1)->children or \App\Goal::find(1)->goals to return its grandchildren, and their children etc?
So, assuming the table you've posted is the goals table, related to App\Goal...
If you have these two relationships set up on the model:
public function children()
{
return $this->hasMany(Goal::class, 'parent_id');
}
public function childrenRecursive()
{
return $this->children()->with('children');
}
You can call Goal::with('childrenRecursive')->get() which will return a nested collection of all the children and children's children.
If you'd like all of the children in a flat array, you could do something like this:
public function getFamilyAttribute()
{
$family = collect([]);
$children = $this->children;
while (!is_null($children )) {
$family->push($children);
$children = $children->children;
}
return $family;
}

How to load just the active relationships in laravel?

I have a query and I am loading 3 relations as below:
$data = Hotel::with('rooms.discount')
->whereHas('rooms.discount')->paginate(10);
return DiscountResource::collection($data);
relations like below :
public function Rooms()
{
return $this->Hasmany(Room::class);
}
and the discount relation with room
public function discount()
{
return $this->belongsTo(Discount::class, 'id', 'room_id');
}
So now every hotel has 50 hotels for example and among them only 1 room has the discount I want just to show that 1 room this code now shows all rooms nether they have discount or not if not it shows null for them but I don't want to show the room without discount in my API because it can make it so heavy.
Now it looks like tablea are realted in such a way:
Hotel[id], Room[id, hotel_id], Discount[id, room_id]
That means that Rooms->Discount is not belongsTo() -> it is hasMany(), hence should be named as: Room->Discounts() - so one room has several discounts:
public function discounts()
{
return $this->hasMany(Discount::class, 'id', 'room_id');
}
And based on this - there could be placed one more relation in Hotel:
public function roomDiscounts()
{
return $this->hasManyThrough(Discount::class, Room::class, 'hotel_id', 'room_id', 'id', 'id');
}
So, you want to find all hotels where rooms have discounts:
$hotels = Hotel::whereHas('roomDiscounts')->get();
Hope it will help.

How can I use relationship with Laravel?

My database stockcomment table as below;
id|user_id|stock_id|comment
1 | 10 | 9034 |RC MONSTER CAR
2 | 1 | 9034 |very cool car
My databese user table as below;
id |user_name |
1 | Ufuk ÇAĞLAR |
10 | Mariana Atencio |
How can I relate to each other.
How to access user information with comments?
I want to do output :
[{"id":1,"user _id":1,"stock_id":9034,"comment":RC MONSTER CAR,"user_name":"Ufuk ÇAĞLAR",
"id":2,"user _id":10,"stock_id":9034,"comment":VERY COOL CAR,"user_name":"MARIANA ATANCIO",]
You can define User Model and StockComment
now in User model.
public function stockComments(){
return $this->hasMany(StockComment::class);
}
Now you can access User object with $user->stockComments
Here is an example
$user = User::find($id);
$user->stockComments;
Hope this helps
Assuming you have User and Stock models and users, stocks and stockcomment tables, you can set a relationship from your user model
public function stock() {
return $this->belongsTo(Stock::class)->withPivot('comment');
}
Then in your stock model
public function users() {
return $this->hasMany(User::class)->withPivot('comment');
}
Then you call them:
$stock = User::find($id)->stock; //Stock from this user
//or
$users = Stock::find($id)->users; //Users from this stock
EDIT:
How to access user information with comments?
With using Query Builder:
$data = DB::table('stockcomment')->where('stock_id', 9034)->get();
or if you have StockComment model and a relationship towards Stock on it, you can do:
$data = StockComment::where('stock_id', 9034)->get();
$data will be:
[
{
"id":1,"user_id":1,"stock_id":9034,"comment":RC MONSTER CAR,"user_name":"Ufuk ÇAĞLAR"
},
{
"id":2,"user_id":10,"stock_id":9034,"comment":VERY COOL CAR,"user_name":"MARIANA ATANCIO"
}
]
Define this relationships in StockComment model:
public function user()
{
return $this->belongsTo(User::class);
}
And this relationship in the User model:
public function stockComments()
{
return $this->hasMany(StockComment::class);
}
https://laravel.com/docs/5.5/eloquent-relationships
On the User model, you need to create a hasMany relationship.
public function stockcomments()
{
return $this->hasMany(StockComment::class);
}
Once created, you'll be able to fetch the comments by doing
$user->stockcomments;
This will return a Collection which will allow you to iterate through
You can use joins to achieve desire result, here is your updated code
$result = User::join('stockcomment', 'users.id', '=', 'stockcomment.user_id')
->select('users.id', 'stockcomment.stock_id', 'stockcomment.comment',stockcomment.username)
->get();

Insert in many to many relation laravel 5

I have 2 models:
class Order extends Model
{
protected $fillable = ['user_id','name','surname','fathers_name','phone_number','city','post_office','comment'];
public function user()
{
return $this->belongsTo('App\User');
}
public function products()
{
return $this->belongsToMany('App\Product', 'order_product');
}
}
class Product extends Model
{
public function order()
{
return $this->belongsToMany('App\Order', 'order_product');
}
public function category()
{
return $this->belongsTo('App\Category');
}
}
3 tables:
product:
id
name
...
order_product:
id
order_id
prod_id
qty
...
order
id
city
phone
...
and 2 arrays of data:
$data = $request->except('_token','submit'); - information about client
$order_content - array with info about products in cart
So, the question is how to insert all this data in DB? I tried to read about many to many insertion: sync, attach, etc.. but understood nothing :c
Imagine you have a product with id 1. And an order with id 1. The product is part of the order, so you have to attach them. You do
$product = Product::find(1);
$order = Order::find(1);
$order->products()->attach($order->id);
However, in your case, your pivot table has more data, like 'qty'. Then you do,
$order->product()->attach($order->id, ['qty' => 2]);
So far, we were only attaching a single product to an order. If you want to attach many products simultaneously, you do:
$order->products()->sync([
$product->id => ['qty' => 1],
$product2->id => ['qty' => 3]
]);
I hope this helps understand better. I recommend you read the doc again and again until it makes sense.

Laravel Eloquent get json from nested mysql data

I have tabel like this
id name parent_id order_id
1 software 0 1
2 hardware 0 2
3 windows 1 3
4 linux 1 4
5 mouse 2 5
6 keyword 2 6
And I use Laravel 5.1 Eloquent
How to get data in model like this
[{"id":1,"children":[{"id":3},{"id":4}]},{"id":2,"children":[{"id":5},{"id":6}]}]
There is a best way to do this.
The package etrepat/baum is so awesome and easy. It has everything you need about nesting elements. Just add it to your composer dependencies and enjoy.
You can also add these methods to your Model and use them as relations.
public function parent() {
return $this->belongsTo(self::class, 'parent_id');
}
public function children() {
return $this->hasMany(self::class, 'parent_id');
}
Then you will simply say:
$results = MyModel::with('children')->get();
Update for comment:
$results = Category::select('id','name')->with([
'children' => function($query) {
$query->select('id', 'parent_id');
// You can customize the selected fields for a relationship like this.
// But you should select the `key` of the relationship.
// In this case it's the `parent_id`.
}
])->get();

Categories