decidim-budgets 0.21.0 → 0.23.2

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 (190) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +38 -3
  3. data/app/assets/images/decidim/budgets/icon.svg +1 -11
  4. data/app/assets/javascripts/decidim/budgets/projects.js.es6 +26 -4
  5. data/app/assets/stylesheets/decidim/budgets/budget/_budget-list.scss +152 -24
  6. data/app/cells/decidim/budgets/base_cell.rb +22 -0
  7. data/app/cells/decidim/budgets/budget_cell.rb +21 -0
  8. data/app/cells/decidim/budgets/budget_information_modal/show.erb +28 -0
  9. data/app/cells/decidim/budgets/budget_information_modal_cell.rb +22 -0
  10. data/app/cells/decidim/budgets/budget_list_item/show.erb +22 -0
  11. data/app/cells/decidim/budgets/budget_list_item_cell.rb +40 -0
  12. data/app/cells/decidim/budgets/budget_m/data.erb +12 -0
  13. data/app/cells/decidim/budgets/budget_m/footer.erb +5 -0
  14. data/app/cells/decidim/budgets/budget_m_cell.rb +16 -0
  15. data/app/cells/decidim/budgets/budgets_header/show.erb +7 -0
  16. data/app/cells/decidim/budgets/budgets_header_cell.rb +14 -0
  17. data/app/cells/decidim/budgets/budgets_list/card_list.erb +7 -0
  18. data/app/cells/decidim/budgets/budgets_list/highlighted.erb +11 -0
  19. data/app/cells/decidim/budgets/budgets_list/show.erb +20 -0
  20. data/app/cells/decidim/budgets/budgets_list/voted.erb +43 -0
  21. data/app/cells/decidim/budgets/budgets_list_cell.rb +39 -0
  22. data/app/cells/decidim/budgets/limit_announcement_cell.rb +52 -0
  23. data/app/cells/decidim/budgets/project_list_item/project_data.erb +19 -0
  24. data/app/cells/decidim/budgets/project_list_item/project_data_vote_button.erb +15 -0
  25. data/app/cells/decidim/budgets/project_list_item/project_image.erb +5 -0
  26. data/app/cells/decidim/budgets/project_list_item/project_text.erb +23 -0
  27. data/app/cells/decidim/budgets/project_list_item/show.erb +5 -0
  28. data/app/cells/decidim/budgets/project_list_item_cell.rb +66 -0
  29. data/app/cells/decidim/budgets/project_m/data.erb +3 -3
  30. data/app/cells/decidim/budgets/project_m/footer.erb +1 -1
  31. data/app/cells/decidim/budgets/project_m_cell.rb +4 -0
  32. data/app/cells/decidim/budgets/project_selected_status_cell.rb +28 -0
  33. data/app/cells/decidim/budgets/project_tags/show.erb +5 -0
  34. data/app/cells/decidim/budgets/project_tags_cell.rb +18 -0
  35. data/app/cells/decidim/budgets/project_voted_hint_cell.rb +33 -0
  36. data/app/cells/decidim/budgets/project_votes_count_cell.rb +44 -0
  37. data/app/commands/decidim/budgets/add_line_item.rb +7 -10
  38. data/app/commands/decidim/budgets/admin/create_budget.rb +48 -0
  39. data/app/commands/decidim/budgets/admin/create_project.rb +26 -11
  40. data/app/commands/decidim/budgets/admin/destroy_budget.rb +42 -0
  41. data/app/commands/decidim/budgets/admin/import_proposals_to_budgets.rb +26 -25
  42. data/app/commands/decidim/budgets/admin/update_budget.rb +48 -0
  43. data/app/commands/decidim/budgets/admin/update_project.rb +20 -2
  44. data/app/commands/decidim/budgets/checkout.rb +7 -6
  45. data/app/commands/decidim/budgets/remove_line_item.rb +3 -2
  46. data/app/controllers/concerns/decidim/budgets/needs_current_order.rb +18 -2
  47. data/app/controllers/concerns/decidim/budgets/orderable.rb +57 -0
  48. data/app/controllers/decidim/budgets/admin/application_controller.rb +10 -2
  49. data/app/controllers/decidim/budgets/admin/attachment_collections_controller.rb +1 -1
  50. data/app/controllers/decidim/budgets/admin/attachments_controller.rb +2 -2
  51. data/app/controllers/decidim/budgets/admin/budgets_controller.rb +82 -0
  52. data/app/controllers/decidim/budgets/admin/projects_controller.rb +15 -12
  53. data/app/controllers/decidim/budgets/admin/proposals_imports_controller.rb +10 -2
  54. data/app/controllers/decidim/budgets/application_controller.rb +23 -0
  55. data/app/controllers/decidim/budgets/budgets_controller.rb +24 -0
  56. data/app/controllers/decidim/budgets/line_items_controller.rb +10 -6
  57. data/app/controllers/decidim/budgets/orders_controller.rb +20 -6
  58. data/app/controllers/decidim/budgets/projects_controller.rb +24 -19
  59. data/app/forms/decidim/budgets/admin/budget_form.rb +39 -0
  60. data/app/forms/decidim/budgets/admin/component_form.rb +44 -0
  61. data/app/forms/decidim/budgets/admin/project_form.rb +25 -9
  62. data/app/forms/decidim/budgets/admin/project_import_proposals_form.rb +4 -0
  63. data/app/helpers/decidim/budgets/admin/application_helper.rb +13 -0
  64. data/app/helpers/decidim/budgets/application_helper.rb +10 -0
  65. data/app/helpers/decidim/budgets/projects_helper.rb +13 -0
  66. data/app/jobs/decidim/budgets/send_order_summary_job.rb +15 -0
  67. data/app/mailers/decidim/budgets/order_summary_mailer.rb +36 -0
  68. data/app/models/decidim/budgets/budget.rb +34 -0
  69. data/app/models/decidim/budgets/line_item.rb +4 -4
  70. data/app/models/decidim/budgets/order.rb +47 -16
  71. data/app/models/decidim/budgets/project.rb +37 -4
  72. data/app/permissions/decidim/budgets/admin/permissions.rb +23 -10
  73. data/app/permissions/decidim/budgets/permissions.rb +28 -6
  74. data/app/presenters/decidim/budgets/admin_log/budget_presenter.rb +42 -0
  75. data/app/queries/decidim/budgets/filtered_projects.rb +9 -1
  76. data/app/queries/decidim/budgets/metrics/budget_followers_metric_measure.rb +3 -2
  77. data/app/queries/decidim/budgets/metrics/budget_participants_metric_measure.rb +6 -5
  78. data/app/serializers/decidim/budgets/data_portability_budgets_order_serializer.rb +3 -2
  79. data/app/services/decidim/budgets/project_search.rb +12 -24
  80. data/app/types/decidim/budgets/budget_type.rb +24 -0
  81. data/app/types/decidim/budgets/budgets_type.rb +6 -6
  82. data/app/types/decidim/budgets/project_type.rb +2 -1
  83. data/app/views/decidim/budgets/admin/budgets/_form.html.erb +23 -0
  84. data/app/views/decidim/budgets/admin/budgets/edit.html.erb +7 -0
  85. data/app/views/decidim/budgets/admin/budgets/index.html.erb +58 -0
  86. data/app/views/decidim/budgets/admin/budgets/new.html.erb +7 -0
  87. data/app/views/decidim/budgets/admin/projects/_form.html.erb +15 -10
  88. data/app/views/decidim/budgets/admin/projects/edit.html.erb +2 -2
  89. data/app/views/decidim/budgets/admin/projects/index.html.erb +20 -7
  90. data/app/views/decidim/budgets/admin/projects/new.html.erb +2 -2
  91. data/app/views/decidim/budgets/admin/projects/proposals_picker.html.erb +1 -0
  92. data/app/views/decidim/budgets/admin/proposals_imports/new.html.erb +1 -1
  93. data/app/views/decidim/budgets/budgets/index.html.erb +5 -0
  94. data/app/views/decidim/budgets/order_summary_mailer/order_summary.html.erb +22 -0
  95. data/app/views/decidim/budgets/projects/_budget_confirm.html.erb +3 -3
  96. data/app/views/decidim/budgets/projects/_budget_summary.html.erb +26 -7
  97. data/app/views/decidim/budgets/projects/_filters.html.erb +15 -7
  98. data/app/views/decidim/budgets/projects/_linked_projects.html.erb +2 -2
  99. data/app/views/decidim/budgets/projects/_order_progress.html.erb +14 -18
  100. data/app/views/decidim/budgets/projects/_order_selected_projects.html.erb +3 -3
  101. data/app/views/decidim/budgets/projects/_project.html.erb +1 -57
  102. data/app/views/decidim/budgets/projects/_project_budget_button.html.erb +36 -7
  103. data/app/views/decidim/budgets/projects/_projects.html.erb +8 -1
  104. data/app/views/decidim/budgets/projects/index.html.erb +15 -7
  105. data/app/views/decidim/budgets/projects/index.js.erb +8 -0
  106. data/app/views/decidim/budgets/projects/show.html.erb +22 -13
  107. data/config/locales/am-ET.yml +1 -0
  108. data/config/locales/ar.yml +2 -16
  109. data/config/locales/bg-BG.yml +7 -0
  110. data/config/locales/bg.yml +6 -0
  111. data/config/locales/ca.yml +125 -11
  112. data/config/locales/cs.yml +148 -34
  113. data/config/locales/da-DK.yml +1 -0
  114. data/config/locales/da.yml +1 -0
  115. data/config/locales/de.yml +143 -29
  116. data/config/locales/el.yml +168 -0
  117. data/config/locales/en.yml +125 -11
  118. data/config/locales/eo.yml +1 -0
  119. data/config/locales/es-MX.yml +125 -11
  120. data/config/locales/es-PY.yml +125 -11
  121. data/config/locales/es.yml +125 -11
  122. data/config/locales/et-EE.yml +1 -0
  123. data/config/locales/et.yml +1 -0
  124. data/config/locales/eu.yml +5 -13
  125. data/config/locales/fi-plain.yml +126 -12
  126. data/config/locales/fi.yml +136 -22
  127. data/config/locales/fr-CA.yml +267 -0
  128. data/config/locales/fr.yml +125 -11
  129. data/config/locales/ga-IE.yml +1 -0
  130. data/config/locales/gl.yml +70 -15
  131. data/config/locales/hr-HR.yml +1 -0
  132. data/config/locales/hr.yml +1 -0
  133. data/config/locales/hu.yml +18 -12
  134. data/config/locales/id-ID.yml +2 -11
  135. data/config/locales/is-IS.yml +0 -11
  136. data/config/locales/is.yml +114 -0
  137. data/config/locales/it.yml +96 -12
  138. data/config/locales/ja-JP.yml +172 -0
  139. data/config/locales/ja.yml +262 -0
  140. data/config/locales/ko-KR.yml +1 -0
  141. data/config/locales/ko.yml +1 -0
  142. data/config/locales/lt-LT.yml +1 -0
  143. data/config/locales/lt.yml +1 -0
  144. data/config/locales/lv.yml +164 -0
  145. data/config/locales/mt-MT.yml +1 -0
  146. data/config/locales/mt.yml +1 -0
  147. data/config/locales/nl.yml +112 -12
  148. data/config/locales/no.yml +42 -13
  149. data/config/locales/om-ET.yml +1 -0
  150. data/config/locales/pl.yml +175 -61
  151. data/config/locales/pt-BR.yml +3 -13
  152. data/config/locales/pt.yml +62 -46
  153. data/config/locales/ro-RO.yml +172 -0
  154. data/config/locales/ru.yml +2 -14
  155. data/config/locales/si-LK.yml +1 -0
  156. data/config/locales/sk-SK.yml +180 -0
  157. data/config/locales/sk.yml +166 -0
  158. data/config/locales/sl.yml +1 -0
  159. data/config/locales/so-SO.yml +1 -0
  160. data/config/locales/sr-CS.yml +27 -0
  161. data/config/locales/sv.yml +125 -11
  162. data/config/locales/sw-KE.yml +1 -0
  163. data/config/locales/ti-ER.yml +1 -0
  164. data/config/locales/tr-TR.yml +152 -38
  165. data/config/locales/uk.yml +2 -14
  166. data/config/locales/vi-VN.yml +1 -0
  167. data/config/locales/vi.yml +1 -0
  168. data/config/locales/zh-CN.yml +260 -0
  169. data/config/locales/zh-TW.yml +1 -0
  170. data/db/migrate/20200617105120_create_decidim_budgets.rb +15 -0
  171. data/db/migrate/20200629072626_rename_budget_to_budget_ammount.rb +7 -0
  172. data/db/migrate/20200629134013_add_budget_reference_to_project.rb +7 -0
  173. data/db/migrate/20200706142609_add_budget_reference_to_order.rb +7 -0
  174. data/db/migrate/20200714103519_move_budgets_to_own_model.rb +109 -0
  175. data/db/migrate/20200717140012_add_scope_to_budgets.rb +7 -0
  176. data/db/migrate/20200728075039_add_selected_at_to_project.rb +7 -0
  177. data/db/migrate/20200804175222_votes_enabled_to_votes_choices.rb +35 -0
  178. data/db/migrate/20200827154129_add_commentable_counter_cache_to_projects.rb +9 -0
  179. data/lib/decidim/budgets.rb +1 -0
  180. data/lib/decidim/budgets/admin_engine.rb +12 -5
  181. data/lib/decidim/budgets/component.rb +87 -38
  182. data/lib/decidim/budgets/engine.rb +8 -6
  183. data/lib/decidim/budgets/seeds/city.jpeg +0 -0
  184. data/lib/decidim/budgets/test/factories.rb +71 -9
  185. data/lib/decidim/budgets/version.rb +1 -1
  186. data/lib/decidim/budgets/workflows.rb +17 -0
  187. data/lib/decidim/budgets/workflows/all.rb +20 -0
  188. data/lib/decidim/budgets/workflows/base.rb +132 -0
  189. data/lib/decidim/budgets/workflows/one.rb +33 -0
  190. metadata +123 -19
