decidim-budgets 0.26.5 → 0.27.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/budgets/order_activity_cell.rb +29 -0
  3. data/app/commands/decidim/budgets/add_line_item.rb +4 -2
  4. data/app/commands/decidim/budgets/admin/create_budget.rb +1 -1
  5. data/app/commands/decidim/budgets/admin/create_order_reminders.rb +66 -0
  6. data/app/commands/decidim/budgets/admin/create_project.rb +5 -2
  7. data/app/commands/decidim/budgets/admin/destroy_budget.rb +1 -1
  8. data/app/commands/decidim/budgets/admin/destroy_project.rb +1 -1
  9. data/app/commands/decidim/budgets/admin/import_proposals_to_budgets.rb +6 -6
  10. data/app/commands/decidim/budgets/admin/update_budget.rb +1 -1
  11. data/app/commands/decidim/budgets/admin/update_project.rb +5 -2
  12. data/app/commands/decidim/budgets/admin/update_project_category.rb +48 -0
  13. data/app/commands/decidim/budgets/admin/update_project_scope.rb +54 -0
  14. data/app/commands/decidim/budgets/admin/update_project_selection.rb +56 -0
  15. data/app/commands/decidim/budgets/cancel_order.rb +1 -1
  16. data/app/commands/decidim/budgets/checkout.rb +10 -3
  17. data/app/commands/decidim/budgets/remove_line_item.rb +1 -1
  18. data/app/controllers/decidim/budgets/admin/projects_controller.rb +149 -1
  19. data/app/controllers/decidim/budgets/projects_controller.rb +13 -13
  20. data/app/forms/decidim/budgets/admin/budget_form.rb +2 -2
  21. data/app/forms/decidim/budgets/admin/order_reminder_form.rb +75 -0
  22. data/app/forms/decidim/budgets/admin/project_form.rb +19 -3
  23. data/app/helpers/decidim/budgets/admin/project_bulk_actions_helper.rb +20 -0
  24. data/app/helpers/decidim/budgets/projects_helper.rb +29 -0
  25. data/app/jobs/decidim/budgets/send_vote_reminder_job.rb +16 -0
  26. data/app/mailers/decidim/budgets/vote_reminder_mailer.rb +39 -0
  27. data/app/models/decidim/budgets/order.rb +2 -3
  28. data/app/models/decidim/budgets/project.rb +12 -4
  29. data/app/packs/entrypoints/decidim_budgets_admin.js +1 -0
  30. data/app/packs/src/decidim/budgets/admin/projects.js +143 -0
  31. data/app/permissions/decidim/budgets/admin/permissions.rb +8 -3
  32. data/app/queries/decidim/budgets/filtered_projects.rb +1 -1
  33. data/app/serializers/decidim/budgets/{data_portability_budgets_order_serializer.rb → download_your_data_budgets_order_serializer.rb} +2 -2
  34. data/app/services/decidim/budgets/order_reminder_generator.rb +85 -0
  35. data/app/views/decidim/budgets/admin/budgets/index.html.erb +3 -0
  36. data/app/views/decidim/budgets/admin/projects/_bulk-actions.html.erb +13 -0
  37. data/app/views/decidim/budgets/admin/projects/_form.html.erb +6 -0
  38. data/app/views/decidim/budgets/admin/projects/_project-tr.html.erb +50 -0
  39. data/app/views/decidim/budgets/admin/projects/bulk_actions/_change-selected.html.erb +15 -0
  40. data/app/views/decidim/budgets/admin/projects/bulk_actions/_dropdown.html.erb +36 -0
  41. data/app/views/decidim/budgets/admin/projects/bulk_actions/_recategorize.html.erb +15 -0
  42. data/app/views/decidim/budgets/admin/projects/bulk_actions/_scope-change.html.erb +25 -0
  43. data/app/views/decidim/budgets/admin/projects/index.html.erb +6 -54
  44. data/app/views/decidim/budgets/admin/projects/update_attribute.js.erb +26 -0
  45. data/app/views/decidim/budgets/projects/_filters.html.erb +4 -4
  46. data/app/views/decidim/budgets/projects/index.html.erb +28 -1
  47. data/app/views/decidim/budgets/projects/show.html.erb +6 -1
  48. data/app/views/decidim/budgets/vote_reminder_mailer/vote_reminder.html.erb +21 -0
  49. data/config/assets.rb +2 -1
  50. data/config/locales/am-ET.yml +1 -0
  51. data/config/locales/ar.yml +4 -0
  52. data/config/locales/bg.yml +1 -0
  53. data/config/locales/ca.yml +47 -1
  54. data/config/locales/cs.yml +51 -1
  55. data/config/locales/da.yml +1 -0
  56. data/config/locales/de.yml +45 -3
  57. data/config/locales/el.yml +2 -0
  58. data/config/locales/en.yml +46 -1
  59. data/config/locales/eo.yml +1 -0
  60. data/config/locales/es-MX.yml +43 -0
  61. data/config/locales/es-PY.yml +46 -0
  62. data/config/locales/es.yml +48 -2
  63. data/config/locales/et.yml +1 -0
  64. data/config/locales/eu.yml +3 -7
  65. data/config/locales/fi-plain.yml +46 -0
  66. data/config/locales/fi.yml +46 -0
  67. data/config/locales/fr-CA.yml +46 -1
  68. data/config/locales/fr.yml +47 -2
  69. data/config/locales/ga-IE.yml +1 -0
  70. data/config/locales/gl.yml +11 -0
  71. data/config/locales/hr.yml +1 -0
  72. data/config/locales/hu.yml +19 -0
  73. data/config/locales/id-ID.yml +1 -0
  74. data/config/locales/is-IS.yml +2 -1
  75. data/config/locales/it.yml +2 -0
  76. data/config/locales/ja.yml +42 -1
  77. data/config/locales/ko.yml +1 -0
  78. data/config/locales/lb.yml +2 -0
  79. data/config/locales/lt.yml +1 -337
  80. data/config/locales/lv.yml +1 -0
  81. data/config/locales/mt.yml +1 -0
  82. data/config/locales/nl.yml +14 -28
  83. data/config/locales/no.yml +17 -0
  84. data/config/locales/om-ET.yml +1 -0
  85. data/config/locales/pl.yml +2 -0
  86. data/config/locales/pt-BR.yml +3 -1
  87. data/config/locales/pt.yml +2 -0
  88. data/config/locales/ro-RO.yml +2 -3
  89. data/config/locales/ru.yml +1 -0
  90. data/config/locales/si-LK.yml +1 -0
  91. data/config/locales/sk.yml +1 -0
  92. data/config/locales/sl.yml +1 -0
  93. data/config/locales/so-SO.yml +1 -0
  94. data/config/locales/sr-CS.yml +1 -0
  95. data/config/locales/sv.yml +24 -4
  96. data/config/locales/sw-KE.yml +1 -0
  97. data/config/locales/ti-ER.yml +1 -0
  98. data/config/locales/tr-TR.yml +2 -0
  99. data/config/locales/uk.yml +1 -0
  100. data/config/locales/val-ES.yml +1 -0
  101. data/config/locales/vi.yml +1 -0
  102. data/config/locales/zh-CN.yml +1 -0
  103. data/config/locales/zh-TW.yml +1 -0
  104. data/db/migrate/20200804175222_votes_enabled_to_votes_choices.rb +2 -2
  105. data/db/migrate/20220428072638_add_geolocalization_fields_to_projects.rb +9 -0
  106. data/lib/decidim/budgets/admin_engine.rb +3 -0
  107. data/lib/decidim/budgets/component.rb +7 -6
  108. data/lib/decidim/budgets/engine.rb +17 -0
  109. data/lib/decidim/budgets/test/factories.rb +11 -0
  110. data/lib/decidim/budgets/version.rb +1 -1
  111. metadata +38 -22
  112. data/app/services/decidim/budgets/project_search.rb +0 -45
  113. data/config/locales/gn-PY.yml +0 -1
  114. data/config/locales/ka-GE.yml +0 -1
  115. data/config/locales/lo-LA.yml +0 -1
  116. data/config/locales/oc-FR.yml +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2a7eb220680e03c3f8ca012a81217a443c5672804687417251c1dffbec45b0e0
