Skip to content

Commit

Permalink
Resolved rubyforgood#55: Add per-site shift reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
glroman committed Jan 1, 2017
1 parent 72d83dd commit 7eba816
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 53 deletions.
16 changes: 13 additions & 3 deletions app/controllers/signatures_reports_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,25 @@

class SignaturesReportsController < ApplicationController
before_action :authenticate_user!
expose(:work_sites) do
WorkSite.where(active: true).select('id, address').order(:address).map do |ws|
[ws.address, ws.id]
end
end

layout 'admin/non_administrate'

def show
@sites = [['All Sites', 0]] + work_sites
@end_date = parse_date params[:end_date], default: Time.zone.today
@begin_date = parse_date params[:begin_date], default: (@end_date - 6.days)
@site_id = ((params[:site] || {})[:id] || 0).to_i

addr_cell = @sites.find {|c| c[1] == @site_id} || ['unknown', 0]
@site_addr = addr_cell[0]

if valid_date_range?
@shift_events = shift_events_for_range(@begin_date, @end_date)
@shift_events = shift_events_for_range(@begin_date, @end_date, @site_id)
else
flash[:error] = 'Invalid date range. Begin date must precede the end date.'
@shift_events = []
Expand All @@ -19,10 +29,10 @@ def show

private

def shift_events_for_range(begin_date, end_date)
def shift_events_for_range(begin_date, end_date, site_id)
SignaturesReport
.for_date_range(beginning: begin_date, ending: end_date)
.pull_join
.pull_join(site_id)
end

def valid_date_range?
Expand Down
14 changes: 12 additions & 2 deletions app/reports/signatures_report.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,23 @@ def csv_headers
# @private
#
# @return [ActiveRecord::Relation]
def pull_join
def pull_join(site_id = 0)
start_time = begin_date.in_time_zone.beginning_of_day
end_time = end_date.in_time_zone.end_of_day

if 0 == site_id
return ShiftEvent
.includes(shift: [:work_site, :volunteer])
.where(occurred_at: start_time..end_time,
work_sites: { active: true })
.order(:occurred_at)
end

ShiftEvent
.joins( shift: [:work_site, :volunteer])
.where(occurred_at: start_time..end_time,
shifts: { work_site_id: site_id })
.includes(shift: [:work_site, :volunteer])
.where(occurred_at: start_time..end_time)
.order(:occurred_at)
end

Expand Down
50 changes: 30 additions & 20 deletions app/views/signatures_reports/_desktop_report.html.erb
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
<table class="hide-on-small-only">
<tr>
<td>Work Site</td>
<td>Day</td>
<td>Time</td>
<td>Action</td>
<td>Volunteer</td>
<td class="hide-on-med-and-down">Signature!</td>
</tr>
<table class="hide-on-small-only striped bordered">
<thead>
<tr>
<th> Work Site </th>
<th> Day </th>
<th> Time </th>
<th> Action </th>
<th> Volunteer </th>
<th class="hide-on-med-and-down">
Signature </th>
</tr>
</thead>

<% @shift_events.each do |event| %>
<tr class="entry">
<td><%= event.address %></td>
<td><%= event.occurred_at.to_date %></td>
<td><%= event.occurred_at.strftime("%I:%M%p") %></td>
<td><%= event.action %></td>
<td><%= event.volunteer_email %></td>
<td class="hide-on-med-and-down"><img src='<%= event.signature %>' /></td>
</tr>
<% end %>
</table>
<tbody>
<% @shift_events.each do |event| %>
<tr class="entry">
<td><%= event.address %></td>
<td><%= event.occurred_at.to_date %></td>
<td><%= event.occurred_at.strftime("%I:%M%p") %></td>
<td><%= event.action %></td>
<td><%= event.volunteer_email %></td>

<td class="m3 hide-on-med-and-down">
<img src="<%= event.signature %>"
style="width: 15em;
padding: 2px;
border: 3px solid #069;" /> </td>
</tr>
<% end %>
</tbody>
</table>
34 changes: 19 additions & 15 deletions app/views/signatures_reports/_mobile_report.html.erb
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
<div class="hide-on-med-and-up">
<p>
This is an abbreviated report meant for mobile use.
To see full report, please view on desktop.
To see the full report, please generate it on a desktop.
</p>

<table>
<tr>
<td>Work Site</td>
<td>Volunteer</td>
<td>Action</td>
</tr>

<% @shift_events.each do |event| %>
<tr class="mobile-entry">
<td><%= event.address %></td>
<td><%= event.volunteer_name %></td>
<td><%= event.action %></td>
</tr>
<% end %>
<thead>
<tr>
<th> Work Site </th>
<th> Volunteer </th>
<th> Action </th>
</tr>
</thead>

