How to merge these two function with Laravel query builder - php

I need to export final amount after calculation of all payable and receivable of a member now I do in two function how to merge them
public function memberReceivable($id){
return $this->join('transactions', 'transactions.id', '=', 'member_transactions.transaction_id')
->leftjoin('accounts', 'accounts.id', '=', 'transactions.account_id')
->selectRaw("transactions.unit as currency,sum(transactions.amount) as amount")
->where('accounts.type','accountsReceivable')
->where('member_transactions.member_id',$id)
->groupBy('transactions.unit')->get();
}
public function memberPayable($id){
return $this->join('transactions', 'transactions.id', '=', 'member_transactions.transaction_id')
->leftjoin('accounts', 'accounts.id', '=', 'transactions.account_id')
->selectRaw("transactions.unit as currency,sum(transactions.amount) as amount")
->where('accounts.type','accountsPayable')
->where('member_transactions.member_id',$id)
->groupBy('transactions.unit')->get();
}

public function member($id = null, $type = ""){
$response = $this->join('transactions', 'transactions.id', '=',
'member_transactions.transaction_id')
->leftjoin('accounts', 'accounts.id', '=', 'transactions.account_id')
->selectRaw("transactions.unit as currency,sum(transactions.amount) as amount");
if($type){
$response->where('accounts.type', $type);
}
if($id){
$response->where('member_transactions.member_id',$id);
}
$response->groupBy('transactions.unit')->get();
return $response;
}
You can try it.

Related

how to use Join with Where condition in laravel controller?

i have this index function that will show data from two different tables:
public function index()
{
$complaints = DB::table('complaint')
->select(['complaint.id','complaint.createdDate','complaint.user_id','complaint.createdDate','complaint.complaint_title','tbl_users.phone','tbl_users.email'])
->join('tbl_users', 'complaint.user_id', '=', 'tbl_users.id')
->get();
return view('admin.complaints',compact('complaints'));
}
and in the next function i want to show a single row using the same thing above by 'id'
i tired this:
public function show($id)
{
$complaints = DB::table('complaint')
->select(['complaint.id','complaint.createdDate','complaint.user_id','complaint.createdDate','complaint.complaint_title','tbl_users.phone','tbl_users.email'])
->join('tbl_users', 'complaint.user_id', '=', 'tbl_users.id')
->where('id', $id)->first()
->get();
return $complaints;
}
but i'm getting this error
Call to undefined method stdClass::get()
For creating where statements, you can use get() and first() methods. The first() method will return only one record, while the get() method will return an array of records , so you should delete first() , so the code should be like that .
public function show($id)
{
$complaints = DB::table('complaint')
->select(['complaint.id','complaint.createdDate','complaint.user_id','complaint.createdDate','complaint.complaint_title','tbl_users.phone','tbl_users.email'])
->join('tbl_users', 'complaint.user_id', '=', 'tbl_users.id')
->where('id', $id)
->get();
return $complaints;
}

How to get Billing Address from Eloquent model with where clause?

For example I can use:
$address = $user->address
which will return the addresses for the user.
// User.php (model)
public function address()
{
return $this->hasMany(Address::class, 'refer_id', 'id');
}
public function billingAddress()
{
return $this->address()
->where('type', '=', 1)
->where('refer_id', '=', $this->id)
->first();
}
However, I would like to return the BillingAddress for the user depending on this where clause. How do I do it?
EDIT:
If I use this inside... OrderController#index it returns correctly
$orders = Order::with('order_fulfillment', 'cart.product', 'user.address', 'payment')->get();
return new OrderResource($orders);
However, If I change it to:
$orders = Order::with('order_fulfillment', 'cart.product', 'user.billingAddress', 'payment')->get();
return new OrderResource($orders);
I get this error:
Symfony\Component\Debug\Exception\FatalThrowableError
Call to a member function addEagerConstraints() on null
One option is you can use whereHas in your query. For example,
$orders = Order::with('order_fulfillment', 'cart.product', 'user.address', 'payment')
->whereHas(
'address', function ($query) {
$query->where('type', '=', 1)
->first();
}
)->get();
return new OrderResource($orders);
This is one option. try to dd($orders) an find if its working.
You had an another option like this, in your model
public function address()
{
return $this->hasMany(Address::class, 'refer_id', 'id');
}
Add relations like
public function billingAddress()
{
return $this->hasOne(Address::class, 'refer_id', 'id')->where('type', 1);
}
And
public function shippingAddress()
{
return $this->hasOne(Address::class, 'refer_id', 'id')->where('type', 2);
}
Then in your query,
$orders = Order::with('order_fulfillment', 'cart.product', 'user.address','user.billingAddress', 'user.shippingAddress', 'payment')->get(); return new OrderResource($orders);

