decidim-budgets 0.27.10 → 0.28.0.rc4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/app/assets/stylesheets/decidim/budgets/budget/_budget-vote-button.scss +5 -5
  4. data/app/cells/decidim/budgets/base_cell.rb +1 -1
  5. data/app/cells/decidim/budgets/budget_cell.rb +6 -1
  6. data/app/cells/decidim/budgets/budget_information_modal/show.erb +14 -26
  7. data/app/cells/decidim/budgets/budget_list_item/projects_count.erb +6 -0
  8. data/app/cells/decidim/budgets/budget_list_item/show.erb +35 -30
  9. data/app/cells/decidim/budgets/budget_list_item/vote_action.erb +13 -0
  10. data/app/cells/decidim/budgets/budget_list_item_cell.rb +24 -1
  11. data/app/cells/decidim/budgets/budget_metadata_cell.rb +29 -0
  12. data/app/cells/decidim/budgets/budget_s_cell.rb +15 -0
  13. data/app/cells/decidim/budgets/budgets_header/show.erb +2 -6
  14. data/app/cells/decidim/budgets/budgets_list/card_list.erb +8 -13
  15. data/app/cells/decidim/budgets/budgets_list/main_list.erb +5 -0
  16. data/app/cells/decidim/budgets/budgets_list/show.erb +12 -16
  17. data/app/cells/decidim/budgets/budgets_list/voted.erb +8 -44
  18. data/app/cells/decidim/budgets/budgets_list_cell.rb +34 -0
  19. data/app/cells/decidim/budgets/limit_announcement/show.erb +3 -0
  20. data/app/cells/decidim/budgets/limit_announcement_cell.rb +2 -2
  21. data/app/cells/decidim/budgets/order_activity_cell.rb +1 -4
  22. data/app/cells/decidim/budgets/project_cell.rb +6 -1
  23. data/app/cells/decidim/budgets/project_l/extra_data.erb +6 -0
  24. data/app/cells/decidim/budgets/project_l/metadata.erb +4 -0
  25. data/app/cells/decidim/budgets/project_l_cell.rb +38 -0
  26. data/app/cells/decidim/budgets/project_metadata_cell.rb +78 -0
  27. data/app/cells/decidim/budgets/project_s_cell.rb +21 -0
  28. data/app/cells/decidim/budgets/project_tags/show.erb +1 -0
  29. data/app/cells/decidim/budgets/project_vote_button/show.erb +21 -15
  30. data/app/cells/decidim/budgets/project_vote_button_cell.rb +69 -1
  31. data/app/cells/decidim/budgets/project_voted_hint_cell.rb +1 -1
  32. data/app/cells/decidim/budgets/project_votes_count_cell.rb +9 -8
  33. data/app/commands/decidim/budgets/admin/create_project.rb +0 -1
  34. data/app/commands/decidim/budgets/admin/import_proposals_to_budgets.rb +1 -1
  35. data/app/commands/decidim/budgets/admin/update_project.rb +1 -2
  36. data/app/commands/decidim/budgets/admin/update_project_scope.rb +1 -1
  37. data/app/commands/decidim/budgets/admin/update_project_selection.rb +1 -1
  38. data/app/commands/decidim/budgets/admin/update_projects_budget.rb +57 -0
  39. data/app/controllers/concerns/decidim/budgets/admin/filterable.rb +1 -1
  40. data/app/controllers/concerns/decidim/budgets/needs_current_order.rb +2 -2
  41. data/app/controllers/decidim/budgets/admin/budgets_controller.rb +5 -5
  42. data/app/controllers/decidim/budgets/admin/projects_controller.rb +52 -10
  43. data/app/controllers/decidim/budgets/admin/proposals_imports_controller.rb +1 -1
  44. data/app/controllers/decidim/budgets/application_controller.rb +0 -4
  45. data/app/controllers/decidim/budgets/budgets_controller.rb +9 -0
  46. data/app/controllers/decidim/budgets/line_items_controller.rb +10 -16
  47. data/app/controllers/decidim/budgets/orders_controller.rb +7 -2
  48. data/app/controllers/decidim/budgets/projects_controller.rb +51 -4
  49. data/app/forms/decidim/budgets/admin/project_form.rb +1 -1
  50. data/app/helpers/decidim/budgets/application_helper.rb +4 -0
  51. data/app/helpers/decidim/budgets/projects_helper.rb +89 -33
  52. data/app/jobs/decidim/budgets/send_vote_reminder_job.rb +1 -1
  53. data/app/mailers/decidim/budgets/order_summary_mailer.rb +1 -1
  54. data/app/mailers/decidim/budgets/vote_reminder_mailer.rb +1 -1
  55. data/app/models/decidim/budgets/budget.rb +1 -0
  56. data/app/models/decidim/budgets/project.rb +17 -7
  57. data/app/packs/entrypoints/decidim_budgets.js +2 -0
  58. data/app/packs/src/decidim/budgets/exit_handler.js +11 -8
  59. data/app/packs/src/decidim/budgets/progressFixed.js +25 -11
  60. data/app/packs/src/decidim/budgets/projects.js +15 -10
  61. data/app/packs/stylesheets/budgets.scss +273 -0
  62. data/app/presenters/decidim/budgets/admin_log/budget_presenter.rb +2 -2
  63. data/app/presenters/decidim/budgets/admin_log/project_presenter.rb +2 -2
  64. data/app/services/decidim/budgets/order_reminder_generator.rb +4 -4
  65. data/app/views/decidim/budgets/admin/budgets/_form.html.erb +17 -12
  66. data/app/views/decidim/budgets/admin/budgets/edit.html.erb +16 -6
  67. data/app/views/decidim/budgets/admin/budgets/index.html.erb +58 -64
  68. data/app/views/decidim/budgets/admin/budgets/new.html.erb +16 -6
  69. data/app/views/decidim/budgets/admin/projects/_bulk-actions.html.erb +19 -10
  70. data/app/views/decidim/budgets/admin/projects/_form.html.erb +31 -35
  71. data/app/views/decidim/budgets/admin/projects/_project-tr.html.erb +15 -13
  72. data/app/views/decidim/budgets/admin/projects/bulk_actions/_budget-change.html.erb +22 -0
  73. data/app/views/decidim/budgets/admin/projects/bulk_actions/_change-selected.html.erb +3 -3
  74. data/app/views/decidim/budgets/admin/projects/bulk_actions/_dropdown.html.erb +8 -2
  75. data/app/views/decidim/budgets/admin/projects/bulk_actions/_recategorize.html.erb +3 -3
  76. data/app/views/decidim/budgets/admin/projects/bulk_actions/_scope-change.html.erb +5 -8
  77. data/app/views/decidim/budgets/admin/projects/edit.html.erb +16 -6
  78. data/app/views/decidim/budgets/admin/projects/index.html.erb +26 -31
  79. data/app/views/decidim/budgets/admin/projects/new.html.erb +16 -6
  80. data/app/views/decidim/budgets/admin/projects/update_attribute.js.erb +8 -4
  81. data/app/views/decidim/budgets/admin/proposals_imports/new.html.erb +40 -28
  82. data/app/views/decidim/budgets/budgets/index.html.erb +21 -3
  83. data/app/views/decidim/budgets/budgets/index.js.erb +6 -0
  84. data/app/views/decidim/budgets/line_items/update_budget.js.erb +21 -11
  85. data/app/views/decidim/budgets/projects/_addition_selector.html.erb +16 -0
  86. data/app/views/decidim/budgets/projects/_budget_confirm.html.erb +42 -31
  87. data/app/views/decidim/budgets/projects/_budget_excess.html.erb +12 -12
  88. data/app/views/decidim/budgets/projects/_budget_summary.html.erb +2 -75
  89. data/app/views/decidim/budgets/projects/_exit_modal.html.erb +15 -18
  90. data/app/views/decidim/budgets/projects/_linked_projects.html.erb +3 -12
  91. data/app/views/decidim/budgets/projects/_order.html.erb +1 -0
  92. data/app/views/decidim/budgets/projects/_order_progress_progressbar_marks_right.html.erb +10 -0
  93. data/app/views/decidim/budgets/projects/_order_progress_summary_content.html.erb +113 -0
  94. data/app/views/decidim/budgets/projects/_order_total_budget.html.erb +6 -7
  95. data/app/views/decidim/budgets/projects/_project.html.erb +2 -1
  96. data/app/views/decidim/budgets/projects/_project_budget_button.html.erb +11 -19
  97. data/app/views/decidim/budgets/projects/_projects.html.erb +8 -6
  98. data/app/views/decidim/budgets/projects/_projects_count.html.erb +5 -0
  99. data/app/views/decidim/budgets/projects/_projects_list.html.erb +3 -0
  100. data/app/views/decidim/budgets/projects/index.html.erb +58 -55
  101. data/app/views/decidim/budgets/projects/index.js.erb +5 -4
  102. data/app/views/decidim/budgets/projects/show.html.erb +78 -51
  103. data/config/assets.rb +0 -1
  104. data/config/locales/ar.yml +0 -50
  105. data/config/locales/bg.yml +0 -381
  106. data/config/locales/ca.yml +75 -84
  107. data/config/locales/cs.yml +73 -82
  108. data/config/locales/de.yml +76 -85
  109. data/config/locales/el.yml +34 -72
  110. data/config/locales/en.yml +79 -88
  111. data/config/locales/es-MX.yml +73 -82
  112. data/config/locales/es-PY.yml +73 -82
  113. data/config/locales/es.yml +75 -84
  114. data/config/locales/eu.yml +74 -86
  115. data/config/locales/fi-plain.yml +75 -84
  116. data/config/locales/fi.yml +79 -88
  117. data/config/locales/fr-CA.yml +74 -86
  118. data/config/locales/fr.yml +78 -90
  119. data/config/locales/ga-IE.yml +0 -12
  120. data/config/locales/gl.yml +0 -58
  121. data/config/locales/hu.yml +58 -81
  122. data/config/locales/id-ID.yml +0 -38
  123. data/config/locales/is-IS.yml +0 -22
  124. data/config/locales/it.yml +0 -84
  125. data/config/locales/ja.yml +69 -81
  126. data/config/locales/ko.yml +0 -54
  127. data/config/locales/lb.yml +0 -85
  128. data/config/locales/lt.yml +59 -82
  129. data/config/locales/lv.yml +0 -44
  130. data/config/locales/nl.yml +0 -96
  131. data/config/locales/no.yml +0 -84
  132. data/config/locales/pl.yml +0 -167
  133. data/config/locales/pt-BR.yml +9 -141
  134. data/config/locales/pt.yml +0 -85
  135. data/config/locales/ro-RO.yml +0 -95
  136. data/config/locales/ru.yml +0 -41
  137. data/config/locales/sk.yml +0 -44
  138. data/config/locales/sq-AL.yml +0 -52
  139. data/config/locales/sr-CS.yml +0 -4
  140. data/config/locales/sv.yml +42 -150
  141. data/config/locales/tr-TR.yml +2 -82
  142. data/config/locales/uk.yml +0 -41
  143. data/config/locales/zh-CN.yml +0 -65
  144. data/config/locales/zh-TW.yml +13 -59
  145. data/lib/decidim/budgets/admin_engine.rb +3 -2
  146. data/lib/decidim/budgets/component.rb +4 -90
  147. data/lib/decidim/budgets/engine.rb +30 -10
  148. data/lib/decidim/budgets/project_serializer.rb +3 -3
  149. data/lib/decidim/budgets/seeds.rb +69 -0
  150. data/lib/decidim/budgets/test/factories.rb +23 -37
  151. data/lib/decidim/budgets/version.rb +1 -1
  152. data/lib/decidim/budgets/workflows/base.rb +1 -1
  153. metadata +46 -42
  154. data/app/cells/decidim/budgets/budget_m/data.erb +0 -12
  155. data/app/cells/decidim/budgets/budget_m/footer.erb +0 -5
  156. data/app/cells/decidim/budgets/budget_m_cell.rb +0 -16
  157. data/app/cells/decidim/budgets/project_list_item/project_data.erb +0 -19
  158. data/app/cells/decidim/budgets/project_list_item/project_image.erb +0 -5
  159. data/app/cells/decidim/budgets/project_list_item/project_text.erb +0 -23
  160. data/app/cells/decidim/budgets/project_list_item/show.erb +0 -5
  161. data/app/cells/decidim/budgets/project_list_item_cell.rb +0 -70
  162. data/app/cells/decidim/budgets/project_m/data.erb +0 -12
  163. data/app/cells/decidim/budgets/project_m/footer.erb +0 -5
  164. data/app/cells/decidim/budgets/project_m_cell.rb +0 -22
  165. data/app/packs/stylesheets/decidim/budgets/_budgets.scss +0 -3
  166. data/app/packs/stylesheets/decidim/budgets/budget/_budget-list.scss +0 -198
  167. data/app/packs/stylesheets/decidim/budgets/budget/_budget-meter.scss +0 -83
  168. data/app/packs/stylesheets/decidim/budgets/budget/_progress.scss +0 -19
  169. data/app/views/decidim/budgets/admin/projects/proposals_picker.html.erb +0 -1
  170. data/app/views/decidim/budgets/projects/_filters.html.erb +0 -30
  171. data/app/views/decidim/budgets/projects/_filters_small_view.html.erb +0 -18
  172. data/app/views/decidim/budgets/projects/_order_progress.html.erb +0 -32
  173. data/app/views/decidim/budgets/projects/_order_selected_projects.html.erb +0 -27
  174. data/config/locales/he-IL.yml +0 -1
  175. data/decidim-budgets.gemspec +0 -34
  176. data/lib/decidim/budgets/seeds/city.jpeg +0 -0
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Budgets
5
+ # This cell renders metadata for an instance of a Project
6
+ class ProjectMetadataCell < Decidim::CardMetadataCell
7
+ include Decidim::Budgets::ProjectsHelper
8
+
9
+ delegate :selected?, to: :model
10
+
11
+ alias project model
12
+
13
+ def initialize(*)
14
+ super
15
+
16
+ @items.prepend(*project_items)
17
+ end
18
+
19
+ private
20
+
21
+ def project_items
22
+ [voted_item, category_item, scope_item, status_item]
23
+ end
24
+
25
+ def project_items_for_map
26
+ [voted_item_for_map, category_item, scope_item].compact_blank.map do |item|
27
+ {
28
+ text: item[:text].to_s.html_safe,
29
+ icon: item[:icon].present? ? icon(item[:icon]).html_safe : nil
30
+ }
31
+ end
32
+ end
33
+
34
+ def voted_item_for_map
35
+ {
36
+ text: "#{model.confirmed_orders_count} #{t("decidim.budgets.projects.project.votes", count: model.confirmed_orders_count)}",
37
+ icon: current_order_checked_out? && resource_added? ? "check-double-line" : "check-line"
38
+ }
39
+ end
40
+
41
+ def show_votes_count?
42
+ project.component.current_settings.show_votes?
43
+ end
44
+
45
+ def voted_item
46
+ return unless show_votes_count? && model.confirmed_orders_count.positive?
47
+
48
+ {
49
+ cell: "decidim/budgets/project_votes_count",
50
+ args: [model, { layout: :one_line }],
51
+ icon: current_order_checked_out? && resource_added? ? "check-double-line" : "check-line"
52
+ }
53
+ end
54
+
55
+ def status_item
56
+ return unless controller.try(:voting_finished?) && selected?
57
+
58
+ {
59
+ cell: "decidim/budgets/project_selected_status",
60
+ args: model,
61
+ icon: "question-line"
62
+ }
63
+ end
64
+
65
+ def current_order
66
+ @current_order ||= controller.try(:current_order)
67
+ end
68
+
69
+ def resource_added?
70
+ current_order && current_order.projects.include?(model)
71
+ end
72
+
73
+ def current_order_checked_out?
74
+ current_order&.checked_out?
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cell/partial"
4
+
5
+ module Decidim
6
+ module Budgets
7
+ # This cell renders the Search (:s) project card
8
+ # for an instance of a Project
9
+ class ProjectSCell < Decidim::CardSCell
10
+ private
11
+
12
+ def resource_path
13
+ resource_locator([model.budget, model]).path
14
+ end
15
+
16
+ def metadata_cell
17
+ "decidim/budgets/project_metadata"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,4 +1,5 @@
1
1
  <%= content_tag :ul, class: tags_classes do %>
