decidim-budgets 0.29.2 → 0.30.0.rc2

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 (123) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/budgets/budget_list_item/vote_action.erb +2 -2
  3. data/app/cells/decidim/budgets/budgets_list/main_list.erb +1 -1
  4. data/app/cells/decidim/budgets/budgets_list/show.erb +1 -1
  5. data/app/cells/decidim/budgets/project_history_cell.rb +48 -0
  6. data/app/cells/decidim/budgets/project_metadata_cell.rb +3 -3
  7. data/app/cells/decidim/budgets/project_vote_button/show.erb +4 -2
  8. data/app/cells/decidim/budgets/project_vote_button_cell.rb +4 -0
  9. data/app/commands/decidim/budgets/admin/create_budget.rb +1 -1
  10. data/app/commands/decidim/budgets/admin/create_project.rb +1 -1
  11. data/app/commands/decidim/budgets/admin/import_proposals_to_budgets.rb +1 -8
  12. data/app/commands/decidim/budgets/admin/update_budget.rb +1 -1
  13. data/app/commands/decidim/budgets/admin/update_project.rb +2 -2
  14. data/app/commands/decidim/budgets/admin/update_project_selection.rb +1 -1
  15. data/app/controllers/concerns/decidim/budgets/admin/filterable.rb +7 -11
  16. data/app/controllers/decidim/budgets/admin/budgets_controller.rb +12 -15
  17. data/app/controllers/decidim/budgets/admin/projects_controller.rb +61 -85
  18. data/app/controllers/decidim/budgets/orders_controller.rb +7 -3
  19. data/app/controllers/decidim/budgets/projects_controller.rb +7 -16
  20. data/app/forms/decidim/budgets/admin/budget_form.rb +0 -17
  21. data/app/forms/decidim/budgets/admin/project_form.rb +7 -33
  22. data/app/forms/decidim/budgets/admin/project_import_proposals_form.rb +0 -11
  23. data/app/helpers/decidim/budgets/projects_helper.rb +6 -31
  24. data/app/models/decidim/budgets/budget.rb +2 -0
  25. data/app/models/decidim/budgets/project.rb +21 -1
  26. data/app/packs/stylesheets/budgets.scss +6 -4
  27. data/app/permissions/decidim/budgets/admin/permissions.rb +4 -4
  28. data/app/presenters/decidim/budgets/admin_log/budget_presenter.rb +1 -1
  29. data/app/presenters/decidim/budgets/admin_log/project_presenter.rb +1 -1
  30. data/app/presenters/decidim/budgets/project_presenter.rb +28 -0
  31. data/app/queries/decidim/budgets/filtered_projects.rb +2 -2
  32. data/app/queries/decidim/budgets/metrics/budget_followers_metric_measure.rb +2 -2
  33. data/app/queries/decidim/budgets/metrics/budget_participants_metric_measure.rb +2 -2
  34. data/app/serializers/decidim/budgets/download_your_data_budgets_order_serializer.rb +2 -2
  35. data/app/views/decidim/budgets/admin/budgets/_actions.html.erb +21 -0
  36. data/app/views/decidim/budgets/admin/budgets/_budget-tr.html.erb +18 -0
  37. data/app/views/decidim/budgets/admin/budgets/_budgets-thead.html.erb +8 -0
  38. data/app/views/decidim/budgets/admin/budgets/_form.html.erb +0 -6
  39. data/app/views/decidim/budgets/admin/budgets/index.html.erb +16 -48
  40. data/app/views/decidim/budgets/admin/budgets/manage_trash.html.erb +19 -0
  41. data/app/views/decidim/budgets/admin/projects/_actions.html.erb +27 -0
  42. data/app/views/decidim/budgets/admin/projects/_bulk-actions.html.erb +0 -2
  43. data/app/views/decidim/budgets/admin/projects/_form.html.erb +6 -8
  44. data/app/views/decidim/budgets/admin/projects/_project-tr.html.erb +2 -27
  45. data/app/views/decidim/budgets/admin/projects/_projects-thead.html.erb +14 -0
  46. data/app/views/decidim/budgets/admin/projects/bulk_actions/_dropdown.html.erb +7 -10
  47. data/app/views/decidim/budgets/admin/projects/bulk_actions/_taxonomy_change.html.erb +23 -0
  48. data/app/views/decidim/budgets/admin/projects/index.html.erb +19 -21
  49. data/app/views/decidim/budgets/admin/projects/manage_trash.html.erb +26 -0
  50. data/app/views/decidim/budgets/admin/projects/update_attribute.js.erb +1 -1
  51. data/app/views/decidim/budgets/admin/proposals_imports/new.html.erb +0 -5
  52. data/app/views/decidim/budgets/budgets/index.html.erb +7 -2
  53. data/app/views/decidim/budgets/order_summary_mailer/order_summary.html.erb +0 -10
  54. data/app/views/decidim/budgets/orders/status.html.erb +52 -0
  55. data/app/views/decidim/budgets/projects/_order.html.erb +1 -1
  56. data/app/views/decidim/budgets/projects/_order_progress_summary_content.html.erb +4 -4
  57. data/app/views/decidim/budgets/projects/index.html.erb +11 -18
  58. data/app/views/decidim/budgets/projects/index.js.erb +1 -1
  59. data/app/views/decidim/budgets/projects/show.html.erb +20 -10
  60. data/config/locales/ar.yml +3 -10
  61. data/config/locales/bg.yml +3 -43
  62. data/config/locales/ca.yml +95 -42
  63. data/config/locales/cs.yml +101 -42
  64. data/config/locales/de.yml +95 -42
  65. data/config/locales/el.yml +3 -39
  66. data/config/locales/en.yml +95 -42
  67. data/config/locales/es-MX.yml +95 -42
  68. data/config/locales/es-PY.yml +95 -42
  69. data/config/locales/es.yml +95 -42
  70. data/config/locales/eu.yml +95 -42
  71. data/config/locales/fi-plain.yml +95 -42
  72. data/config/locales/fi.yml +94 -41
  73. data/config/locales/fr-CA.yml +38 -44
  74. data/config/locales/fr.yml +38 -44
  75. data/config/locales/ga-IE.yml +0 -3
  76. data/config/locales/gl.yml +3 -7
  77. data/config/locales/hu.yml +3 -40
  78. data/config/locales/id-ID.yml +3 -3
  79. data/config/locales/is-IS.yml +0 -3
  80. data/config/locales/it.yml +3 -5
  81. data/config/locales/ja.yml +92 -42
  82. data/config/locales/kaa.yml +0 -1
  83. data/config/locales/ko.yml +0 -20
  84. data/config/locales/lb.yml +3 -5
  85. data/config/locales/lt.yml +3 -41
  86. data/config/locales/lv.yml +3 -3
  87. data/config/locales/nl.yml +3 -24
  88. data/config/locales/no.yml +3 -8
  89. data/config/locales/pl.yml +5 -43
  90. data/config/locales/pt-BR.yml +4 -43
  91. data/config/locales/pt.yml +3 -5
  92. data/config/locales/ro-RO.yml +3 -17
  93. data/config/locales/ru.yml +3 -3
  94. data/config/locales/sk.yml +3 -3
  95. data/config/locales/sq-AL.yml +0 -16
  96. data/config/locales/sv.yml +94 -41
  97. data/config/locales/tr-TR.yml +3 -5
  98. data/config/locales/uk.yml +3 -3
  99. data/config/locales/zh-CN.yml +3 -4
  100. data/config/locales/zh-TW.yml +3 -39
  101. data/db/migrate/20200827154129_add_commentable_counter_cache_to_projects.rb +1 -1
  102. data/db/migrate/20210310120613_add_followable_counter_cache_to_budgets.rb +1 -1
  103. data/db/migrate/20240828103724_add_deleted_at_to_decidim_budgets_budgets.rb +8 -0
  104. data/db/migrate/20240916135141_add_deleted_at_to_decidim_budgets_projects.rb +8 -0
  105. data/decidim-budgets.gemspec +1 -1
  106. data/lib/decidim/api/budget_type.rb +3 -6
  107. data/lib/decidim/api/budgets_type.rb +4 -5
  108. data/lib/decidim/api/project_type.rb +6 -8
  109. data/lib/decidim/budgets/admin_engine.rb +16 -2
  110. data/lib/decidim/budgets/component.rb +4 -5
  111. data/lib/decidim/budgets/engine.rb +1 -0
  112. data/lib/decidim/budgets/project_serializer.rb +16 -14
  113. data/lib/decidim/budgets/seeds.rb +0 -2
  114. data/lib/decidim/budgets/version.rb +1 -1
  115. metadata +27 -22
  116. data/app/cells/decidim/budgets/project_tags/show.erb +0 -5
  117. data/app/cells/decidim/budgets/project_tags_cell.rb +0 -18
  118. data/app/commands/decidim/budgets/admin/destroy_budget.rb +0 -17
  119. data/app/commands/decidim/budgets/admin/update_project_category.rb +0 -48
  120. data/app/commands/decidim/budgets/admin/update_project_scope.rb +0 -54
  121. data/app/helpers/decidim/budgets/admin/application_helper.rb +0 -13
  122. data/app/views/decidim/budgets/admin/projects/bulk_actions/_recategorize.html.erb +0 -15
  123. data/app/views/decidim/budgets/admin/projects/bulk_actions/_scope-change.html.erb +0 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8035323f2c92022b29c587c1ee9aa1e0fdfae190202d214ab365a9081dd045ea