4
- data.tar.gz: 49dfd04c441922ca035ba2960af1fa9bcecdc96a714f4ce8c8aa174a0518c6ed
3
+ metadata.gz: 3fa531ee417f1965e642ac669891a7ab1705d2a39bbad0fbd20b862d2366887a
4
+ data.tar.gz: 014fee8507d07e68e6dcce958912efac0d6c4264ba08a380a4cc6bf77b95171f
5
5
  SHA512:
6
- metadata.gz: d12adac75f375e11e435c5615036e501597afe8a4e3708f7d7444ebb7c9205748962171e8025f8f5570dc0359a62abdac396c90fca00d869dc1823cd655eaee7
7
- data.tar.gz: 3aa335a63d70836da050ef789353eef75cef7e0c1943b055e219d0d2cb7a0e58dc09edf7a09b37a5865b781d2d263e3721d24ea182f773b64922230ca5e57216
6
+ metadata.gz: 347007356a92385202d42ba9380cab18a1b04122a18477df5b640d54d84daf8b440a0e5c6300b3161d5d69b87b1ba5dc4dd04903be5eb0d7f68eb638df34fe5f
7
+ data.tar.gz: 5174a84a9e0a1c73efb3fd0b94c4a7ed4fc9a176891905e4497adbccc4181af2d924740df96e704666f13f594879f70a8ffa162e39dc4ad0f31e403ee88ca88e
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Budgets
5
+ # A cell to display when actions happen on an order.
6
+ class OrderActivityCell < ActivityCell
7
+ def title
8
+ I18n.t(
9
+ "decidim.budgets.last_activity.new_vote_at_html",
10
+ link: participatory_space_link
11
+ )
12
+ end
13
+
14
+ def resource_link_path
15
+ resource_locator(budget).path
16
+ end
17
+
18
+ def resource_link_text
19
+ decidim_html_escape(translated_attribute(budget.title))
20
+ end
21
+
22
+ private
23
+
24
+ def budget
25
+ @budget ||= resource.budget
26
+ end
27
+ end
28
+ end
29
+ end
@@ -3,7 +3,7 @@
3
3
  module Decidim