2
+ <%= icon "price-tag-3-line", class: "inline-block" %>
2
3
  <%= content_tag :li, link_to_category if category? %>
3
4
 
4
5
  <%= content_tag :li, link_to_scope if scope? %>
@@ -1,17 +1,23 @@
1
1
  <%= action_authorized_button_to "vote",
2
- budget_order_line_item_path(model.budget, project_id: model),
3
- method: vote_button_method,
4
- remote: true,
5
- class: "button tiny budget-list__action #{vote_button_class}",
6
- id: "project-vote-button-#{model.id}",
7
- data: {
8
- add: !resource_added?,
9
- disable: true,
10
- budget: model.budget_amount,
11
- allocation: resource_allocation,
12
- "redirect-url": resource_path
13
- },
14
- disabled: vote_button_disabled?,
15
- title: vote_button_label do %>
16
- <%= icon(resource_added? ? "x" : "check", class: "icon--small", aria_label: vote_button_label, role: "img") %>
2
+ budget_order_line_item_path(model.budget, project_id: model, show_only_added: options[:show_only_added]),
3
+ method: vote_button_method,
4
+ remote: true,
5
+ class: "button w-full #{vote_button_classes}",
6
+ id: "project-vote-button-#{model.id}",
7
+ data: {
8
+ add: !resource_added?,
9
+ disable: true,
10
+ budget: model.budget_amount,
11
+ allocation: resource_allocation,
12
+ "redirect-url": resource_path
13
+ },
14
+ disabled: vote_button_disabled?,
15
+ title: vote_button_label do %>
16
+ <% if resource_added? %>
17
+ <%= t("added", scope: "decidim.budgets.projects.project_budget_button") %>
18
+ <%= icon "checkbox-circle-line", class: "inline-block" %>
19
+ <% else %>
20
+ <%= t("add", scope: "decidim.budgets.projects.project_budget_button") %>
21
+ <%= icon "add-fill", class: "inline-block" %>
22
+ <% end %>
17
23
  <% end %>