@@ -1,5 +1,5 @@
1
1
  <div class="card__footer">
2
2
  <div class="card__support">
3
- <%= link_to t("view", scope: "decidim.budgets.projects.project"), resource_path, class: "card__button button secondary button--sc small light" %>
3
+ <%= link_to t("view", scope: "decidim.budgets.projects.project"), resource_path, class: "card__button button button--sc small" %>
4
4
  </div>
5
5
  </div>
@@ -13,6 +13,10 @@ module Decidim
13
13
  def resource_icon
14
14
  icon "projects", class: "icon--big"
15
15
  end
16
+
17
+ def resource_path
18
+ resource_locator([model.budget, model]).path
19
+ end
16
20
  end
17
21
  end
18
22
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Budgets
5
+ # This cell renders the selected status if the project has been selected
6
+ class ProjectSelectedStatusCell < Decidim::ViewModel
7
+ delegate :voting_finished?, to: :controller
8
+
9
+ def show
10
+ if voting_finished? && model.selected?
11
+ content_tag :span, class: css_class do
12
+ t("decidim.budgets.projects.project.selected")
13
+ end
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def css_class
20
+ if options[:as_label] == true
21
+ "success label project-status"
22
+ else
23
+ "success card__text--status"
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,5 @@
1
+ <%= content_tag :ul, class: tags_classes do %>
2
+ <%= content_tag :li, link_to_category if category? %>
3
+
4
+ <%= content_tag :li, link_to_scope if scope? %>
5
+ <% end %>
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Budgets
5
+ # This cell overrides *_path methods from Decidim::TagsCell for project tags
6
+ class ProjectTagsCell < Decidim::TagsCell
7
+ private
8
+
9
+ def category_path
10
+ resource_locator([model.budget, model]).index(filter: { category_id: [model.category.id.to_s] })
11
+ end
12
+
13
+ def scope_path
14
+ resource_locator([model.budget, model]).index(filter: { scope_id: [model.scope.id] })
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Budgets
5
+ # This cell renders a checkmark with a text.
6
+ class ProjectVotedHintCell < BaseCell
7
+ include Decidim::IconHelper
8
+
9
+ delegate :voted_for?, :current_order, to: :controller
10
+
11
+ def show
12
+ return unless voted_for?(model)
13
+
14
+ content_tag :span, safe_join(hint), class: css_class
15
+ end
16
+
17
+ private
18
+
19
+ def hint
20
+ contents = []
21
+ contents << icon("check", role: "img")
22
+ contents << " "
23
+ contents << t("decidim.budgets.projects.project.you_voted")
24
+ end
25
+
26
+ def css_class
27
+ css = ["text-sm", "text-success"]
28
+ css << options[:class] if options[:class]
29
+ css.join(" ")
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Budgets
5
+ # This cell renders the vote count.
6
+ # Two possible layouts: One or two lines
7
+ class ProjectVotesCountCell < Decidim::ViewModel
8
+ include Decidim::IconHelper
9
+ delegate :show_votes_count?, to: :controller
10
+
11
+ def show
12
+ return unless show_votes_count?
13
+
14
+ content_tag :span, content, class: css_class
15
+ end
16
+
17
+ private
18
+
19
+ def content
20
+ 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))])
23
+ else
24
+ safe_join([number, label(t("decidim.budgets.projects.project.votes",
25
+ count: model.confirmed_orders_count))])
26
+ end
27
+ end
28
+
29
+ def number
30
+ content_tag :div, model.confirmed_orders_count, class: "text-large"
31
+ end
32
+
33
+ def label(i18n_string)
34
+ content_tag :span, i18n_string, class: "text-uppercase text-small"
35
+ end
36
+
37
+ def css_class
38
+ css = ["project-votes"]
39
+ css << options[:class] if options[:class]
40
+ css.join(" ")
41
+ end
42
+ end
43
+ end
44
+ end
@@ -23,7 +23,7 @@ module Decidim
23
23
  # Returns nothing.
