Laravel Sum each section using foreach - laravel-5

I have below table with data.
ID - CLASS - CATEGORY - AMOUNT
--------------------------------
1 I A 5000
2 I B 6000
3 I C 7000
4 V A 9000
5 V B 12000
now I want to sum the amount classwise in blade.php using foreach loop. like class I total is 18000, class V 21000 etc..
Controller Function:
$viewRecords = YearlyFees::Where('registration_id',Auth::user()->id)->get();
return view('yearly_fees_setup',
['viewRecords' => $viewRecords]);
Blade.php
#foreach($viewRecords as $record)
<tr>
<td>{{$record->Standard->class}}</td>
<td>
{{$record->Category->category}}
</td>
<td>{{$record->amount}}
</td>
</tr>
<tr>
<td> ?????? TOTAL of each class </td></tr>
#endforeach
Result:
Class Category Amount
I School Fees 5000
I Tution Fees 6000
I Library Fees 7000
**I WANT TOTAL HERE**
V School Fees 9000
V Tution Fees 12000
**I WANT TOTAL HERE**
Please help

You need to create a variable (or two) inside the for loop do conditionally echo out the total.
#php
$total = 0;
$category = null;
#endphp
#foreach(...)
#php
$total += $record->amount;
#endphp
#if ($category != $record->category)
{{ $total }}
#endif
#endforeach

Related

How to create a list of due dates which are dynamically added base from approved date in Laravel?

I am doing a credit collection app which offer loans to the borrowers. I've been stock in this for so many days now because I can't think of a better way to do it.
SO basically I want to achieve is to have a list of due dates which I will display in the borrower dashboard. for example, the borrower applied for a 2 months loan duration and bi-monthly payment scheme and let say the admin approve it today. So what I want is base from the date today, 12-10-2021 the system will generate 4 due dates(12-25-2021, 12-8-2021, 1-23-2022 and 02-7-2022) and will save them to a separate due dates table.
With regards to the payments, I can analyze the part where the system can check if the payment is done on or before the first due date but how can I tell to the system that the payment is advance payment for the next 3 due date?
what I only have right now is this
$date_approval = Carbon::createFromTimestamp(strtotime($loan_application->date_approval));
$scheme_numdays = $loan_application->scheme->num_days;
$days = (intdiv($date_approval->diff(Carbon::now())->days , $scheme_numdays) + 1) * $scheme_numdays
$due_date = $date_approval->addDays($days)->format('M d Y');
Which can identify the first due date.
Can you help to point to any resources out there than will help me achieve my objective? I am hoping I was able to describe the question and my objective clearly. Any suggestions will be very much appreciated. Thank you so much in advance!
RESPONSE FOR #GRANT
I am following your code
$date_approval = Carbon::createFromTimestamp(strtotime($loanapplication->date_approval));
$scheme_numdays = $loanapplication->scheme->num_days;
$days = (intdiv($date_approval->diff(Carbon::now())->days , $scheme_numdays) + 1) * $scheme_numdays;
$due_date = $date_approval->addDays($days)->format('Y-m-d');
$due_date_plus = $date_approval->addDays(60)->format('Y-m-d');
# Carbon Period usage:
$result = CarbonPeriod::create($due_date, $scheme_numdays.' days', $due_date_plus);
I replace the '# days' in the $result with $scheme_numdays so which contains the number of days.
Then I display it like this,
<div class="col-md-6">
{{$date_approval}}<br/>
{{$loanapplication->date_approval}}<br/>
#foreach ($result as $dt)
{{$dt->format("M d Y")}} <br/>
#endforeach
</div>
the result is
2022-02-27 00:00:00
2021-12-14
Dec 29 2021
Jan 13 2022
Jan 28 2022
Feb 12 2022
Feb 27 2022
Question:
why {{$date_approval}} (2022-02-27 00:00:00) and {{$loanapplication->date_approval}} (2021-12-14) gave different result? The date 2021-12-14 is what I have in my database.
My second question is why the result is five instead of 4 only?
The Data I'm displaying is, the loan duration is 60 days and the payment scheme is on every 15 days or fortnightly.
CarbonPeriod would be perfect for this particular scenario. Have you tried the following:
$date_approval = Carbon::createFromTimestamp(strtotime($loan_application->date_approval));
$scheme_numdays = $loan_application->scheme->num_days;
$days = (intdiv($date_approval->diff(Carbon::now())->days , $scheme_numdays) + 1) * $scheme_numdays
$due_date = $date_approval->addDays($days)->format('Y-m-d');
$due_date_plus = $date_approval->addMonths(8)->format('Y-m-d');
# Carbon Period usage:
$result = CarbonPeriod::create($due_date, '2 months', $due_date_plus);
foreach ($result as $dt) {
echo $dt->format("M d Y");
}
You may need to namespace it:
use Carbon\CarbonPeriod;
Edited answer for followup questions:
<div class="col-md-6">
{{ $date_approval->format('M d Y') }}<br/>
{{ $loanapplication->date_approval->format('M d Y') }}<br/>
#foreach ($result as $dt)
#if($loop->index > 3)
#break
#endif
{{ $dt->format('M d Y') }}<br />
#endforeach
</div>
An alternative is date casting when getting dates from models.
(in loan application model):
protected $casts = [
'date_approval' => 'datetime:M d Y',
];