@@ -4,7 +4,75 @@ module Decidim
4
4
  module Budgets
5
5
  # This cell renders an authorized_action button
6
6
  # to vote a given instance of a Project in a budget list
7
- class ProjectVoteButtonCell < ProjectListItemCell
7
+ class ProjectVoteButtonCell < Decidim::ViewModel
8
+ include Decidim::ActionAuthorizationHelper
9
+ include Decidim::Budgets::ProjectsHelper
10
+ include Decidim::Budgets::Engine.routes.url_helpers
11
+
12
+ delegate :current_user, :current_order, :current_component, :can_have_order?, to: :parent_controller
13
+
14
+ private
15
+
16
+ def project_item?
17
+ options[:project_item]
18
+ end
19
+
20
+ def resource_path
21
+ resource_locator([model.budget, model]).path
22
+ end
23
+
24
+ def resource_title
25
+ translated_attribute model.title
26
+ end
27
+
28
+ def resource_added?
29
+ current_order && current_order.projects.include?(model)
30
+ end
31
+
32
+ def resource_allocation
33
+ current_order.allocation_for(model)
34
+ end
35
+
36
+ def vote_button_disabled?
37
+ current_user && !can_have_order?
38
+ end
39
+
40
+ def vote_button_classes
41
+ classes = []
42
+
43
+ classes << if resource_added?
44
+ "success button__secondary budget-list__data--added"
45
+ else
46
+ "hollow button__transparent-secondary"
47
+ end
48
+
49
+ classes << if project_item?
50
+ "button__lg"
51
+ else
52
+ "button__sm"
53
+ end
54
+
55
+ classes << "budget-list__action" unless vote_button_disabled?
56
+
57
+ classes.join(" ")
58
+ end
59
+
60
+ def vote_button_method
61
+ return :delete if resource_added?
62
+
63
+ :post
64
+ end
65
+
66
+ def vote_button_label
67
+ if resource_added?
68
+ return t(
69
+ "decidim.budgets.projects.project.remove",
70
+ resource_name: resource_title
71
+ )
72
+ end
73
+
74
+ t("decidim.budgets.projects.project.add", resource_name: resource_title)
75
+ end
8
76
  end
