Class: Decidim::Proposals::Proposal

Inherits:
ApplicationRecord show all
Includes:
Amendable, Coauthorable, DataPortability, Fingerprintable, Followable, HasAttachments, HasCategory, HasComponent, HasReference, Hashtaggable, Loggable, CommentableProposal, ParticipatoryTextSection, Reportable, Resourceable, ScopableComponent, Searchable, Traceable
Defined in:
app/models/decidim/proposals/proposal.rb

Overview

The data store for a Proposal in the Decidim::Proposals component.

Constant Summary

Constants included from ParticipatoryTextSection

Decidim::Proposals::ParticipatoryTextSection::LEVELS

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.data_portability_images(user) ⇒ Object



237
238
239
# File 'app/models/decidim/proposals/proposal.rb', line 237

def self.data_portability_images(user)
  user_collection(user).map { |p| p.attachments.collect(&:file) }
end

.export_serializerObject



233
234
235
# File 'app/models/decidim/proposals/proposal.rb', line 233

def self.export_serializer
  Decidim::Proposals::ProposalSerializer
end

.log_presenter_class_for(_log) ⇒ Object



79
80
81
# File 'app/models/decidim/proposals/proposal.rb', line 79

def self.log_presenter_class_for(_log)
  Decidim::Proposals::AdminLog::ProposalPresenter
end

.order_randomly(seed) ⇒ Object



72
73
74
75
76
77
# File 'app/models/decidim/proposals/proposal.rb', line 72

def self.order_randomly(seed)
  transaction do
    connection.execute("SELECT setseed(#{connection.quote(seed)})")
    order(Arel.sql("RANDOM()")).load
  end
end

.user_collection(author) ⇒ Object

Returns a collection scoped by an author. Overrides this method in DataPortability to support Coauthorable.



85
86
87
88
89
90
91
# File 'app/models/decidim/proposals/proposal.rb', line 85

def self.user_collection(author)
  return unless author.is_a?(Decidim::User)

  joins(:coauthorships)
    .where("decidim_coauthorships.coauthorable_type = ?", name)
    .where("decidim_coauthorships.decidim_author_id = ? AND decidim_coauthorships.decidim_author_type = ? ", author.id, author.class.base_class.name)
end

Instance Method Details

#accepted?Boolean

Public: Checks if the organization has accepted a proposal.

Returns Boolean.

Returns:

  • (Boolean)


134
135
136
# File 'app/models/decidim/proposals/proposal.rb', line 134

def accepted?
  answered? && state == "accepted"
end

#allow_resource_permissions?Boolean