24
24
  def call
25
25
  transaction do
26
- return broadcast(:invalid) if votes_disabled? || order.checked_out?
26
+ return broadcast(:invalid) if voting_not_enabled? || order.checked_out?
27
27
 
28
28
  add_line_item
29
29
  broadcast(:ok, order)
@@ -32,23 +32,20 @@ module Decidim
32
32
 
33
33
  private
34
34
 
35
+ attr_reader :current_user, :project
36
+
35
37
  def order
36
- @order ||= Order.create!(user: @current_user, component: @project.component)
38
+ @order ||= Order.create!(user: current_user, budget: project.budget)
37
39
  end
38
40
 
39
41
  def add_line_item
40
42
  order.with_lock do
41
- order.projects << @project
42
- order.save!
43
+ order.projects << project
43
44
  end
44
45
  end
45
46
 
46
- def component
47
- @project.component
48
- end
49
-
50
- def votes_disabled?
51
- !component.current_settings.votes_enabled?
47
+ def voting_not_enabled?
48
+ project.component.current_settings.votes != "enabled"
52
49
  end
53
50
  end
54
51
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Budgets
5
+ module Admin
6
+ # This command is executed when the user creates an Budget
7
+ # from the admin panel.
8
+ class CreateBudget < Rectify::Command
9
+ def initialize(form)
10
+ @form = form
11
+ end
12
+
13
+ # Creates the budget if valid.
14
+ #
15
+ # Broadcasts :ok if successful, :invalid otherwise.
16
+ def call
17
+ return broadcast(:invalid) if form.invalid?
18
+
19
+ create_budget!
20
+
21
+ broadcast(:ok, budget)
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :form, :budget
27
+
28
+ def create_budget!
29
+ attributes = {
30
+ component: form.current_component,
31
+ scope: form.scope,
32
+ title: form.title,
33
+ weight: form.weight,
34
+ description: form.description,
35
+ total_budget: form.total_budget
36
+ }
37
+
38
+ @budget = Decidim.traceability.create!(
39
+ Budget,
40
+ form.current_user,
41
+ attributes,
42
+ visibility: "all"
43
+ )
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -6,6 +6,9 @@ module Decidim
6
6
  # This command is executed when the user creates a Project from the admin