9
77
  end
10
78
  end
@@ -18,7 +18,7 @@ module Decidim
18
18
 
19
19
  def hint
20
20
  contents = []
21
- contents << icon("check", role: "img", "aria-hidden": true)
21
+ contents << icon("check-line", role: "img", "aria-hidden": true)
22
22
  contents << " "
23
23
  contents << t("decidim.budgets.projects.project.you_voted")
24
24
  end
@@ -6,7 +6,6 @@ module Decidim
6
6
  # Two possible layouts: One or two lines
7
7
  class ProjectVotesCountCell < Decidim::ViewModel
8
8
  include Decidim::IconHelper
9
- delegate :show_votes_count?, to: :controller
10
9
 
11
10
  def show
12
11
  return unless show_votes_count?
@@ -16,22 +15,24 @@ module Decidim
16
15
 
17
16
  private
18
17
 
18
+ def show_votes_count?
19
+ model.component.current_settings.show_votes?
20
+ end
21
+
19
22
  def content
20
23
  if options[:layout] == :one_line
21
- safe_join([model.confirmed_orders_count, " ", label(t("decidim.budgets.projects.project.votes",
22
- count: model.confirmed_orders_count))])
24
+ safe_join([model.confirmed_orders_count, " ", count_label])
23
25
  else