Use variable in relationship

I have some customfield functionality on my site where users can add custom fields to a model.
I've just found that if you enter data into one of the fields the same field won't show up for another model because of the way I get the empty fields for a model
public function Customfield()
{
return $this->hasMany(Customfield::class);
}
public function getEmptyCustomfields($model)
{
return $this->has('customfield', '<', 1)
->select('customfieldslabels.id as label_id', 'customfieldslabels.datatype as datatype', 'customfieldslabels.label_name as label_name',
'customfieldslabels.customfield_tab_id as customfield_tab_id', 'customfieldstabs.name as name')
->join('customfieldstabs', 'customfieldstabs.id', '=', 'customfieldslabels.customfield_tab_id')
->where('customfieldstabs.model', '=', $model)
->get();
}
public function getEmptyCustomfieldsByTab($tabIDm)
{
return $this->has('customfield', '<', 1)->where('customfield_tab_id', '=', $tabID)->get();
}
This is what I had originally and I realised that if a label has a field that is assigned to another model then the relationship exists and won't return as empty for another model.
So I'm trying to also check against the model ID now but I'm not quite sure how to use the model ID while checking the relationship
public function Customfield()
{
return $this->hasMany(Customfield::class);
}
public function customfieldByModel($modelID)
{
return $this->has('customfield' => function ($query) use ($modelID){
$query->where('model_id', '=', $modelID);
})->get();
}
public function getEmptyCustomfields($model, $modelID)
{
return $this->has($this->customfieldByModel($modelID), '<', 1)
->select('customfieldslabels.id as label_id', 'customfieldslabels.datatype as datatype', 'customfieldslabels.label_name as label_name',
'customfieldslabels.customfield_tab_id as customfield_tab_id', 'customfieldstabs.name as name')
->join('customfieldstabs', 'customfieldstabs.id', '=', 'customfieldslabels.customfield_tab_id')
->where('customfieldstabs.model', '=', $model)
->get();
}
public function getEmptyCustomfieldsByTab($tabIDm, $modelID)
{
return $this->has($this->customfieldByModel($modelID), '<', 1)->where('customfield_tab_id', '=', $tabID)->get();
}
I would like to return empty fields for one model that they haven't been filled in for yet.
They return just find once there is data for a model assigned to a field as it doesn't need to check for empty fields anymore.
UPDATE
I've tried using a left join which I think will work but I can't get to the method because I get an error saying: 'The method name must be a string'
I changed this
public function getEmptyCustomfieldsByTab($tabID, $modelID)
{
return $this->has($this->customfieldByModel($modelID), '<', 1)->where('customfield_tab_id', '=', $tabID)->get();
}
To this:
public function getEmptyCustomfieldsByTab($tabID, $modelID)
{
return $this->has('customfieldbymodel', '<', 1)->where('customfield_tab_id', '=', $tabID)->get();
}
But now I can't send the $modelID as a parameter. Is it possible to sned a parameter while doing a has?
MY SOLUTION
I have created a protected variable on the model that just gets reassigned everytime.
protected $modelID;
public function customfieldByModel()
{
return $this->hasMany(Customfield::class)->where('model_id', '=', $this->modelID);
}
public function getEmptyCustomfields($model, $modelID)
{
$this->modelID = $modelID;
return $this->has('customfieldByModel', '<', 1)
->select('customfieldslabels.id as label_id', 'customfieldslabels.datatype as datatype', 'customfieldslabels.label_name as label_name',
'customfieldslabels.customfield_tab_id as customfield_tab_id', 'customfieldstabs.name as name')
->join('customfieldstabs', 'customfieldstabs.id', '=', 'customfieldslabels.customfield_tab_id')
->where('customfieldstabs.model', '=', $model)
->get();
}
public function getEmptyCustomfieldsByTab($tabID, $modelID)
{
$this->modelID = $modelID;
return $this->has('customfieldByModel', '<', 1)->where('customfield_tab_id', '=', $tabID)->get();
}

Print the name of function has highest value

