decidim-budgets 0.22.0 → 0.23.0

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 (171) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +38 -3
  3. data/app/assets/stylesheets/decidim/budgets/budget/_budget-list.scss +5 -0
  4. data/app/cells/decidim/budgets/base_cell.rb +22 -0
  5. data/app/cells/decidim/budgets/budget_cell.rb +21 -0
  6. data/app/cells/decidim/budgets/budget_information_modal/show.erb +28 -0
  7. data/app/cells/decidim/budgets/budget_information_modal_cell.rb +22 -0
  8. data/app/cells/decidim/budgets/budget_list_item/show.erb +22 -0
  9. data/app/cells/decidim/budgets/budget_list_item_cell.rb +40 -0
  10. data/app/cells/decidim/budgets/budget_m/data.erb +12 -0
  11. data/app/cells/decidim/budgets/budget_m/footer.erb +5 -0
  12. data/app/cells/decidim/budgets/budget_m_cell.rb +16 -0
  13. data/app/cells/decidim/budgets/budgets_header/show.erb +7 -0
  14. data/app/cells/decidim/budgets/budgets_header_cell.rb +14 -0
  15. data/app/cells/decidim/budgets/budgets_list/card_list.erb +7 -0
  16. data/app/cells/decidim/budgets/budgets_list/highlighted.erb +11 -0
  17. data/app/cells/decidim/budgets/budgets_list/show.erb +20 -0
  18. data/app/cells/decidim/budgets/budgets_list/voted.erb +43 -0
  19. data/app/cells/decidim/budgets/budgets_list_cell.rb +39 -0
  20. data/app/cells/decidim/budgets/limit_announcement_cell.rb +52 -0
  21. data/app/cells/decidim/budgets/project_list_item/project_data.erb +17 -3
  22. data/app/cells/decidim/budgets/project_list_item/project_data_vote_button.erb +2 -2
  23. data/app/cells/decidim/budgets/project_list_item/project_text.erb +11 -5
  24. data/app/cells/decidim/budgets/project_list_item/show.erb +3 -3
  25. data/app/cells/decidim/budgets/project_list_item_cell.rb +8 -28
  26. data/app/cells/decidim/budgets/project_m/data.erb +1 -1
  27. data/app/cells/decidim/budgets/project_m_cell.rb +4 -0
  28. data/app/cells/decidim/budgets/project_selected_status_cell.rb +28 -0
  29. data/app/cells/decidim/budgets/project_tags/show.erb +5 -0
  30. data/app/cells/decidim/budgets/project_tags_cell.rb +18 -0
  31. data/app/cells/decidim/budgets/project_voted_hint_cell.rb +33 -0
  32. data/app/cells/decidim/budgets/project_votes_count_cell.rb +44 -0
  33. data/app/commands/decidim/budgets/add_line_item.rb +7 -10
  34. data/app/commands/decidim/budgets/admin/create_budget.rb +48 -0
  35. data/app/commands/decidim/budgets/admin/create_project.rb +12 -7
  36. data/app/commands/decidim/budgets/admin/destroy_budget.rb +42 -0
  37. data/app/commands/decidim/budgets/admin/import_proposals_to_budgets.rb +26 -25
  38. data/app/commands/decidim/budgets/admin/update_budget.rb +48 -0
  39. data/app/commands/decidim/budgets/admin/update_project.rb +8 -1
  40. data/app/commands/decidim/budgets/checkout.rb +6 -6
  41. data/app/commands/decidim/budgets/remove_line_item.rb +3 -2
  42. data/app/controllers/concerns/decidim/budgets/needs_current_order.rb +14 -2
  43. data/app/controllers/concerns/decidim/budgets/orderable.rb +3 -7
  44. data/app/controllers/decidim/budgets/admin/application_controller.rb +10 -2
  45. data/app/controllers/decidim/budgets/admin/attachment_collections_controller.rb +1 -1
  46. data/app/controllers/decidim/budgets/admin/attachments_controller.rb +2 -2
  47. data/app/controllers/decidim/budgets/admin/budgets_controller.rb +82 -0
  48. data/app/controllers/decidim/budgets/admin/projects_controller.rb +7 -7
  49. data/app/controllers/decidim/budgets/admin/proposals_imports_controller.rb +10 -2
  50. data/app/controllers/decidim/budgets/application_controller.rb +23 -0
  51. data/app/controllers/decidim/budgets/budgets_controller.rb +24 -0
  52. data/app/controllers/decidim/budgets/line_items_controller.rb +9 -5
  53. data/app/controllers/decidim/budgets/orders_controller.rb +20 -6
  54. data/app/controllers/decidim/budgets/projects_controller.rb +19 -18
  55. data/app/forms/decidim/budgets/admin/budget_form.rb +39 -0
  56. data/app/forms/decidim/budgets/admin/project_form.rb +14 -10
  57. data/app/forms/decidim/budgets/admin/project_import_proposals_form.rb +4 -0
  58. data/app/helpers/decidim/budgets/admin/application_helper.rb +13 -0
  59. data/app/helpers/decidim/budgets/application_helper.rb +10 -0
  60. data/app/helpers/decidim/budgets/projects_helper.rb +0 -4
  61. data/app/mailers/decidim/budgets/order_summary_mailer.rb +5 -3
  62. data/app/models/decidim/budgets/budget.rb +34 -0
  63. data/app/models/decidim/budgets/line_item.rb +4 -4
  64. data/app/models/decidim/budgets/order.rb +22 -19
  65. data/app/models/decidim/budgets/project.rb +34 -5
  66. data/app/permissions/decidim/budgets/admin/permissions.rb +23 -10
  67. data/app/permissions/decidim/budgets/permissions.rb +28 -6
  68. data/app/presenters/decidim/budgets/admin_log/budget_presenter.rb +42 -0
  69. data/app/queries/decidim/budgets/filtered_projects.rb +9 -1
  70. data/app/queries/decidim/budgets/metrics/budget_followers_metric_measure.rb +3 -2
  71. data/app/queries/decidim/budgets/metrics/budget_participants_metric_measure.rb +6 -5
  72. data/app/serializers/decidim/budgets/data_portability_budgets_order_serializer.rb +3 -2
  73. data/app/services/decidim/budgets/project_search.rb +12 -24
  74. data/app/types/decidim/budgets/budget_type.rb +24 -0
  75. data/app/types/decidim/budgets/budgets_type.rb +6 -6
  76. data/app/types/decidim/budgets/project_type.rb +2 -1
  77. data/app/views/decidim/budgets/admin/budgets/_form.html.erb +23 -0
  78. data/app/views/decidim/budgets/admin/budgets/edit.html.erb +7 -0
  79. data/app/views/decidim/budgets/admin/budgets/index.html.erb +58 -0
  80. data/app/views/decidim/budgets/admin/budgets/new.html.erb +7 -0
  81. data/app/views/decidim/budgets/admin/projects/_form.html.erb +12 -4
  82. data/app/views/decidim/budgets/admin/projects/edit.html.erb +2 -2
  83. data/app/views/decidim/budgets/admin/projects/index.html.erb +20 -7
  84. data/app/views/decidim/budgets/admin/projects/new.html.erb +2 -2
  85. data/app/views/decidim/budgets/admin/proposals_imports/new.html.erb +1 -1
  86. data/app/views/decidim/budgets/budgets/index.html.erb +5 -0
  87. data/app/views/decidim/budgets/order_summary_mailer/order_summary.html.erb +1 -0
  88. data/app/views/decidim/budgets/projects/_budget_confirm.html.erb +3 -3
  89. data/app/views/decidim/budgets/projects/_budget_summary.html.erb +19 -6
  90. data/app/views/decidim/budgets/projects/_filters.html.erb +6 -2
  91. data/app/views/decidim/budgets/projects/_linked_projects.html.erb +1 -1
  92. data/app/views/decidim/budgets/projects/_order_progress.html.erb +10 -6
  93. data/app/views/decidim/budgets/projects/_order_selected_projects.html.erb +3 -3
  94. data/app/views/decidim/budgets/projects/_project_budget_button.html.erb +36 -7
  95. data/app/views/decidim/budgets/projects/index.html.erb +12 -4
  96. data/app/views/decidim/budgets/projects/show.html.erb +17 -10
  97. data/config/locales/am-ET.yml +1 -0
  98. data/config/locales/ar.yml +2 -11
  99. data/config/locales/bg.yml +6 -0
  100. data/config/locales/ca.yml +102 -10
  101. data/config/locales/cs.yml +105 -13
  102. data/config/locales/da.yml +1 -0
  103. data/config/locales/de.yml +90 -9
  104. data/config/locales/el.yml +3 -9
  105. data/config/locales/en.yml +101 -9
  106. data/config/locales/eo.yml +1 -0
  107. data/config/locales/es-MX.yml +101 -9
  108. data/config/locales/es-PY.yml +101 -9
  109. data/config/locales/es.yml +102 -10
  110. data/config/locales/et.yml +1 -0
  111. data/config/locales/eu.yml +3 -8
  112. data/config/locales/fi-plain.yml +102 -10
  113. data/config/locales/fi.yml +103 -11
  114. data/config/locales/fr-CA.yml +100 -9
  115. data/config/locales/fr.yml +100 -9
  116. data/config/locales/gl.yml +2 -7
  117. data/config/locales/hr.yml +1 -0
  118. data/config/locales/hu.yml +2 -7
  119. data/config/locales/id-ID.yml +2 -6
  120. data/config/locales/is-IS.yml +0 -6
  121. data/config/locales/is.yml +114 -0
  122. data/config/locales/it.yml +71 -9
  123. data/config/locales/ja-JP.yml +1 -0
  124. data/config/locales/ja.yml +262 -0
  125. data/config/locales/ko-KR.yml +1 -0
  126. data/config/locales/ko.yml +1 -0
  127. data/config/locales/lt.yml +1 -0
  128. data/config/locales/{lv-LV.yml → lv.yml} +2 -10
  129. data/config/locales/mt.yml +1 -0
  130. data/config/locales/nl.yml +88 -10
  131. data/config/locales/no.yml +22 -9
  132. data/config/locales/om-ET.yml +1 -0
  133. data/config/locales/pl.yml +113 -22
  134. data/config/locales/pt-BR.yml +2 -7
  135. data/config/locales/pt.yml +3 -9
  136. data/config/locales/ro-RO.yml +3 -10
  137. data/config/locales/ru.yml +2 -9
  138. data/config/locales/sk.yml +2 -11
  139. data/config/locales/sl.yml +0 -4
  140. data/config/locales/so-SO.yml +1 -0
  141. data/config/locales/sr-CS.yml +0 -2
  142. data/config/locales/sv.yml +80 -9
  143. data/config/locales/ti-ER.yml +1 -0
  144. data/config/locales/tr-TR.yml +2 -7
  145. data/config/locales/uk.yml +2 -9
  146. data/config/locales/vi-VN.yml +1 -0
  147. data/config/locales/vi.yml +1 -0
  148. data/config/locales/zh-CN.yml +260 -0
  149. data/config/locales/zh-TW.yml +1 -0
  150. data/db/migrate/20200617105120_create_decidim_budgets.rb +15 -0
  151. data/db/migrate/20200629072626_rename_budget_to_budget_ammount.rb +7 -0
  152. data/db/migrate/20200629134013_add_budget_reference_to_project.rb +7 -0
  153. data/db/migrate/20200706142609_add_budget_reference_to_order.rb +7 -0
  154. data/db/migrate/20200714103519_move_budgets_to_own_model.rb +109 -0
  155. data/db/migrate/20200717140012_add_scope_to_budgets.rb +7 -0
  156. data/db/migrate/20200728075039_add_selected_at_to_project.rb +7 -0
  157. data/db/migrate/20200804175222_votes_enabled_to_votes_choices.rb +35 -0
  158. data/db/migrate/20200827154129_add_commentable_counter_cache_to_projects.rb +9 -0
  159. data/lib/decidim/budgets.rb +1 -0
  160. data/lib/decidim/budgets/admin_engine.rb +10 -5
  161. data/lib/decidim/budgets/component.rb +83 -38
  162. data/lib/decidim/budgets/engine.rb +8 -6
  163. data/lib/decidim/budgets/test/factories.rb +42 -13
  164. data/lib/decidim/budgets/version.rb +1 -1
  165. data/lib/decidim/budgets/workflows.rb +17 -0
  166. data/lib/decidim/budgets/workflows/all.rb +20 -0
  167. data/lib/decidim/budgets/workflows/base.rb +132 -0
  168. data/lib/decidim/budgets/workflows/one.rb +33 -0
  169. metadata +84 -17
  170. data/app/cells/decidim/budgets/project_list_item/project_data_number.erb +0 -3
  171. data/app/cells/decidim/budgets/project_list_item/project_data_votes.erb +0 -7