Laravel total foreach index number

I want to total all the rows to loop, what do I do?
example :
index 0
ixdex 1
I want this ซ
index 2
My code :
#if(isset($unread[$messages_conversation_teachers->conversation_id]))
#foreach($unread[$messages_conversation_teachers->conversation_id] as $_index =>$unreads)
{{$_index}}
#endforeach
#endif
try this $loop->iteration it start from 1 not 0
#if(isset($unread[$messages_conversation_teachers->conversation_id]))
#foreach($unread[$messages_conversation_teachers->conversation_id] as $_index =>$unreads)
{{ $loop->iteration }}
#endforeach
#endif
ref link https://laravel.com/docs/8.x/blade#the-loop-variable

Laravel Display Many to Many with Pivot in Blade

Background:
I have a pivot table with Medication, Patient with pivot element day, time, given, given by and lock.
Example:
id medication_id patient_id Day time given
1 1 (MED X) 1 (Patient X) Yesterday 0900 1
2 1 (MED X) 1 (Patient X) Yesterday 1200 1
3 1 (MED X) 1 (Patient X) Today 0900 0
4 2 (MED Y) 1 (Patient X) Tomorrow 1200 0
5 2 (MED Y) 1 (Patient X) Yesterday 0900 1
6 1 (MED X) 2 (Patient Y) Yesterday 1200 1
7 1 (MED X) 2 (Patient Y) Yesterday 0900 1
8 3 (MED Z) 2 (Patient Y) Yesterday 1200 0
A patient can have the same medication but at multiple times within the same day. Let's say Patient X had Med X yesterday at 0900 and 1200, today at 0900 but not tomorrow.
To see all the Medication assigned to the Patient X
$assignedMeds = $patient->medication()->get();
And passed it into the view.
What I have right now is
#if(isset($assignedMeds))
<div class="card-body">
<table class="table table-hover">
<tbody>
<tr>
<th>Name</th>
<th>Yesterday</th>
<th>Today</th>
<th>Tomorrow</th>
</tr>
#foreach($assignedMeds as $assignedMed)
<tr>
<td>{{$assignedMed->name}}</td>
<td>
#if(($assignedMed->pivot->day) == 'yesterday')
#if($assignedMed->pivot->given)
<i class="fas fa-check green"></i>
<strike>{{$assignedMed->pivot->time}}</strike>
<em>{{$assignedMed->pivot->givenby}}</em>
#else
{{$assignedMed->pivot->time}}
#endif
#endif
</td>
<td>
#if(($assignedMed->pivot->day) == 'today')
#if($assignedMed->pivot->given)
<i class="fas fa-check green"></i>
<strike>{{$assignedMed->pivot->time}}</strike>
<em>{{$assignedMed->pivot->givenby}}</em>
#else
<form method="post" action="/mar/{{$assignedMed->id}}">
#csrf
#method('PATCH')
<input hidden name="givenby" id="givenby" value="1">
<button>{{$assignedMed->pivot->time}}</button>
</form>
#endif
#endif
</td>
<td>
#if(($assignedMed->pivot->day) == 'tomorrow')
{{$assignedMed->pivot->time}}
#endif
</td>
</tr>
#endforeach
</tbody>
</table>
</div>
#endif
And it gives me
Medication Name Yesterday Today Tomorrow
Med X 0900 Given
Med X 0900
Med X 1200 Given
Med Y 0900 Given
Med Y 0900
What I am looking for
What I am trying to get is to display the name of medication once and show the time in it.
Example for Patient X
Medication Name Yesterday Today Tomorrow
Med X 0900 Given 0900
1200 Given
Med Y 0900 Given 0900
You could use the groupBy() and where() Collection methods in your #foreach. It should end up looking like this.
<!-- $index will be the 'name' we grouped by (medication name) -->
#foreach($assignedMeds->groupBy('name') as $index => $assignedMed)
<tr>
<!-- medication name -->
<td>{{ $index }}</td>
<!-- yesterday's medications -->
<td>
#foreach($assignedMed->where('pivot.day', 'Yesterday') as $yesterdaysMeds)
#if($yesterdaysMeds->pivot->given)
<i class="fas fa-check green"></i>
<strike>{{$yesterdaysMeds->pivot->time}}</strike>
<em>{{$yesterdaysMeds->pivot->givenby}}</em>
#else
{{$yesterdaysMeds->pivot->time}}
#endif
<!-- line break -->
<br>
#endforeach
</td>
<!-- today's medications -->
<td>
#foreach($assignedMed->where('pivot.day', 'Today') as $todaysMeds)
#if($todaysMeds->pivot->given)
<i class="fas fa-check green"></i>
<strike>{{$todaysMeds->pivot->time}}</strike>
<em>{{$todaysMeds->pivot->givenby}}</em>
#else
<form method="post" action="/mar/{{$todaysMeds->id}}">
#csrf
#method('PATCH')
<input hidden name="givenby" id="givenby" value="1">
<button>{{$todaysMeds->pivot->time}}</button>
</form>
#endif
<!-- line break -->
<br>
#endforeach
</td>
<!-- tomorrow's medications -->
<td>
#foreach($assignedMed->where('pivot.day', 'Tomorrow') as $tomorrowsMeds)
{{ $tomorrowsMeds->pivot->time }}
<!-- line break -->
<br>
#endforeach
</td>
</tr>
#endforeach