My 3 different function given me value as below: in JSON.
I want to PRINT name of function which has highest value. The Functions are;
public function firstHourTrades()
{
$user_id = Auth::user()->id;
$data = DB::table('finaltrade')
->select(DB::raw('count(*) as first_hour'))
->join('exchanges', 'finaltrade.exchange_id', '=', 'exchanges.id')
->where('finaltrade.user_id', $user_id)
->whereTime(DB::raw('IF(finaltrade.buy_datetime<finaltrade.sell_datetime, finaltrade.buy_datetime, finaltrade.sell_datetime) '), '>=', DB::raw('exchanges.start_time'))
->whereTime(DB::raw('IF(finaltrade.buy_datetime<finaltrade.sell_datetime, finaltrade.buy_datetime, finaltrade.sell_datetime) '), '<=', DB::raw("ADDTIME(exchanges.start_time, '1:00:00')"))
->get();
return response()->json($data);
}
public function lastHourTrades()
{
$user_id = Auth::user()->id;
$data = DB::table('finaltrade')
->select(DB::raw('count(*) as last_hour'))
->join('exchanges', 'finaltrade.exchange_id', '=', 'exchanges.id')
->where('finaltrade.user_id', $user_id)
->whereTime(DB::raw('IF(finaltrade.buy_datetime<finaltrade.sell_datetime, finaltrade.buy_datetime, finaltrade.sell_datetime) '), '<=', DB::raw('exchanges.close_time'))
->whereTime(DB::raw('IF(finaltrade.buy_datetime<finaltrade.sell_datetime, finaltrade.buy_datetime, finaltrade.sell_datetime) '), '>=', DB::raw("SUBTIME(exchanges.close_time, '01:00:00')"))
->get();
return response()->json($data);
}
public function otherHoursTrades()
{
$user_id = Auth::user()->id;
$data = DB::table('finaltrade')
->select(DB::raw('count(*) as other_hours'))
->join('exchanges', 'finaltrade.exchange_id', '=', 'exchanges.id')
->where('finaltrade.user_id', $user_id)
->whereRaw('finaltrade.created_at NOT BETWEEN exchanges.start_time AND DATE_ADD(exchanges.start_time, INTERVAL 1 HOUR)')
->whereRaw('finaltrade.created_at NOT BETWEEN exchanges.close_time AND DATE_SUB(exchanges.close_time, INTERVAL 1 HOUR)')
->get();
return response()->json($data);
}
FROM THE ANSWER I HAVE CREATED:
public function allCmp()
{
$func_names = ['firstHourTrades()','lastHourTrades()','otherHoursTrades()'];
foreach($func_names as $name)
$results[$name] = $name();
$max = max($results);
DD($max);
}
<?php
function one()
{
return 1;
}
function two()
{
return 2;
}
function three()
{
return 3;
}
$func_names = ['three','one','two'];
// Call each function and store result.
foreach($func_names as $name)
$results[$name] = $name();
$max = max($results);
$max_funcs = array_keys($results, $max);
var_dump($max_funcs);
Output:
array(1) {
[0]=>
string(5) "three"
}
You may need to decode your JSON at some point, something like:
function get_val_from_my_json($json) {
return array_values(json_decode($json, true))[0];
}
print get_val_from_my_json('{"some_key":5}');
Output:
5
And run all the results through that function (assuming valid json).
$results = array_map('get_val_from_my_json', $results);

Loop over Laravel Collection

public function showJobCategoryContent($id){
$jobsInfoById = DB::table('jobs')->where('category_id', '=', $id)->where('published', '=', 1)->paginate(3);
// Imagine here i got 5 data
foreach ($jobsInfoById as $jobInfoById) {
return $current=$jobInfoById->created_at;
//$trialExpires []= $current->addDays(30);
}
}
If i loop it it only show 1 data. How is it possible If use array sign then it will show 1 data.
If you want to get an array of all created_at dates, you don't need a loop.
public function showJobCategoryContent($id)
{
$jobsInfoById = DB::table('jobs')->where('category_id', '=', $id)->where('published', '=', 1)->paginate(3);
return $jobsInfoById->pluck('created_at');
}
Using the loop:
public function showJobCategoryContent($id)
{
$jobsInfoById = DB::table('jobs')->where('category_id', '=', $id)->where('published', '=', 1)->paginate(3);
$dates = [];
foreach ($jobsInfoById as $jobInfoById) {
$dates[] = $current = $jobInfoById->created_at;
}
return $dates;
}
If want to add 30 days to each date:
public function showJobCategoryContent($id)
{
$jobsInfoById = DB::table('jobs')->where('category_id', '=', $id)->where('published', '=', 1)->paginate(3);
$jobsInfoById = $jobsInfoById->map(function ($job) {
return $job->created_at->addDays(30);
});
return $jobsInfoById->pluck('created_at');
}
Have a look at Laravel collections and how they can be useful: link

Categories