4
4
  module Budgets
5
5
  # A command with all the business to add new line items to orders
6
- class AddLineItem < Rectify::Command
6
+ class AddLineItem < Decidim::Command
7
7
  # Public: Initializes the command.
8
8
  #
9
9
  # order - The current order for the user or nil if it is not created yet.
@@ -23,11 +23,13 @@ module Decidim
23
23
  # Returns nothing.
24
24
  def call
25
25
  transaction do
26
- return broadcast(:invalid) if voting_not_enabled? || order.checked_out? || exceeds_budget?
26
+ raise ActiveRecord::RecordInvalid if voting_not_enabled? || order.checked_out? || exceeds_budget?
27
27
 
28
28
  add_line_item
29
29
  broadcast(:ok, order)
30
30
  end
31
+ rescue ActiveRecord::RecordInvalid
32
+ broadcast(:invalid)
31
33
  end
32
34
 
33
35
  private
@@ -5,7 +5,7 @@ module Decidim
5
5
  module Admin
6
6
  # This command is executed when the user creates an Budget
7
7
  # from the admin panel.
8
- class CreateBudget < Rectify::Command
8
+ class CreateBudget < Decidim::Command
9
9
  def initialize(form)
10
10
  @form = form
11
11
  end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Budgets
5
+ module Admin
6
+ # This command is executed when admin sends vote reminders.
7
+ class CreateOrderReminders < Decidim::Command
8
+ def initialize(form)
9
+ @form = form
10
+ end
11
+
12
+ def call
13
+ return broadcast(:invalid) if form.invalid?
14
+ return broadcast(:invalid) unless voting_enabled?
15
+ return broadcast(:invalid) if voting_ends_soon?
16
+
17
+ generator.generate_for(current_component, &alternative_refresh_state)
18
+
19
+ broadcast(:ok, generator.reminder_jobs_queued)
20
+ end
21
+
22
+ private
23
+
24
+ attr_reader :form
25
+
26
+ def alternative_refresh_state
27
+ proc do |reminder|
28
+ reminder.records.each do |record|
29
+ next if %w(active pending).exclude? record.state
30
+
31
+ record.state = begin
32
+ if record.remindable.created_at > minimum_time_between_reminders ||
33
+ (reminder.deliveries.present? && reminder.deliveries.last.created_at > minimum_time_between_reminders)
34
+ "pending"
35
+ else
36
+ "active"
37
+ end
38
+ end
39
+ record.save if record.changed?
40
+ end
41
+ end
42
+ end
43
+
44
+ def minimum_time_between_reminders
45
+ form.minimum_interval_between_reminders.ago
46
+ end
47
+
48
+ def generator
49
+ @generator ||= Decidim::Budgets::OrderReminderGenerator.new
50
+ end
51
+
52
+ def current_component
53
+ form.current_component
54
+ end
55
+
56
+ def voting_enabled?
57
+ form.voting_enabled?
58
+ end
59
+
60
+ def voting_ends_soon?
61
+ form.voting_ends_soon?
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -5,7 +5,7 @@ module Decidim
5
5
  module Admin