24
- safe_join([number, label(t("decidim.budgets.projects.project.votes",
25
- count: model.confirmed_orders_count))])
26
+ safe_join([number, count_label])
26
27
  end
27
28
  end
28
29
 
29
30
  def number
30
- content_tag :div, model.confirmed_orders_count, class: "text-large"
31
+ content_tag :div, model.confirmed_orders_count
31
32
  end
32
33
 
33
- def label(i18n_string)
34
- content_tag :span, i18n_string, class: "text-uppercase text-small"
34
+ def count_label
35
+ content_tag(:span, t("decidim.budgets.projects.project.votes", count: model.confirmed_orders_count))
35
36
  end
36
37
 
37
38
  def css_class
@@ -6,7 +6,6 @@ module Decidim
6
6
  # This command is executed when the user creates a Project from the admin
7
7
  # panel.
8
8
  class CreateProject < Decidim::Command
9
- include ::Decidim::AttachmentMethods
10
9
  include ::Decidim::GalleryMethods
11
10
 
12
11
  def initialize(form)
@@ -16,7 +16,7 @@ module Decidim
16
16
  # Executes the command. Broadcasts these events:
17
17
  #
18
18
  # - :ok when everything is valid.
19
- # - :invalid if the form wasn't valid and we couldn't proceed.
19
+ # - :invalid if the form was not valid and we could not proceed.
20
20
  #