@@ -4,6 +4,8 @@ module Decidim
4
4
  module Budgets
5
5
  module Admin
6
6
  class ProposalsImportsController < Admin::ApplicationController
7
+ helper_method :budget
8
+
7
9
  def new
8
10
  enforce_permission_to :import_proposals, :projects
9
11
 
@@ -13,11 +15,11 @@ module Decidim
13
15
  def create
14
16
  enforce_permission_to :import_proposals, :projects
15
17
 
16
- @form = form(Admin::ProjectImportProposalsForm).from_params(params)
18
+ @form = form(Admin::ProjectImportProposalsForm).from_params(params, budget: budget)
17
19
  Admin::ImportProposalsToBudgets.call(@form) do
18
20
  on(:ok) do |projects|
19
21
  flash[:notice] = I18n.t("proposals_imports.create.success", scope: "decidim.budgets.admin", number: projects.length)
20
- redirect_to EngineRouter.admin_proxy(current_component).root_path
22
+ redirect_to budget_projects_path(budget)
21
23
  end
22
24
 
23
25
  on(:invalid) do
@@ -26,6 +28,12 @@ module Decidim
26
28
  end
27
29
  end
28
30
  end
31
+
32
+ private
33
+
34
+ def budget
35
+ @budget ||= Budget.where(component: current_component).find_by(id: params[:budget_id])
36
+ end
29
37
  end