7
7
  # panel.
8
8
  class CreateProject < Rectify::Command
9
+ include ::Decidim::AttachmentMethods
10
+ include ::Decidim::GalleryMethods
11
+
9
12
  def initialize(form)
10
13
  @form = form
11
14
  end
@@ -16,9 +19,15 @@ module Decidim
16
19
  def call
17
20
  return broadcast(:invalid) if @form.invalid?
18
21
 
22
+ if process_gallery?
23
+ build_gallery
24
+ return broadcast(:invalid) if gallery_invalid?
25
+ end
26
+
19
27
  transaction do
20
- create_project
28
+ create_project!
21
29
  link_proposals
30
+ create_gallery if process_gallery?
22
31
  end
23
32
 
24
33
  broadcast(:ok)
@@ -26,23 +35,29 @@ module Decidim
26
35
 
27
36
  private
28
37
 
29
- attr_reader :project
38
+ attr_reader :form, :project, :gallery
39
+
40
+ def create_project!
41
+ attributes = {
42
+ budget: form.budget,
43
+ scope: form.scope,
44
+ category: form.category,
45
+ title: form.title,
46
+ description: form.description,
47
+ budget_amount: form.budget_amount
48
+ }
30
49
 
31
- def create_project
32
50
  @project = Decidim.traceability.create!(
33
51
  Project,
34
- @form.current_user,
35
- scope: @form.scope,
36
- category: @form.category,
37
- component: @form.current_component,
38
- title: @form.title,
39
- description: @form.description,
40
- budget: @form.budget
52
+ form.current_user,
53
+ attributes,
54
+ visibility: "all"
41
55
  )
