adds results creation by poll officers

This commit is contained in:
Juanjo Bazán
2017-02-02 14:44:44 +01:00
parent 8776ef8a12
commit 592fdffe4e
10 changed files with 209 additions and 29 deletions

View File

@@ -1,8 +1,79 @@
class Officing::ResultsController < Officing::BaseController class Officing::ResultsController < Officing::BaseController
before_action :load_poll before_action :load_poll
before_action :load_officer_assignments, only: :new
before_action :load_partial_results, only: :new
before_action :load_officer_assignment, only: :create before_action :load_officer_assignment, only: :create
before_action :check_booth_and_date, only: :create
before_action :build_results, only: :create
def new def new
end
def create
@results.each { |result| result.save! }
notice = t("officing.results.flash.create")
redirect_to new_officing_poll_result_path(@poll), notice: notice
end
private
def check_booth_and_date
if @officer_assignment.blank?
go_back_to_new(t("officing.results.flash.error_wrong_booth"))
elsif results_params[:date].blank? ||
Date.parse(results_params[:date]) < @poll.starts_at.to_date ||
Date.parse(results_params[:date]) > @poll.ends_at.to_date
go_back_to_new(t("officing.results.flash.error_wrong_date"))
end
end
def build_results
@results = []
params[:questions].each_pair do |question_id, results|
question = @poll.questions.find(question_id)
go_back_to_new if question.blank?
results.each_pair do |answer_index, count|
if count.present?
answer = question.valid_answers[answer_index.to_i]
go_back_to_new if question.blank?
partial_result = ::Poll::PartialResult.find_or_initialize_by(booth_assignment_id: @officer_assignment.booth_assignment_id,
date: results_params[:date],
question_id: question_id,
answer: answer)
partial_result.officer_assignment_id = @officer_assignment.id
partial_result.amount = count.to_i
partial_result.author = current_user
partial_result.origin = 'booth'
@results << partial_result
end
end
end
end
def go_back_to_new(alert = nil)
params[:d] = results_params[:date]
params[:oa] = results_params[:officer_assignment_id]
flash.now[:alert] = (alert || t("officing.results.flash.error_create"))
load_officer_assignments
render :new
end
def load_poll
@poll = ::Poll.expired.includes(:questions).find(params[:poll_id])
end
def load_officer_assignment
@officer_assignment = current_user.poll_officer.
officer_assignments.final.find_by(id: results_params[:officer_assignment_id])
end
def load_officer_assignments
@officer_assignments = ::Poll::OfficerAssignment. @officer_assignments = ::Poll::OfficerAssignment.
includes(booth_assignment: [:booth]). includes(booth_assignment: [:booth]).
joins(:booth_assignment). joins(:booth_assignment).
@@ -12,30 +83,14 @@ class Officing::ResultsController < Officing::BaseController
order(date: :asc) order(date: :asc)
end end
def create def load_partial_results
if false if @officer_assignments.present?
notice = t("officing.results.flash.create") @partial_results = ::Poll::PartialResult.where(officer_assignment_id: @officer_assignments.map(&:id)).order(:booth_assignment_id, :date)
else
notice = t("officing.results.flash.error_create")
end
redirect_to new_officing_poll_result_path(@poll), notice: notice
end
private
def load_poll
@poll = Poll.expired.includes(:questions).find(params[:poll_id])
end
def load_officer_assignment
@officer_assignment = current_user.poll_officer.
officer_assignments.final.find_by(id: final_recount_params[:officer_assignment_id])
if @officer_assignment.blank?
redirect_to new_officing_poll_result_path(@poll), notice: t("officing.results.flash.error_create")
end end
end end
def final_recount_params def results_params
params.permit(:officer_assignment_id, :count, :date) params.permit(:officer_assignment_id, :date, :questions)
end end
end end

View File

@@ -25,4 +25,11 @@ module OfficingHelper
final_recount.booth_assignment.voters.select {|v| v.created_at.to_date == final_recount.date}.size final_recount.booth_assignment.voters.select {|v| v.created_at.to_date == final_recount.date}.size
end end
def answer_result_value(question_id, answer_index)
return nil if params.blank?
return nil if params[:questions].blank?
return nil if params[:questions][question_id.to_s].blank?
params[:questions][question_id.to_s][answer_index.to_s]
end
end end