<tbody>
<% @shift_events.each do |event| %>
<tr class="mobile-entry">
<td><%= event.address %></td>
<td><%= event.volunteer_name %></td>
<td><%= event.action %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
24 changes: 20 additions & 4 deletions app/views/signatures_reports/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,34 @@
<div class="row">
<div class="col s12 m4">
<%= label_tag :begin_date %>
<%= date_field_tag :begin_date, @begin_date.strftime('%e %B, %Y'), class: 'datepicker' %>
<%= date_field_tag :begin_date, @begin_date.strftime('%e %B %Y'),
class: 'datepicker' %>
</div>

<div class="col s12 m4">
<%= label_tag :end_date %>
<%= date_field_tag :end_date, @end_date.strftime('%e %B, %Y'), class: 'datepicker' %>
<%= date_field_tag :end_date, @end_date.strftime('%e %B %Y'),
class: 'datepicker' %>
</div>
<div class="col s12 m4">
<%= submit_tag 'Generate', name: nil, class: 'waves-effect waves-light btn-large' %>
</div>

<div class="row">
<div class="col s12 m8">
<%= label_tag :site_id %>
<%= select :site, :id, @sites %>
</div>
</div>

<div class="row">
<div class="col s12 m6">
<%= submit_tag 'Generate', name: nil,
class: 'waves-effect waves-light btn-large' %>
</div>
</div>
<% end %>

<h5>Site: <%= @site_addr %> </h5>

<% if @shift_events.any? %>
<%= render 'desktop_report' %>
<%= render 'mobile_report' %>
Expand Down
64 changes: 55 additions & 9 deletions spec/features/signature_report_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,20 @@
before { Timecop.freeze Time.zone.parse('July 24, 1969, 16:50:35 UTC') }
after { Timecop.return }

let(:no_data_for_dates) { 'No data for this date range' }

# Given I am not signed in as an admin
# When I visit the volunteer signature report page
# Then I am redirected to the sign in page
scenario 'when the visitor is not an admin' do
visit signatures_report_path
expect(current_path).to eq new_user_session_path
end

# Given I am a signed-in site admin
# When I visit the volunteer signature report page
# Then I see a list of volunteer actions for the past week
scenario 'when an admin visits the page' do
scenario 'when an admin visits the page and uses the default dates' do
generate_entries dates: [Time.zone.today, 5.days.ago, 1.month.ago]

sign_in_as_admin
Expand Down Expand Up @@ -51,7 +61,7 @@

expect(page).not_to have_css '.entry'
expect(page).not_to have_content 'Work Site'
expect(page).to have_content 'No data for this date range'
expect(page).to have_content no_data_for_dates
end

# Given I am a signed-in site admin
Expand All @@ -72,7 +82,7 @@

expect(page).to have_css '.alert-error'
expect(page).to have_content 'Invalid date range'
expect(page).to have_content 'No data for this date range'
expect(page).to have_content no_data_for_dates
end

# Given I am a signed-in site admin
Expand Down Expand Up @@ -110,14 +120,50 @@
end
click_button 'Generate'

expect(page).to have_content 'No data for this date range'
expect(page).to have_content no_data_for_dates
end

# Given I am not signed in as an admin
# When I visit the volunteer signature report page
# Then I am redirected to the sign in page
scenario 'when the visitor is not an admin' do
# Given I am a signed-in site admin
# When I take the default value for the Site drop-down
# Then I see a list for all sites
scenario 'when the default of "all sites" is used' do
generate_entries(dates: [6.days.ago, 1.days.ago])
start_date = 6.days.ago.to_date
end_date = 1.days.ago.to_date

sign_in_as_admin
visit signatures_report_path
expect(current_path).to eq new_user_session_path
within 'form#set_date_range' do
fill_in 'Begin date', with: start_date.to_s
fill_in 'End date', with: end_date.to_s
end
click_button 'Generate'

#binding.pry

expect(page).to have_content 'Site: All Sites'
end

# Given I am a signed-in site admin
# When I select a particular Site
# Then I see a list for that site
scenario 'when a specific site is selected' do
generate_entries(dates: [6.days.ago, 1.days.ago])
start_date = 6.days.ago.to_date
end_date = 1.days.ago.to_date

sign_in_as_admin
visit signatures_report_path
within 'form#set_date_range' do
fill_in 'Begin date', with: start_date.to_s
fill_in 'End date', with: end_date.to_s
find('#site_id').find(:xpath, 'option[2]').select_option
end
click_button 'Generate'

#binding.pry

expect(page).not_to have_content 'Site: All Sites'
end

end

0 comments on commit 7eba816

Please sign in to comment.