Laravel - Using Where Clause with If Statement and Parameter - laravel

I have a Laravel Query with where clause statement and a parameter in it. The $plan coming from the source is string and the values are:
Daily, Weekly, Monthly, Wallet
but the value of $plan in the destination, users table ($users) are:
1,2,3,4
Parameter Source:
#foreach($billings as $key => $billing)
<tr>
<td>{{ ++$key }}</td>
<td><a class="btn btn-info" href="{{ route('revenueDetail',$billing->plan) }}">{{ $billing->plan }}</a></td>
<td>{{ $billing->total_plans }}</td>
<td>{{ $billing->total_amount }}</td>
</tr>
#endforeach
<tr>
<td colspan="8">
{{ $billings->links() }}
</td>
</tr>
Controller: Query
public function revenueDetail($plan = null)
{
$revenuedetails = DB::table("users")
->select(
"users.username",
DB::raw("DATE(users.created_at) as subscription_date")
)
->where('users.plan', $plan)
->get();
}
What I want to achieve is that, in the where clause in revenueDetail() function, if:
$plan = Daily then users.plan = 1
$plan = Weekly then users.plan = 2
$plan = Monthly then users.plan = 3
$plan = Wallet then users.plan = 4
How do I achieve this?

Based on last sentences, i assume you need to map Daily string which == 1
protected static $type = [
'Daily' => 1,
'Weekly' => 2,
'Montly' => 3,
]
then
public function revenueDetail($plan = null)
{
$revenuedetails = DB::table("users")
->select("users.username", DB::raw("DATE(users.created_at) as subscription_date"))
->where('users.plan', self::$type[$plan] ?? null) // ?? will escape exception if $plan is null
->get();
}

From view user should send id instead of value. However if u want to send value you should ask plans table for id of value u send. I recommend to store plans in cache. Another solution is to make class with Constans like your plans (if u dont want to extend it in the future)

Related

Laravel 9 Calling oldestOfMany() in Controller from Model

I have a Customer model and Customer hasMany Xray_machines. I am trying to select the oldest cert_date from the xray_machines table to populate a table in the view that lists the customer_name and the oldest cert_date. I found oldestOfMany() and it seems to be a good option but it is displaying the first cert_date rather than the oldest.
Customer Model
public function xray_machine()
{
return $this->hasMany(Xray_machine::class);
}
public function oldestCert(){
return $this->hasOne(Xray_machine::class)->oldestOfMany('cert_date','min');
}
Controller
public function xray_unscheduled(){
$due = Carbon::now()->addMonth(3)->endOfMonth()->toDateTimeString();
$customers = Customer::whereHas('Xray_machine', function ($query) use($due) {
$query->where('cert_date','<=', $due);
})
->whereNull('xray_scheduled')->orWhere('xray_scheduled','<>','')
->oldestCert()
->orderBy(
Xray_machine::select('cert_date')
->whereColumn('xray_machines.customer_id','customers.id')
->take(1),'asc'
)
->get()->all();
return view('work_orders/xray_unscheduled', compact('customers'));
}
View
#foreach ($customers as $customer)
<tr>
<td>
{{ $customer->customer_name}}
</td>
<td>
{{ \Carbon\Carbon::parse($customer->oldestCert()->cert_date)->format('Y-m-d')}}
</td>
</tr>
#endforeach

Laravel, how to get selected, db fields

