From 456429f08b50b5a1a5364a09dfe7001c8a4d6a89 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 4 Aug 2017 20:43:07 +0200 Subject: [PATCH] adds shifts --- .../admin/poll/shifts_controller.rb | 53 +++++++++++++++++++ app/helpers/shifts_helper.rb | 23 ++++++++ app/models/poll.rb | 4 ++ app/models/poll/booth.rb | 1 + app/models/poll/shift.rb | 22 ++++++++ app/views/admin/poll/booths/_booth.html.erb | 3 ++ app/views/admin/poll/booths/index.html.erb | 1 + app/views/admin/poll/shifts/_shifts.html.erb | 24 +++++++++ app/views/admin/poll/shifts/new.html.erb | 46 ++++++++++++++++ config/locales/en/admin.yml | 29 ++++++---- config/locales/es/admin.yml | 29 ++++++---- config/routes.rb | 5 +- .../20170724190805_create_poll_shifts.rb | 15 ++++++ db/schema.rb | 14 ++++- 14 files changed, 245 insertions(+), 24 deletions(-) create mode 100644 app/controllers/admin/poll/shifts_controller.rb create mode 100644 app/helpers/shifts_helper.rb create mode 100644 app/models/poll/shift.rb create mode 100644 app/views/admin/poll/shifts/_shifts.html.erb create mode 100644 app/views/admin/poll/shifts/new.html.erb create mode 100644 db/migrate/20170724190805_create_poll_shifts.rb diff --git a/app/controllers/admin/poll/shifts_controller.rb b/app/controllers/admin/poll/shifts_controller.rb new file mode 100644 index 000000000..8a808a7a9 --- /dev/null +++ b/app/controllers/admin/poll/shifts_controller.rb @@ -0,0 +1,53 @@ +class Admin::Poll::ShiftsController < Admin::BaseController + + before_action :load_booth + before_action :load_polls + + def new + load_officers + load_shifts + @shift = ::Poll::Shift.new + end + + def create + @shift = ::Poll::Shift.new(shift_params) + if @shift.save + notice = t("admin.poll_shifts.flash.create") + redirect_to new_admin_booth_shift_path(@shift.booth), notice: notice + else + load_officers + load_shifts + render :new + end + end + + def destroy + @shift = Poll::Shift.find(params[:id]) + @shift.destroy + notice = t("admin.poll_shifts.flash.destroy") + redirect_to new_admin_booth_shift_path(@booth), notice: notice + end + + private + + def load_booth + @booth = ::Poll::Booth.find(params[:booth_id]) + end + + def load_polls + @polls = ::Poll.current_or_incoming + end + + def load_officers + @officers = ::Poll::Officer.all + end + + def load_shifts + @shifts = @booth.shifts + end + + def shift_params + params.require(:shift).permit(:booth_id, :officer_id, :date) + end + +end \ No newline at end of file diff --git a/app/helpers/shifts_helper.rb b/app/helpers/shifts_helper.rb new file mode 100644 index 000000000..37f22a3e2 --- /dev/null +++ b/app/helpers/shifts_helper.rb @@ -0,0 +1,23 @@ +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]) + end + + def start_date(polls) + polls.map(&:starts_at).min.to_date + end + + def end_date(polls) + polls.map(&:ends_at).max.to_date + end + + def officer_select_options(officers) + officers.collect { |officer| [officer.name, officer.id] } + end + +end diff --git a/app/models/poll.rb b/app/models/poll.rb index 6d033f514..4ba313963 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -35,6 +35,10 @@ class Poll < ActiveRecord::Base ends_at < timestamp end + def self.current_or_incoming + current + incoming + end + def answerable_by?(user) user.present? && user.level_two_or_three_verified? && diff --git a/app/models/poll/booth.rb b/app/models/poll/booth.rb index c7fb63efc..9edbcbaf0 100644 --- a/app/models/poll/booth.rb +++ b/app/models/poll/booth.rb @@ -2,6 +2,7 @@ class Poll class Booth < ActiveRecord::Base has_many :booth_assignments, class_name: "Poll::BoothAssignment" has_many :polls, through: :booth_assignments + has_many :shifts validates :name, presence: true, uniqueness: true diff --git a/app/models/poll/shift.rb b/app/models/poll/shift.rb new file mode 100644 index 000000000..8ee646ea4 --- /dev/null +++ b/app/models/poll/shift.rb @@ -0,0 +1,22 @@ +class Poll + class Shift < ActiveRecord::Base + belongs_to :booth + belongs_to :officer + + validates :booth_id, presence: true + validates :officer_id, presence: true + validates :date, presence: true + validates :date, uniqueness: { scope: [:officer_id, :booth_id] } + + after_create :create_officer_assignments + + def create_officer_assignments + booth.booth_assignments.each do |booth_assignment| + attrs = { officer_id: officer_id, + date: date, + booth_assignment_id: booth_assignment.id } + Poll::OfficerAssignment.create!(attrs) + end + end + end + end \ No newline at end of file diff --git a/app/views/admin/poll/booths/_booth.html.erb b/app/views/admin/poll/booths/_booth.html.erb index 5732400a8..80b1ef38f 100644 --- a/app/views/admin/poll/booths/_booth.html.erb +++ b/app/views/admin/poll/booths/_booth.html.erb @@ -6,6 +6,9 @@ <%= booth.location %> + <%= link_to t("admin.booths.booth.shifts"), + new_admin_booth_shift_path(booth), + class: "button hollow" %> <%= link_to t("admin.actions.edit"), edit_admin_booth_path(booth), class: "button hollow" %> diff --git a/app/views/admin/poll/booths/index.html.erb b/app/views/admin/poll/booths/index.html.erb index 9618aec59..0dbb62cdf 100644 --- a/app/views/admin/poll/booths/index.html.erb +++ b/app/views/admin/poll/booths/index.html.erb @@ -16,6 +16,7 @@ <%= t("admin.booths.index.name") %> <%= t("admin.booths.index.location") %>   +   <% @booths.each do |booth| %> diff --git a/app/views/admin/poll/shifts/_shifts.html.erb b/app/views/admin/poll/shifts/_shifts.html.erb new file mode 100644 index 000000000..800c6944b --- /dev/null +++ b/app/views/admin/poll/shifts/_shifts.html.erb @@ -0,0 +1,24 @@ +

