From 3c682b8a9b5bd0fc577d62268b25f151e7c90962 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Tue, 20 Dec 2016 12:21:05 +0100 Subject: [PATCH] adds signature sheets --- .../admin/signature_sheets_controller.rb | 33 +++++++++ app/helpers/signature_sheets_helper.rb | 8 +++ app/models/proposal.rb | 4 +- app/models/signature.rb | 72 +++++++++++++++++++ app/models/signature_sheet.rb | 43 +++++++++++ app/models/spending_proposal.rb | 8 ++- app/views/admin/_menu.html.erb | 8 +++ .../admin/signature_sheets/index.html.erb | 26 +++++++ app/views/admin/signature_sheets/new.html.erb | 9 +++ .../admin/signature_sheets/show.html.erb | 28 ++++++++ app/views/debates/_form.html.erb | 1 - config/initializers/vote_extensions.rb | 3 + config/routes.rb | 2 + .../20161214212918_create_signature_sheets.rb | 11 +++ .../20161214233817_create_signatures.rb | 11 +++ db/schema.rb | 21 +++++- 16 files changed, 282 insertions(+), 6 deletions(-) create mode 100644 app/controllers/admin/signature_sheets_controller.rb create mode 100644 app/helpers/signature_sheets_helper.rb create mode 100644 app/models/signature.rb create mode 100644 app/models/signature_sheet.rb create mode 100644 app/views/admin/signature_sheets/index.html.erb create mode 100644 app/views/admin/signature_sheets/new.html.erb create mode 100644 app/views/admin/signature_sheets/show.html.erb create mode 100644 db/migrate/20161214212918_create_signature_sheets.rb create mode 100644 db/migrate/20161214233817_create_signatures.rb diff --git a/app/controllers/admin/signature_sheets_controller.rb b/app/controllers/admin/signature_sheets_controller.rb new file mode 100644 index 000000000..83d1e93ce --- /dev/null +++ b/app/controllers/admin/signature_sheets_controller.rb @@ -0,0 +1,33 @@ +class Admin::SignatureSheetsController < Admin::BaseController + + def index + @signature_sheets = SignatureSheet.all + end + + def new + @signature_sheet = SignatureSheet.new + end + + def create + @signature_sheet = SignatureSheet.new(signature_sheet_params) + @signature_sheet.author = current_user + if @signature_sheet.save + @signature_sheet.delay.verify_signatures + redirect_to [:admin, @signature_sheet] + else + render :new + end + end + + def show + @signature_sheet = SignatureSheet.find(params[:id]) + @invalid_signatures = @signature_sheet.invalid_signatures + end + + private + + def signature_sheet_params + params.require(:signature_sheet).permit(:signable_type, :signable_id, :document_numbers) + end + +end \ No newline at end of file diff --git a/app/helpers/signature_sheets_helper.rb b/app/helpers/signature_sheets_helper.rb new file mode 100644 index 000000000..14424639c --- /dev/null +++ b/app/helpers/signature_sheets_helper.rb @@ -0,0 +1,8 @@ +module SignatureSheetsHelper + + def signable_options + [[t("activerecord.models.proposal", count: 1), Proposal], + [t("activerecord.models.spending_proposal", count: 1), SpendingProposal]] + end + +end \ No newline at end of file diff --git a/app/models/proposal.rb b/app/models/proposal.rb index 7bd4b7a92..fd828c31e 100644 --- a/app/models/proposal.rb +++ b/app/models/proposal.rb @@ -122,9 +122,9 @@ class Proposal < ActiveRecord::Base retired_at.present? end - def register_vote(user, vote_value) + def register_vote(user, vote_value, signature=nil) if votable_by?(user) && !archived? - vote_by(voter: user, vote: vote_value) + vote_by(voter: user, vote: vote_value, vote_scope: signature) end end diff --git a/app/models/signature.rb b/app/models/signature.rb new file mode 100644 index 000000000..3a1d197eb --- /dev/null +++ b/app/models/signature.rb @@ -0,0 +1,72 @@ +class Signature < ActiveRecord::Base + belongs_to :signature_sheet + belongs_to :user + + validate :in_census + validate :not_already_voted + + scope :valid, -> { where(status: 'verified') } + scope :invalid, -> { where.not(status: 'verified') } + + def in_census + return true if user_exists? + errors.add(:document_number, :not_in_census) unless in_census? + end + + def not_already_voted + errors.add(:document_number, :already_voted) if already_voted? + end + + def verify + if valid? + assign_vote + update_attribute(:status, 'verified') + else + error = errors.messages[:document_number].first + update_attribute(:status, error) + end + end + + private + + def assign_vote + if user_exists? + assign_vote_to_user + else + create_user + assign_vote_to_user + end + end + + def assign_vote_to_user + signable.register_vote(user, "yes", "signature") + #Vote.create(votable: signable, voter: user, signature: self) + end + + def user_exists? + user = User.where(document_number: document_number).exists? + end + + def create_user + user = User.where(document_number: document_number, erased_at: Time.now).create + end + + def in_census? + document_types.any? do |document_type| + CensusApi.new.call(document_type, document_number).valid? + end + end + + def already_voted? + signable.voters.where(document_number: document_number).exists? + end + + def signable + signature_sheet.signable + end + + def document_types + %w(1 2 3 4) + end + +end \ No newline at end of file diff --git a/app/models/signature_sheet.rb b/app/models/signature_sheet.rb new file mode 100644 index 000000000..7829833a3 --- /dev/null +++ b/app/models/signature_sheet.rb @@ -0,0 +1,43 @@ +class SignatureSheet < ActiveRecord::Base + belongs_to :signable, polymorphic: true + belongs_to :author, class_name: 'User', foreign_key: 'author_id' + + VALID_SIGNABLES = %w( Proposal SpendingProposal ) + + has_many :signatures + + validates :author, presence: true + validates :signable_type, inclusion: {in: VALID_SIGNABLES} + validates :document_numbers, presence: true + validates :signable, presence: true + validate :signable_found + + def name + "#{signable_name} + #{signable_id}" + end + + def signable_name + I18n.t("activerecord.models.#{signable_type.underscore}", count: 1) + end + + def verify_signatures + parsed_document_numbers.each do |document_number| + signature = signatures.new(document_number: document_number) + signature.save(validate: false) + signature.verify + end + update(processed: true) + end + + def invalid_signatures + signatures.invalid.group_by(&:status) + end + + def parsed_document_numbers + document_numbers.split(",") + end + + def signable_found + errors.add(:signable_id, :not_found) if errors.messages[:signable].present? + end +end \ No newline at end of file diff --git a/app/models/spending_proposal.rb b/app/models/spending_proposal.rb index 223e9adfe..111f4c3dd 100644 --- a/app/models/spending_proposal.rb +++ b/app/models/spending_proposal.rb @@ -125,13 +125,17 @@ class SpendingProposal < ActiveRecord::Base return :organization if user.organization? end + def voters + User.active.where(id: votes_for.voters) + end + def votable_by?(user) reason_for_not_being_votable_by(user).blank? end - def register_vote(user, vote_value) + def register_vote(user, vote_value, signature=nil) if votable_by?(user) - vote_by(voter: user, vote: vote_value) + vote_by(voter: user, vote: vote_value, vote_scope: signature) end end diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 3d3e807c7..3cdb057fb 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -35,6 +35,14 @@ <% end %> + <% if feature?(:signature_sheets) %> +
  • > + <%= link_to admin_signature_sheets_path do %> + <%= t("admin.menu.signature_sheets") %> + <% end %> +
  • + <% end %> +
  • > <%= link_to admin_banners_path do %> <%= t("admin.menu.banner") %> diff --git a/app/views/admin/signature_sheets/index.html.erb b/app/views/admin/signature_sheets/index.html.erb new file mode 100644 index 000000000..d03530e3b --- /dev/null +++ b/app/views/admin/signature_sheets/index.html.erb @@ -0,0 +1,26 @@ +

    Signatures

    + +
    + <%= link_to 'Nueva hoja de firmas', new_admin_signature_sheet_path %> +
    + + + + + + + + <% @signature_sheets.each do |signature_sheet| %> + + + + + + <% end %> +
    <%= t("admin.signature_sheet.name") %><%= t("admin.signature_sheet.author") %><%= t("admin.signature_sheet.created_at") %>
    + <%= link_to signature_sheet.name, [:admin, signature_sheet] %> + + <%= signature_sheet.author.name %> + + <%= l(signature_sheet.created_at, format: :short) %> +
    \ No newline at end of file diff --git a/app/views/admin/signature_sheets/new.html.erb b/app/views/admin/signature_sheets/new.html.erb new file mode 100644 index 000000000..c3fe19b55 --- /dev/null +++ b/app/views/admin/signature_sheets/new.html.erb @@ -0,0 +1,9 @@ +<%= form_for [:admin, @signature_sheet] do |f| %> + <%= render 'shared/errors', + resource: @signature_sheet %> + + <%= f.select :signable_type, signable_options %> + <%= f.text_field :signable_id %> + <%= f.text_area :document_numbers %> + <%= f.submit %> +<% end %> \ No newline at end of file diff --git a/app/views/admin/signature_sheets/show.html.erb b/app/views/admin/signature_sheets/show.html.erb new file mode 100644 index 000000000..84f5cb672 --- /dev/null +++ b/app/views/admin/signature_sheets/show.html.erb @@ -0,0 +1,28 @@ +

    <%= @signature_sheet.name %>

    + +
    Documentos: <%= @signature_sheet.document_numbers %>
    +
    Creado: <%= l(@signature_sheet.created_at, format: :short) %>
    +
    Autor: <%= @signature_sheet.author.name %>
    +
    + +
    + Hay <%= @signature_sheet.signatures.valid.count %> firmas válidas +
    + +
    + Hay <%= @signature_sheet.signatures.invalid.count %> firmas inválidas +
    +
    + +<% if @signature_sheet.signatures.invalid.any? %> + <% @invalid_signatures.each do |error, signatures| %> +
    <%= error %>
    +
    + <%= signatures.map(&:document_number).join(",") %> +
    + <% end %> +<% end %> + +<% unless @signature_sheet.processed? %> + Aún hay firmas que se están verificando por el Padrón, por favor refresca la página en unos instantes. +<% end %> \ No newline at end of file diff --git a/app/views/debates/_form.html.erb b/app/views/debates/_form.html.erb index 30152b366..c88045f26 100644 --- a/app/views/debates/_form.html.erb +++ b/app/views/debates/_form.html.erb @@ -1,6 +1,5 @@ <%= form_for(@debate) do |f| %> - <%= render 'shared/errors', resource: @debate %>
    diff --git a/config/initializers/vote_extensions.rb b/config/initializers/vote_extensions.rb index 345cb8f01..fce7b49eb 100644 --- a/config/initializers/vote_extensions.rb +++ b/config/initializers/vote_extensions.rb @@ -1,4 +1,6 @@ ActsAsVotable::Vote.class_eval do + belongs_to :signature + def self.for_debates(debates) where(votable_type: 'Debate', votable_id: debates) end @@ -14,4 +16,5 @@ ActsAsVotable::Vote.class_eval do def value vote_flag end + end diff --git a/config/routes.rb b/config/routes.rb index 885d155db..5019cda40 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -149,6 +149,8 @@ Rails.application.routes.draw do get :summary, on: :collection end + resources :signature_sheets, only: [:index, :new, :create, :show] + resources :banners, only: [:index, :new, :create, :edit, :update, :destroy] do collection { get :search} end diff --git a/db/migrate/20161214212918_create_signature_sheets.rb b/db/migrate/20161214212918_create_signature_sheets.rb new file mode 100644 index 000000000..e3f4e6a58 --- /dev/null +++ b/db/migrate/20161214212918_create_signature_sheets.rb @@ -0,0 +1,11 @@ +class CreateSignatureSheets < ActiveRecord::Migration + def change + create_table :signature_sheets do |t| + t.references :signable, polymorphic: true + t.text :document_numbers + t.boolean :processed + t.references :author + t.timestamps + end + end +end \ No newline at end of file diff --git a/db/migrate/20161214233817_create_signatures.rb b/db/migrate/20161214233817_create_signatures.rb new file mode 100644 index 000000000..c8c178582 --- /dev/null +++ b/db/migrate/20161214233817_create_signatures.rb @@ -0,0 +1,11 @@ +class CreateSignatures < ActiveRecord::Migration + def change + create_table :signatures do |t| + t.references :signature_sheet + t.references :user + t.string :document_number + t.string :status, default: nil + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index a93942873..ab8dead98 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: 20161102133838) do +ActiveRecord::Schema.define(version: 20161214233817) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -326,6 +326,25 @@ ActiveRecord::Schema.define(version: 20161102133838) do add_index "settings", ["key"], name: "index_settings_on_key", using: :btree + create_table "signature_sheets", force: :cascade do |t| + t.integer "signable_id" + t.string "signable_type" + t.text "document_numbers" + t.boolean "processed" + t.integer "author_id" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "signatures", force: :cascade do |t| + t.integer "signature_sheet_id" + t.integer "user_id" + t.string "document_number" + t.string "status" + t.datetime "created_at" + t.datetime "updated_at" + end + create_table "spending_proposals", force: :cascade do |t| t.string "title" t.text "description"