56
+ @attached_to = @project
42
57
  end
43
58
 
44
59
  def proposals
45
- @proposals ||= project.sibling_scope(:proposals).where(id: @form.proposal_ids)
60
+ @proposals ||= project.sibling_scope(:proposals).where(id: form.proposal_ids)
46
61
  end
47
62
 
48
63
  def link_proposals
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Budgets
5
+ module Admin
6
+ # This command is executed when the user destroys a Budget
7
+ # from the admin panel.
8
+ class DestroyBudget < Rectify::Command
9
+ def initialize(budget, current_user)
10
+ @budget = budget
11
+ @current_user = current_user
12
+ end
13
+
14
+ # Destroys the budget if valid.
15
+ #
16
+ # Broadcasts :ok if successful, :invalid otherwise.
17
+ def call
18
+ return broadcast(:invalid) if budget.projects.present?
19
+
20
+ destroy_budget!
21
+
22
+ broadcast(:ok, budget)
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :budget, :current_user
28
+
29
+ def destroy_budget!
30
+ Decidim.traceability.perform_action!(
31
+ :delete,
32
+ budget,
33
+ current_user,
34
+ visibility: "all"
35
+ ) do
36
+ budget.destroy!
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -4,7 +4,7 @@ module Decidim
4
4
  module Budgets