4
- data.tar.gz: 5b0edaf8adf6a365a5bd37a39d8e821883cbd506ab44bfeadf177a1b500d14e3
3
+ metadata.gz: 2ac01f24906a4284045e39dd5103823bace918a7591111374f0aa98d1676ff5c
4
+ data.tar.gz: bc83d044d339f27a4b992cf7ca615516311aba70eea610e79d0d6accafbf265a
5
5
  SHA512:
6
- metadata.gz: 44dbca0151dd7d7c62a1b0117e0cf0b80dc9955456ca5cfae915bf08320e08c80f3fd0ca9075b01faa91f779c0974bcb523a9959488365f666a3b7fb495a304e
7
- data.tar.gz: f37767d2bc6185229a13ea5a5e8fc12b120a74f6b1381a73757c92b06ee768e71a6aa8551ab18e0e39f37620cff01a55516a26aa8e1472bbd82e753170ce0ede
6
+ metadata.gz: 32a8a05c435d72e6343b57ec7de96c84eb9c638b9f2fe17ab61304f822f59d633a12432b23af010a5e18b49d1cb99c08fd77738f46a8cfb19b348df3c129156f
7
+ data.tar.gz: 1df446122d0bd8dc3d10b2d81df279a1f6e79d378554c0a3a4e4dc5d1ae75e6b29b88d750ade3deb62cccd9a2c1d9f47f5e12e37ea5ad5dfc06ffe44adc6027c
@@ -5,8 +5,8 @@
5
5
  class: "pl-4",
