decidim-proposals 0.18.1 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/decidim_proposals_manifest.js +0 -1
  3. data/app/assets/javascripts/decidim/proposals/admin/proposals_form.js.es6 +5 -0
  4. data/app/cells/decidim/proposals/collaborative_draft_m_cell.rb +1 -0
  5. data/app/cells/decidim/proposals/endorsers_list_cell.rb +1 -0
  6. data/app/cells/decidim/proposals/irreversible_action_modal_cell.rb +1 -0
  7. data/app/cells/decidim/proposals/participatory_text_proposal/buttons.erb +8 -8
  8. data/app/cells/decidim/proposals/participatory_text_proposal_cell.rb +13 -0
  9. data/app/cells/decidim/proposals/proposal_link_to_collaborative_draft_cell.rb +4 -8
  10. data/app/cells/decidim/proposals/{proposal_link_to_collaborative_draft → proposal_link_to_rejected_emendation}/show.erb +0 -0
  11. data/app/cells/decidim/proposals/proposal_link_to_rejected_emendation_cell.rb +34 -0
  12. data/app/cells/decidim/proposals/proposal_linked_resources/show.erb +9 -0
  13. data/app/cells/decidim/proposals/proposal_linked_resources_cell.rb +14 -0
  14. data/app/cells/decidim/proposals/proposal_m_cell.rb +3 -0
  15. data/app/commands/decidim/proposals/admin/create_proposal.rb +10 -33
  16. data/app/commands/decidim/proposals/admin/import_participatory_text.rb +2 -0
  17. data/app/commands/decidim/proposals/admin/merge_proposals.rb +1 -0
  18. data/app/commands/decidim/proposals/admin/publish_participatory_text.rb +24 -1
  19. data/app/commands/decidim/proposals/admin/update_participatory_text.rb +11 -7
  20. data/app/commands/decidim/proposals/admin/update_proposal.rb +9 -1
  21. data/app/commands/decidim/proposals/gallery_methods.rb +67 -0
  22. data/app/commands/decidim/proposals/unvote_proposal.rb +1 -0
  23. data/app/commands/decidim/proposals/update_proposal.rb +6 -1
  24. data/app/commands/decidim/proposals/vote_proposal.rb +1 -0
  25. data/app/controllers/concerns/decidim/proposals/collaborative_orderable.rb +1 -15
  26. data/app/controllers/concerns/decidim/proposals/orderable.rb +1 -15
  27. data/app/controllers/decidim/proposals/admin/participatory_texts_controller.rb +5 -0
  28. data/app/controllers/decidim/proposals/application_controller.rb +1 -0
  29. data/app/controllers/decidim/proposals/collaborative_drafts_controller.rb +1 -0
  30. data/app/controllers/decidim/proposals/proposal_endorsements_controller.rb +1 -1
  31. data/app/controllers/decidim/proposals/proposal_votes_controller.rb +1 -1
  32. data/app/controllers/decidim/proposals/proposals_controller.rb +22 -23
  33. data/app/forms/decidim/proposals/admin/proposal_form.rb +3 -0
  34. data/app/forms/decidim/proposals/admin/proposals_fork_form.rb +1 -0
  35. data/app/forms/decidim/proposals/proposal_wizard_create_step_form.rb +1 -0
  36. data/app/helpers/decidim/proposals/admin/proposals_helper.rb +1 -0
  37. data/app/helpers/decidim/proposals/map_helper.rb +1 -1
  38. data/app/helpers/decidim/proposals/proposal_cells_helper.rb +2 -0
  39. data/app/helpers/decidim/proposals/proposal_endorsements_helper.rb +1 -0
  40. data/app/helpers/decidim/proposals/proposal_votes_helper.rb +5 -0
  41. data/app/helpers/decidim/proposals/proposal_wizard_helper.rb +1 -0
  42. data/app/models/decidim/proposals/collaborative_draft.rb +1 -0
  43. data/app/models/decidim/proposals/proposal.rb +4 -8
  44. data/app/models/decidim/proposals/proposal_endorsement.rb +2 -0
  45. data/app/models/decidim/proposals/proposal_vote.rb +2 -0
  46. data/app/permissions/decidim/proposals/admin/permissions.rb +1 -0
  47. data/app/permissions/decidim/proposals/permissions.rb +17 -0
  48. data/app/presenters/decidim/proposals/admin_log/value_types/proposal_state_presenter.rb +1 -0
  49. data/app/presenters/decidim/proposals/collaborative_draft_presenter.rb +1 -1
  50. data/app/presenters/decidim/proposals/proposal_presenter.rb +4 -2
  51. data/app/queries/decidim/proposals/metrics/endorsements_metric_manage.rb +1 -0
  52. data/app/queries/decidim/proposals/metrics/proposal_followers_metric_measure.rb +2 -0
  53. data/app/queries/decidim/proposals/metrics/proposal_participants_metric_measure.rb +3 -0
  54. data/app/queries/decidim/proposals/metrics/proposals_metric_manage.rb +1 -0
  55. data/app/queries/decidim/proposals/metrics/votes_metric_manage.rb +1 -0
  56. data/app/services/decidim/proposals/diff_renderer.rb +43 -0
  57. data/app/services/decidim/proposals/proposal_builder.rb +23 -0
  58. data/app/services/decidim/proposals/proposal_search.rb +5 -3
  59. data/app/views/decidim/proposals/admin/proposals/_form.html.erb +24 -0
  60. data/app/views/decidim/proposals/admin/proposals/_proposal-tr.html.erb +3 -3
  61. data/app/views/decidim/proposals/collaborative_drafts/_collaborative_drafts.html.erb +1 -1
  62. data/app/views/decidim/proposals/collaborative_drafts/show.html.erb +0 -3
  63. data/app/views/decidim/proposals/proposal_endorsements/_identity.html.erb +1 -1
  64. data/app/views/decidim/proposals/proposals/_filters.html.erb +2 -1
  65. data/app/views/decidim/proposals/proposals/_proposal_preview.html.erb +1 -1
  66. data/app/views/decidim/proposals/proposals/_proposals.html.erb +1 -1
  67. data/app/views/decidim/proposals/proposals/index.html.erb +1 -1
  68. data/app/views/decidim/proposals/proposals/participatory_texts/_index.html.erb +1 -1
  69. data/app/views/decidim/proposals/proposals/show.html.erb +13 -9
  70. data/config/locales/ar.yml +2 -0
  71. data/config/locales/ca.yml +20 -0
  72. data/config/locales/cs.yml +20 -0
  73. data/config/locales/de.yml +2 -0
  74. data/config/locales/en.yml +20 -0
  75. data/config/locales/es-MX.yml +18 -0
  76. data/config/locales/es-PY.yml +18 -0
  77. data/config/locales/es.yml +20 -0
  78. data/config/locales/fi-plain.yml +20 -0
  79. data/config/locales/fi.yml +20 -0
  80. data/config/locales/fr.yml +21 -1
  81. data/config/locales/hu.yml +20 -0
  82. data/config/locales/it.yml +16 -0
  83. data/config/locales/nl.yml +20 -0
  84. data/config/locales/sv.yml +15 -0
  85. data/config/locales/tr-TR.yml +7 -0
  86. data/lib/decidim/content_parsers/proposal_parser.rb +2 -2
  87. data/lib/decidim/content_renderers/proposal_renderer.rb +1 -1
  88. data/lib/decidim/proposals/commentable_proposal.rb +1 -0
  89. data/lib/decidim/proposals/component.rb +8 -3
  90. data/lib/decidim/proposals/engine.rb +0 -1
  91. data/lib/decidim/proposals/markdown_to_proposals.rb +11 -7
  92. data/lib/decidim/proposals/proposal_serializer.rb +20 -2
  93. data/lib/decidim/proposals/version.rb +1 -1
  94. metadata +24 -38
  95. data/app/assets/config/decidim_proposals_manifest.css +0 -3
  96. data/app/assets/javascripts/decidim/proposals/social_share.js +0 -2
  97. data/app/assets/stylesheets/decidim/proposals/social_share.css.scss +0 -22
  98. data/config/initializers/social_share_button.rb +0 -5