21
21
  # Returns nothing.
22
22
  def call
@@ -6,7 +6,6 @@ module Decidim
6
6
  # This command is executed when the user changes a Project from the admin
7
7
  # panel.
8
8
  class UpdateProject < Decidim::Command
9
- include ::Decidim::AttachmentMethods
10
9
  include ::Decidim::GalleryMethods
11
10
 
12
11
  # Initializes an UpdateProject Command.
@@ -53,7 +52,7 @@ module Decidim
53
52
  title: form.title,
54
53
  description: form.description,
55
54
  budget_amount: form.budget_amount,
56
- selected_at: selected_at,
55
+ selected_at:,
57
56
  address: form.address,
58
57
  latitude: form.latitude,
59
58
  longitude: form.longitude
@@ -45,7 +45,7 @@ module Decidim
45
45
 
46
46
  def update_project_scope(project)
47
47
  project.update!(
48
- scope: scope
48
+ scope:
49
49
  )
50
50
  end
51
51
  end
@@ -47,7 +47,7 @@ module Decidim
47
47
  def update_project_selection(project)
48
48
  selected_at = selection ? Time.current : nil
49
49
  project.update!(
50
- selected_at: selected_at
50
+ selected_at:
51
51
  )
52
52
  end
53
53
  end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Budgets
5
+ module Admin
6
+ class UpdateProjectsBudget < Decidim::Command
7
+ include TranslatableAttributes
8
+
9
+ # Public: Initializes the command.
10
+ #
11
+ # destination_budget - the destination budget for which the projects should update to.
12
+ # project_ids - the project ids to update.
13
+ def initialize(destination_budget, project_ids)
14
+ @destination_budget = destination_budget
15
+ @project_ids = project_ids
16
+ @response = { selection_name: "", successful: [], errored: [], failed_ids: [] }
17
+ end
18
+
19
+ def call
20
+ return broadcast(:invalid_project_ids) if @project_ids.blank?
21
+ return broadcast(:invalid_project_ids) if @destination_budget.blank?
22
+
23
+ update_projects_budget
24
+
25
+ broadcast(:update_projects_budget, @response)
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :selection, :project_ids
31
+
32
+ def update_projects_budget
33
+ ::Decidim::Budgets::Project.includes(:budget, budget: { component: :participatory_space }).where(id: project_ids).find_each do |project|
34
+ if update_allowed?(project)
35
+ transaction do
36
+ project.update!(
37
+ decidim_budgets_budget_id: @destination_budget.id
38
+ )
39
+ end
40
+ @response[:successful] << translated_attribute(project.title)
41
+ else
42
+ @response[:errored] << translated_attribute(project.title)
43
+ @response[:failed_ids] << project.id
44
+ end
45
+ end
46
+ end
47
+
48
+ def update_allowed?(project)
49
+ origin_budget = project.budget
50
+ return false if origin_budget == @destination_budget
51
+
52
+ origin_budget.participatory_space == @destination_budget.participatory_space
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -39,7 +39,7 @@ module Decidim
39
39
  }
40
40
  end
41
41
 
42
- # Can't user `super` here, because it does not belong to a superclass
42
+ # Cannot user `super` here, because it does not belong to a superclass
43
43
  # but to a concern.
44
44
  def dynamically_translated_filters
45
45
  [:scope_id_eq, :category_id_eq]
@@ -15,7 +15,7 @@ module Decidim
15
15
  #
16
16
  # Returns an Order.
17
17
  def current_order
18
- @current_order ||= Order.includes(:projects).find_or_initialize_by(user: current_user, budget: budget)
18
+ @current_order ||= Order.includes(:projects).find_or_initialize_by(user: current_user, budget:)
19
19
  end
20
20
 
21
21
  def current_order=(order)
@@ -30,7 +30,7 @@ module Decidim
30
30
  current_user.present? &&
31
31
  voting_open? &&
32
32
  current_participatory_space.can_participate?(current_user) &&
33
- allowed_to?(:create, :order, budget: budget, workflow: current_workflow)
33
+ allowed_to?(:create, :order, budget:, workflow: current_workflow)
34
34
  end
35
35
 
36
36
  # Return true if the user has voted the project
@@ -15,7 +15,7 @@ module Decidim
15
15
 