6
6
  data: { confirm: t(:are_you_sure, scope: "decidim.budgets.projects.budget_summary") }
7
7
  ) do %>
8
- <%= icon "delete-bin-line", class: "inline-block align-middle text-gray fill-current" %>
9
- <span class="inline-block align-middle underline text-alert">
8
+ <%= icon "delete-bin-line", class: "inline-block align-middle text-gray fill-secondary" %>
9
+ <span class="inline-block align-middle underline text-secondary">
10
10
  <%= t("cancel_order", scope: "decidim.budgets.projects.budget_summary") %>
11
11
  </span>
12
12
  <% end %>
@@ -1,5 +1,5 @@
1
1
  <h2 class="h5 md:h3 decorator"><%= t(:count, scope: i18n_scope, count: budgets.length) %></h2>
2
2
 
3
- <%= render partial: "decidim/shared/orders", formats: [:html], locals: { orders: AVAILABLE_ORDERS, i18n_scope: "decidim.budgets.budgets_list.orders" } %>
3
+ <%= render partial: "decidim/shared/orders", formats: [:html], locals: { orders: AVAILABLE_ORDERS, i18n_scope: "decidim.budgets.budgets_list.orders", css_class: "items-start ml-6", b_css_class: "!justify-start pb-0 pl-0" } %>
4
4
 
5
5
  <%= render :card_list %>
@@ -7,7 +7,7 @@
7
7
  <% end %>
8
8
 
9
9
  <% if budgets.where.not(id: voted.map(&:id)).exists? %>
10
- <div id="budgets" class="card__list-list">
10
+ <div id="budgets" class="card__list-list !space-y-5 w-full">
11
11
  <%= main_list %>
12
12
  </div>
13
13
  <% end %>
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Budgets
5
+ # This cell is used to render the project history panel of a resource
6
+ # inside a tab of a show view
7
+ #
8
+ # The `model` must be a project's budget resource to get the history from.
9
+ #
10
+ # Example:
11
+ #
12
+ # cell(
13
+ # "decidim/project_history",
14
+ # budget
15
+ # )
16
+ class ProjectHistoryCell < Decidim::ResourceHistoryCell
17
+ def linked_resources_items
18
+ [
19
+ {
20
+ resources: @model.linked_resources(:proposals, "included_proposals"),
21
+ link_name: "included_proposals",
22
+ text_key: "decidim.proposals.proposal.budget_text",
23
+ icon_key: "Decidim::Proposals::Proposal"
24
+ },
25
+ {
26
+ resources: @model.linked_resources(:results, "included_projects"),
27
+ link_name: "included_projects",
28
+ text_key: "decidim.accountability.result.budget_text",
29
+ icon_key: "Decidim::Accountability::Result"
30
+ }
31
+ ]
32
+ end
33
+
34
+ def creation_item
35
+ {
36
+ id: "budget_creation",
37
+ date: @model.created_at,
38
+ text: t("decidim.budgets.creation.text"),
39
+ icon: resource_type_icon_key("Decidim::Budgets::Project")
40
+ }
41
+ end
42
+
43
+ def history_cell_id
44
+ "budget"
45
+ end
46
+ end
47
+ end
48
+ end
@@ -19,11 +19,11 @@ module Decidim
19
19
  private