@@ -50,6 +50,7 @@ module Decidim
50
50
 
51
51
  def update_temporary_votes
52
52
  return unless minimum_votes_per_user? && user_votes.count < minimum_votes_per_user
53
+
53
54
  user_votes.each { |vote| vote.update(temporary: true) }
54
55
  end
55
56
 
@@ -67,7 +67,12 @@ module Decidim
67
67
  end
68
68
 
69
69
  def update_proposal
70
- @proposal.update!(attributes)
70
+ @proposal = Decidim.traceability.update!(
71
+ @proposal,
72
+ current_user,
73
+ attributes,
74
+ visibility: "public-only"
75
+ )
71
76
  @proposal.coauthorships.clear
72
77
  @proposal.add_coauthor(current_user, user_group: user_group)
73
78
  end
@@ -55,6 +55,7 @@ module Decidim
55
55
 
56
56
  def update_temporary_votes
57
57
  return unless minimum_votes_per_user? && user_votes.count >= minimum_votes_per_user
58
+
58
59
  user_votes.each { |vote| vote.update(temporary: false) }
59
60
  end
60
61
 
@@ -9,15 +9,10 @@ module Decidim
9
9
  extend ActiveSupport::Concern
10
10
 
11
11
  included do
12
- helper_method :order, :available_orders, :random_seed
12
+ include Decidim::Orderable
13
13
 