<%= t("admin.poll_shifts.new.assignments") %>

+ + + + + + + + + + <% @shifts.each do |shift| %> + + + + + + <% end %> + +
<%= t("admin.poll_shifts.new.date") %><%= t("admin.poll_shifts.new.officer") %><%= t("admin.poll_shifts.new.assignment") %>
<%= l(shift.date.to_date, format: :long) %><%= shift.officer.name %> + <%= link_to t("admin.poll_shifts.new.remove_assignment"), + admin_booth_shift_path(@booth, shift), + method: :delete, + class: "button hollow alert" %> +
diff --git a/app/views/admin/poll/shifts/new.html.erb b/app/views/admin/poll/shifts/new.html.erb new file mode 100644 index 000000000..c997dc35f --- /dev/null +++ b/app/views/admin/poll/shifts/new.html.erb @@ -0,0 +1,46 @@ +<%= back_link_to admin_booths_path %> + +

<%= @booth.name %>

+ +<%= form_for @shift, as: :shift, url: admin_booth_shifts_path do |f| %> + <%= render "shared/errors", resource: @shift %> + +
+ + <%= t("admin.poll_shifts.new.new_assignment") %> + + +
+ + <%= f.select :date, + shift_dates_select_options(@polls), + prompt: t("admin.poll_shifts.new.select_date"), + label: false %> +
+ +
+ + <%= f.select :officer_id, + officer_select_options(@officers), + prompt: t("admin.poll_shifts.new.select_officer"), + label: false %> +
+ + <%= f.hidden_field :booth_id, value: @booth.id %> + +
+ <%= f.submit t("admin.poll_shifts.new.add_assignment"), + class: "button expanded hollow margin-top" %> +
+
+<% end %> + +
+ <% if @shifts.empty? %> +
+ <%= t("admin.poll_shifts.new.no_assignments") %> +
+ <% else %> + <%= render "shifts" %> + <% end %> +
\ No newline at end of file diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 69ffa296e..dea45c3a3 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -403,6 +403,7 @@ en: poll_officers: Poll officers polls: Polls poll_booths: Booths location + poll_shifts: Manage shifts officials: Officials organizations: Organisations settings: Configuration settings @@ -481,11 +482,6 @@ en: search: Search user_not_found: User not found poll_officer_assignments: - flash: - destroy: "Officing shift removed" - create: "Officing shift added" - error_destroy: "An error ocurred when removing officer assignment" - error_create: "An error ocurred when adding officer assignment" index: officers_title: "List of officers" no_officers: "There are no officers assigned to this poll." @@ -494,18 +490,27 @@ en: add_officer_assignments: "Add shifts as officer" edit_officer_assignments: "Edit officing shifts" by_officer: - new_assignment: "New shift" date: "Date" booth: "Booth" - assignment: "Assignment" - select_date: "Select day" - select_booth: "Select booth" - add_assignment: "Add shift" - remove_assignment: "Remove" assignments: "Officing shifts in this poll" no_assignments: "This user has no officing shifts in this poll." final_recounts: "Final recounts" final_recount: "Final recount (by officer)" + poll_shifts: + new: + new_assignment: "New shift" + date: "Date" + officer: "Officer" + assignment: "Assignment" + select_date: "Select day" + select_officer: "Select officer" + add_assignment: "Add shift" + remove_assignment: "Remove" + assignments: "Shifts in this booth" + no_assignments: "This booth has no shifts" + flash: + create: "Shift added" + destroy: "Shift removed" poll_booth_assignments: flash: destroy: "Booth not assigned anymore" @@ -618,6 +623,8 @@ en: submit_button: "Update booth" show: location: "Location" + booth: + shifts: "Manage shifts" officials: edit: destroy: Remove 'Official' status diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 280033353..6e4fb2abf 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -414,6 +414,7 @@ es: poll_officers: Presidentes de mesa polls: Votaciones poll_booths: Ubicación de urnas + poll_shifts: Asignar turnos officials: Cargos públicos organizations: Organizaciones settings: Configuración global @@ -481,11 +482,6 @@ es: search: Buscar user_not_found: Usuario no encontrado poll_officer_assignments: - flash: - destroy: "Eliminado turno de presidente de mesa" - create: "Añadido turno de presidente de mesa" - error_destroy: "Se ha producido un error al eliminar el turno" - error_create: "Se ha producido un error al intentar crear el turno" index: officers_title: "Listado de presidentes de mesa asignados" no_officers: "No hay presidentes de mesa asignados a esta votación." @@ -494,18 +490,27 @@ es: add_officer_assignments: "Añadir turnos como presidente de mesa" edit_officer_assignments: "Editar turnos" by_officer: - new_assignment: "Nuevo turno" date: "Fecha" booth: "Urna" - assignment: "Asignación" - select_date: "Seleccionar día" - select_booth: "Seleccionar urna" - add_assignment: "Añadir turno" - remove_assignment: "Eliminar turno" assignments: "Turnos como presidente de mesa en esta votación" no_assignments: "No tiene turnos como presidente de mesa en esta votación." final_recounts: "Recuentos finales" final_recount: "Recuento final (presidente de mesa)" + poll_shifts: + new: + new_assignment: "Nuevo turno" + date: "Fecha" + officer: "Presidente de mesa" + assignment: "Asignación" + select_date: "Seleccionar día" + select_officer: "Seleccionar presidente de mesa" + add_assignment: "Añadir turno" + remove_assignment: "Eliminar turno" + assignments: "Turnos en esta urna" + no_assignments: "Esta urna no tiene turnos asignados" + flash: + create: "Añadido turno de presidente de mesa" + destroy: "Eliminado turno de presidente de mesa" poll_booth_assignments: flash: destroy: "Urna desasignada" @@ -618,6 +623,8 @@ es: submit_button: "Actualizar urna" show: location: "Ubicación" + booth: + shifts: "Asignar turnos" officials: edit: destroy: Eliminar condición de 'Cargo Público' diff --git a/config/routes.rb b/config/routes.rb index d151fdb6c..e3d3b5bcb 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -273,7 +273,10 @@ Rails.application.routes.draw do get :search, on: :collection end - resources :booths + resources :booths do + resources :shifts + end + resources :questions end diff --git a/db/migrate/20170724190805_create_poll_shifts.rb b/db/migrate/20170724190805_create_poll_shifts.rb new file mode 100644 index 000000000..8bb6eafd7 --- /dev/null +++ b/db/migrate/20170724190805_create_poll_shifts.rb @@ -0,0 +1,15 @@ +class CreatePollShifts < ActiveRecord::Migration + def change + create_table :poll_shifts do |t| + t.integer :booth_id + t.integer :officer_id + t.date :date + + t.timestamps + end + + add_index :poll_shifts, :booth_id + add_index :poll_shifts, :officer_id + add_index :poll_shifts, [:booth_id, :officer_id] + end +end diff --git a/db/schema.rb b/db/schema.rb index 91a26adeb..4170c10f2 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: 20170719174326) do +ActiveRecord::Schema.define(version: 20170724190805) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -652,6 +652,18 @@ ActiveRecord::Schema.define(version: 20170719174326) do add_index "poll_questions", ["proposal_id"], name: "index_poll_questions_on_proposal_id", using: :btree add_index "poll_questions", ["tsv"], name: "index_poll_questions_on_tsv", using: :gin + create_table "poll_shifts", force: :cascade do |t| + t.integer "booth_id" + t.integer "officer_id" + t.date "date" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "poll_shifts", ["booth_id", "officer_id"], name: "index_poll_shifts_on_booth_id_and_officer_id", using: :btree + add_index "poll_shifts", ["booth_id"], name: "index_poll_shifts_on_booth_id", using: :btree + add_index "poll_shifts", ["officer_id"], name: "index_poll_shifts_on_officer_id", using: :btree + create_table "poll_voters", force: :cascade do |t| t.string "document_number" t.string "document_type"