20
20
 
21
21
  def project_items
22
- [voted_item, category_item, scope_item, status_item]
22
+ [voted_item] + taxonomy_items + [status_item]
23
23
  end
24
24
 
25
- def project_items_for_map
26
- [voted_item_for_map, category_item, scope_item].compact_blank.map do |item|
25
+ def items_for_map
26
+ ([voted_item_for_map] + taxonomy_items).compact_blank.map do |item|
27
27
  {
28
28
  text: item[:text].to_s.html_safe,
29
29
  icon: item[:icon].present? ? icon(item[:icon]).html_safe : nil
@@ -2,14 +2,16 @@
2
2
  budget_order_line_item_path(model.budget, project_id: model, show_only_added: options[:show_only_added]),
3
3
  method: vote_button_method,
4
4
  remote: true,
5
- class: "button w-full #{vote_button_classes}",
5
+ resource: model,
6
+ class: "button #{vote_button_classes}",
6
7
  id: "project-vote-button-#{model.id}",
7
8
  data: {
8
9
  add: !resource_added?,
9
10
  disable: true,
10
11
  budget: model.budget_amount,
11
12
  allocation: resource_allocation,
12
- "redirect-url": resource_path
13
+ "redirect-url": resource_path,
14
+ onboarding_redirect_path: resource_index_path
13
15
  },
14
16
  disabled: vote_button_disabled?,
15
17
  title: vote_button_label do %>
@@ -20,6 +20,10 @@ module Decidim
20
20
  resource_locator([model.budget, model]).path
21
21
  end
22
22
 
23
+ def resource_index_path
24
+ resource_locator(model.budget).path
25
+ end
26
+
23
27
  def resource_title
24
28
  translated_attribute model.title
25
29
  end
@@ -6,7 +6,7 @@ module Decidim
6
6
  # This command is executed when the user creates an Budget
7
7
  # from the admin panel.
8
8
  class CreateBudget < Decidim::Commands::CreateResource
9
- fetch_form_attributes :component, :scope, :title, :weight, :description, :total_budget
9
+ fetch_form_attributes :component, :title, :weight, :description, :total_budget
10
10
 
11
11
  private
12
12
 
@@ -7,7 +7,7 @@ module Decidim
7
7
  # panel.
8
8
  class CreateProject < Decidim::Commands::CreateResource
9
9
  include ::Decidim::GalleryMethods
10
- fetch_form_attributes :budget, :scope, :category, :title, :description, :budget_amount, :address, :latitude, :longitude
10
+ fetch_form_attributes :budget, :taxonomizations, :title, :description, :budget_amount, :address, :latitude, :longitude
11
11
 
12
12
  private
13
13
 
@@ -47,8 +47,7 @@ module Decidim
47
47
  title: original_proposal.title,
48
48
  description: original_proposal.body,
49
49
  budget_amount: budget_for(original_proposal),
50
- category: original_proposal.category,
51
- scope: original_proposal.scope,
50
+ taxonomies: original_proposal.taxonomies,
52
51
  address: original_proposal.address,
53
52
  latitude: original_proposal.latitude,
54
53
  longitude: original_proposal.longitude
@@ -69,12 +68,6 @@ module Decidim
69
68
  end
70
69
 
71
70
  def proposals
72
- return all_proposals if form.scope_id.blank?
73
-
74
- all_proposals.where(decidim_scope_id: form.scope_id)
75
- end
76
-
77
- def all_proposals
78
71
  Decidim::Proposals::Proposal.where(component: origin_component).published.not_hidden.not_withdrawn.accepted.order(:published_at)
79
72
  end
80
73
 
@@ -6,7 +6,7 @@ module Decidim
6
6
  # This command is executed when the user updates a Budget
7
7
  # from the admin panel.
8
8
  class UpdateBudget < Decidim::Commands::UpdateResource
9
- fetch_form_attributes :scope, :title, :weight, :description, :total_budget
9
+ fetch_form_attributes :title, :weight, :description, :total_budget
10
10
 
11
11
  protected
12
12
 
@@ -7,10 +7,10 @@ module Decidim
7
7
  # panel.
8
8
  class UpdateProject < Decidim::Commands::UpdateResource
9
9
  include ::Decidim::GalleryMethods
10
- fetch_form_attributes :scope, :category, :title, :description, :budget_amount, :address, :latitude, :longitude
10
+ fetch_form_attributes :taxonomizations, :title, :description, :budget_amount, :address, :latitude, :longitude
11
11
 
12
12
  def initialize(form, project)
13
- super(form, project)
13
+ super
14
14
  @attached_to = project
15
15
  end
16
16
 
@@ -24,7 +24,7 @@ module Decidim
24
24
 
25
25
  update_projects_selection
26
26
 
27
- broadcast(:update_projects_selection, @response)
27
+ broadcast(:update_projects_selection, @response, @selection)
28
28
  end
29
29
 
30
30
  private
@@ -16,7 +16,11 @@ module Decidim
16
16
  private
17
17
 
18
18
  def base_query
19
- collection
19
+ return collection unless taxonomy_order_or_search?
20
+
21
+ # this is a trick to avoid duplicates when using search in associations as suggested in:
22
+ # https://activerecord-hackery.github.io/ransack/going-further/other-notes/#problem-with-distinct-selects
23
+ collection.includes(:taxonomies).joins(:taxonomies)
20
24
  end
21
25
 
22
26
  def search_field_predicate
@@ -25,25 +29,17 @@ module Decidim
25
29
 
26
30
  def filters
27
31
  [
28
- :scope_id_eq,
29
- :category_id_eq,
32
+ :taxonomies_part_of_contains,
30
33
  :selected_at_null
31
34
  ]
32
35
  end
33
36
 
34
37
  def filters_with_values
35
38
  {
36
- scope_id_eq: scope_ids_hash(scopes.top_level),
37
- category_id_eq: category_ids_hash(categories.first_class),
39
+ taxonomies_part_of_contains: taxonomy_ids_hash(available_root_taxonomies),
38
40
  selected_at_null: [true, false]
39
41
  }
40
42
  end
41
-
42
- # Cannot user `super` here, because it does not belong to a superclass
43
- # but to a concern.
44
- def dynamically_translated_filters
45
- [:scope_id_eq, :category_id_eq]
46
- end
47
43
  end
48
44
  end
49
45
  end
@@ -5,6 +5,7 @@ module Decidim
5
5
  module Admin
6
6
  # This controller allows the create or update a budget.
7
7
  class BudgetsController < Admin::ApplicationController
8
+ include Decidim::Admin::HasTrashableResources
8
9
  helper_method :budgets, :budget, :finished_orders, :pending_orders,
9
10
  :users_with_pending_orders, :users_with_finished_orders
10
11
 
@@ -52,30 +53,26 @@ module Decidim
52
53
  end
53
54
  end
54
55
 
55
- def destroy
56
- enforce_permission_to(:delete, :budget, budget:)
57
-
58
- DestroyBudget.call(budget, current_user) do
59
- on(:ok) do
60
- flash[:notice] = I18n.t("budgets.destroy.success", scope: "decidim.budgets.admin")
61
- end
62
-
63
- on(:invalid) do
64
- flash.now[:alert] = I18n.t("budgets.destroy.invalid", scope: "decidim.budgets.admin")
65
- end
66
- end
56
+ private
67
57
 
68
- redirect_to budgets_path
58
+ def trashable_deleted_resource_type
59
+ :budget
69
60
  end
70
61
 
71
- private
62
+ def trashable_deleted_collection
63
+ @trashable_deleted_collection ||= Budget.where(component: current_component).only_deleted.deleted_at_desc
64
+ end
72
65
 
73
66
  def budgets
74
67
  @budgets ||= Budget.where(component: current_component).order(weight: :asc)
75
68
  end
76
69
 
77
70
  def budget
78
- @budget ||= budgets.find_by(id: params[:id])
71
+ @budget ||= Budget.where(component: current_component).find_by(id: params[:id])
72
+ end
73
+
74
+ def trashable_deleted_resource
75
+ @trashable_deleted_resource ||= Budget.with_deleted.find_by(component: current_component, id: params[:id])
79
76
  end
80
77
 
81
78
  def orders
@@ -6,6 +6,8 @@ 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::Admin::HasTrashableResources
10
+ include Decidim::Admin::ComponentTaxonomiesHelper
9
11
  include Decidim::Budgets::Admin::Filterable
10
12
  helper Decidim::Budgets::Admin::ProjectBulkActionsHelper
11
13
  helper Decidim::Budgets::ProjectsHelper
@@ -65,73 +67,37 @@ module Decidim
65
67
  end
66
68
  end
67
69
 
68
- def destroy
69
- enforce_permission_to(:destroy, :project, project:)
70
+ def update_taxonomies
71
+ enforce_permission_to :update, :project_taxonomy
70
72
 
71
- Decidim::Commands::DestroyResource.call(project, current_user) do
72
- on(:ok) do
73
- flash[:notice] = I18n.t("projects.destroy.success", scope: "decidim.budgets.admin")
74
- redirect_to budget_projects_path(budget)
75
- end
76
- end
77
- end
78
-
79
- def update_category
80
- enforce_permission_to :update, :project_category
81
-
82
- ::Decidim::Budgets::Admin::UpdateProjectCategory.call(params[:category][:id], project_ids) do
83
- on(:invalid_category) do
84
- flash.now[:error] = I18n.t(
85
- "projects.update_category.select_a_category",
86
- scope: "decidim.budgets.admin"
87
- )
88
- end
89
-
90
- on(:invalid_project_ids) do
91
- flash.now[:alert] = I18n.t(
92
- "projects.update_category.select_a_project",
73
+ UpdateResourcesTaxonomies.call(params[:taxonomies], Decidim::Budgets::Project.where(id: project_ids), current_organization) do
74
+ on(:invalid_taxonomies) do
75
+ flash[:error] = I18n.t(
76
+ "projects.update_taxonomies.select_a_taxonomy",
93
77
  scope: "decidim.budgets.admin"
94
78
  )
95
79
  end
96
80
 
97
- on(:update_projects_category) do
98
- flash.now[:notice] = update_projects_bulk_response_successful(@response, :category)
99
- flash.now[:alert] = update_projects_bulk_response_errored(@response, :category)
100
- end
101
- end
102
-
103
- respond_to do |format|
104
- format.js { render :update_attribute, locals: { form_selector: "#js-form-recategorize-projects", attribute_selector: "#category_id" } }
105
- end
106
- end
107
-
108
- def update_scope
109
- enforce_permission_to :update, :project_scope
110
-
111
- ::Decidim::Budgets::Admin::UpdateProjectScope.call(params[:scope_id], project_ids) do
112
- on(:invalid_scope) do
113
- flash.now[:error] = t(
114
- "projects.update_scope.select_a_scope",
81
+ on(:invalid_resources) do
82
+ flash[:alert] = I18n.t(
83
+ "projects.update_taxonomies.select_a_project",
115
84
  scope: "decidim.budgets.admin"
116
85
  )
117
86
  end
118
87
 
119
- on(:invalid_project_ids) do
120
- flash.now[:alert] = t(
121
- "projects.update_scope.select_a_project",
122
- scope: "decidim.budgets.admin"
123
- )
124
- end
88
+ on(:update_resources_taxonomies) do |response|
89
+ interpolations = {
90
+ successful: response[:successful].map { |resource| decidim_escape_translated(resource.title) }.to_sentence,
91
+ errored: response[:errored].map { |resource| decidim_escape_translated(resource.title) }.to_sentence,
92
+ taxonomies: response[:taxonomies].map { |taxonomy| decidim_escape_translated(taxonomy.name) }.to_sentence
93
+ }
125
94
 
126
- on(:update_projects_scope) do
127
- flash.now[:notice] = update_projects_bulk_response_successful(@response, :scope)
128
- flash.now[:alert] = update_projects_bulk_response_errored(@response, :scope)
95
+ flash[:notice] = update_projects_bulk_response_successful(interpolations, :taxonomy) if response[:successful].any?
96
+ flash[:alert] = update_projects_bulk_response_errored(interpolations, :taxonomy) if response[:errored].any?
129
97
  end
130
98
  end
131
99
 
132
- respond_to do |format|
133
- format.js { render :update_attribute, locals: { form_selector: "#js-form-scope-change-projects", attribute_selector: "#scope_id" } }
134
- end
100
+ redirect_to budget_projects_path
135
101
  end
136
102
 
137
103
  def update_selected
@@ -152,9 +118,15 @@ module Decidim
152
118
  )
153
119
  end
154
120
 
155
- on(:update_projects_selection) do
156
- flash.now[:notice] = update_projects_bulk_response_successful(@response, :selected, selection: @selection)
157
- flash.now[:alert] = update_projects_bulk_response_errored(@response, :selected, selection: @selection)
121
+ on(:update_projects_selection) do |response, selection|
122
+ interpolations = {
123
+ subject_name: response[:subject_name],
124
+ successful: response[:successful].to_sentence,
125
+ errored: response[:errored].to_sentence
126
+ }
127
+
128
+ flash.now[:notice] = update_projects_bulk_response_successful(interpolations, :selected, selection:) if response[:successful].any?
129
+ flash.now[:alert] = update_projects_bulk_response_errored(interpolations, :selected, selection:) if response[:errored].any?
158
130
  end
159
131
  end
160
132
 
@@ -170,10 +142,16 @@ module Decidim
170
142
  flash.now[:alert] = t("projects.update_budget.select_a_project", scope: "decidim.budgets.admin")
171
143
  end
172
144
 
173
- on(:update_projects_budget) do
174
- moved_items(@response)
175
- flash.now[:notice] = update_projects_bulk_response_successful(@response, :budget)
176
- flash.now[:alert] = update_projects_bulk_response_errored(@response, :budget)
145
+ on(:update_projects_budget) do |response|
146
+ moved_items(response)
147
+ interpolations = {
148
+ subject_name: response[:subject_name],
149
+ successful: response[:successful].to_sentence,
150
+ errored: response[:errored].to_sentence
151
+ }
152
+
153
+ flash.now[:notice] = update_projects_bulk_response_successful(interpolations, :budget) if response[:successful].any?
154
+ flash.now[:alert] = update_projects_bulk_response_errored(interpolations, :budget) if response[:errored].any?
177
155
  end
178
156
  end
179
157
 
@@ -184,6 +162,18 @@ module Decidim
184
162
 
185
163
  private
186
164
 
165
+ def trashable_deleted_resource_type
166
+ :project
167
+ end
168
+
169
+ def trashable_deleted_collection
170
+ @trashable_deleted_collection ||= filtered_collection.only_deleted.deleted_at_desc
171
+ end
172
+
173
+ def find_parent_resource
174
+ @find_parent_resource ||= budget
175
+ end
176
+
187
177
  def projects
188
178
  @projects ||= filtered_collection
189
179
  end
@@ -217,22 +207,17 @@ module Decidim
217
207
  end
218
208
 
219
209
  def project
220
- @project ||= projects.find(params[:id])
210
+ @project ||= filtered_collection.find_by(id: params[:id])
221
211
  end
222
212
 
223
- def update_projects_bulk_response_successful(response, subject, extra = {})
224
- return if response[:successful].blank?
225
-
226
- interpolations = {
227
- subject_name: response[:subject_name],
228
- projects: response[:successful].to_sentence
229
- }
213
+ def trashable_deleted_resource
214
+ @trashable_deleted_resource ||= filtered_collection.with_deleted.find_by(id: params[:id])
215
+ end
230
216
 
217
+ def update_projects_bulk_response_successful(interpolations, subject, extra = {})
231
218
  case subject
232
- when :category
233
- t("projects.update_category.success", scope: "decidim.budgets.admin", **interpolations)
234
- when :scope
235
- t("projects.update_scope.success", scope: "decidim.budgets.admin", **interpolations)
219
+ when :taxonomy
220
+ t("projects.update_taxonomies.success", scope: "decidim.budgets.admin", **interpolations)
236
221
  when :budget
237
222
  t("projects.update_budget.success", scope: "decidim.budgets.admin", **interpolations)
238
223
  when :selected
@@ -244,19 +229,10 @@ module Decidim
244
229
  end
245
230
  end
246
231
 
247
- def update_projects_bulk_response_errored(response, subject, extra = {})
248
- return if response[:errored].blank?
249
-
250
- interpolations = {
251
- subject_name: response[:subject_name],
252
- projects: response[:errored].to_sentence
253
- }
254
-
232
+ def update_projects_bulk_response_errored(interpolations, subject, extra = {})
255
233
  case subject
256
- when :category
257
- t("projects.update_category.invalid", scope: "decidim.budgets.admin", **interpolations)
258
- when :scope
259
- t("projects.update_scope.invalid", scope: "decidim.budgets.admin", **interpolations)
234
+ when :taxonomy
235
+ t("projects.update_taxonomies.invalid", scope: "decidim.budgets.admin", **interpolations)
260
236
  when :budget
261
237
  t("projects.update_budget.invalid", scope: "decidim.budgets.admin", **interpolations)
262
238
  when :selected
@@ -6,14 +6,14 @@ module Decidim
6
6
  class OrdersController < Decidim::Budgets::ApplicationController
7
7
  include NeedsCurrentOrder
8
8
 
9
+ helper_method :pending_to_vote_budgets
10
+
9
11
  def checkout
10
12
  enforce_permission_to :vote, :project, order: current_order, budget:, workflow: current_workflow
11
13
 
12
14
  Checkout.call(current_order) do
13
15
  on(:ok) do
14
- i18n_key = pending_to_vote_budgets.any? ? "success_html" : "success_no_left_budgets_html"
15
- flash[:notice] = I18n.t(i18n_key, scope: "decidim.orders.checkout", rest_of_budgets_link: "#budgets")
16
- redirect_to budgets_path
16
+ redirect_to status_budget_order_path(budget)
17
17
  end
18
18
 
19
19
  on(:invalid) do
@@ -37,6 +37,10 @@ module Decidim
37
37
  end
38
38
  end
39
39
 
40
+ def status
41
+ redirect_to redirect_path unless current_order.persisted?
42
+ end
43
+
40
44
  private
41
45
 
42
46
  def budget
@@ -42,15 +42,14 @@ module Decidim
42
42
  end
43
43
 
44
44
  def search_collection
45
- budget.projects.includes([:scope, :component, :attachments, :category]).with_order(filter_params[:addition_type] == "added" ? current_order : nil)
45
+ budget.projects.includes([:component, :attachments, :taxonomies]).with_order(filter_params[:addition_type] == "added" ? current_order : nil)
46
46
  end
47
47
 
48
48
  def default_filter_params
49
49
  {
50
50
  search_text_cont: "",
51
51
  with_any_status: default_filter_status_params,
52
- with_any_scope: nil,
53
- with_any_category: nil,
52
+ with_any_taxonomies: nil,
54
53
  addition_type: "all"
55
54
  }
56
55
  end
@@ -74,20 +73,12 @@ module Decidim
74
73
  def items
75
74
  @items ||= [
76
75
  {
77
- enabled: @project.linked_resources(:proposals, "included_proposals").present?,
78
- id: "included_proposals",
79
- text: t("decidim/proposals/proposal", scope: "activerecord.models", count: 2),
80
- icon: resource_type_icon_key("Decidim::Budgets::Project"),
76
+ enabled: ProjectHistoryCell.new(@project).render?,
77
+ id: "included_history",
78
+ text: t("decidim.history", scope: "activerecord.models", count: 2),
79
+ icon: resource_type_icon_key("history"),
81
80
  method: :cell,
82
- args: ["decidim/linked_resources_for", @project, { type: :proposals, link_name: "included_proposals" }]
83
- },
84
- {
85
- enabled: @project.linked_resources(:results, "included_projects").present?,
86
- id: "included_results",
87
- text: t("decidim/accountability/result", scope: "activerecord.models", count: 2),
88
- icon: resource_type_icon_key("Decidim::Accountability::Result"),
89
- method: :cell,
90
- args: ["decidim/linked_resources_for", @project, { type: :results, link_name: "included_projects" }]
81
+ args: ["decidim/budgets/project_history", @project]
91
82
  },
92
83
  {
93
84
  enabled: @project.photos.present?,
@@ -13,27 +13,10 @@ module Decidim
13
13
  attribute :weight, Integer, default: 0
14
14
  translatable_attribute :description, Decidim::Attributes::RichText
15
15
  attribute :total_budget, Integer, default: 0
16
- attribute :decidim_scope_id, Integer
17
16
 
18
17
  validates :title, translatable_presence: true
19
18
  validates :weight, numericality: { greater_than_or_equal_to: 0 }
20
19
  validates :total_budget, numericality: { greater_than: 0 }
21
- validates :scope, presence: true, if: ->(form) { form.decidim_scope_id.present? }
22
- validates :decidim_scope_id, scope_belongs_to_component: true, if: ->(form) { form.decidim_scope_id.present? }
23
-
24
- # Finds the Scope from the given decidim_scope_id, uses the component scope if missing.
25
- #
26
- # Returns a Decidim::Scope
27
- def scope
28
- @scope ||= @attributes["decidim_scope_id"].value ? current_component.scopes.find_by(id: @attributes["decidim_scope_id"].value) : current_component.scope
29
- end
30
-
31
- # Scope identifier
32
- #
33
- # Returns the scope identifier related to the meeting
34
- def decidim_scope_id
35
- super || scope&.id
36
- end
37
20
  end
38
21
  end
39
22
  end