14
14
  private
15
15
 
16
- # Gets how the proposals should be ordered based on the choice made by the user.
17
- def order
18
- @order ||= detect_order(params[:order]) || default_order
19
- end
20
-
21
16
  # Available orders based on enabled settings
22
17
  def available_orders
23
18
  @available_orders ||= begin
@@ -31,15 +26,6 @@ module Decidim
31
26
  detect_order("most_contributed")
32
27
  end
33
28
 
34
- # Returns: A random float number between -1 and 1 to be used as a random seed at the database.
35
- def random_seed
36
- @random_seed ||= (params[:random_seed] ? params[:random_seed].to_f : (rand * 2 - 1))
37
- end
38
-
39
- def detect_order(candidate)
40
- available_orders.detect { |order| order == candidate }
41
- end
42
-
43
29
  def reorder(drafts)
44
30
  case order
45
31
  when "random"
@@ -9,15 +9,10 @@ module Decidim
9
9
  extend ActiveSupport::Concern
10
10
 
11
11
  included do
12
- helper_method :order, :available_orders, :random_seed
12
+ include Decidim::Orderable
13
13
 
14
14
  private
15
15
 
16
- # Gets how the proposals should be ordered based on the choice made by the user.
17
- def order
18
- @order ||= detect_order(params[:order]) || default_order
19
- end
20
-
21
16
  # Available orders based on enabled settings
22
17
  def available_orders
23
18
  @available_orders ||= begin
@@ -43,15 +38,6 @@ module Decidim
43
38
  most_voted_order_available? && current_settings.votes_blocked?
44
39
  end
45
40
 
46
- # Returns: A random float number between -1 and 1 to be used as a random seed at the database.
47
- def random_seed
48
- @random_seed ||= (params[:random_seed] ? params[:random_seed].to_f : (rand * 2 - 1))
49
- end
50
-
51
- def detect_order(candidate)
52
- available_orders.detect { |order| order == candidate }
53
- end
54
-
55
41
  def reorder(proposals)
56
42
  case order
57
43
  when "random"
@@ -34,6 +34,11 @@ module Decidim
34
34
  flash.now[:alert] = I18n.t("participatory_texts.import.invalid", scope: "decidim.proposals.admin")
35
35
  render action: "new_import"
36
36
  end
37
+
38
+ on(:invalid_file) do
39
+ flash.now[:alert] = I18n.t("participatory_texts.import.invalid_file", scope: "decidim.proposals.admin")
40
+ render action: "new_import"
41
+ end
37
42
  end
38
43
  end
39
44
 
@@ -13,6 +13,7 @@ module Decidim
13
13
 
14
14
  def proposal_limit
15
15
  return nil if component_settings.proposal_limit.zero?
16
+
16
17
  component_settings.proposal_limit
17
18
  end
18
19
 
@@ -34,6 +34,7 @@ module Decidim
34
34
 
35
35
  def show
36
36
  raise ActionController::RoutingError, "Not Found" unless retrieve_collaborative_draft
37
+
37
38
  @report_form = form(Decidim::ReportForm).from_params(reason: "spam")
38
39
  @request_access_form = form(RequestAccessToCollaborativeDraftForm).from_params({})
39
40
  @accept_request_form = form(AcceptAccessToCollaborativeDraftForm).from_params({})
@@ -20,7 +20,7 @@ module Decidim
20
20
  end
21
21
 
22
22
  on(:invalid) do
23
- render json: { error: I18n.t("proposal_endorsements.create.error", scope: "decidim.proposals") }, status: 422
23
+ render json: { error: I18n.t("proposal_endorsements.create.error", scope: "decidim.proposals") }, status: :unprocessable_entity
24
24
  end
