podemos-info/participa2

View on GitHub
decidim-module-votings/app/models/decidim/votings/voting.rb

Summary

Maintainability
A
0 mins
Test Coverage
# frozen_string_literal: true

module Decidim
  module Votings
    # Model for collaboration campaigns defined inside a
    # participatory space.
    class Voting < Decidim::Votings::ApplicationRecord
      include Decidim::Resourceable
      include Decidim::HasComponent
      include Decidim::Followable
      include Decidim::ScopableComponent

      component_manifest_name "votings"

      mount_uploader :image, Decidim::Votings::VotingUploader

      store_accessor :system_configuration, :voting_domain_name, :voting_identifier, :shared_key

      validates :image, file_size: { less_than_or_equal_to: ->(_attachment) { Decidim.maximum_attachment_size } }

      has_many :votes, foreign_key: "decidim_votings_voting_id", inverse_of: :voting, dependent: :destroy
      has_many :simulated_votes, foreign_key: "decidim_votings_voting_id", inverse_of: :voting, dependent: :destroy

      has_many :electoral_districts, foreign_key: "decidim_votings_voting_id", inverse_of: :voting, dependent: :destroy

      scope :for_component, ->(component) { where(component: component) }
      scope :active_range, ->(before_start, after_end) { where("start_date <= ? AND ? <= end_date", before_start.from_now, after_end.ago) }
      scope :order_by_importance, -> { order(:importance) }

      def active?
        @active ||= started? && !finished?
      end

      def started?
        @started ||= start_date < Time.zone.now
      end

      def finished?
        @finished ||= end_date < Time.zone.now
      end

      def simulating?
        @simulating ||= !started?
      end

      def target_votes
        simulating? ? simulated_votes.by_simulation_code(simulation_code) : votes
      end

      def simulation_key
        Digest::SHA256.hexdigest("#{Rails.application.secrets.secret_key_base}:#{created_at}:#{id}:#{voting_system}")
      end

      def status
        return :upcoming unless started?
        return :closed if finished?

        :active
      end

      def has_voted?(user)
        target_votes.by_user(user).first&.confirmed?
      end

      def can_change_shared_key?
        simulated_votes.empty? && votes.empty?
      end

      def allow_resource_permissions?
        component.settings.resources_permissions_enabled
      end

      def voting_identifier_for(user_scope)
        raise "Invalid user scope for this voting" if scope && user_scope && !scope.ancestor_of?(user_scope)

        district_voting_identifier = ordered_electoral_districts(user_scope.part_of).map(&:voting_identifier).first if user_scope
        district_voting_identifier || voting_identifier
      end

      private

      def ordered_electoral_districts(scope_ids)
        electoral_districts.where(decidim_scope_id: scope_ids).sort do |district1, district2|
          scope_ids.index(district2.id) <=> scope_ids.index(district1.id)
        end
      end
    end
  end
end