16
16
  def create
17
17
  enforce_permission_to :create, :budget
18
- @form = form(BudgetForm).from_params(params, current_component: current_component)
18
+ @form = form(BudgetForm).from_params(params, current_component:)
19
19
 
20
20
  CreateBudget.call(@form) do
21
21
  on(:ok) do
@@ -31,13 +31,13 @@ module Decidim
31
31
  end
32
32
 
33
33
  def edit
34
- enforce_permission_to :update, :budget, budget: budget
34
+ enforce_permission_to(:update, :budget, budget:)
35
35
  @form = form(BudgetForm).from_model(budget)
36
36
  end
37
37
 
38
38
  def update
39
- enforce_permission_to :update, :budget, budget: budget
40
- @form = form(BudgetForm).from_params(params, current_component: current_component)
39
+ enforce_permission_to(:update, :budget, budget:)
40
+ @form = form(BudgetForm).from_params(params, current_component:)
41
41
 
42
42
  UpdateBudget.call(@form, budget) do
43
43
  on(:ok) do
@@ -53,7 +53,7 @@ module Decidim
53
53
  end
54
54
 
55
55
  def destroy
56
- enforce_permission_to :delete, :budget, budget: budget
56
+ enforce_permission_to(:delete, :budget, budget:)
57
57
 
58
58
  DestroyBudget.call(budget, current_user) do
59
59
  on(:ok) do
@@ -6,9 +6,9 @@ module Decidim
6
6
  # This controller allows an admin to manage projects from a Participatory Process
7
7
  class ProjectsController < Admin::ApplicationController
8
8
  include Decidim::ApplicationHelper
9
- include Decidim::Proposals::Admin::Picker if Decidim::Budgets.enable_proposal_linking
10
9
  include Decidim::Budgets::Admin::Filterable
11
10
  helper Decidim::Budgets::Admin::ProjectBulkActionsHelper
11
+ helper Decidim::Budgets::ProjectsHelper
12
12
 
13
13
  helper_method :projects, :finished_orders, :pending_orders, :present, :project_ids
14
14
 
@@ -19,15 +19,14 @@ module Decidim
19
19
  def new
20
20
  enforce_permission_to :create, :project
21
21
  @form = form(ProjectForm).from_params(
22
- { attachment: form(AttachmentForm).instance },
23
- budget: budget
22
+ attachment: form(AttachmentForm).instance
24
23
  )
25
24
  end
26
25
 
27
26
  def create
28
27
  enforce_permission_to :create, :project
29
28
 
30
- @form = form(ProjectForm).from_params(params, budget: budget)
29
+ @form = form(ProjectForm).from_params(params, budget:)
31
30
 
32
31
  CreateProject.call(@form) do
33
32
  on(:ok) do
@@ -43,14 +42,14 @@ module Decidim
43
42
  end
44
43
 
45
44
  def edit
46
- enforce_permission_to :update, :project, project: project
47
- @form = form(ProjectForm).from_model(project, budget: budget)
45
+ enforce_permission_to(:update, :project, project:)
46
+ @form = form(ProjectForm).from_model(project)
48
47
  @form.attachment = form(AttachmentForm).instance
49
48
  end
50
49
 
51
50
  def update
52
- enforce_permission_to :update, :project, project: project
53
- @form = form(ProjectForm).from_params(params, budget: budget)
51
+ enforce_permission_to(:update, :project, project:)
52
+ @form = form(ProjectForm).from_params(params, budget:)
54
53
 
55
54
  UpdateProject.call(@form, project) do
56
55
  on(:ok) do
@@ -66,7 +65,7 @@ module Decidim
66
65
  end
67
66
 
68
67
  def destroy
69
- enforce_permission_to :destroy, :project, project: project
68
+ enforce_permission_to(:destroy, :project, project:)
70
69
 
71
70
  DestroyProject.call(project, current_user) do
72
71
  on(:ok) do
@@ -163,6 +162,25 @@ module Decidim
163
162
  end
164
163
  end
165
164
 
165
+ def update_budget
166
+ enforce_permission_to :update, :project, project: sample_project
167
+ ::Decidim::Budgets::Admin::UpdateProjectsBudget.call(reference_budget, project_ids) do
168
+ on(:invalid_project_ids) do
169
+ flash.now[:alert] = t("projects.update_budget.select_a_project", scope: "decidim.budgets.admin")
170
+ end
171
+
172
+ on(:update_projects_budget) do
173
+ moved_items(@response)
174
+ flash.now[:notice] = update_projects_bulk_response_successful(@response, :budget)
175
+ flash.now[:alert] = update_projects_bulk_response_errored(@response, :budget)
176
+ end
177
+ end
178
+
179
+ respond_to do |format|
180
+ format.js { render :update_attribute, locals: { form_selector: "#js-form-budget-change-projects", attribute_selector: "#selected_value", moved_items: } }
181
+ end
182
+ end
183
+
166
184
  private
