Rails 3. Get totals from array - ruby-on-rails

I'm printing out a table with line totals but I also want to get the grand total of the columns. This following code doesn't work, instead of the grand totals it just prints out the values of the last iteration.
<% #shipments.each do |shipment| %>
<tr>
<td style="text-align:center;"><%= shipment.file_number %></td>
<td><%= shipment.shipper.company_name %></td>
<td><%= shipment.hbl %></td>
<td><%= shipment.status %></td>
<td><%= shipment.age %></td>
<td><%= shipment.invoice.read_issued_at unless shipment.invoice.nil? %></td>
<td><%= number_to_currency shipment.invoice.customer_total unless shipment.invoice.nil? %></td>
<td><%= number_to_currency shipment.invoice.customer_amount_paid unless shipment.invoice.nil? %></td>
<td><%= number_to_currency shipment.invoice.customer_open_balance unless shipment.invoice.nil? %></td>
</tr>
<%
grand_customer_total = 0
grand_customer_amount_paid = 0
grand_customer_open_balance = 0
grand_customer_total += shipment.invoice.customer_total
grand_customer_amount_paid += shipment.invoice.customer_amount_paid
grand_customer_open_balance += shipment.invoice.customer_open_balance
%>
<% if #shipments.last == shipment %>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<th>Totals</th>
<td><%= number_to_currency grand_customer_total %></td>
<td><%= number_to_currency grand_customer_amount_paid %></td>
<td><%= number_to_currency grand_customer_open_balance %></td>
</tr>
<% end %>

The reason your code isn't working is that your variables are defined in the block, so they're considered block-local variables. Once the block is exited those variables are marked to be cleared; each iteration re-defines those variables. It also doesn't help that you're reassigning them to 0 on each iteration, but that isn't even coming into effect here because the variables aren't defined each time through.
You could simply define the variables before the block, but that's still pretty messy. Since Ruby idioms and conventions put an emphasis on clean and well-organized code, I'd stray away from that and instead calculate these numbers separately, possibly in your controller.
#totals = {
:overall => #shipments.reduce(0) { |total, shipment| total + shipment.invoice.customer_total },
:paid => #shipments.reduce(0) { |total, shipment| total + shipment.invoice.customer_amount_paid },
:balance => #shipments.reduce(0) { |total, shipment| total + shipment.invoice.customer_open_balance }
}
Then, instead of using #shipments.last comparison, you can just do the following after your shipments table output:
<tr>
<td colspan="5"></td>
<th>Totals</th>
<td><%= number_to_currency #totals[:overall] %></td>
<td><%= number_to_currency #totals[:paid] %></td>
<td><%= number_to_currency #totals[:balance] %></td>
</tr>

You set the grand total to zero every time through the loop. move the initialization up before the loop.

you can use ruby inject
something like
#shipments.inject(0) { |sum, shipment| sum + shipment.invoice.customer_total }
or to keep with your code layout, just initialize the grand_customer_* objects outside of the #shipments.each loop because you are resetting them every time through

<%
grand_customer_total = 0
grand_customer_amount_paid = 0
grand_customer_open_balance = 0
%>
<% #shipments.each do |shipment| %>
<tr>
<td style="text-align:center;"><%= shipment.file_number %></td>
<td><%= shipment.shipper.company_name %></td>
<td><%= shipment.hbl %></td>
<td><%= shipment.status %></td>
<td><%= shipment.age %></td>
<td><%= shipment.invoice.read_issued_at unless shipment.invoice.nil? %></td>
<td><%= number_to_currency shipment.invoice.customer_total unless shipment.invoice.nil? %></td>
<td><%= number_to_currency shipment.invoice.customer_amount_paid unless shipment.invoice.nil? %></td>
<td><%= number_to_currency shipment.invoice.customer_open_balance unless shipment.invoice.nil? %></td>
</tr>
<%
grand_customer_total += shipment.invoice.customer_total
grand_customer_amount_paid += shipment.invoice.customer_amount_paid
grand_customer_open_balance += shipment.invoice.customer_open_balance
%>
<% if #shipments.last == shipment %>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<th>Totals</th>
<td><%= number_to_currency grand_customer_total %></td>
<td><%= number_to_currency grand_customer_amount_paid %></td>
<td><%= number_to_currency grand_customer_open_balance %></td>
</tr>
<% end %>

Related

Iterate in array of hashes in side array in ruby