30
38
  end
31
39
  end
@@ -8,6 +8,29 @@ module Decidim
8
8
  # Note that it inherits from `Decidim::Components::BaseController`, which
9
9
  # override its layout and provide all kinds of useful methods.
10
10
  class ApplicationController < Decidim::Components::BaseController
11
+ helper_method :current_workflow, :voting_finished?, :voting_open?
12
+
13
+ def current_workflow
14
+ @current_workflow ||= Decidim::Budgets.workflows[workflow_name].new(current_component, current_user)
15
+ end
16
+
17
+ def voting_open?
18
+ current_settings.votes == "enabled"
19
+ end
20
+
21
+ def voting_finished?
22
+ current_settings.votes == "finished"
23
+ end
24
+
25
+ def show_votes_count?
26
+ current_settings.show_votes?
27
+ end
28
+
29
+ private
30
+
31
+ def workflow_name
32
+ @workflow_name ||= current_component.settings.workflow.to_sym
33
+ end
11
34
  end
12
35
  end
13
36
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Budgets
5
+ # Exposes the budget resources so users can participate on them
6
+ class BudgetsController < Decidim::Budgets::ApplicationController
7
+ def index
8
+ redirect_to budget_projects_path(current_workflow.single) if current_workflow.single?
9
+ end
10
+
11
+ def show
12
+ raise ActionController::RoutingError, "Not Found" unless budget
13
+
14
+ redirect_to budget_projects_path(budget)
15
+ end
16
+
17
+ private
18
+
19
+ def budget
20
+ @budget ||= Budget.where(component: current_component).includes(:projects).find_by(id: params[:id])
21
+ end
22
+ end
23
+ end
24
+ end
@@ -6,16 +6,16 @@ module Decidim
6
6
  class LineItemsController < Decidim::Budgets::ApplicationController