25
25
  end
26
26
  end
@@ -29,7 +29,7 @@ module Decidim
29
29
  end
30
30
 
31
31
  on(:invalid) do
32
- render json: { error: I18n.t("proposal_votes.create.error", scope: "decidim.proposals") }, status: 422
32
+ render json: { error: I18n.t("proposal_votes.create.error", scope: "decidim.proposals") }, status: :unprocessable_entity
33
33
  end
34
34
  end
35
35
  end
@@ -10,7 +10,7 @@ module Decidim
10
10
  include Decidim::ApplicationHelper
11
11
  include FormFactory
12
12
  include FilterResource
13
- include Orderable
13
+ include Decidim::Proposals::Orderable
14
14
  include Paginable
15
15
 
16
16
  helper_method :form_presenter
@@ -54,7 +54,8 @@ module Decidim
54
54
  end
55
55
 
56
56
  def show
57
- raise ActionController::RoutingError, "Not Found" unless set_proposal
57
+ raise ActionController::RoutingError, "Not Found" if @proposal.blank? || !can_show_proposal?
58
+
58
59
  @report_form = form(Decidim::ReportForm).from_params(reason: "spam")
59
60
  end
60
61
 
@@ -189,27 +190,15 @@ module Decidim
189
190
 
190
191
  def withdraw
191
192
  enforce_permission_to :withdraw, :proposal, proposal: @proposal
192
- if @proposal.emendation?
193
- Decidim::Amendable::Withdraw.call(@proposal, current_user) do
194
- on(:ok) do |_proposal|
195
- flash[:notice] = I18n.t("proposals.update.success", scope: "decidim")
196
- redirect_to Decidim::ResourceLocatorPresenter.new(@emendation).path
197
- end
198
- on(:invalid) do
199
- flash[:alert] = I18n.t("proposals.update.error", scope: "decidim")
200
- redirect_to Decidim::ResourceLocatorPresenter.new(@emendation).path
201
- end
193
+
194
+ WithdrawProposal.call(@proposal, current_user) do
195
+ on(:ok) do
196
+ flash[:notice] = I18n.t("proposals.update.success", scope: "decidim")
197
+ redirect_to Decidim::ResourceLocatorPresenter.new(@proposal).path
202
198
  end
203
- else
204
- WithdrawProposal.call(@proposal, current_user) do
205
- on(:ok) do |_proposal|
206
- flash[:notice] = I18n.t("proposals.update.success", scope: "decidim")
207
- redirect_to Decidim::ResourceLocatorPresenter.new(@proposal).path
208
- end
209
- on(:has_supports) do
210
- flash[:alert] = I18n.t("proposals.withdraw.errors.has_supports", scope: "decidim")
211
- redirect_to Decidim::ResourceLocatorPresenter.new(@proposal).path
212
- end
199
+ on(:has_supports) do
200
+ flash[:alert] = I18n.t("proposals.withdraw.errors.has_supports", scope: "decidim")
201
+ redirect_to Decidim::ResourceLocatorPresenter.new(@proposal).path
213
202
  end
214
203
  end
215
204
  end
@@ -234,7 +223,8 @@ module Decidim
234
223
  end
235
224
 
236
225
  def proposal_draft
237
- Proposal.from_all_author_identities(current_user).not_hidden.where(component: current_component).find_by(published_at: nil)
226
+ Proposal.from_all_author_identities(current_user).not_hidden.only_amendables
227
+ .where(component: current_component).find_by(published_at: nil)
238
228
  end
239
229
 
240
230
  def ensure_is_draft
@@ -246,6 +236,15 @@ module Decidim
246
236
  @proposal = Proposal.published.not_hidden.where(component: current_component).find_by(id: params[:id])
247
237
  end
248
238
 
239
+ # Returns true if the proposal is NOT an emendation or the user IS an admin.
240
+ # Returns false if the proposal is not found or the proposal IS an emendation
241
+ # and is NOT visible to the user based on the component's amendments settings.
242
+ def can_show_proposal?
243
+ return true if @proposal&.amendable? || current_user&.admin?
244
+
245
+ Proposal.only_visible_emendations_for(current_user, current_component).published.include?(@proposal)
246
+ end
247
+
249
248
  def form_proposal_params
250
249
  form(ProposalForm).from_params(params)
251
250
  end
@@ -20,6 +20,8 @@ module Decidim
20
20
  attribute :created_in_meeting, Boolean