6
6
  # This command is executed when the user creates a Project from the admin
7
7
  # panel.
8
- class CreateProject < Rectify::Command
8
+ class CreateProject < Decidim::Command
9
9
  include ::Decidim::AttachmentMethods
10
10
  include ::Decidim::GalleryMethods
11
11
 
@@ -44,7 +44,10 @@ module Decidim
44
44
  category: form.category,
45
45
  title: form.title,
46
46
  description: form.description,
47
- budget_amount: form.budget_amount
47
+ budget_amount: form.budget_amount,
48
+ address: form.address,
49
+ latitude: form.latitude,
50
+ longitude: form.longitude
48
51
  }
49
52
 
50
53
  @project = Decidim.traceability.create!(
@@ -5,7 +5,7 @@ module Decidim
5
5
  module Admin
6
6
  # This command is executed when the user destroys a Budget
7
7
  # from the admin panel.
8
- class DestroyBudget < Rectify::Command
8
+ class DestroyBudget < Decidim::Command
9
9
  def initialize(budget, current_user)
10
10
  @budget = budget
11
11
  @current_user = current_user
@@ -5,7 +5,7 @@ module Decidim
5
5
  module Admin
6
6
  # This command is executed when the user deletes a Project from the admin
7
7
  # panel.
8
- class DestroyProject < Rectify::Command
8
+ class DestroyProject < Decidim::Command
9
9
  # Initializes an UpdateProject Command.
10
10
  #
11
11
  # project - The current instance of the project to be destroyed.
@@ -5,7 +5,7 @@ module Decidim
5
5
  module Admin
6
6
  # A command with all the business logic when an admin imports proposals from
7
7
  # one component to projects of a budget.
8
- class ImportProposalsToBudgets < Rectify::Command
8
+ class ImportProposalsToBudgets < Decidim::Command
9
9
  # Public: Initializes the command.
10
10
  #
11
11
  # form - A form object with the params.
@@ -48,7 +48,10 @@ module Decidim
48
48
  description: original_proposal.body,
49
49
  budget_amount: budget_for(original_proposal),
50
50
  category: original_proposal.category,
51
- scope: original_proposal.scope
51
+ scope: original_proposal.scope,
52
+ address: original_proposal.address,
53
+ latitude: original_proposal.latitude,
54
+ longitude: original_proposal.longitude
52
55
  }
53
56
 
54
57
  @project = Decidim.traceability.create!(
@@ -81,10 +84,7 @@ module Decidim
81
84
  end
82
85
 
83
86
  def proposal_already_copied?(original_proposal)
84
- # Note: we are including also projects from unpublished components
85
- # because otherwise duplicates could be created until the component is
86
- # published.
87
- original_proposal.linked_resources(:projects, "included_proposals", component_published: false).any? do |project|
87
+ original_proposal.linked_resources(:projects, "included_proposals").any? do |project|
88
88
  project.budget == form.budget
89
89
  end
90
90
  end
@@ -5,7 +5,7 @@ module Decidim
5
5
  module Admin
6
6
  # This command is executed when the user updates a Budget
7
7
  # from the admin panel.
8
- class UpdateBudget < Rectify::Command
8
+ class UpdateBudget < Decidim::Command
9
9
  def initialize(form, budget)
10
10
  @form = form
11
11
  @budget = budget
@@ -5,7 +5,7 @@ module Decidim
5
5
  module Admin
6
6
  # This command is executed when the user changes a Project from the admin
7
7
  # panel.
8
- class UpdateProject < Rectify::Command
8
+ class UpdateProject < Decidim::Command
9
9
  include ::Decidim::AttachmentMethods
10
10
  include ::Decidim::GalleryMethods
11
11
 
@@ -53,7 +53,10 @@ module Decidim
53
53
  title: form.title,
54
54
  description: form.description,
55
55
  budget_amount: form.budget_amount,
56
- selected_at: selected_at
56
+ selected_at: selected_at,
57
+ address: form.address,
58
+ latitude: form.latitude,
59
+ longitude: form.longitude
57
60
  )