Have a model, from controller, I need access this Model db fields.
Code in controller:
$crud -> get() -> getAttributes();
//$crud->attributesToArray()
print_r($crud);
I was able to get entire table fields, but I need only fields, which are selected. Need dynamically show table with selected fields only, which can change during run time.
Assume you have a query:
$query = Crud::select('id as Id', 'name as Name', 'something')
->selectRaw('CONCAT(id, "-", name) as Serial')
->get();
Without knowing what the query is, to get a table that looks like this
Id
Name
something
Serial
1
A
lorem
1-A
..
....
.........
......
You need to use the Builder instance (before calling ->get()
$query = Crud::select('id as Id', 'name as Name', 'something')
->selectRaw('CONCAT(id, "-", name) as Serial');
$results = $query->get();
dump($query->getQuery()->columns);
/*
[
'id as Id',
'name as Name',
'something',
Illuminate\Database\Query\Expression
]
*/
dump(array_map(function ($column) {
return $column instanceof Illuminate\Database\Query\Expression
? Str::afterLast($column->getValue(), 'as ')
: Str::afterLast($column, 'as ');
}, $query->getQuery()->columns));
/*
[
'Id',
'Name',
'something',
'Serial'
]
*/
So you could that to a view.
$query = Crud::select('id as Id', 'name as Name', 'something')
->selectRaw('CONCAT(id, "-", name) as Serial')
->get();
$columns = array_map(function ($column) {
return $column instanceof Illuminate\Database\Query\Expression
? Str::afterLast($column->getValue(), 'as ')
: Str::afterLast($column, 'as ');
}, $query->getQuery()->columns);
$results = $query->get();
return view('view', compact('columns', 'results'));
And then in your view
<table>
<thead>
<tr>
#foreach ($columns as $column)
<th>{{ $column }}</th>
#endforeach
</tr>
</thead>
<tbody>
#foreach ($results as $result)
<tr>
#foreach ($columns as $column)
<td>{{ $result->{$column} }}</td>
#endforeach
</tr>
#endforeach
</tbody>
</table>
I'm not sure what you mean by 'selected' database fields. If this is a list of column names coming from a form, you can simply pass that to the get() method:
$crud->get([
'id',
'name',
'created_at',
]);
If instead you want a list of the available columns, you can't get that from the model itself (it is unaware of which columns exist). Instead you can use:
$table = (new Crud)->getTable();
$columns = DB::getSchemaBuilder()->getColumnListing($table);
You can use two methods, get() or all()
$crud -> get(['column1', 'column2'])
$crud -> all(['column1', 'column2'])

How to combine html table row with 1 reference and multiple items?

I am wondering if its possible to merge rows with same reference id into one but still display its data.
I am using Laravel and Datatables. Any idea?
From this:
To this:
I am using laravel.
here is my mysql query if it helps:
create temporary table purchasemgmnt
SELECT item_id,item_name FROM astramc.pm_employee_benefits where isactive = 'Yes'
UNION ALL
SELECT item_id,item_name FROM astramc.pm_furn_fixture where isactive = 'Yes'
UNION ALL
SELECT item_id,item_name FROM astramc.pm_ir_supplies where isactive = 'Yes'
UNION ALL
SELECT item_id,item_name FROM astramc.pm_marketing where isactive = 'Yes'
UNION ALL
SELECT item_id,item_name FROM astramc.pm_office_equipments where isactive = 'Yes'
UNION ALL
SELECT item_id,item_name FROM astramc.pm_office_supplies where isactive = 'Yes';
create temporary table purchaserequest
select
ppr.pr_id,
ppri.item_id,
pm.item_name,
ppr.remarks,
ppr.pr_status,
ppr.date_created
from pr_purchase_request as ppr
left join pr_purchase_request_information as ppri
on ppr.pr_id = ppri.pr_id
left join purchasemgmnt as pm on ppri.item_id = pm.item_id order by pr_id asc;
SET #row_number = 0;
select
#row_number:=#row_number + 1 AS rownum,
pr_id,
item_id,
item_name,
remarks,
pr_status,
date_created
from purchaserequest order by pr_id asc;
and my laravel view:
#foreach ($pmrequests as $pmrequest)
<tr>
<td>{{$pmrequest->rownum}}</td>
<td>{{$pmrequest->pr_id}}</td>
<td>{{$pmrequest->item_id}}</td>
<td>{{$pmrequest->item_name}}</td>
<td>{{$pmrequest->remarks}}</td>
<td>{{$pmrequest->date_created}}</td>
<td>{{$pmrequest->pr_status}}</td>
</tr>
#endforeach
Scenario:
Model PurchaseRequestHeader - underlying database table pr_header has many PurchaseRequestDetail - underlying database table pr_Details
Define both way relationship in the Model classes
class PurchaseRequestHeader extends Model
{
protected $table = 'pr_header';
public function details()
{
return $this->hasMany(PurchaseRequestDetails::class, 'pr_id', 'pr_id');
}
}
class PurchaseRequest Detail extends Model
{
protected $table = 'pr_details';
public function header()
{
return $this->belongsTo(PurchaseRequestHeader::class, 'pr_id', 'pr_id');
}
}
Once relationships are defined, we can retrieve all the PurchaseRequestDetail records related/associated with a record of PurchaseRequestHeader.
$data = PurchaseRequestHeader::with('details')->paginate(25);
$data will have PurchaseRequestHeader(s) with related PurchaseRequestDetails which can be rendered on the view
<tbody>
#foreach($data as $header)
<tr>
<td>{{ $header->pr_id }}</td>
<td>
<table><tbody>
#foreach($header->details as $detail)
<tr>
<td> {{ $detail->field1 }}</td>
<td> {{ $detail->field2 }}</td>
<td> {{ $detail->field3 }}</td>
<td> {{ $detail->field4 }}</td>
</tr>
#endforeach
</tbody></table>
</td>
</tr>
#endforeach
</tbody>

Make a sum() of column accessors Laravel

im improving my skills in laravel making a simple challenges web but i stuck on the next problem.
I have the users table with the id, name, mail, etc. The challenges table where i list all the challenges (with columns id, name, body, answer, score) and a third table called "Answers" where i post each try of the users solving a challenge with the columns id, user_id, challenge_id, success (boolean) and score.
Now i'am trying to make a ranking of users with their scores. The problem is to show a sum() of the column 'score' in the table answers where user_id.answers = users.id. So i can get easy the total score for each user.
For now i solved the problem doing this in blade:
#foreach($users as $user)
<tr>
<th>{{ $user->id }}</th>
<td>{{ $user->name }}</td>
<td>Team pindonga</td>
<td>{{ score = DB::table('answers')->where('user_id', $user->id)->sum('score') }} </td> </tr>
#endforeach
works perfectly, but i want to get them by desc score (for now i solved the desc with js but want to get desc order from the eloquent query) and have something like this in the blade:
#foreach($users as $user)
<tr>
<th>{{ $user->id }}</th>
<td>{{ $user->name }}</td>
<td>Team pindonga</td>
<td>{{ $team->score }} </td> </tr>
#endforeach
I was thinking about solve it with accessors doing something like this:
public function getScoreAttribute($value)
{
return $this->groupBy('user_id')->where('user_id', '=', $value)->sum('score');
}
also i have a relationship belongsTo in the answers modle to users and a hasMany in the users to answers. But i'm not sure of how pass the results to blade. Tried in tinker:
>>> \App\Answer::find(1)->score;
=> "3400"
>>> \App\Answer::find(2)->score;
=> "3400"
>>> \App\Answer::find(5)->score;
=> "3400"
allways getting the sum of the id = 1. And with $user->score; in the blade foreach i got a '0'.
Using the relationship with Blade would be {{ $user->answers->sum('score') }}. No accessor needed.
For sorting I would use the sortByDesc collection method.
$users = User::get();
$users = $users->sortByDesc(function ($user) {
return $user->answers->sum('score');
});
I think this is what you're looking for. It takes a while to get used to Eloquent ORM :-)
foreach($users as $user){
print $user->answers->sum('score');
}
https://laravel.com/docs/5.6/queries#aggregates

Laravel print role of user in table

I have a Laravel application. I'm using this package for roles and permissions. It works great.
I would now like to display a table of all users with their roles. Currently I'm solving it through the definition of the following in my UsersController.
public function listUsers()
{
$users_admin = Role::where('name', 'admin')->first()->users()->get();
$users_buyers = Role::where('name', 'buyer')->first()->users()->get();
$users_sellers = Role::where('name', 'seller')->first()->users()->get();
return view('admin.users.index', [
'users_admin' => $users_admin,
'users_buyers' => $users_buyers,
'users_sellers' => $users_sellers
]);
}
In the view, I then have 3 separate loops to display 3 tables (for admin users, buyers and sellers).
Needless to say I don't really like this approach and I would ideally have a single table displaying the users with their role.
So the idea is that I can write the following code (or similar) in the UsersController:
$users = User::all();
while my view contains a single foreach stating the following:
#foreach( $users_sellers as $user )
<tr>
<td align="center" class="hidden-xs">{{ $user->id }}</td>
<td>{{ $user->name }}</td>
<td>{{ $user->email }}</td>
<td>{{ $user->displayRole($user->id) }}</td>
</tr>
#endforeach
In the above pseudocode, I have defined a helper that retrieves the role based on the user-id. Problem is I can't figure out what to put in the helper function?
Note: if there are other (better) methods than a helper, that would work as well for me.
As far as I see this package adds a relation in your User model, so $user->roles should be a collection with the roles assigned to the current user. To not make a query for each user you should eager load the users with their roles, like this: $users = User::with('roles')->get();.
In your Controller, get the Role, if you have it in your table
public function listUsers()
{
$users_admin = Role::where('name', 'admin')->first()->users()->get();
$users_buyers = Role::where('name', 'buyer')->first()->users()->get();
$users_sellers = Role::where('name', 'seller')->first()->users()->get();
$role = Role::get();
return view('admin.users.index', [
'users_admin' => $users_admin,
'users_buyers' => $users_buyers,
'users_sellers' => $users_sellers
'role' => $role
]);
}
In your view, just print the Role's name like this
#foreach( $users_sellers as $user )
<tr>
<td align="center" class="hidden-xs">{{ $user->id }}</td>
<td>{{ $user->name }}</td>
<td>{{ $user->email }}</td>
<td>{{ $role['$user->id']['role_name']</td>
</tr>
#endforeach
Note :
<td>{{ $role['$user->id']['role_name']</td>
This line depends on how you send the $role from controller to your view. It's purpose is to return the name of the role's id's array
Hope this helps you.

Resources