7
7
  include NeedsCurrentOrder
8
8
 
9
- helper_method :project
9
+ helper_method :budget, :project
10
10
 
11
11
  def create
12
- enforce_permission_to :vote, :project, project: project
12
+ enforce_permission_to :vote, :project, project: project, budget: budget, workflow: current_workflow
13
13
 
14
14
  respond_to do |format|
15
15
  AddLineItem.call(persisted_current_order, project, current_user) do
16
16
  on(:ok) do |order|
17
17
  self.current_order = order
18
- format.html { redirect_to :back }
18
+ format.html { redirect_back(fallback_location: budget_path(budget)) }
19
19
  format.js { render "update_budget" }
20
20
  end
21
21
 
@@ -30,7 +30,7 @@ module Decidim
30
30
  respond_to do |format|
31
31
  RemoveLineItem.call(current_order, project) do
32
32
  on(:ok) do |_order|
33
- format.html { redirect_to :back }
33
+ format.html { redirect_back(fallback_location: budget_path(budget)) }
34
34
  format.js { render "update_budget" }
35
35
  end
36
36
 
@@ -44,7 +44,11 @@ module Decidim
44
44
  private
45
45
 
46
46
  def project
47
- @project ||= Project.find_by(id: params[:project_id], component: current_component)
47
+ @project ||= Project.includes(:budget).find_by(id: params[:project_id], decidim_budgets_budget_id: params[:budget_id])
48
+ end
49
+
50
+ def budget
51
+ @budget ||= project.budget
48
52
  end