21
21
  attribute :meeting_id, Integer
22
22
  attribute :suggested_hashtags, Array[String]
23
+ attribute :photos, Array[String]
24
+ attribute :add_photos, Array
23
25
 
24
26
  validates :title, :body, presence: true
25
27
  validates :title, length: { maximum: 150 }
@@ -116,6 +118,7 @@ module Decidim
116
118
  # this problem.
117
119
  def notify_missing_attachment_if_errored
118
120
  errors.add(:attachment, :needs_to_be_reattached) if errors.any? && attachment.present?
121
+ errors.add(:add_photos, :needs_to_be_reattached) if errors.any? && add_photos.present?
119
122
  end
120
123
 
121
124
  def ordered_hashtag_list(string)
@@ -20,6 +20,7 @@ module Decidim
20
20
 
21
21
  def target_component
22
22
  return current_component if clean_target_component_id == current_component.id
23
+
23
24
  @target_component ||= current_component.siblings.find_by(id: target_component_id)
24
25
  end
25
26
 
@@ -28,6 +28,7 @@ module Decidim
28
28
 
29
29
  def proposal_length
30
30
  return unless body.presence
31
+
31
32
  length = current_component.settings.proposal_length
32
33
  errors.add(:body, :too_long, count: length) if body.length > length
33
34
  end
@@ -11,6 +11,7 @@ module Decidim
11
11
  # in forms.
12
12
  def meetings_as_authors_selected
13
13
  return unless @proposal.present? && @proposal.official_meeting?
14
+
14
15
  @meetings_as_authors_selected ||= @proposal.authors.pluck(:id)
15
16
  end
16
17
  end
@@ -10,7 +10,7 @@ module Decidim
10
10
  # geocoded_proposals - A collection of geocoded proposals
11
11
  def proposals_data_for_map(geocoded_proposals)
12
12
  geocoded_proposals.map do |proposal|
13
- proposal.slice(:latitude, :longitude, :address).merge(title: present(proposal).title,
13
+ proposal.slice(:latitude, :longitude, :address).merge(title: present(proposal).title,
14
14
  body: truncate(present(proposal).body, length: 100),
15
15
  icon: icon("proposals", width: 40, height: 70, remove_icon_class: true),
16
16
  link: proposal_path(proposal))
@@ -18,11 +18,13 @@ module Decidim
18
18
 
19
19
  def has_actions?
20
20
  return context[:has_actions] if context[:has_actions].present?
21
+
21
22
  proposals_controller? && index_action? && current_settings.votes_enabled? && !model.draft?
22
23
  end
23
24
 
24
25
  def has_footer?
25
26
  return context[:has_footer] if context[:has_footer].present?
27
+
26
28
  proposals_controller? && index_action? && current_settings.votes_enabled? && !model.draft?
27
29
  end
28
30
 
@@ -11,6 +11,7 @@ module Decidim
11
11
  # Returns a string with the value of the css classes.
12
12
  def endorsement_button_classes(from_proposals_list)
13
13
  return "small" if from_proposals_list
14
+
14
15
  "small compact light button--sc expanded"
15
16
  end
16
17
 
@@ -11,6 +11,7 @@ module Decidim
11
11
  # Returns a hash with the css classes for the count number and label
12
12
  def votes_count_classes(from_proposals_list)
13
13
  return { number: "card__support__number", label: "" } if from_proposals_list
14
+
14
15
  { number: "extra__suport-number", label: "extra__suport-text" }
15
16
  end
16
17
 
@@ -21,6 +22,7 @@ module Decidim
21
22
  # Returns a string with the value of the css classes.
22
23
  def vote_button_classes(from_proposals_list)
23
24
  return "card__button button--sc" if from_proposals_list
25
+
24
26
  "expanded button--sc"
25
27
  end
26
28
 
@@ -29,6 +31,7 @@ module Decidim
29
31
  # Returns an Integer if set, nil otherwise.
30
32
  def vote_limit
31
33
  return nil if component_settings.vote_limit.zero?
34
+
32
35
  component_settings.vote_limit
33
36
  end
34
37
 
@@ -51,6 +54,7 @@ module Decidim
51
54
  # Returns an Integer with the maximum amount of votes, nil otherwise.
52
55
  def threshold_per_proposal
53
56
  return nil unless component_settings.threshold_per_proposal.positive?
57
+
54
58
  component_settings.threshold_per_proposal
55
59
  end
56
60
 
@@ -89,6 +93,7 @@ module Decidim
89
93
  # Returns a number with the remaining votes for that user
90
94
  def remaining_votes_count_for(user)
91
95
  return 0 unless vote_limit_enabled?
96
+
92
97
  proposals = Proposal.where(component: current_component)
93
98
  votes_count = ProposalVote.where(author: user, proposal: proposals).size
94
99
  component_settings.vote_limit - votes_count
@@ -57,6 +57,7 @@ module Decidim
57
57
  # current_step - A symbol of the current step
58
58
  def proposal_wizard_stepper_step(step, current_step)
59
59
  return if step == :step_4 && type_of == :collaborative_drafts
60
+
60
61
  content_tag(:li, proposal_wizard_step_name(step), class: proposal_wizard_step_classes(step, current_step).to_s)
61
62
  end
62
63
 
@@ -15,6 +15,7 @@ module Decidim
15
15
  include Decidim::Proposals::CommentableCollaborativeDraft
16
16
  include Decidim::Traceable
17
17
  include Decidim::Loggable
18
+ include Decidim::Randomable
18
19
 
19
20
  has_many :collaborator_requests,
20
21
  class_name: "Decidim::Proposals::CollaborativeDraftCollaboratorRequest",
@@ -23,12 +23,13 @@ module Decidim
23
23
  include Decidim::Proposals::ParticipatoryTextSection
24
24
  include Decidim::Amendable
25
25
  include Decidim::NewsletterParticipant
26
+ include Decidim::Randomable
26
27
 
27
28
  fingerprint fields: [:title, :body]
28
29
 
29
30
  amendable(
30
31
  fields: [:title, :body],
31
- form: "Decidim::Proposals::ProposalForm"
32
+ form: "Decidim::Proposals::ProposalForm"
32
33
  )
33
34
 
34
35
  component_manifest_name "proposals"
@@ -69,13 +70,6 @@ module Decidim
69
70
  index_on_create: ->(proposal) { proposal.official? },
70
71
  index_on_update: ->(proposal) { proposal.visible? })