58
61
  end
59
62
 
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Budgets
5
+ module Admin
6
+ class UpdateProjectCategory < Decidim::Command
7
+ include TranslatableAttributes
8
+
9
+ # Public: Initializes the command.
10
+ #
11
+ # category_id - the category id to update
12
+ # project_ids - the project ids to update.
13
+ def initialize(category_id, project_ids)
14
+ @category = Decidim::Category.find_by id: category_id
15
+ @project_ids = project_ids
16
+ @response = { category_name: "", successful: [], errored: [] }
17
+ end
18
+
19
+ def call
20
+ return broadcast(:invalid_category) if @category.blank?
21
+ return broadcast(:invalid_project_ids) if @project_ids.blank?
22
+
23
+ @response[:category_name] = @category.translated_name
24
+ Project.where(id: @project_ids).find_each do |project|
25
+ if @category == project.category
26
+ @response[:errored] << translated_attribute(project.title)
27
+ else
28
+ transaction do
29
+ update_project_category project
30
+ end
31
+ @response[:successful] << translated_attribute(project.title)
32
+ end
33
+ end
34
+
35
+ broadcast(:update_projects_category, @response)
36
+ end
37
+
38
+ private
39
+
40
+ def update_project_category(project)
41
+ project.update!(
42
+ category: @category
43
+ )
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Budgets
5
+ module Admin
6
+ class UpdateProjectScope < Decidim::Command
7
+ include TranslatableAttributes
8
+
9
+ # Public: Initializes the command.
10
+ #
11
+ # scope_id - the scope id to update
12
+ # project_ids - the project ids to update.
13
+ def initialize(scope_id, project_ids)
14
+ @scope = ::Decidim::Scope.find_by id: scope_id
15
+ @project_ids = project_ids
16
+ @response = { scope_name: "", successful: [], errored: [] }
17
+ end
18
+
19
+ def call
20
+ return broadcast(:invalid_scope) if @scope.blank?
21
+ return broadcast(:invalid_project_ids) if @project_ids.blank?
22
+
23
+ update_projects_scope
24
+
25
+ broadcast(:update_projects_scope, @response)
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :scope, :project_ids
31
+
32
+ def update_projects_scope
33
+ @response[:scope_name] = translated_attribute(scope.name, scope.organization)
34
+ ::Decidim::Budgets::Project.where(id: project_ids).find_each do |project|
35
+ if scope == project.scope
36
+ @response[:errored] << translated_attribute(project.title)
37
+ else
38
+ transaction do
39
+ update_project_scope project
40
+ end
41
+ @response[:successful] << translated_attribute(project.title)
42
+ end
43
+ end
44
+ end
45
+
46
+ def update_project_scope(project)
47
+ project.update!(
48
+ scope: scope
49
+ )
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Budgets
5
+ module Admin
6
+ class UpdateProjectSelection < Decidim::Command
7
+ include TranslatableAttributes
8
+
9
+ # Public: Initializes the command.
10
+ #
11
+ # selection - Defines if projects are selected (for implementation)
12
+ # project_ids - the project ids to update.
13
+ def initialize(selection, project_ids)
14
+ @selection = selection
15
+ @project_ids = project_ids
16
+ @response = { selection_name: "", successful: [], errored: [] }
17
+ end
18
+
19
+ def call
20
+ return broadcast(:invalid_selection) if @selection.blank? || [true, false, "true", "false"].exclude?(@selection)
21
+ return broadcast(:invalid_project_ids) if @project_ids.blank?
22
+
23
+ @selection = ActiveModel::Type::Boolean.new.cast(@selection)
24
+
25
+ update_projects_selection
26
+
27
+ broadcast(:update_projects_selection, @response)
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :selection, :project_ids
33
+
34
+ def update_projects_selection
35
+ ::Decidim::Budgets::Project.where(id: project_ids).find_each do |project|
36
+ if (selection == false && !project.selected?) || (selection && project.selected?)
37
+ @response[:errored] << translated_attribute(project.title)
38
+ else
39
+ transaction do
40
+ update_project_selection project
41
+ end
42
+ @response[:successful] << translated_attribute(project.title)
43
+ end
44
+ end
45
+ end
46
+
47
+ def update_project_selection(project)
48
+ selected_at = selection ? Time.current : nil
49
+ project.update!(
50
+ selected_at: selected_at
51
+ )
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -3,7 +3,7 @@
3
3
  module Decidim
