diff --git a/app/controllers/officing/ballot_sheets_controller.rb b/app/controllers/officing/ballot_sheets_controller.rb new file mode 100644 index 000000000..e23ea4613 --- /dev/null +++ b/app/controllers/officing/ballot_sheets_controller.rb @@ -0,0 +1,77 @@ +class Officing::BallotSheetsController < Officing::BaseController + + before_action :verify_booth + before_action :load_poll + before_action :load_officer_assignments, only: [:new, :create] + + helper_method :namespace + + def index + load_ballot_sheets + end + + def show + load_ballot_sheet + end + + def new + end + + def create + load_officer_assignment + check_officer_assignment + + @ballot_sheet = Poll::BallotSheet.new(ballot_sheet_params) + + if @ballot_sheet.save + redirect_to officing_poll_ballot_sheet_path(@poll, @ballot_sheet) + else + render :new + end + end + + private + + def namespace + "officing" + end + + def load_poll + @poll = Poll.find(params[:poll_id]) + end + + def load_ballot_sheets + @ballot_sheets = Poll::BallotSheet.where(poll: @poll) + end + + def load_ballot_sheet + @ballot_sheet = Poll::BallotSheet.find(params[:id]) + end + + def load_officer_assignments + @officer_assignments = ::Poll::OfficerAssignment. + includes(booth_assignment: [:booth]). + joins(:booth_assignment). + final. + where(id: current_user.poll_officer.officer_assignment_ids). + where("poll_booth_assignments.poll_id = ?", @poll.id). + where(date: Date.current) + end + + def load_officer_assignment + @officer_assignment = current_user.poll_officer.officer_assignments.final + .find_by(id: ballot_sheet_params[:officer_assignment_id]) + end + + def check_officer_assignment + if @officer_assignment.blank? + flash.now[:alert] = t("officing.results.flash.error_wrong_booth") + render :new + end + end + + def ballot_sheet_params + params.permit(:data, :poll_id, :officer_assignment_id) + end + +end diff --git a/app/controllers/officing/base_controller.rb b/app/controllers/officing/base_controller.rb index 58ba3c8b2..e73f2b696 100644 --- a/app/controllers/officing/base_controller.rb +++ b/app/controllers/officing/base_controller.rb @@ -13,6 +13,12 @@ class Officing::BaseController < ApplicationController raise CanCan::AccessDenied unless current_user.try(:poll_officer?) end + def check_officer_assignment + if @officer_assignment.blank? + go_back_to_new(t("officing.results.flash.error_wrong_booth")) + end + end + def load_officer_assignment @officer_assignments ||= current_user.poll_officer. officer_assignments. diff --git a/app/controllers/officing/poll/ballot_sheets_controller.rb b/app/controllers/officing/poll/ballot_sheets_controller.rb new file mode 100644 index 000000000..344be299f --- /dev/null +++ b/app/controllers/officing/poll/ballot_sheets_controller.rb @@ -0,0 +1,61 @@ +class Officing::PollBallotSheetsController < Officing::BaseController + + before_action :verify_booth + before_action :load_poll + before_action :load_ballot_sheets, only: :index + before_action :load_ballot_sheet, only: :show + + before_action :load_officer_assignments, only: :new + before_action :load_officer_assignment, only: :create + before_action :check_officer_assignment, only: :create + + helper_method :namespace + + def index + end + + def show + end + + def new + end + + def create + Poll::BallotSheet.create(ballot_sheet_params) + + render :show + end + + private + + def namespace + "officing" + end + + def load_poll + @poll = Poll.find(params[:poll_id]) + end + + def load_ballot_sheets + @ballot_sheets = Poll::BallotSheet.where(poll: @poll) + end + + def load_ballot_sheet + @ballot_sheet = Poll::BallotSheet.find(params[:ballot_sheet_id]) + end + + def load_officer_assignments + @officer_assignments = ::Poll::OfficerAssignment. + includes(booth_assignment: [:booth]). + joins(:booth_assignment). + final. + where(id: current_user.poll_officer.officer_assignment_ids). + where("poll_booth_assignments.poll_id = ?", @poll_budget.id). + where(date: Date.current) + end + + def ballot_sheet_params + params.permit(:csv_data, :poll_id, :officer_assignment_id) + end + +end diff --git a/app/controllers/officing/results_controller.rb b/app/controllers/officing/results_controller.rb index ff9bf3925..cba0d6b0b 100644 --- a/app/controllers/officing/results_controller.rb +++ b/app/controllers/officing/results_controller.rb @@ -33,12 +33,6 @@ class Officing::ResultsController < Officing::BaseController private - def check_officer_assignment - if @officer_assignment.blank? - go_back_to_new(t("officing.results.flash.error_wrong_booth")) - end - end - def build_results @results = [] diff --git a/app/views/officing/polls/ballot_sheets/index.html.erb b/app/views/officing/polls/ballot_sheets/index.html.erb new file mode 100644 index 000000000..2dc905b4f --- /dev/null +++ b/app/views/officing/polls/ballot_sheets/index.html.erb @@ -0,0 +1,26 @@ +

