diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index d7c36e944..b73c07474 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -67,6 +67,7 @@ //= require tree_navigator //= require custom //= require tag_autocomplete +//= require polls_admin //= require leaflet //= require map @@ -105,6 +106,7 @@ var initialize_modules = function() { App.Documentable.initialize(); App.Imageable.initialize(); App.TagAutocomplete.initialize(); + App.PollsAdmin.initialize(); App.Map.initialize(); }; diff --git a/app/assets/javascripts/polls_admin.js.coffee b/app/assets/javascripts/polls_admin.js.coffee new file mode 100644 index 000000000..ef1dd44f1 --- /dev/null +++ b/app/assets/javascripts/polls_admin.js.coffee @@ -0,0 +1,12 @@ +App.PollsAdmin = + + initialize: -> + $("select[class='js-poll-shifts']").on + change: -> + switch ($(this).val()) + when 'vote_collection' + $("select[class='js-shift-vote-collection-dates']").show(); + $("select[class='js-shift-recount-scrutiny-dates']").hide(); + when 'recount_scrutiny' + $("select[class='js-shift-recount-scrutiny-dates']").show(); + $("select[class='js-shift-vote-collection-dates']").hide(); diff --git a/app/controllers/admin/poll/shifts_controller.rb b/app/controllers/admin/poll/shifts_controller.rb index 48f540c07..577e8afad 100644 --- a/app/controllers/admin/poll/shifts_controller.rb +++ b/app/controllers/admin/poll/shifts_controller.rb @@ -14,10 +14,10 @@ class Admin::Poll::ShiftsController < Admin::Poll::BaseController @officer = @shift.officer if @shift.save - notice = t("admin.poll_shifts.flash.create") - redirect_to new_admin_booth_shift_path(@shift.booth), notice: notice + redirect_to new_admin_booth_shift_path(@shift.booth), notice: t("admin.poll_shifts.flash.create") else load_shifts + flash[:error] = t("admin.poll_shifts.flash.date_missing") render :new end end @@ -54,7 +54,7 @@ class Admin::Poll::ShiftsController < Admin::Poll::BaseController end def shift_params - params.require(:shift).permit(:booth_id, :officer_id, :date) + shift_params = params.require(:shift).permit(:booth_id, :officer_id, :task, date:[:vote_collection_date, :recount_scrutiny_date]) + shift_params.merge(date: shift_params[:date]["#{shift_params[:task]}_date".to_sym]) end - end diff --git a/app/helpers/shifts_helper.rb b/app/helpers/shifts_helper.rb index 37f22a3e2..af291779a 100644 --- a/app/helpers/shifts_helper.rb +++ b/app/helpers/shifts_helper.rb @@ -1,11 +1,15 @@ module ShiftsHelper - def shift_dates_select_options(polls) - options = [] - (start_date(polls)..end_date(polls)).each do |date| - options << [l(date, format: :long), l(date)] - end - options_for_select(options, params[:date]) + def shift_vote_collection_dates(polls) + date_options((start_date(polls)..end_date(polls))) + end + + def shift_recount_scrutiny_dates(polls) + date_options(polls.map(&:ends_at).map(&:to_date).inject([]) { |total, date| total << (date..date + 1.week).to_a }.flatten.uniq) + end + + def date_options(dates) + dates.map { |date| [l(date, format: :long), l(date)] } end def start_date(polls) diff --git a/app/models/poll/shift.rb b/app/models/poll/shift.rb index d894df5a4..d64bce9ac 100644 --- a/app/models/poll/shift.rb +++ b/app/models/poll/shift.rb @@ -7,6 +7,9 @@ class Poll validates :officer_id, presence: true validates :date, presence: true validates :date, uniqueness: { scope: [:officer_id, :booth_id] } + validates :task, presence: true + + enum task: { vote_collection: 0, recount_scrutiny: 1 } before_create :persist_data after_create :create_officer_assignments diff --git a/app/views/admin/poll/shifts/_form.html.erb b/app/views/admin/poll/shifts/_form.html.erb index f0461855f..6a70396cb 100644 --- a/app/views/admin/poll/shifts/_form.html.erb +++ b/app/views/admin/poll/shifts/_form.html.erb @@ -6,23 +6,39 @@ <%= t("admin.poll_shifts.new.new_shift") %> -
+
<%= t("admin.poll_shifts.new.officer") %>
<%= @officer.name %> <%= f.hidden_field :officer_id, value: @officer.id %>
-
+
+ + <%= f.select :task, + Poll::Shift.tasks.map {|k,v| [t("admin.poll_shifts.#{k}"), k]}, + { prompt: t("admin.poll_shifts.new.select_task"), + label: false }, + class: 'js-poll-shifts' %> +
+ +
- <%= f.select :date, - shift_dates_select_options(@polls), - prompt: t("admin.poll_shifts.new.select_date"), - label: false %> + <%= select 'shift[date]', 'vote_collection_date', + options_for_select(shift_vote_collection_dates(@polls)), + { prompt: t("admin.poll_shifts.new.select_date"), + label: false }, + class: 'js-shift-vote-collection-dates' %> + <%= select 'shift[date]', 'recount_scrutiny_date', + options_for_select(shift_recount_scrutiny_dates(@polls)), + { prompt: t("admin.poll_shifts.new.select_date"), + label: false }, + class: 'js-shift-recount-scrutiny-dates', + hidden: 'hidden' %>
<%= f.hidden_field :booth_id, value: @booth.id %> -
+
<%= f.submit t("admin.poll_shifts.new.add_shift"), class: "button expanded margin-top" %>
diff --git a/app/views/admin/poll/shifts/_shifts.html.erb b/app/views/admin/poll/shifts/_shifts.html.erb index f2de53548..63cbe0690 100644 --- a/app/views/admin/poll/shifts/_shifts.html.erb +++ b/app/views/admin/poll/shifts/_shifts.html.erb @@ -4,6 +4,7 @@ <%= t("admin.poll_shifts.new.date") %> <%= t("admin.poll_shifts.new.officer") %> + <%= t("admin.poll_shifts.new.task") %> <%= t("admin.poll_shifts.new.shift") %> @@ -12,6 +13,7 @@ <%= l(shift.date.to_date, format: :long) %> <%= shift.officer_name %> + <%= t("admin.poll_shifts.#{shift.task}") %> <%= link_to t("admin.poll_shifts.new.remove_shift"), admin_booth_shift_path(@booth, shift), diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index f5fa020bd..0545e6af5 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -504,6 +504,7 @@ en: shift: "Assignment" shifts: "Shifts in this booth" date: "Date" + task: "Task" edit_shifts: Edit shifts new_shift: "New shift" no_shifts: "This booth has no shifts" @@ -513,12 +514,16 @@ en: search_officer_placeholder: Search officer search_officer_text: Search for an officer to assign a new shift select_date: "Select day" + select_task: "Select task" table_shift: "Shift" table_email: "Email" table_name: "Name" flash: create: "Shift added" destroy: "Shift removed" + date_missing: "A date must be selected" + vote_collection: Collect Votes + recount_scrutiny: Recount & Scrutiny poll_booth_assignments: flash: destroy: "Booth not assigned anymore" diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 2e44ea7b4..816cadd57 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -504,6 +504,7 @@ es: shift: "Asignación" shifts: "Turnos en esta urna" date: "Fecha" + task: "Tarea" edit_shifts: Asignar turno new_shift: "Nuevo turno" no_shifts: "Esta urna no tiene turnos asignados" @@ -513,12 +514,16 @@ es: search_officer_placeholder: Buscar presidentes de mesa search_officer_text: Busca al presidente de mesa para asignar un turno select_date: "Seleccionar día" + select_task: "Seleccionar tarea" table_shift: "Turno" table_email: "Email" table_name: "Nombre" flash: create: "Añadido turno de presidente de mesa" destroy: "Eliminado turno de presidente de mesa" + date_missing: "Debe seleccionarse una fecha" + vote_collection: Recoger Votos + recount_scrutiny: Recuento & Escrutinio poll_booth_assignments: flash: destroy: "Urna desasignada" diff --git a/db/migrate/20170927110953_add_shift_task.rb b/db/migrate/20170927110953_add_shift_task.rb new file mode 100644 index 000000000..8adf23dd1 --- /dev/null +++ b/db/migrate/20170927110953_add_shift_task.rb @@ -0,0 +1,5 @@ +class AddShiftTask < ActiveRecord::Migration + def change + add_column :poll_shifts, :task, :integer, null: false, default: 0 + end +end diff --git a/db/schema.rb b/db/schema.rb index 86d22f3b2..500f03540 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170918231410) do +ActiveRecord::Schema.define(version: 20170927110953) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -698,6 +698,7 @@ ActiveRecord::Schema.define(version: 20170918231410) do t.datetime "updated_at" t.string "officer_name" t.string "officer_email" + t.integer "task", default: 0, null: false end add_index "poll_shifts", ["booth_id", "officer_id"], name: "index_poll_shifts_on_booth_id_and_officer_id", using: :btree diff --git a/spec/features/admin/poll/shifts_spec.rb b/spec/features/admin/poll/shifts_spec.rb index 1e5bb6328..46c737c64 100644 --- a/spec/features/admin/poll/shifts_spec.rb +++ b/spec/features/admin/poll/shifts_spec.rb @@ -30,8 +30,10 @@ feature 'Admin shifts' do expect(page).to have_content officer.name end - scenario "Create", :js do + scenario "Create Vote Collection Shift", :js do poll = create(:poll) + vote_collection_dates = (poll.starts_at.to_date..poll.ends_at.to_date).to_a.map { |date| I18n.l(date, format: :long) } + booth = create(:poll_booth) officer = create(:poll_officer) @@ -45,7 +47,9 @@ feature 'Admin shifts' do click_button "Search" click_link "Edit shifts" - select I18n.l(poll.starts_at.to_date, format: :long), from: 'shift_date' + expect(page).to have_select('shift_date_vote_collection_date', options: ["Select day", *vote_collection_dates]) + expect(page).not_to have_select('shift_date_recount_scrutiny_date') + select I18n.l(poll.starts_at.to_date, format: :long), from: 'shift_date_vote_collection_date' click_button "Add shift" expect(page).to have_content "Shift added" @@ -53,11 +57,46 @@ feature 'Admin shifts' do within("#shifts") do expect(page).to have_css(".shift", count: 1) expect(page).to have_content(I18n.l(poll.starts_at.to_date, format: :long)) + expect(page).to have_content("Collect Votes") expect(page).to have_content(officer.name) end end - scenario "Erros on create", :js do + scenario "Create Recount & Scrutiny Shift", :js do + poll = create(:poll) + recount_scrutiny_dates = (poll.ends_at.to_date..poll.ends_at.to_date + 1.week).to_a.map { |date| I18n.l(date, format: :long) } + + booth = create(:poll_booth) + officer = create(:poll_officer) + + visit admin_booths_path + + within("#booth_#{booth.id}") do + click_link "Manage shifts" + end + + fill_in "search", with: officer.email + click_button "Search" + click_link "Edit shifts" + + select "Recount & Scrutiny", from: 'shift_task' + + expect(page).to have_select('shift_date_recount_scrutiny_date', options: ["Select day", *recount_scrutiny_dates]) + expect(page).not_to have_select('shift_date_vote_collection_date') + select I18n.l(poll.ends_at.to_date + 4.days, format: :long), from: 'shift_date_recount_scrutiny_date' + click_button "Add shift" + + expect(page).to have_content "Shift added" + + within("#shifts") do + expect(page).to have_css(".shift", count: 1) + expect(page).to have_content(I18n.l(poll.ends_at.to_date + 4.days, format: :long)) + expect(page).to have_content("Recount & Scrutiny") + expect(page).to have_content(officer.name) + end + end + + scenario "Error on create", :js do poll = create(:poll) booth = create(:poll_booth) officer = create(:poll_officer) @@ -73,7 +112,7 @@ feature 'Admin shifts' do click_link "Edit shifts" click_button "Add shift" - expect(page).to have_content "can't be blank" + expect(page).to have_content "A date must be selected" end scenario "Destroy" do