View File

@@ -8,5 +8,6 @@ class Poll
has_many :final_recounts, class_name: "Poll::FinalRecount", dependent: :destroy has_many :final_recounts, class_name: "Poll::FinalRecount", dependent: :destroy
has_many :officers, through: :officer_assignments has_many :officers, through: :officer_assignments
has_many :voters has_many :voters
has_many :partial_results
end end
end end

View File

@@ -4,6 +4,7 @@ class Poll
belongs_to :booth_assignment belongs_to :booth_assignment
has_one :recount has_one :recount
has_many :final_recounts has_many :final_recounts
has_many :partial_results
has_many :voters has_many :voters
validates :officer_id, presence: true validates :officer_id, presence: true

View File

@@ -1,9 +1,11 @@
class Poll::PartialResult < ActiveRecord::Base class Poll::PartialResult < ActiveRecord::Base
VALID_ORIGINS = %w{ web } VALID_ORIGINS = %w{ web booth }
belongs_to :question, -> { with_hidden } belongs_to :question, -> { with_hidden }
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
belongs_to :booth_assignment
belongs_to :officer_assignment
validates :question, presence: true validates :question, presence: true
validates :author, presence: true validates :author, presence: true

View File

@@ -27,10 +27,10 @@
<div class="small-12 column"> <div class="small-12 column">
<h3><%= question.title %></h3> <h3><%= question.title %></h3>
</div> </div>
<% question.valid_answers.each do |answer| %> <% question.valid_answers.each_with_index do |answer, i| %>
<div class="small-12 medium-6 large-3 column end"> <div class="small-12 medium-6 large-3 column end">
<label><%= answer %></label> <label><%= answer %></label>
<%= text_field_tag :count, nil, placeholder: "0" %> <%= text_field_tag "questions[#{question.id}][#{i}]", answer_result_value(question.id, i), placeholder: "0" %>
</div> </div>
<% end %> <% end %>
</div> </div>
@@ -64,3 +64,36 @@
</div> </div>
<% end %> <% end %>
<% if @partial_results.present? %>
<hr>
<h3><%= t("officing.results.new.results_list") %></h3>
<table>
<thead>
<th><%= t("officing.results.new.date") %></th>
<th><%= t("officing.results.new.booth") %></th>
<th>&nbsp;</th>
</thead>
<tbody>
<% results_by_booth = @partial_results.group_by(&:booth_assignment_id) %>
<% results_by_booth.keys.each do |booth_assignment| %>
<% results_by_booth[booth_assignment].group_by(&:date).keys.each do |date| %>
<tr id="results_<%= booth_assignment %>_<%= date.strftime('%Y%m%d') %>">
<td>
<%= l(date.to_date, format: :long) %>
</td>
<td>
<%= results_by_booth[booth_assignment].first.booth_assignment.booth.name %>
</td>
<td>
</td>
</tr>
<% end %>
<% end %>
</tbody>
</table>
<% end %>

View File

@@ -8,7 +8,7 @@ en:
menu: menu:
voters: Validate document voters: Validate document
recounts: Store recount recounts: Store recount
final_recounts: Final recounts final_recounts: Final recounts and results
polls: polls:
index: index:
title: Poll list title: Poll list
@@ -57,6 +57,8 @@ en:
flash: flash:
create: "Results saved" create: "Results saved"
error_create: "Results NOT saved. Error in data." error_create: "Results NOT saved. Error in data."
error_wrong_booth: "Wrong booth. Results NOT saved."
error_wrong_date: "Wrong date. Results NOT saved."
new: new:
title: "%{poll} - Add results" title: "%{poll} - Add results"
not_allowed: "You are allowed to add results for this poll" not_allowed: "You are allowed to add results for this poll"
@@ -67,6 +69,7 @@ en:
ballots_blank: "Blank ballots" ballots_blank: "Blank ballots"
ballots_null: "Invalid ballots" ballots_null: "Invalid ballots"
submit: "Save" submit: "Save"
results_list: "Your results"
residence: residence:
flash: flash:
create: "Document verified with Census" create: "Document verified with Census"

View File