I want to iterate this oject and print in table
[
{
:invoice_details=>
{
:customer_name=>"Dylan Sollfrank",
:invoice_number=>"1060",
:invoice_status=>"paid",
:transaction_total_amount=>50.0,
:trnsaction_details=>
[
{
:transaction_number=>"QB1601361635",
:customer_name=>"Dylan Sollfrank",
:amount=> {:amount_to_pay=>50.0, :payment_fee=>0.0},
:created_time=>"12:10 PM",
:created_date=>"Sep 29,2020",
:payment_method=>"Quickbook",
:payment_status=>"completed"
}
]
}
}
]
invoice_details in one row and transaction_details in another row in table format. transaction_details is an array inside the invoice_details.
EDIT
I did it by
I did it
<% ar_activity.first.each do |invoice, invoices_hash| %>
<tr>
<td><%= invoices_hash[:invoice_number] %> </td>
<td><%= invoices_hash[:invoice_status]%></td>
<td><%= invoices_hash[:customer_name] %> </td>
<td><%= invoices_hash[:transaction_total_amount]%></td>
</tr>
<% invoices_hash[:trnsaction_details].each do |transaction|%>
<tr>
<td></td>
<td><%= transaction[:transaction_number]%></td>
<td><%= transaction[:customer_name]%></td>
<td><%= transaction[:amount][:amount_to_pay].to_f + transaction[:amount][:payment_fee].to_f%></td>
<td><%= "#{transaction[:created_time]} " "#{transaction[:created_date]}" %></td>
<td><%= transaction[:payment_method] %></td>
<td><%= transaction[:payment_status] %></td>
</tr>
<%end%>
<%end%>
but its only good for the first invoice_details so it's not working
Thanks
I did it
<% ar_activity.each do |invoices|%>
<% invoices.each do |invoice, invoices_hash| %>
<tr>
<td><%= invoices_hash[:invoice_number] %> </td>
<td><%= invoices_hash[:invoice_status]%></td>
<td><%= invoices_hash[:customer_name] %> </td>
<td><%= invoices_hash[:transaction_total_amount]%></td>
</tr>
<% invoices_hash[:trnsaction_details].each do |transaction|%>
<tr>
<td></td>
<td><%= transaction[:transaction_number]%></td>
<td><%= transaction[:customer_name]%></td>
<td><%= transaction[:amount][:amount_to_pay].to_f + transaction[:amount][:payment_fee].to_f%></td>
<td><%= "#{transaction[:created_time]} " "#{transaction[:created_date]}" %></td>
<td><%= transaction[:payment_method] %></td>
<td><%= transaction[:payment_status] %></td>
</tr>
<%end%>
<%end%>
<%end%>

Capybara check if no selector has text of numbers greater than 500

I want to check if there are 0 instances of numbers greater than 500 in all of the rows of a table.
The table looks like this:
<% #trips.each do |trip| %>
<tr class="trip-row" data-categories= "<%= #categories.map(&:name).join(":") %>">
<td id="ranking"><%= #trips.index(trip) + 1 %></td>
<td id="trip-title"> <%= trip.title %> </td>
<td><%= trip.departure_city %></td>
<td><%= trip.arrival_city %></td>
<td><%= trip.departure_airline %></td>
<td><%= trip.short_description %></td>
<td><%= trip.departure_date.strftime("%b %d, %Y, %I:%M") %></td>
<td><%= trip.return_date.strftime("%b %d, %Y, %I:%M") %></td>
<td><%= trip.price %></td>
<td><%= link_to "Details", real_trip_path(trip, info: { departure_date: trip.departure_date, return_date: trip.return_date, price: trip.price }), class: "btn btn-info" %></td>
</tr>
<% end %>
Can I write this:
within all(".trip-row") do
refute page has.content? #number greater than 500?
end
You can evaluate values in each cell rather than row by row.
page.all(.'trip-row td').each do |c|
#evaluate here
end
You'll probably want to use regex to pull the numbers out from each cell, then evaluate from there using an rspec expectation.

How to display a list based on date in rails?

I'm trying to build a real simple event listing app that list a bunch of event based on Dates. I'm fairly new and was wondering how would I display a list or table based on dates? This is what I have now.
<thead>
<tr>
<th>Title</th>
<th>Description</th>
<th>Link</th>
<th>Date</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #events.each do |event| %>
<tr>
<td><%= event.title %></td>
<td><%= event.description %></td>
<td><%= event.link %></td>
<td><%= event.date %></td>
<td><%= link_to 'Show', event %></td>
<td><%= link_to 'Edit', edit_event_path(event) %></td>
<td><%= link_to 'Destroy', event, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
I would like it display in a date format. For example all events under the date of February/21 will appear under that specific heading.
Thanks!
You can try something like this:
<% #events.group_by(&:date).each do |date, events| %>
<tr><td colspan="7"><h1><%= date %></h1></td></tr>
<% events.each do |event| %>
<tr>
<td><%= event.title %></td>
<td><%= event.description %></td>
<td><%= event.link %></td>
<td><%= event.date %></td>
<td><%= link_to 'Show', event %></td>
<td><%= link_to 'Edit', edit_event_path(event) %></td>
<td><%= link_to 'Destroy', event, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
<% end %>

Rails create new records based on checked records

