Class: Decidim::Initiative
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- Decidim::Initiative
- Includes:
- ActiveModel::Dirty, Authorable, Comments::Commentable, FilterableResource, Followable, HasArea, HasAttachmentCollections, HasAttachments, HasReference, HasResourcePermission, Decidim::Initiatives::HasArea, Decidim::Initiatives::InitiativeSlug, Loggable, Participable, Publicable, Randomable, Resourceable, ScopableParticipatorySpace, Searchable, Traceable, TranslatableResource
- Defined in:
- decidim-initiatives/app/models/decidim/initiative.rb
Overview
The data store for a Initiative in the Decidim::Initiatives component.
Class Method Summary collapse
- .log_presenter_class_for(_log) ⇒ Object
- .ransack(params = {}, options = {}) ⇒ Object
- .ransackable_scopes(_auth_object = nil) ⇒ Object
Instance Method Summary collapse
- #accepts_offline_votes? ⇒ Boolean
- #accepts_online_unvotes? ⇒ Boolean
- #accepts_online_votes? ⇒ Boolean
-
#allow_resource_permissions? ⇒ Boolean
Public: Overrides the ‘allow_resource_permissions?` Resourceable concern method.
-
#answered? ⇒ Boolean
Public: Checks if the organization has given an answer for the initiative.
-
#author_name ⇒ Object
Public: Returns the author name.
- #author_users ⇒ Object
-
#banner_image ⇒ Object
Public: Overrides participatory space’s banner image with the banner image defined for the initiative type.
-
#closed? ⇒ Boolean
Public: Checks if an initiative is closed.
-
#commentable? ⇒ Boolean
Public: Whether the object’s comments are visible or not.
-
#comments_have_alignment? ⇒ Boolean
Public: Overrides the ‘comments_have_alignment?` Commentable concern method.
-
#comments_have_votes? ⇒ Boolean
Public: Overrides the ‘comments_have_votes?` Commentable concern method.
- #component ⇒ Object
-
#created_by_individual? ⇒ Boolean
Public: Check if an initiative has been created by an individual person.
- #enough_committee_members? ⇒ Boolean
-
#has_authorship?(user) ⇒ Boolean
Public: Checks if user is the author or is part of the promotal committee of the initiative.
-
#has_signature_interval_defined? ⇒ Boolean
Public: Returns wether the signature interval is already defined or not.
-
#hashtag ⇒ Object
Public: Returns the hashtag for the initiative.
- #minimum_committee_members ⇒ Object
- #missing_committee_members ⇒ Object
- #offline_votes_count ⇒ Object
- #offline_votes_count_for(scope) ⇒ Object
-
#online_votes_count ⇒ Object
Public: Calculates all the votes across all the scopes.
- #online_votes_count_for(scope) ⇒ Object
-
#open? ⇒ Boolean
Public: check if an initiative is open.
-
#percentage ⇒ Object
Public: Returns the percentage of required supports reached.
-
#publish! ⇒ Object
Public: Publishes this initiative.
-
#scopes_enabled ⇒ Object
Public: Overrides scopes enabled attribute value.
-
#scopes_enabled? ⇒ Boolean
Public: Overrides scopes enabled flag available in other models like participatory space or assemblies.
- #set_offline_votes_total ⇒ Object
-
#slug ⇒ Object
Public: Overrides slug attribute from participatory processes.
-
#supports_count ⇒ Object
Public: Calculates the number of total current supports.
-
#supports_count_for(scope) ⇒ Object
Public: Calculates the number of current supports for a scope.
-
#supports_goal_reached? ⇒ Boolean
Public: Whether the supports required objective has been reached.
-
#supports_goal_reached_for?(scope) ⇒ Boolean
Public: Whether the supports required objective has been reached for a scope.
-
#supports_required_for(scope) ⇒ Object
Public: Calculates the number of supports required to accept the initiative for a scope.
- #to_param ⇒ Object
-
#unpublish! ⇒ Object
Public: Unpublishes this initiative.
- #update_online_votes_counters ⇒ Object
- #user_allowed_to_comment?(user) ⇒ Boolean
-
#user_role_config_for(_user, _role_name) ⇒ Object
Public: Returns an empty object.
-
#validate_sms_code_on_votes? ⇒ Boolean
Public: Checks if the type the initiative belongs to enables SMS code verification step.
-
#votable_initiative_type_scopes ⇒ Object
Public: Finds all the InitiativeTypeScopes that are eligible to be voted by a user.
-
#voted_by?(user) ⇒ Boolean
Public: Check if the user has voted the question.
- #votes_enabled? ⇒ Boolean
Methods included from Searchable
searchable_resources, searchable_resources_by_type, searchable_resources_of_type_comment, searchable_resources_of_type_component, searchable_resources_of_type_participant, searchable_resources_of_type_participatory_space
Methods included from Decidim::Initiatives::InitiativeSlug
Methods included from HasAttachments
Methods included from Followable
Methods included from Publicable
#previously_published?, #published?
Class Method Details
.log_presenter_class_for(_log) ⇒ Object
163 164 165 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 163 def self.log_presenter_class_for(_log) Decidim::Initiatives::AdminLog::InitiativePresenter end |
.ransack(params = {}, options = {}) ⇒ Object
473 474 475 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 473 def self.ransack(params = {}, = {}) Initiatives::InitiativeSearch.new(self, params, ) end |
.ransackable_scopes(_auth_object = nil) ⇒ Object
167 168 169 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 167 def self.ransackable_scopes(_auth_object = nil) [:with_any_state, :with_any_type, :with_any_scope, :with_any_area] end |
Instance Method Details
#accepts_offline_votes? ⇒ Boolean
420 421 422 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 420 def accepts_offline_votes? published? && (offline_signature_type? || any_signature_type?) end |
#accepts_online_unvotes? ⇒ Boolean
428 429 430 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 428 def accepts_online_unvotes? accepts_online_votes? && type.undo_online_signatures_enabled? end |
#accepts_online_votes? ⇒ Boolean
424 425 426 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 424 def accepts_online_votes? votes_enabled? && (online_signature_type? || any_signature_type?) end |
#allow_resource_permissions? ⇒ Boolean
Public: Overrides the ‘allow_resource_permissions?` Resourceable concern method.
465 466 467 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 465 def true end |
#answered? ⇒ Boolean
Public: Checks if the organization has given an answer for the initiative.
Returns a Boolean.
236 237 238 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 236 def answered? answered_at.present? end |
#author_name ⇒ Object
Public: Returns the author name. If it has been created by an organization it will return the organization’s name. Otherwise it will return author’s name.
Returns a string
216 217 218 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 216 def user_group&.name || .name end |
#author_users ⇒ Object
416 417 418 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 416 def [].concat(committee_members..map(&:user)) end |
#banner_image ⇒ Object
Public: Overrides participatory space’s banner image with the banner image defined for the initiative type.
Returns Decidim::BannerImageUploader
175 176 177 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 175 def type.attached_uploader(:banner_image) end |
#closed? ⇒ Boolean
Public: Checks if an initiative is closed. An initiative is closed when at least one of the following conditions is true:
-
It has been discarded.
-
It has been rejected.
-
It has been accepted.
-
Signature collection period has finished.
Returns a Boolean
208 209 210 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 208 def closed? discarded? || rejected? || accepted? || !votes_enabled? end |
#commentable? ⇒ Boolean
Public: Whether the object’s comments are visible or not.
180 181 182 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 180 def commentable? type.comments_enabled? end |
#comments_have_alignment? ⇒ Boolean
Public: Overrides the ‘comments_have_alignment?` Commentable concern method.
397 398 399 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 397 def comments_have_alignment? true end |
#comments_have_votes? ⇒ Boolean
Public: Overrides the ‘comments_have_votes?` Commentable concern method.
402 403 404 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 402 def comments_have_votes? true end |
#component ⇒ Object
444 445 446 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 444 def component nil end |
#created_by_individual? ⇒ Boolean
Public: Check if an initiative has been created by an individual person. If it is false, then it has been created by an authorized organization.
Returns a Boolean
188 189 190 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 188 def created_by_individual? decidim_user_group_id.nil? end |
#enough_committee_members? ⇒ Boolean
436 437 438 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 436 def enough_committee_members? committee_members.approved.count >= minimum_committee_members end |
#has_authorship?(user) ⇒ Boolean
Public: Checks if user is the author or is part of the promotal committee of the initiative.
Returns a Boolean.
410 411 412 413 414 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 410 def (user) return true if .id == user.id committee_members.approved.where(decidim_users_id: user.id).any? end |
#has_signature_interval_defined? ⇒ Boolean
Public: Returns wether the signature interval is already defined or not.
278 279 280 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 278 def has_signature_interval_defined? signature_end_date.present? && signature_start_date.present? end |
#hashtag ⇒ Object
Public: Returns the hashtag for the initiative.
283 284 285 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 283 def hashtag attributes["hashtag"].to_s.delete("#") end |
#minimum_committee_members ⇒ Object
432 433 434 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 432 def minimum_committee_members type.minimum_committee_members || Decidim::Initiatives.minimum_committee_members end |
#missing_committee_members ⇒ Object
440 441 442 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 440 def missing_committee_members minimum_committee_members - committee_members.approved.count end |
#offline_votes_count ⇒ Object
332 333 334 335 336 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 332 def offline_votes_count return 0 if online_signature_type? offline_votes["total"].to_i end |
#offline_votes_count_for(scope) ⇒ Object
346 347 348 349 350 351 352 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 346 def offline_votes_count_for(scope) return 0 if online_signature_type? scope_key = (scope&.id || "global").to_s (offline_votes || {}).fetch(scope_key, 0).to_i end |
#online_votes_count ⇒ Object
Public: Calculates all the votes across all the scopes.
Returns an Integer.
326 327 328 329 330 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 326 def online_votes_count return 0 if offline_signature_type? online_votes["total"].to_i end |
#online_votes_count_for(scope) ⇒ Object
338 339 340 341 342 343 344 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 338 def online_votes_count_for(scope) return 0 if offline_signature_type? scope_key = (scope&.id || "global").to_s (online_votes || {}).fetch(scope_key, 0).to_i end |
#open? ⇒ Boolean
Public: check if an initiative is open
Returns a Boolean
195 196 197 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 195 def open? !closed? end |
#percentage ⇒ Object
Public: Returns the percentage of required supports reached
309 310 311 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 309 def percentage [supports_count * 100 / supports_required, 100].min end |
#publish! ⇒ Object
Public: Publishes this initiative
Returns true if the record was properly saved, false otherwise.
257 258 259 260 261 262 263 264 265 266 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 257 def publish! return false if published? update( published_at: Time.current, state: "published", signature_start_date: Date.current, signature_end_date: signature_end_date || (Date.current + Decidim::Initiatives.default_signature_time_period_length) ) end |
#scopes_enabled ⇒ Object
Public: Overrides scopes enabled attribute value. For initiatives it will not be directly managed by the user and it will be enabled by default.
250 251 252 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 250 def scopes_enabled true end |
#scopes_enabled? ⇒ Boolean
Public: Overrides scopes enabled flag available in other models like participatory space or assemblies. For initiatives it will not be directly managed by the user and it will be enabled by default.
243 244 245 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 243 def scopes_enabled? true end |
#set_offline_votes_total ⇒ Object
366 367 368 369 370 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 366 def set_offline_votes_total return if offline_votes.blank? offline_votes["total"] = offline_votes[scope&.id.to_s] || offline_votes["global"] end |
#slug ⇒ Object
Public: Overrides slug attribute from participatory processes.
387 388 389 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 387 def slug slug_from_id(id) end |
#supports_count ⇒ Object
Public: Calculates the number of total current supports.
Returns an Integer.
290 291 292 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 290 def supports_count online_votes_count + offline_votes_count end |
#supports_count_for(scope) ⇒ Object
Public: Calculates the number of current supports for a scope.
Returns an Integer.
297 298 299 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 297 def supports_count_for(scope) online_votes_count_for(scope) + offline_votes_count_for(scope) end |
#supports_goal_reached? ⇒ Boolean
Public: Whether the supports required objective has been reached
314 315 316 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 314 def supports_goal_reached? votable_initiative_type_scopes.map(&:scope).all? { |scope| supports_goal_reached_for?(scope) } end |
#supports_goal_reached_for?(scope) ⇒ Boolean
Public: Whether the supports required objective has been reached for a scope
319 320 321 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 319 def supports_goal_reached_for?(scope) supports_count_for(scope) >= supports_required_for(scope) end |
#supports_required_for(scope) ⇒ Object
Public: Calculates the number of supports required to accept the initiative for a scope.
Returns an Integer.
304 305 306 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 304 def supports_required_for(scope) initiative_type_scopes.find_by(decidim_scopes_id: scope&.id).supports_required end |
#to_param ⇒ Object
391 392 393 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 391 def to_param slug end |
#unpublish! ⇒ Object
Public: Unpublishes this initiative
Returns true if the record was properly saved, false otherwise.
271 272 273 274 275 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 271 def unpublish! return false unless published? update(published_at: nil, state: "discarded") end |
#update_online_votes_counters ⇒ Object
354 355 356 357 358 359 360 361 362 363 364 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 354 def update_online_votes_counters online_votes = votes.group(:scope).count.each_with_object({}) do |(scope, count), counters| counters[scope&.id || "global"] = count counters["total"] ||= 0 counters["total"] += count end # rubocop:disable Rails/SkipsModelValidations update_column("online_votes", online_votes) # rubocop:enable Rails/SkipsModelValidations end |
#user_allowed_to_comment?(user) ⇒ Boolean
469 470 471 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 469 def user_allowed_to_comment?(user) ActionAuthorizer.new(user, "comment", self, nil)..ok? end |
#user_role_config_for(_user, _role_name) ⇒ Object
Public: Returns an empty object. This method should be implemented by ‘ParticipatorySpaceResourceable`, but for some reason this model does not implement this interface.
460 461 462 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 460 def user_role_config_for(_user, _role_name) Decidim::ParticipatorySpaceRoleConfig::Base.new(:empty_role_name) end |
#validate_sms_code_on_votes? ⇒ Boolean
Public: Checks if the type the initiative belongs to enables SMS code verification step. Tis configuration is ignored if the organization does not have the sms authorization available
Returns a Boolean
453 454 455 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 453 def validate_sms_code_on_votes? organization..include?("sms") && type.validate_sms_code_on_votes? end |
#votable_initiative_type_scopes ⇒ Object
Public: Finds all the InitiativeTypeScopes that are eligible to be voted by a user. Usually this is only the ‘scoped_type` but voting on children of the scoped type is enabled we have to filter all the available scopes in the initiative type to select the ones that are a descendant of the initiative type.
Returns an Array of Decidim::InitiativesScopeType.
378 379 380 381 382 383 384 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 378 def votable_initiative_type_scopes return Array(scoped_type) unless type.child_scope_threshold_enabled? initiative_type_scopes.select do |initiative_type_scope| initiative_type_scope.scope.present? && (scoped_type.global_scope? || scoped_type.scope.ancestor_of?(initiative_type_scope.scope)) end.prepend(scoped_type).uniq end |
#voted_by?(user) ⇒ Boolean
Public: Check if the user has voted the question.
Returns Boolean.
229 230 231 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 229 def voted_by?(user) votes.where(author: user).any? end |
#votes_enabled? ⇒ Boolean
220 221 222 223 224 |
# File 'decidim-initiatives/app/models/decidim/initiative.rb', line 220 def votes_enabled? published? && signature_start_date <= Date.current && signature_end_date >= Date.current end |