5
5
  module Admin
6
6
  # A command with all the business logic when an admin imports proposals from
7
- # one component to budget component.
7
+ # one component to projects of a budget.
8
8
  class ImportProposalsToBudgets < Rectify::Command
9
9
  # Public: Initializes the command.
10
10
  #
@@ -32,45 +32,46 @@ module Decidim
32
32
  def create_projects_from_accepted_proposals
33
33
  transaction do
34
34
  proposals.map do |original_proposal|
35
- next if proposal_already_copied?(original_proposal, target_component)
35
+ next if proposal_already_copied?(original_proposal)
36
36
 
37
- project = Decidim::Budgets::Project.new
38
- project.title = project_localized(original_proposal.title)
39
- project.description = project_localized(original_proposal.body)
40
- project.budget = form.default_budget
41
- project.category = original_proposal.category
42
- project.scope = original_proposal.scope
43
- project.component = target_component
44
- project.save!
37
+ new_project = create_project_from_proposal!(original_proposal)
45
38
 
46
- project.link_resources([original_proposal], "included_proposals")
39
+ new_project.link_resources([original_proposal], "included_proposals")
47
40
  end.compact
48
41
  end
49
42
  end
50
43
 
44
+ def create_project_from_proposal!(original_proposal)
45
+ params = {
46
+ budget: form.budget,
47
+ title: original_proposal.title,
48
+ description: original_proposal.body,
49
+ budget_amount: form.default_budget,
50
+ category: original_proposal.category,
51
+ scope: original_proposal.scope
52
+ }
53
+
54
+ @project = Decidim.traceability.create!(
55
+ Project,
56
+ form.current_user,
57
+ params,
58
+ visibility: "all"
59
+ )
60
+ end
61
+
51
62
  def proposals