49
53
  end
50
54
  end
@@ -7,17 +7,17 @@ module Decidim
7
7
  include NeedsCurrentOrder
8
8
 
9
9
  def checkout
10
- enforce_permission_to :vote, :project, order: current_order
10
+ enforce_permission_to :vote, :project, order: current_order, budget: budget, workflow: current_workflow
11
11
 
12
- Checkout.call(current_order, current_component) do
12
+ Checkout.call(current_order) do
13
13
  on(:ok) do
14
14
  flash[:notice] = I18n.t("orders.checkout.success", scope: "decidim")
15
- redirect_to projects_path
15
+ redirect_to budgets_path
16
16
  end
17
17
 
18
18
  on(:invalid) do
19
19
  flash.now[:alert] = I18n.t("orders.checkout.error", scope: "decidim")
20
- redirect_to projects_path
20
+ redirect_to budgets_path
21
21
  end
22
22
  end
23
23
  end
@@ -26,15 +26,29 @@ module Decidim
26
26
  CancelOrder.call(current_order) do
27
27
  on(:ok) do
28
28
  flash[:notice] = I18n.t("orders.destroy.success", scope: "decidim")
29
- redirect_to projects_path
29
+ redirect_to redirect_path
30
30
  end
31
31
 
32
32
  on(:invalid) do
33
33
  flash.now[:alert] = I18n.t("orders.destroy.error", scope: "decidim")
34
- redirect_to projects_path
34
+ redirect_to redirect_path
35
35
  end
36
36
  end
37
37
  end
38
+
39
+ private
40
+
41
+ def budget
42
+ @budget ||= Budget.find_by(id: params[:budget_id])
43
+ end
44
+
45
+ def redirect_path
46
+ if params.dig(:return_to) == "budget"
47
+ budget_path(budget)
48
+ else
49
+ budgets_path
50
+ end
51
+ end
38
52
  end
39
53
  end
40
54
  end
@@ -6,13 +6,25 @@ module Decidim
6
6
  class ProjectsController < Decidim::Budgets::ApplicationController
7
7
  include FilterResource
8
8
  include NeedsCurrentOrder
9
- include Orderable
10
9
  include Decidim::Budgets::Orderable
11
10
 
12
- helper_method :projects, :project
11
+ helper_method :projects, :project, :budget
12
+
13
+ def index
14
+ raise ActionController::RoutingError, "Not Found" unless budget
15
+ end
16
+
17
+ def show
18
+ raise ActionController::RoutingError, "Not Found" unless budget
19
+ raise ActionController::RoutingError, "Not Found" unless project
20
+ end
13
21
 
14
22
  private
15
23
 
24
+ def budget
25
+ @budget ||= Budget.where(component: current_component).includes(:projects).find_by(id: params[:budget_id])
26
+ end
27
+
16
28
  def projects
17
29
  return @projects if @projects
18
30
 
@@ -21,7 +33,7 @@ module Decidim
21
33
  end
22
34
 
23
35
  def project
24
- @project ||= search.results.find(params[:id])
36
+ @project ||= Project.find_by(id: params[:id])
25
37
  end
26
38
 
27
39
  def search_klass
@@ -31,29 +43,18 @@ module Decidim
31
43
  def default_filter_params
32
44
  {
33
45
  search_text: "",
46
+ status: default_filter_status_params,
34
47
  scope_id: default_filter_scope_params,
35
48
  category_id: default_filter_category_params
36
49
  }
37
50
  end
38
51
 
39
- def default_filter_category_params
40
- return "all" unless current_component.participatory_space.categories.any?
41
-
42
- ["all"] + current_component.participatory_space.categories.map { |category| category.id.to_s }
43
- end
44
-
45
- def default_filter_scope_params
46
- return "all" unless current_component.participatory_space.scopes.any?
47
-
48
- if current_component.participatory_space.scope
49
- ["all", current_component.participatory_space.scope.id] + current_component.participatory_space.scope.children.map { |scope| scope.id.to_s }
50
- else
51
- %w(all global) + current_component.participatory_space.scopes.map { |scope| scope.id.to_s }
52
- end
52
+ def default_filter_status_params
53
+ voting_finished? ? %w(selected) : %w(all)
53
54
  end