<%= t("officing.poll_budgets.index.title", poll_budget: @poll_budget) %>

+ +<% if @ballot_sheets.any? %> + + + + + + + + + + <% @ballot_sheets.each do |ballot_sheet| %> + + + + + + <% end %> + +
<%= t("officing.poll_budgets.index.ballot_sheet_name") %><%= t("officing.poll_budgets.index.ballot_sheet_author") %><%= t("officing.poll_budgets.index.ballot_sheet_creation_date") %>
+<% else %> +
+ <%= t("officing.poll_budgets.index.empty_results") %> +
+<% end %> diff --git a/app/views/officing/polls/ballot_sheets/new.html.erb b/app/views/officing/polls/ballot_sheets/new.html.erb new file mode 100644 index 000000000..335477ec3 --- /dev/null +++ b/app/views/officing/polls/ballot_sheets/new.html.erb @@ -0,0 +1,16 @@ +<% if @officer_assignments.any? %> +

<%= t("officing.poll_budgets.new.title", poll: @poll.name) %>

+ + <%= form_tag(officing_poll_ballot_sheets_path(@poll)) do %> + + <%= select_tag :officer_assignment_id, + booths_for_officer_select_options(@officer_assignments), + { prompt: t("officing.poll_budgets.new.select_booth"), + label: false } %> + + + <%= text_area_tag :csv_data, nil, rows: 10 %> + + <%= submit_tag t("officing.poll_budgets.new.submit"), class: "button" %> + <% end %> +<% end %> diff --git a/app/views/officing/polls/ballot_sheets/show.html.erb b/app/views/officing/polls/ballot_sheets/show.html.erb new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/officing/polls/final.html.erb b/app/views/officing/polls/final.html.erb index 149551d1e..01f9f45fd 100644 --- a/app/views/officing/polls/final.html.erb +++ b/app/views/officing/polls/final.html.erb @@ -14,9 +14,19 @@ - <%= link_to t("officing.polls.final.add_results"), - new_officing_poll_result_path(poll), - class: "button hollow" %> + <% if poll.budget.present? %> + <%= link_to t("officing.poll_budgets.see_ballot_sheets"), + officing_poll_ballot_sheets_path(poll), + class: "button" %> + + <%= link_to t("officing.polls.final.add_results"), + new_officing_poll_ballot_sheet_path(poll), + class: "button hollow" %> + <% else %> + <%= link_to t("officing.polls.final.add_results"), + new_officing_poll_result_path(poll), + class: "button hollow" %> + <% end %> <% end %> diff --git a/config/locales/en/activerecord.yml b/config/locales/en/activerecord.yml index ed1a70880..cec43d798 100644 --- a/config/locales/en/activerecord.yml +++ b/config/locales/en/activerecord.yml @@ -61,6 +61,9 @@ en: poll/officer: one: "officer" other: "officers" + poll/ballot_sheet: + one: Ballot sheet + other: Ballot sheets proposal: one: "Citizen proposal" other: "Citizen proposals" @@ -208,6 +211,10 @@ en: external_url: "Link to additional documentation" poll/question/translation: title: "Question" + poll/ballot_sheet: + data: CSV data + poll_id: Poll + officer_assignment_id: Officer assignment signature_sheet: signable_type: "Signable type" signable_id: "Signable ID" diff --git a/config/locales/en/officing.yml b/config/locales/en/officing.yml index e377654f0..b40f7c448 100644 --- a/config/locales/en/officing.yml +++ b/config/locales/en/officing.yml @@ -16,6 +16,20 @@ en: no_polls: You are not officing final recounts in any active poll select_poll: Select poll add_results: Add results + poll_budgets: + see_ballot_sheets: See ballot sheets list + index: + title: "%{poll_budget} - Ballot sheets list" + ballot_sheet_name: Name + ballot_sheet_author: Author + ballot_sheet_creation_date: Creation date + empty_results: There are no ballot sheets for this poll yet + new: + title: "%{poll_budget} - New ballot sheet" + booth: Booth + select_booth: Select booth + csv_data: CSV data + submit: Save booth: new: title: "Choose your booth" diff --git a/config/locales/es/activerecord.yml b/config/locales/es/activerecord.yml index e85cd5110..acdd743a4 100644 --- a/config/locales/es/activerecord.yml +++ b/config/locales/es/activerecord.yml @@ -61,6 +61,9 @@ es: poll/officer: one: "presidente de mesa" other: "presidentes de mesa" + poll/ballot_sheet: + one: Papeleta de votación + other: Papeletas de votación proposal: one: "Propuesta ciudadana" other: "Propuestas ciudadanas" @@ -208,6 +211,10 @@ es: external_url: "Enlace a documentación adicional" poll/question/translation: title: "Pregunta" + poll/ballot_sheet: + data: Datos de CSV + poll_id: Votación + officer_assignment_id: Turno signature_sheet: signable_type: "Tipo de hoja de firmas" signable_id: "ID Propuesta ciudadana/Proyecto de gasto" diff --git a/config/locales/es/officing.yml b/config/locales/es/officing.yml index e25f9cde8..103a25982 100644 --- a/config/locales/es/officing.yml +++ b/config/locales/es/officing.yml @@ -16,6 +16,20 @@ es: no_polls: No tienes permiso para recuento final en ninguna votación reciente select_poll: Selecciona votación add_results: Añadir resultados + poll_budgets: + see_ballot_sheets: Ver lista de papeletas de votación + index: + title: "%{poll_budget} - Listado de papeletas de votación" + ballot_sheet_name: Nombre + ballot_sheet_author: Autor + ballot_sheet_creation_date: Fecha de creación + empty_results: Aún no se han subido papeletas de votación + new: + title: "%{poll_budget} - Nueva papeleta de votación" + booth: Urna + select_booth: Elegir urna + csv_data: Datos de CSV + submit: Guardar booth: new: title: "Escoge tu urna" diff --git a/config/routes/officing.rb b/config/routes/officing.rb index 6be5e5bc2..020767b28 100644 --- a/config/routes/officing.rb +++ b/config/routes/officing.rb @@ -2,6 +2,8 @@ namespace :officing do resources :polls, only: [:index] do get :final, on: :collection resources :results, only: [:new, :create, :index] + + resources :ballot_sheets, only: [:new, :create, :show, :index] end resource :booth, controller: "booth", only: [:new, :create] diff --git a/spec/features/budget_polls/ballot_sheets_spec.rb b/spec/features/budget_polls/ballot_sheets_spec.rb new file mode 100644 index 000000000..a20921126 --- /dev/null +++ b/spec/features/budget_polls/ballot_sheets_spec.rb @@ -0,0 +1,32 @@ +require "rails_helper" + +feature "Poll budget ballot sheets" do + let(:budget) { create(:budget) } + let(:poll) { create(:poll, budget: budget, ends_at: 1.day.ago) } + let(:booth) { create(:poll_booth) } + let(:poll_officer) { create(:poll_officer) } + + background do + create(:poll_booth_assignment, poll: poll, booth: booth) + create(:poll_shift, :recount_scrutiny_task, officer: poll_officer, booth: booth, date: Date.current) + create(:poll_officer_assignment, officer: poll_officer) + + login_as(poll_officer.user) + set_officing_booth(booth) + end + + scenario "Budget polls are visible in 'Recounts and results' view" do + visit root_path + click_link "Polling officers" + + within("#side_menu") do + click_link "Total recounts and results" + end + + within("#poll_#{poll.id}") do + expect(page).to have_content("#{poll.name}") + expect(page).to have_content("See ballot sheets list") + expect(page).to have_content("Add results") + end + end +end