I have a table showing time entries (events) related to a workorder.
The user can enter a check on any of the table rows.
For each checked row, I want to create a new record in the invtime table.
invtime belongs_to :event
event has_many :invtimes
This is the table:
<table>
<thead>
<tr>
<th>Title</th>
<th>Employee</th>
<th>Date</th>
<th>Hours</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% Event.where("workorder_id = ?", Invoice.find(#invoice).workorder_id).where("billed = ?", false).each do |event| %>
<tr>
<td><%= check_box_tag(:add_record) %></td>
<td><%= event.title %></td>
<td><%= event.employee.employee_full_name %></td>
<td><%= event.starts_at.strftime("%m/%d/%Y") %></td>
<td><%= event.hours %></td>
<td></td>
</tr>
<% end %>
</tbody>
</table>
I'm not sure how to process the returned page with the checkboxes checked.
Should I use Javascript (coffeescript)? Or can I do it with Ruby?
This should do it:
<tbody>
<%= form_tag(your_path_helper) do %>
<% Event.where("workorder_id = ?", Invoice.find(#invoice).workorder_id).where("billed = ?", false).each do |event| %>
<tr>
<td><%= check_box_tag 'event_ids_to_save[]', value: event.id, checked: Invtime.exists?(event_id: event.id) %></td>
<td><%= event.title %></td>
<td><%= event.employee.employee_full_name %></td>
<td><%= event.starts_at.strftime("%m/%d/%Y") %></td>
<td><%= event.hours %></td>
<td></td>
</tr>
<% end %>
<tr><td colspan='6'><%= submit_tag %></td></tr>
<% end %>
</tbody>
The corresponding action of the controller responding to the form_tag submit:
def action_of_the_form_tag
params[:event_ids_to_save].each do |event_id|
event = Event.where(id: event_id)
# do your logic here
end
end

Using a if statement in a looped table rails

I have two models, one with cards and another with their associated rewards programs. I'm showing all of them in a table with a conditional if statement in some of the columns but I can't figure out why an if else statement screws up my columns. I posted two examples one that works and one that doesn't. I need the second one to work to add some additional functionality
This example works
<table>
<tr>
<th>Card</th>
<th>General Rewards</th>
<th>Gas Amount</th>
<th>Movies Amount</th>
<th>Museums Amount</th>
<th>Theme Park Amount</th>
<th>Restaurant Amount</th>
<th>Department Store Amount</th>
</tr>
<% #cards.each do |card| %>
<tr>
<td><%= card.name %></td>
<td><%= card.general_rate %> </td>
<% card.rewards.each do |category| %>
<% if category.name.downcase == "gas" %>
<td><%= category.threshold_check(#gas) %></td>
<% end %>
<% if category.name.downcase == "movies" %>
<td><%= category.threshold_check(#movies) %></td>
<% end %>
<% if category.name.downcase == "museums" %>
<td><%= category.threshold_check(#museums) %></td>
<% end %>
<% if category.name.downcase == "theme parks" %>
<td><%= category.threshold_check(#theme_parks) %></td>
<% end %>
<% if category.name.downcase == "restaurants" %>
<td><%= category.threshold_check(#restaurants) %></td>
<% end %>
<% if category.name.downcase == "department stores" %>
<td><%= category.threshold_check(#department_stores) %></td>
<% end %>
<% end %>
</tr>
<% end %>
</table>
This adds extra columns to the end
<table>
<tr>
<th>Card</th>
<th>General Rewards</th>
<th>Gas Amount</th>
<th>Movies Amount</th>
<th>Museums Amount</th>
<th>Theme Park Amount</th>
<th>Restaurant Amount</th>
<th>Department Store Amount</th>
</tr>
<% #cards.each do |card| %>
<tr>
<td><%= card.name %></td>
<td><%= card.general_rate %> </td>
<% card.rewards.each do |category| %>
<td><%= category.name.downcase == "gas" ? category.threshold_check(#gas) : 0 %></td>
<td><%= category.name.downcase == "movies" ? category.threshold_check(#movies) : 0 %></td>
<td><%= category.name.downcase == "museums" ? category.threshold_check(#museums) : 0 %></td>
<td><%= category.name.downcase == "theme parks" ? category.threshold_check(#theme_parks) : 0 %></td>
<td><%= category.name.downcase == "restaurants" ? category.threshold_check(#restaurants) : 0 %></td>
<td><%= category.name.downcase == "department stores" ? category.threshold_check(#department_stores) : 0 %></td>
<% end %>
</tr>
<% end %>
</table>
If you will notice the main difference between your 2 versions is that the first one if your conditionals dont comply, you will not issue a <td></td>
On the other hand your second version does have <td></td> no matter if the conditionals are true or not.
Maybe that could be the source for your extra columns.
P.S. In your first example I think you have a typo but <%= category.threshold_check(#movies) %> doesn't have an opening <td> and it's closing </td> is outside the if statement.

Resources