54
55
 
55
56
  def context_params
56
- { component: current_component, organization: current_organization }
57
+ { budget: budget, component: current_component, organization: current_organization }
57
58
  end
58
59
  end
59
60
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Budgets
5
+ module Admin
6
+ # This class holds a Form to create/update budgets from Decidim's admin panel.
7
+ class BudgetForm < Decidim::Form
8
+ include TranslatableAttributes
9
+
10
+ mimic :budget
11
+
12
+ translatable_attribute :title, String
13
+ attribute :weight, Integer, default: 0
14
+ translatable_attribute :description, String
15
+ attribute :total_budget, Integer, default: 0
16
+ attribute :decidim_scope_id, Integer
17
+
18
+ validates :title, translatable_presence: true
19
+ validates :weight, :total_budget, numericality: { greater_than_or_equal_to: 0 }
20
+ validates :scope, presence: true, if: ->(form) { form.decidim_scope_id.present? }
21
+ validates :decidim_scope_id, scope_belongs_to_component: true, if: ->(form) { form.decidim_scope_id.present? }
22
+
23
+ # Finds the Scope from the given decidim_scope_id, uses the compoenent scope if missing.
24
+ #
25
+ # Returns a Decidim::Scope
26
+ def scope
27
+ @scope ||= @decidim_scope_id ? current_component.scopes.find_by(id: @decidim_scope_id) : current_component.scope
28
+ end
29
+
30
+ # Scope identifier
31
+ #
32
+ # Returns the scope identifier related to the meeting
33
+ def decidim_scope_id
34
+ @decidim_scope_id || scope&.id
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -12,22 +12,22 @@ module Decidim
12
12
  translatable_attribute :title, String
13
13
  translatable_attribute :description, String
14
14
 
15
- attribute :budget, Integer
15
+ attribute :budget_amount, Integer
16
16
  attribute :decidim_scope_id, Integer
17
17
  attribute :decidim_category_id, Integer
18
18
  attribute :proposal_ids, Array[Integer]
19
19
  attribute :attachment, AttachmentForm
20
20
  attribute :photos, Array[String]
21
21
  attribute :add_photos, Array
22
+ attribute :selected, Boolean
22
23
 
23
24
  validates :title, translatable_presence: true
24
25
  validates :description, translatable_presence: true
25
- validates :budget, presence: true, numericality: { greater_than: 0 }
26
+ validates :budget_amount, presence: true, numericality: { greater_than: 0 }
26
27
 
27
28
  validates :category, presence: true, if: ->(form) { form.decidim_category_id.present? }
28
29
  validates :scope, presence: true, if: ->(form) { form.decidim_scope_id.present? }
29
-
30
- validate :scope_belongs_to_participatory_space_scope
30
+ validates :decidim_scope_id, scope_belongs_to_component: true, if: ->(form) { form.decidim_scope_id.present? }
31
31
 
32
32
  validate :notify_missing_attachment_if_errored
33
33
 
@@ -35,6 +35,7 @@ module Decidim
35
35
 
36
36
  def map_model(model)
37
37
  self.proposal_ids = model.linked_resources(:proposals, "included_proposals").pluck(:id)
38
+ self.selected = model.selected?
38
39
 
39
40
  return unless model.categorization
40
41
 
@@ -47,6 +48,13 @@ module Decidim
47
48
  &.order(title: :asc)
48
49
  end
49
50
 
51
+ # Finds the Budget from the decidim_budgets_budget_id.
52
+ #
53
+ # Returns a Decidim::Budgets:Budget
54
+ def budget
55
+ @budget ||= context[:budget]
56
+ end
57
+
50
58
  # Finds the Category from the decidim_category_id.
51
59
  #
52
60
  # Returns a Decidim::Category
@@ -54,11 +62,11 @@ module Decidim
54
62
  @category ||= categories.find_by(id: decidim_category_id)
55
63
  end
56
64
 
57
- # Finds the Scope from the given decidim_scope_id, uses participatory space scope if missing.
65
+ # Finds the Scope from the given decidim_scope_id, uses the component scope if missing.
58
66
  #
59
67
  # Returns a Decidim::Scope
60
68
  def scope
61
- @scope ||= @decidim_scope_id ? current_participatory_space.scopes.find_by(id: @decidim_scope_id) : current_participatory_space.scope
69
+ @scope ||= @decidim_scope_id ? current_component.scopes.find_by(id: @decidim_scope_id) : current_component.scope
62
70
  end