167
185
 
168
186
  def projects
@@ -170,13 +188,19 @@ module Decidim
170
188
  end
171
189
 
172
190
  def orders
173
- @orders ||= Order.where(budget: budget)
191
+ @orders ||= Order.where(budget:)
174
192
  end
175
193
 
176
194
  def project_ids
177
195
  @project_ids ||= params[:project_ids]
178
196
  end
179
197
 
198
+ def reference_budget
199
+ return unless params[:reference_id]
200
+
201
+ Budget.find(params[:reference_id])
202
+ end
203
+
180
204
  def pending_orders
181
205
  orders.pending
182
206
  end
@@ -185,6 +209,12 @@ module Decidim
185
209
  orders.finished
186
210
  end
187
211
 
212
+ def sample_project
213
+ return if project_ids.empty?
214
+
215
+ Decidim::Budgets::Project.find(project_ids.first)
216
+ end
217
+
188
218
  def project
189
219
  @project ||= projects.find(params[:id])
190
220
  end
@@ -202,6 +232,8 @@ module Decidim
202
232
  t("projects.update_category.success", scope: "decidim.budgets.admin", **interpolations)
203
233
  when :scope
204
234
  t("projects.update_scope.success", scope: "decidim.budgets.admin", **interpolations)
235
+ when :budget
236
+ t("projects.update_budget.success", scope: "decidim.budgets.admin", **interpolations)
205
237
  when :selected
206
238
  if extra[:selection]
207
239
  t("projects.update_selected.success.selected", scope: "decidim.budgets.admin", **interpolations)
@@ -224,6 +256,8 @@ module Decidim
224
256
  t("projects.update_category.invalid", scope: "decidim.budgets.admin", **interpolations)
225
257
  when :scope
226
258
  t("projects.update_scope.invalid", scope: "decidim.budgets.admin", **interpolations)
259
+ when :budget
260
+ t("projects.update_budget.invalid", scope: "decidim.budgets.admin", **interpolations)
227
261
  when :selected
228
262
  if extra[:selection]
229
263
  t("projects.update_selected.invalid.selected", scope: "decidim.budgets.admin", **interpolations)
@@ -232,6 +266,14 @@ module Decidim
232
266
  end
233
267
  end
234
268
  end
269
+
270
+ def moved_items(response = nil)
271
+ @moved_items ||= if response
272
+ @project_ids - response[:failed_ids]
273
+ else
274
+ @project_ids
275
+ end
276
+ end
235
277
  end
236
278
  end
237
279
  end
@@ -15,7 +15,7 @@ module Decidim
15
15
  def create
16
16
  enforce_permission_to :import_proposals, :projects
17
17
 
18
- @form = form(Admin::ProjectImportProposalsForm).from_params(params, budget: budget)
18
+ @form = form(Admin::ProjectImportProposalsForm).from_params(params, budget:)
19
19
  Admin::ImportProposalsToBudgets.call(@form) do
20
20
  on(:ok) do |projects|
21
21
  flash[:notice] = I18n.t("proposals_imports.create.success", scope: "decidim.budgets.admin", number: projects.length)
@@ -22,10 +22,6 @@ module Decidim
22
22
  current_settings.votes == "finished"
23
23
  end
24
24
 
25
- def show_votes_count?
26
- current_settings.show_votes?
27
- end
28
-
29
25
  private
30
26
 
31
27
  def workflow_name
@@ -4,6 +4,11 @@ module Decidim
4
4
  module Budgets
5
5
  # Exposes the budget resources so users can participate on them
6
6
  class BudgetsController < Decidim::Budgets::ApplicationController
7
+ helper_method :announcement_body
8
+
9
+ include Decidim::Budgets::Orderable
10
+ include Decidim::TranslatableAttributes
11
+
7
12
  def index
8
13
  redirect_to budget_projects_path(current_workflow.single) if current_workflow.single?
9
14
  end
@@ -16,6 +21,10 @@ module Decidim
16
21
 
17
22
  private
18
23
 
24
+ def announcement_body
25
+ @announcement_body ||= [translated_attribute(current_settings.announcement), translated_attribute(component_settings.announcement)].find(&:present?)&.html_safe
26
+ end
27
+
19
28
  def budget
20
29
  @budget ||= Budget.where(component: current_component).includes(:projects).find_by(id: params[:id])
21
30
  end