4
4
  module Budgets
5
5
  # A command with all the business to cancel an order.
6
- class CancelOrder < Rectify::Command
6
+ class CancelOrder < Decidim::Command
7
7
  # Public: Initializes the command.
8
8
  #
9
9
  # order - The current order for the user.
@@ -3,7 +3,7 @@
3
3
  module Decidim
4
4
  module Budgets
5
5
  # A command with all the business to checkout.
6
- class Checkout < Rectify::Command
6
+ class Checkout < Decidim::Command
7
7
  # Public: Initializes the command.
8
8
  #
9
9
  # order - The current order for the user.
@@ -32,8 +32,15 @@ module Decidim
32
32
 
33
33
  @order.with_lock do
34
34
  SendOrderSummaryJob.perform_later(@order)
35
- @order.checked_out_at = Time.current
36
- @order.save
35
+
36
+ Decidim.traceability.update!(
37
+ @order,
38
+ @order.user,
39
+ { checked_out_at: Time.current },
40
+ visibility: "private-only"
41
+ )
42
+ rescue ActiveRecord::RecordInvalid
43
+ false
37
44
  end
38
45
  end
39
46
  end
@@ -3,7 +3,7 @@
3
3
  module Decidim
4
4
  module Budgets
5
5
  # A command with all the business to add remove line items from orders
6
- class RemoveLineItem < Rectify::Command
6
+ class RemoveLineItem < Decidim::Command
7
7
  # Public: Initializes the command.
8
8
  #
9
9
  # order - The current order for the user
@@ -8,8 +8,9 @@ module Decidim
8
8
  include Decidim::ApplicationHelper
9
9
  include Decidim::Proposals::Admin::Picker if Decidim::Budgets.enable_proposal_linking
10
10
  include Decidim::Budgets::Admin::Filterable
11
+ helper Decidim::Budgets::Admin::ProjectBulkActionsHelper
11
12
 
12
- helper_method :projects, :finished_orders, :pending_orders, :present
13
+ helper_method :projects, :finished_orders, :pending_orders, :present, :project_ids
13
14
 
14
15
  def collection
15
16
  @collection ||= budget.projects.page(params[:page]).per(15)
@@ -74,6 +75,93 @@ module Decidim
74
75
  end
75
76
  end
76
77
 