63
71
 
64
72
  # Scope identifier
@@ -70,10 +78,6 @@ module Decidim
70
78
 
71
79
  private
72
80
 
73
- def scope_belongs_to_participatory_space_scope
74
- errors.add(:decidim_scope_id, :invalid) if current_participatory_space.out_of_scope?(scope)
75
- end
76
-
77
81
  # This method will add an error to the `attachment` field only if there's
78
82
  # any error in any other field. This is needed because when the form has
79
83
  # an error, the attachment is lost, so we need a way to inform the user of
@@ -29,6 +29,10 @@ module Decidim
29
29
  [component.name[I18n.locale.to_s], component.id]
30
30
  end
31
31
  end
32
+
33
+ def budget
34
+ @budget ||= context[:budget]
35
+ end
32
36
  end
33
37
  end
34
38
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Budgets
5
+ module Admin
6
+ # Custom helpers, scoped to the budgets admin engine.
7
+ #
8
+ module ApplicationHelper
9
+ include Decidim::Admin::ResourceScopeHelper
10
+ end
11
+ end
12
+ end
13
+ end
@@ -9,6 +9,16 @@ module Decidim
9
9
  include Decidim::Comments::CommentsHelper
10
10
  include ProjectsHelper
11
11
  include Decidim::CheckBoxesTreeHelper
12
+
13
+ def filter_status_values
14
+ TreeNode.new(
15
+ TreePoint.new("", t("decidim.budgets.projects.filters.status_values.all")),
16
+ [
17
+ TreePoint.new("selected", t("decidim.budgets.projects.filters.status_values.selected")),
18
+ TreePoint.new("not_selected", t("decidim.budgets.projects.filters.status_values.not_selected"))
19
+ ]
20
+ )
21
+ end
12
22
  end
13
23
  end
14
24
  end
@@ -36,10 +36,6 @@ module Decidim
36
36
  def current_order_can_be_checked_out?
37
37
  current_order&.can_checkout?
38
38
  end
39
-
40
- def projects_base_url
41
- URI.parse(root_url).tap { |uri| uri.query = uri.fragment = nil } .to_s
42
- end
43
39
  end
44
40
  end
45
41
  end
@@ -17,13 +17,15 @@ module Decidim
17
17
  with_user(user) do
18
18
  @user = user
19
19
  @order = order
20
- @space = order.participatory_space
21
- @component = order.component
22
- @organization = order.participatory_space.organization
20
+ @budget = order.budget
21
+ @space = order.budget.participatory_space
22
+ @component = order.budget.component
23
+ @organization = order.budget.participatory_space.organization
23
24
 
24
25
  subject = I18n.t(
25
26
  "order_summary.subject",
26
27
  scope: "decidim.budgets.order_summary_mailer",
28
+ budget_name: translated_attribute(@budget.title),
27
29
  space_name: translated_attribute(@space.title)
28
30
  )
29
31
  mail(to: user.email, subject: subject)
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Budgets
5
+ # The data store for a budget in the Decidim::Budgets component.
6
+ class Budget < ApplicationRecord
7
+ include Decidim::Resourceable
8
+ include Decidim::ScopableResource
9
+ include Decidim::HasComponent
10
+ include Decidim::Searchable
11
+ include Traceable
12
+ include Loggable
13
+
14
+ component_manifest_name "budgets"
15
+
16
+ has_many :projects, foreign_key: "decidim_budgets_budget_id", class_name: "Decidim::Budgets::Project", inverse_of: :budget, dependent: :destroy
17
+ has_many :orders, foreign_key: "decidim_budgets_budget_id", class_name: "Decidim::Budgets::Order", inverse_of: :budget, dependent: :destroy
18
+
19
+ delegate :participatory_space, :manifest, :settings, to: :component
20
+
21
+ searchable_fields({
22
+ participatory_space: { component: :participatory_space },
23
+ A: :title,
24
+ D: [:description, :total_budget]
25
+ },
26
+ index_on_create: ->(budget) { budget.visible? },
27
+ index_on_update: ->(budget) { budget.visible? })
28
+
29
+ def self.log_presenter_class_for(_log)
30
+ Decidim::Budgets::AdminLog::BudgetPresenter
31
+ end
32
+ end
33
+ end
34
+ end