71
72
 
72
- def self.order_randomly(seed)
73
- transaction do
74
- connection.execute("SELECT setseed(#{connection.quote(seed)})")
75
- order(Arel.sql("RANDOM()")).load
76
- end
77
- end
78
-
79
73
  def self.log_presenter_class_for(_log)
80
74
  Decidim::Proposals::AdminLog::ProposalPresenter
81
75
  end
@@ -226,6 +220,7 @@ module Decidim
226
220
  # user - the user to check for authorship
227
221
  def editable_by?(user)
228
222
  return true if draft?
223
+
229
224
  !answered? && within_edit_time_limit? && !copied_from_other_component? && created_by?(user)
230
225
  end
231
226
 
@@ -270,6 +265,7 @@ module Decidim
270
265
  # Checks whether the proposal is inside the time window to be editable or not once published.
271
266
  def within_edit_time_limit?
272
267
  return true if draft?
268
+
273
269
  limit = updated_at + component.settings.proposal_edit_before_minutes.minutes
274
270
  Time.current < limit
275
271
  end
@@ -23,11 +23,13 @@ module Decidim
23
23
  # Private: check if the proposal and the author have the same organization
24
24
  def author_and_proposal_same_organization
25
25
  return if !proposal || !author
26
+
26
27
  errors.add(:proposal, :invalid) unless author.organization == proposal.organization
27
28
  end
28
29
 
29
30
  def proposal_not_rejected
30
31
  return unless proposal
32
+
31
33
  errors.add(:proposal, :invalid) if proposal.rejected?
32
34
  end
33
35
  end
@@ -36,11 +36,13 @@ module Decidim
36
36
  # Private: check if the proposal and the author have the same organization
37
37
  def author_and_proposal_same_organization
38
38
  return if !proposal || !author
39
+
39
40
  errors.add(:proposal, :invalid) unless author.organization == proposal.organization
40
41
  end
41
42
 
42
43
  def proposal_not_rejected
43
44
  return unless proposal
45
+
44
46
  errors.add(:proposal, :invalid) if proposal.rejected?
45
47
  end
46
48
  end
@@ -59,6 +59,7 @@ module Decidim
59
59
 
60
60
  def admin_edition_is_available?
61
61
  return unless proposal
62
+
62
63
  (proposal.official? || proposal.official_meeting?) && proposal.votes.empty?
63
64
  end
64
65