52
63
  Decidim::Proposals::Proposal.where(component: origin_component).where(state: "accepted")
53
64
  end
54
65
 
55
66
  def origin_component
56
- @form.origin_component
67
+ form.origin_component
57
68
  end
58
69
 
59
- def target_component
60
- @form.current_component
61
- end
62
-
63
- def proposal_already_copied?(original_proposal, target_component)
64
- original_proposal.linked_resources(:projects, "included_proposals").any? do |proposal|
65
- proposal.component == target_component
70
+ def proposal_already_copied?(original_proposal)
71
+ original_proposal.linked_resources(:projects, "included_proposals").any? do |project|
72
+ project.budget == form.budget
66
73
  end
67
74
  end
68
-
69
- def project_localized(text)
70
- Decidim.available_locales.inject({}) do |result, locale|
71
- result.update(locale => text)
72
- end.with_indifferent_access
73
- end
74
75
  end
75
76
  end
76
77
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Budgets
5
+ module Admin
6
+ # This command is executed when the user updates a Budget
7
+ # from the admin panel.
8
+ class UpdateBudget < Rectify::Command
9
+ def initialize(form, budget)
10
+ @form = form
11
+ @budget = budget
12
+ end
13
+
14
+ # Updates the budget if valid.
15
+ #
16
+ # Broadcasts :ok if successful, :invalid otherwise.
17
+ def call
18
+ return broadcast(:invalid) if form.invalid?
19
+
20
+ update_budget!
21
+
22
+ broadcast(:ok, budget)
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :form, :budget
28
+
29
+ def update_budget!
30
+ attributes = {
31
+ scope: form.scope,
32
+ title: form.title,
33
+ weight: form.weight,
34
+ description: form.description,
35
+ total_budget: form.total_budget
36
+ }
37
+
38
+ Decidim.traceability.update!(
39
+ budget,
40
+ form.current_user,
41
+ attributes,
42
+ visibility: "all"
43
+ )
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end