Public: Overrides the ‘allow_resource_permissions?` Resourceable concern method.

Returns:

  • (Boolean)


242
243
244
# File 'app/models/decidim/proposals/proposal.rb', line 242

def allow_resource_permissions?
  component.settings.resources_permissions_enabled
end

#answered?Boolean

Public: Checks if the organization has given an answer for the proposal.

Returns Boolean.

Returns:

  • (Boolean)


127
128
129
# File 'app/models/decidim/proposals/proposal.rb', line 127

def answered?
  answered_at.present? && state.present?
end

#can_accumulate_supports_beyond_thresholdObject

Public: Can accumulate more votres than maximum for this proposal.

Returns true if can accumulate, false otherwise



196
197
198
# File 'app/models/decidim/proposals/proposal.rb', line 196

def can_accumulate_supports_beyond_threshold
  component.settings.can_accumulate_supports_beyond_threshold
end

#draft?Boolean

Public: Whether the proposal is a draft or not.

Returns:

  • (Boolean)


216
217
218
# File 'app/models/decidim/proposals/proposal.rb', line 216

def draft?
  published_at.nil?
end

#editable_by?(user) ⇒ Boolean

Checks whether the user can edit the given proposal.

user - the user to check for authorship

Returns:

  • (Boolean)


203
204
205
206
# File 'app/models/decidim/proposals/proposal.rb', line 203

def editable_by?(user)
  return true if draft?
  !answered? && within_edit_time_limit? && !copied_from_other_component? && created_by?(user)
end

#endorsed_by?(user, user_group = nil) ⇒ Boolean

Public: Check if the user has endorsed the proposal.

  • user_group: may be nil if user is not representing any user_group.

Returns Boolean.

Returns:

  • (Boolean)


113
114
115
# File 'app/models/decidim/proposals/proposal.rb', line 113

def endorsed_by?(user, user_group = nil)
  endorsements.where(author: user, user_group: user_group).any?
end

#evaluating?Boolean

Public: Checks if the organization has marked the proposal as evaluating it.

Returns Boolean.

Returns:

  • (Boolean)


148
149
150
# File 'app/models/decidim/proposals/proposal.rb', line 148

def evaluating?
  answered? && state == "evaluating"
end

#maximum_votesObject

Public: The maximum amount of votes allowed for this proposal.

Returns an Integer with the maximum amount of votes, nil otherwise.



177
178
179
180
181
182
# File 'app/models/decidim/proposals/proposal.rb', line 177

def maximum_votes
  maximum_votes = component.settings.threshold_per_proposal
  return nil if maximum_votes.zero?

  maximum_votes
end

#maximum_votes_reached?Boolean

Public: The maximum amount of votes allowed for this proposal. 0 means infinite.

Returns true if reached, false otherwise.

Returns:

  • (Boolean)


187
188
189
190
191
# File 'app/models/decidim/proposals/proposal.rb', line 187

def maximum_votes_reached?
  return false unless maximum_votes

  votes.count >= maximum_votes
end

#official?Boolean

Public: Whether the proposal is official or not.

Returns:

  • (Boolean)


165
166
167
# File 'app/models/decidim/proposals/proposal.rb', line 165

def official?
  authors.first.is_a?(Decidim::Organization)
end

#official_meeting?Boolean

Public: Whether the proposal is created in a meeting or not.

Returns:

  • (Boolean)


170
171
172
# File 'app/models/decidim/proposals/proposal.rb', line 170

def official_meeting?
  authors.first.class.name == "Decidim::Meetings::Meeting"
end

#published?Boolean

Public: Checks if the proposal has been published or not.

Returns Boolean.

Returns:

  • (Boolean)


120
121
122
# File 'app/models/decidim/proposals/proposal.rb', line 120

def published?
  published_at.present?
end

#rejected?Boolean

Public: Checks if the organization has rejected a proposal.

Returns Boolean.

Returns:

  • (Boolean)


141
142
143
# File 'app/models/decidim/proposals/proposal.rb', line 141

def rejected?
  answered? && state == "rejected"
end

#reported_content_urlObject

Public: Overrides the ‘reported_content_url` Reportable concern method.



160
161
162
# File 'app/models/decidim/proposals/proposal.rb', line 160

def reported_content_url
  ResourceLocatorPresenter.new(self).url
end

#update_votes_countObject

Public: Updates the vote count of this proposal.

Returns nothing. rubocop:disable Rails/SkipsModelValidations



97
98
99
# File 'app/models/decidim/proposals/proposal.rb', line 97

def update_votes_count
  update_columns(proposal_votes_count: votes.count)
end

#voted_by?(user) ⇒ Boolean

Public: Check if the user has voted the proposal.

Returns Boolean.

Returns:

  • (Boolean)


105
106
107
# File 'app/models/decidim/proposals/proposal.rb', line 105

def voted_by?(user)
  ProposalVote.where(proposal: self, author: user).any?
end

#withdrawable_by?(user) ⇒ Boolean

Checks whether the user can withdraw the given proposal.

user - the user to check for withdrawability.

Returns:

  • (Boolean)


211
212
213
# File 'app/models/decidim/proposals/proposal.rb', line 211

def withdrawable_by?(user)
  user && !withdrawn? && authored_by?(user) && !copied_from_other_component?
end

#withdrawn?Boolean

Public: Checks if the author has withdrawn the proposal.

Returns Boolean.

Returns:

  • (Boolean)


155
156
157
# File 'app/models/decidim/proposals/proposal.rb', line 155

def withdrawn?
  state == "withdrawn"
end

#within_edit_time_limit?Boolean

Checks whether the proposal is inside the time window to be editable or not once published.

Returns:

  • (Boolean)


247
248
249
250
251
# File 'app/models/decidim/proposals/proposal.rb', line 247

def within_edit_time_limit?
  return true if draft?
  limit = updated_at + component.settings.proposal_edit_before_minutes.minutes
  Time.current < limit
end