78
+ def update_category
79
+ enforce_permission_to :update, :project_category
80
+
81
+ ::Decidim::Budgets::Admin::UpdateProjectCategory.call(params[:category][:id], project_ids) do
82
+ on(:invalid_category) do
83
+ flash.now[:error] = I18n.t(
84
+ "projects.update_category.select_a_category",
85
+ scope: "decidim.budgets.admin"
86
+ )
87
+ end
88
+
89
+ on(:invalid_project_ids) do
90
+ flash.now[:alert] = I18n.t(
91
+ "projects.update_category.select_a_project",
92
+ scope: "decidim.budgets.admin"
93
+ )
94
+ end
95
+
96
+ on(:update_projects_category) do
97
+ flash.now[:notice] = update_projects_bulk_response_successful(@response, :category)
98
+ flash.now[:alert] = update_projects_bulk_response_errored(@response, :category)
99
+ end
100
+ end
101
+
102
+ respond_to do |format|
103
+ format.js { render :update_attribute, locals: { form_selector: "#js-form-recategorize-projects", attribute_selector: "#category_id" } }
104
+ end
105
+ end
106
+
107
+ def update_scope
108
+ enforce_permission_to :update, :project_scope
109
+
110
+ ::Decidim::Budgets::Admin::UpdateProjectScope.call(params[:scope_id], project_ids) do
111
+ on(:invalid_scope) do
112
+ flash.now[:error] = t(
113
+ "projects.update_scope.select_a_scope",
114
+ scope: "decidim.budgets.admin"
115
+ )
116
+ end
117
+
118
+ on(:invalid_project_ids) do
119
+ flash.now[:alert] = t(
120
+ "projects.update_scope.select_a_project",
121
+ scope: "decidim.budgets.admin"
122
+ )
123
+ end
124
+
125
+ on(:update_projects_scope) do
126
+ flash.now[:notice] = update_projects_bulk_response_successful(@response, :scope)
127
+ flash.now[:alert] = update_projects_bulk_response_errored(@response, :scope)
128
+ end
129
+ end
130
+
131
+ respond_to do |format|
132
+ format.js { render :update_attribute, locals: { form_selector: "#js-form-scope-change-projects", attribute_selector: "#scope_id" } }
133
+ end
134
+ end
135
+
136
+ def update_selected
137
+ enforce_permission_to :update, :project_selected
138
+
139
+ ::Decidim::Budgets::Admin::UpdateProjectSelection.call(params.dig(:selected, "value"), project_ids) do
140
+ on(:invalid_selection) do
141
+ flash.now[:error] = t(
142
+ "projects.update_selected.select_a_selection",
143
+ scope: "decidim.budgets.admin"
144
+ )
145
+ end
146
+
147
+ on(:invalid_project_ids) do
148
+ flash.now[:alert] = t(
149
+ "projects.update_selected.select_a_project",
150
+ scope: "decidim.budgets.admin"
151
+ )
152
+ end
153
+
154
+ on(:update_projects_selection) do
155
+ flash.now[:notice] = update_projects_bulk_response_successful(@response, :selected)
156
+ flash.now[:alert] = update_projects_bulk_response_errored(@response, :selected)
157
+ end
158
+ end
159
+
160
+ respond_to do |format|
161
+ format.js { render :update_attribute, locals: { form_selector: "#js-form-change-selected-projects", attribute_selector: "#selected_value" } }
162
+ end
163
+ end
164
+
77
165
  private
78
166
 
79
167
  def projects
@@ -84,6 +172,10 @@ module Decidim
84
172
  @orders ||= Order.where(budget: budget)
85
173
  end
86
174
 
175
+ def project_ids
176
+ @project_ids ||= params[:project_ids]
177
+ end
178
+
87
179
  def pending_orders
88
180
  orders.pending
89
181
  end
@@ -95,6 +187,62 @@ module Decidim
95
187
  def project
96
188
  @project ||= projects.find(params[:id])
97
189
  end
190
+
191
+ def update_projects_bulk_response_successful(response, subject)
192
+ return if response[:successful].blank?
193
+
194
+ case subject
195
+ when :category
196
+ t(
197
+ "projects.update_category.success",
198
+ subject_name: response[:subject_name],
199
+ projects: response[:successful].to_sentence,
200
+ scope: "decidim.budgets.admin"
201
+ )
202
+ when :scope
203
+ t(
204
+ "projects.update_scope.success",
205
+ subject_name: response[:subject_name],
206
+ projects: response[:successful].to_sentence,
207
+ scope: "decidim.budgets.admin"
208
+ )
209
+ when :selected
210
+ t(
211
+ "projects.update_selected.success",
212
+ subject_name: response[:subject_name],
213
+ projects: response[:successful].to_sentence,
214
+ scope: "decidim.budgets.admin"
215
+ )
216
+ end
217
+ end
218
+
219
+ def update_projects_bulk_response_errored(response, subject)
220
+ return if response[:errored].blank?
221
+
222
+ case subject
223
+ when :category
224
+ t(
225
+ "projects.update_category.invalid",
226
+ subject_name: response[:subject_name],
227
+ projects: response[:errored].to_sentence,
228
+ scope: "decidim.budgets.admin"
229
+ )
230
+ when :scope
231
+ t(
232
+ "projects.update_scope.invalid",
233
+ subject_name: response[:subject_name],
234
+ projects: response[:errored].to_sentence,
235
+ scope: "decidim.budgets.admin"
236
+ )
237
+ when :selected
238
+ t(
239
+ "projects.update_selected.invalid",
240
+ subject_name: response[:subject_name],
241
+ projects: response[:errored].to_sentence,
242
+ scope: "decidim.budgets.admin"
243
+ )
244
+ end
245
+ end
98
246
  end
99
247
  end
100
248
  end