Laravel print object into html table

I have this kind structured object
{
- NewYorkCity: [
-{
Men:100
},
-{
Women: 100
},
],
- Boston: [
-{
Men:120
},
-{
Women: 180
}
I just want to print those inline, like this:
NewyorkCity | 100 | 100
Boston | 120 | 180
I tried this code:
#foreach($cities as $key => $val)
<tr>
<td> {{$key}}</td>
<td>{{$val[1]}}</td>
</tr>
#endforeach
In this situation, $key (city names ) prints without problem.
men and women counts not. it gives error "Array to string conversion "
How can i fix it?
Thanks.
If you would want your array to be indexable you should change your data accordingly e.g.
array(
NewYorkCity => array(
100,
100
)
);
Than you could use $val[0] and $val[1] in your blade foreach loop, but i would not do this, since than there is no clarification what these values stand for. If you would have to provide more data in the future it gets even more messy, so just use $val["Men"] or $val["Women"].
Try $val['Men'] and $val['Women']

How do I parse a plain HTML table with Nokogiri?

I'd like to parse a HTML page with the Nokogiri. There is a table in part of the page which does not use any specific ID. Is it possible to extract something like:
Today,3,455,34
Today,1,1300,3664
Today,10,100000,3444,
Yesterday,3454,5656,3
Yesterday,3545,1000,10
Yesterday,3411,36223,15
From this HTML:
<div id="__DailyStat__">
<table>
<tr class="blh"><th colspan="3">Today</th><th class="r" colspan="3">Yesterday</th></tr>
<tr class="blh"><th>Qnty</th><th>Size</th><th>Length</th><th class="r">Length</th><th class="r">Size</th><th class="r">Qnty</th></tr>
<tr class="blr">
<td>3</td>
<td>455</td>
<td>34</td>
<td class="r">3454</td>
<td class="r">5656</td>
<td class="r">3</td>
</tr>
<tr class="bla">
<td>1</td>
<td>1300</td>
<td>3664</td>
<td class="r">3545</td>
<td class="r">1000</td>
<td class="r">10</td>
</tr>
<tr class="blr">
<td>10</td>
<td>100000</td>
<td>3444</td>
<td class="r">3411</td>
<td class="r">36223</td>
<td class="r">15</td>
</tr>
</table>
</div>
As a quick and dirty first pass I'd do:
html = <<EOT
<div id="__DailyStat__">
<table>
<tr class="blh"><th colspan="3">Today</th><th class="r" colspan="3">Yesterday</th></tr>
<tr class="blh"><th>Qnty</th><th>Size</th><th>Length</th><th class="r">Length</th><th class="r">Size</th><th class="r">Qnty</th></tr>
<tr class="blr">
<td>3</td>
<td>455</td>
<td>34</td>
<td class="r">3454</td>
<td class="r">5656</td>
<td class="r">3</td>
</tr>
<tr class="bla">
<td>1</td>
<td>1300</td>
<td>3664</td>
<td class="r">3545</td>
<td class="r">1000</td>
<td class="r">10</td>
</tr>
<tr class="blr">
<td>10</td>
<td>100000</td>
<td>3444</td>
<td class="r">3411</td>
<td class="r">36223</td>
<td class="r">15</td>
</tr>
</table>
</div>
EOT
# Today Yesterday
# Qnty Size Length Length Size Qnty
# 3 455 34 3454 5656 3
# 1 1300 3664 3545 1000 10
# 10 100000 3444 3411 36223 15
require 'nokogiri'
doc = Nokogiri::HTML(html)
Use CSS to find the start of the table, and define some places to hold the data we're capturing:
table = doc.at('div#__DailyStat__ table')
today_data = []
yesterday_data = []
Loop over the rows in the table, rejecting the headers:
table.search('tr').each do |tr|
next if (tr['class'] == 'blh')
Initialize arrays to capture the pertinent data from each row, selectively push the data into the appropriate array:
today_td_data = [ 'Today' ]
yesterday_td_data = [ 'Yesterday' ]
tr.search('td').each do |td|
if (td['class'] == 'r')
yesterday_td_data << td.text.to_i
else
today_td_data << td.text.to_i
end
end
today_data << today_td_data
yesterday_data << yesterday_td_data
end
And output the data:
puts today_data.map{ |a| a.join(',') }
puts yesterday_data.map{ |a| a.join(',') }
> Today,3,455,34
> Today,1,1300,3664
> Today,10,100000,3444
> Yesterday,3454,5656,3
> Yesterday,3545,1000,10
> Yesterday,3411,36223,15
Just to help you visualize what's going, at the exit from the "tr" loop, the today_data and yesterday_data arrays are arrays-of-arrays looking like:
[["Today", 3, 455, 34], ["Today", 1, 1300, 3664], ["Today", 10, 100000, 3444]]
Alternatively, instead of looping over the "td" tags and sensing the class for the tag, I could have grabbed the contents of the "tr" and then used scan to grab the numbers and sliced the resulting array into "today" and "yesterday" arrays:
tr_data = tr.text.scan(/\d+/).map{ |i| i.to_i }
today_td_data = [ 'Today', *tr_data[0, 3] ]
yesterday_td_data = [ 'Yesterday', *tr_data[3, 3] ]
In real-world development, like at work, I'd use that instead of what I first wrote because it's succinct.
And notice that I didn't use XPath. It's very doable in Nokogiri to use XPath and accomplish this, but for simplicity I prefer CSS accessors. XPath would have allowed accessing individual "td" tag contents, but it also would begin to look like line-noise, which is something we want to avoid when writing code, because it impacts maintenance. I could also have used CSS to drill down to the correct "td" tags like 'tr td.r', but I don't think it would improve the code, it would just be an alternate way of doing it.

Resources