@@ -57,6 +57,8 @@ es:
flash: flash:
create: "Datos guardados" create: "Datos guardados"
error_create: "Resultados NO añadidos. Error en los datos" error_create: "Resultados NO añadidos. Error en los datos"
error_wrong_booth: "Urna incorrecta. Resultados NO guardados."
error_wrong_date: "Fecha incorrecta. Resultados NO guardados."
new: new:
title: "%{poll} - Añadir resultados" title: "%{poll} - Añadir resultados"
not_allowed: "No tienes permiso para introducir resultados" not_allowed: "No tienes permiso para introducir resultados"
@@ -67,6 +69,7 @@ es:
ballots_blank: "Papeletas en blanco" ballots_blank: "Papeletas en blanco"
ballots_null: "Papeletas nulas" ballots_null: "Papeletas nulas"
submit: "Guardar" submit: "Guardar"
results_list: "Tus resultados"
residence: residence:
flash: flash:
create: "Documento verificado con el Padrón" create: "Documento verificado con el Padrón"

View File

@@ -24,7 +24,7 @@ feature 'Officing Final Recount' do
expect(page).to have_content('Poll officing') expect(page).to have_content('Poll officing')
within('#side_menu') do within('#side_menu') do
click_link 'Final recounts' click_link 'Final recounts and results'
end end
expect(page).to_not have_content(not_allowed_poll_1.name) expect(page).to_not have_content(not_allowed_poll_1.name)
@@ -40,7 +40,7 @@ feature 'Officing Final Recount' do
visit officing_root_path visit officing_root_path
within('#side_menu') do within('#side_menu') do
click_link 'Final recounts' click_link 'Final recounts and results'
end end
within("#poll_#{@poll.id}") do within("#poll_#{@poll.id}") do

View File

@@ -0,0 +1,75 @@
require 'rails_helper'
feature 'Officing Results' do
background do
@poll_officer = create(:poll_officer)
@officer_assignment = create(:poll_officer_assignment, :final, officer: @poll_officer)
@poll = @officer_assignment.booth_assignment.poll
@poll.update(ends_at: 1.day.ago)
@question_1 = create(:poll_question, poll: @poll, valid_answers: "Yes,No")
@question_2 = create(:poll_question, poll: @poll, valid_answers: "Today,Tomorrow")
login_as(@poll_officer.user)
end
scenario 'Only polls where user is officer for results are accessible' do
regular_officer_assignment_1 = create(:poll_officer_assignment, officer: @poll_officer)
regular_officer_assignment_2 = create(:poll_officer_assignment, officer: @poll_officer)
not_allowed_poll_1 = create(:poll, :expired)
not_allowed_poll_2 = regular_officer_assignment_1.booth_assignment.poll
not_allowed_poll_2.update(ends_at: 1.day.ago)
not_allowed_poll_3 = regular_officer_assignment_2.booth_assignment.poll
visit root_path
click_link 'Polling officers'
expect(page).to have_content('Poll officing')
within('#side_menu') do
click_link 'Final recounts and results'
end
expect(page).to_not have_content(not_allowed_poll_1.name)
expect(page).to_not have_content(not_allowed_poll_2.name)
expect(page).to_not have_content(not_allowed_poll_3.name)
expect(page).to have_content(@poll.name)
visit new_officing_poll_result_path(not_allowed_poll_1)
expect(page).to have_content('You are allowed to add results for this poll')
end
scenario 'Add results' do
visit officing_root_path
within('#side_menu') do
click_link 'Final recounts and results'
end
within("#poll_#{@poll.id}") do
expect(page).to have_content(@poll.name)
click_link 'Add results'
end
expect(page).to_not have_content('Your results')
booth_name = @officer_assignment.booth_assignment.booth.name
date = I18n.l(@poll.starts_at.to_date, format: :long)
select booth_name, from: 'officer_assignment_id'
select date, from: 'date'
fill_in "questions[#{@question_1.id}][0]", with: '100'
fill_in "questions[#{@question_1.id}][1]", with: '200'
fill_in "questions[#{@question_2.id}][0]", with: '333'
fill_in "questions[#{@question_2.id}][1]", with: '444'
click_button 'Save'
expect(page).to have_content('Your results')
within("#results_#{@officer_assignment.booth_assignment_id}_#{@poll.starts_at.to_date.strftime('%Y%m%d')}") do
expect(page).to have_content(date)
expect(page).to have_content(booth_name)
end
end
end