decidim-plans 0.16.1 → 0.16.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a0beab872d687c4002db352e84e5de788545493a03a5c9e06d22af045d014a10
4
- data.tar.gz: b422c03351c34cb8919b22bef233b85451c808edaf90b638e213d027493f2484
3
+ metadata.gz: 7e8c60c3aad835eee3789f5d65146952a7233b0375cef797fbfb221d44954354
4
+ data.tar.gz: 0e6c025fefdedf2d8056244a10103cdd8e82a70f89817dfa415065be08a058d7
5
5
  SHA512:
6
- metadata.gz: e3a45ded830363d9e5c1bffe7f9f22b52fff04f62ba8f5d2dea1cb44cf22a716466ce945c67b5bf9f8230becc3102add69f7196fc90f36cb4fb3207fb0b3e9ec
7
- data.tar.gz: 5fc28c2575d607f354eb8fe677f9d33886239b948614c939b04f40ddfc095a816c61d0cfaa272af340922184d3c32fe418a956c92163626c83f0989dc5fb1ee8
6
+ metadata.gz: 3b4eed8d262f4da32503813c798e52a4cc3ca2fe8f8f731478b36d60d6e887df09a14f20471c56e76bdca29221836d66c123418d54c443a3966f60d8b9ffb23b
7
+ data.tar.gz: 6efc6bdb4c26729630870b7147615297dd2bde7861f5d3ea60f9655b0459740426f62ac056a335f94dd55cb17c789402e5b3cceb42ced92e6bcb6a25deb03643
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Plans
5
+ module Admin
6
+ # A command with all the business logic when an admin exports plans to a
7
+ # single budget component.
8
+ class ExportPlansToBudgets < Rectify::Command
9
+ # Public: Initializes the command.
10
+ #
11
+ # form - A form object with the params.
12
+ def initialize(form)
13
+ @form = form
14
+ end
15
+
16
+ # Executes the command. Broadcasts these events:
17
+ #
18
+ # - :ok when everything is valid.
19
+ # - :invalid if the form wasn't valid and we couldn't proceed.
20
+ #
21
+ # Returns nothing.
22
+ def call
23
+ return broadcast(:invalid) unless @form.valid?
24
+
25
+ broadcast(:ok, create_projects_from_closed_plans)
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :form
31
+
32
+ def create_projects_from_closed_plans
33
+ transaction do
34
+ plans.map do |original_plan|
35
+ next if plan_already_copied?(original_plan, target_component)
36
+
37
+ project = Decidim::Budgets::Project.new
38
+ project.title = original_plan.title
39
+ project.description = project_description(original_plan)
40
+ project.budget = form.default_budget
41
+ project.category = original_plan.category
42
+ project.component = target_component
43
+ original_plan.attachments.each do |at|
44
+ project.attachments.build(
45
+ title: at.title,
46
+ file: at.file
47
+ )
48
+ end
49
+ project.save!
50
+
51
+ # Link included proposals to the project
52
+ project.link_resources(original_plan.proposals, "included_proposals")
53
+
54
+ # Link the plan to the project
55
+ project.link_resources([original_plan], "included_plans")
56
+ end.compact
57
+ end
58
+ end
59
+
60
+ def plans
61
+ Decidim::Plans::Plan.where(component: origin_component)
62
+ .where.not(closed_at: nil)
63
+ end
64
+
65
+ def origin_component
66
+ @form.current_component
67
+ end
68
+
69
+ def target_component
70
+ @form.target_component
71
+ end
72
+
73
+ def plan_already_copied?(original_plan, target_component)
74
+ original_plan.linked_resources(:projects, "included_plans").any? do |plan|
75
+ plan.component == target_component
76
+ end
77
+ end
78
+
79
+ def project_description(original_plan)
80
+ pr_desc = {}
81
+
82
+ # Add content for all sections and languages
83
+ original_plan.sections.each do |section|
84
+ content = original_plan.contents.find_by(section: section)
85
+ content.body.each do |locale, body_text|
86
+ title = section.body[locale]
87
+ pr_desc[locale] ||= ""
88
+ pr_desc[locale] += "<h3>#{title}</h3>\n"
89
+
90
+ # In case the text is already HTML, append as is.
91
+ # Wrap non-HTML strings within a <p> tag and replace newlines with
92
+ # <br>.
93
+ pr_desc[locale] += (
94
+ if body_text =~ %r{<\/?[^>]*>}
95
+ "#{body_text}\n"
96
+ else
97
+ "<p>#{body_text.gsub(/\n/, "<br>")}</p>\n"
98
+ end
99
+ )
100
+ end
101
+ end
102
+
103
+ # Cleanup the unnecessary whitespace
104
+ pr_desc.each_value(&:strip!)
105
+
106
+ pr_desc
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Plans
5
+ module Admin
6
+ class BudgetsExportsController < Admin::ApplicationController
7
+ def new
8
+ enforce_permission_to :export_budgets, :plans
9
+
10
+ @form = form(Admin::PlanExportBudgetsForm).instance
11
+ end
12
+
13
+ def create
14
+ enforce_permission_to :export_budgets, :plans
15
+
16
+ @form = form(Admin::PlanExportBudgetsForm).from_params(params)
17
+ Admin::ExportPlansToBudgets.call(@form) do
18
+ on(:ok) do |projects|
19
+ flash[:notice] = I18n.t("budgets_exports.create.success", scope: "decidim.plans.admin", number: projects.length)
20
+ redirect_to EngineRouter.admin_proxy(current_component).root_path
21
+ end
22
+
23
+ on(:invalid) do
24
+ flash[:alert] = I18n.t("budgets_exports.create.invalid", scope: "decidim.plans.admin")
25
+ render action: "new"
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Plans
5
+ module Admin
6
+ # A form object to be used when admin users want to export a collection of
7
+ # plans into the budgeting projects component.
8
+ class PlanExportBudgetsForm < Decidim::Form
9
+ mimic :budgets_export
10
+
11
+ attribute :target_component_id, Integer
12
+ attribute :default_budget, Integer
13
+ attribute :export_all_closed_plans, Boolean
14
+
15
+ validates :target_component_id, :target_component, :current_component, presence: true
16
+ validates :export_all_closed_plans, allow_nil: false, acceptance: true
17
+ validates :default_budget, presence: true, numericality: { greater_than: 0 }
18
+
19
+ def target_component
20
+ @target_component ||= target_components.find_by(id: target_component_id)
21
+ end
22
+
23
+ def target_components
24
+ @target_components ||= current_participatory_space.components.where(manifest_name: :budgets)
25
+ end
26
+
27
+ def target_components_collection
28
+ target_components.map do |component|
29
+ [component.name[I18n.locale.to_s], component.id]
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -19,7 +19,7 @@ module Decidim
19
19
  permission_action.subject != :sections
20
20
 
21
21
  case permission_action.action
22
- when :create
22
+ when :create, :export_budgets
23
23
  permission_action.allow!
24
24
  when :edit, :update, :destroy
25
25
  permission_action.allow! if plan.present? || section.present?
@@ -0,0 +1,27 @@
1
+ <%= decidim_form_for(@form, url: budgets_export_path, html: { class: "form import_proposals" }) do |f| %>
2
+ <% if @form.target_components.any? %>
3
+ <div class="card">
4
+ <div class="card-divider">
5
+ <h2 class="card-title"><%= title %></h2>
6
+ </div>
7
+
8
+ <div class="card-section">
9
+ <div class="row column">
10
+ <%= f.select :target_component_id, @form.target_components_collection, prompt: t(".select_component") %>
11
+ </div>
12
+ <div class="row column">
13
+ <%= f.number_field :default_budget %>
14
+ </div>
15
+ <div class="row column">
16
+ <%= f.check_box :export_all_closed_plans %>
17
+ </div>
18
+ </div>
19
+ </div>
20
+
21
+ <div class="button--double form-general-submit">
22
+ <%= f.submit t(".create") %>
23
+ </div>
24
+ <% else %>
25
+ <p><%= t(".no_components") %></p>
26
+ <% end %>
27
+ <% end %>
@@ -6,6 +6,10 @@
6
6
  <%= link_to t("actions.new", scope: "decidim.plans"), new_plan_path, class: "button tiny button--simple" %>
7
7
  <% end %>
8
8
 
9
+ <% if allowed_to? :export_budgets, :plans %>
10
+ <%= link_to t("actions.export_budgets", scope: "decidim.plans"), new_budgets_export_path, class: "button tiny button--simple" %>
11
+ <% end %>
12
+
9
13
  <%= export_dropdown %>
10
14
  </div>
11
15
  </div>
@@ -44,7 +44,7 @@
44
44
  <% if plan.closed? %>
45
45
  <%= icon_link_to "action-undo", reopen_plan_path(plan), t("actions.reopen_plan", scope: "decidim.plans"), method: :post, class: "action-icon--reopen-plan" %>
46
46
  <% else %>
47
- <%= icon_link_to "ban", close_plan_path(plan), t("actions.close_plan", scope: "decidim.plans"), method: :post, class: "action-icon--close-plan" %>
47
+ <%= icon_link_to "check", close_plan_path(plan), t("actions.close_plan", scope: "decidim.plans"), method: :post, class: "action-icon--close-plan" %>
48
48
  <% end %>
49
49
  <% end %>
50
50
 
@@ -55,6 +55,7 @@ en:
55
55
  answer: Answer
56
56
  close_plan: Mark as done
57
57
  edit_plan: Edit
58
+ export_budgets: Convert to projects
58
59
  new: Submit new plan
59
60
  reopen_plan: Open for editing
60
61
  sections: Sections
@@ -62,6 +63,14 @@ en:
62
63
  admin:
63
64
  actions:
64
65
  preview: Preview
66
+ budgets_exports:
67
+ create:
68
+ invalid: There's been a problem exporting the items into budgeting projects
69
+ success: "%{number} items successfully exported into budgeting projects"
70
+ new:
71
+ create: Export to projects
72
+ no_components: There are no other budgets components in this participatory space to export the items into projects.
73
+ select_component: Please select a component
65
74
  exports:
66
75
  plans: Plans
67
76
  plan_answers:
@@ -1,4 +1,3 @@
1
- ---
2
1
  fi:
3
2
  activerecord:
4
3
  models:
@@ -55,6 +54,7 @@ fi:
55
54
  answer: Vastaa
56
55
  close_plan: Merkitse valmiiksi
57
56
  edit_plan: Muokkaa
57
+ export_budgets: Muunna projekteiksi
58
58
  new: Tee uusi suunnitelma
59
59
  reopen_plan: Avaa muokattavaksi
60
60
  sections: Osiot
@@ -62,6 +62,14 @@ fi:
62
62
  admin:
63
63
  actions:
64
64
  preview: Esikatsele
65
+ budgets_exports:
66
+ create:
67
+ invalid: Kohteiden vienti budjetointiprojekteiksi epäonnistui
68
+ success: "%{number} kohdetta viety onnistuneesti budjetointiprojekteiksi"
69
+ new:
70
+ create: Vie projekteiksi
71
+ no_components: Tässä osallisuustilassa ei ole yhtään budjetointikomponenttia, johon projektit voitaisiin luoda.
72
+ select_component: Valitse komponentti
65
73
  exports:
66
74
  plans: Suunnitelmat
67
75
  plan_answers:
@@ -112,15 +120,11 @@ fi:
112
120
  plans: Suunnitelmat
113
121
  admin_log:
114
122
  plan:
115
- answer: "%{user_name} vastasi sisältöön %{resource_name}
116
- osallisuustilassa %{space_name}."
117
- create: "%{user_name} loi sisällön %{resource_name} osallisuustilassa
118
- %{space_name}."
119
- update: "%{user_name} päivitti sisältöä %{resource_name}
120
- osallisuustilassa %{space_name}."
123
+ answer: "%{user_name} vastasi sisältöön %{resource_name} osallisuustilassa %{space_name}."
124
+ create: "%{user_name} loi sisällön %{resource_name} osallisuustilassa %{space_name}."
125
+ update: "%{user_name} päivitti sisältöä %{resource_name} osallisuustilassa %{space_name}."
121
126
  plan_note:
122
- create: "%{user_name} lisäsi yksityisen viestin sisältöön
123
- %{resource_name} osallisuustilassa %{space_name}."
127
+ create: "%{user_name} lisäsi yksityisen viestin sisältöön %{resource_name} osallisuustilassa %{space_name}."
124
128
  answers:
125
129
  accepted: Hyväksytty
126
130
  evaluating: Arvioitavana
@@ -235,14 +239,12 @@ fi:
235
239
  show:
236
240
  back: Takaisin
237
241
  close: Merkitse valmiiksi
238
- close_confirm: Haluatko varmasti merkitä tämän kohteen valmiiksi? Kun
239
- kohde on merkitty valmiiksi, sitä ei voi enää muokata.
242
+ close_confirm: Haluatko varmasti merkitä tämän kohteen valmiiksi? Kun kohde on merkitty valmiiksi, sitä ei voi enää muokata.
240
243
  edit: Muokkaa
241
244
  hidden_authors_count:
242
245
  one: ja %{count} muu henkilö
243
246
  other: ja %{count} muuta henkilöä
244
- info-message: Voit osalllistua joko jättämällä kommentin sivun
245
- alalaidassa tai pyytämällä itsellesi muokkausoikeudet sisältöön.
247
+ info-message: Voit osalllistua joko jättämällä kommentin sivun alalaidassa tai pyytämällä itsellesi muokkausoikeudet sisältöön.
246
248
  of_versions: "(versioista %{number})"
247
249
  plan_accepted_reason: 'Tämä suunnitelma on hyväksytty, koska:'
248
250
  plan_in_evaluation_reason: Tämä suunnitelma on arvioitavana
@@ -1,4 +1,3 @@
1
- ---
2
1
  sv:
3
2
  activerecord:
4
3
  models:
@@ -10,7 +9,6 @@ sv:
10
9
  category_id: Category
11
10
  decidim_category_id: Category
12
11
  decidim_component_id: Component
13
- decidim_proposal_id: Proposal
14
12
  decidim_scope_id: Scope
15
13
  state: State
16
14
  title: Title
@@ -56,6 +54,7 @@ sv:
56
54
  answer: Answer
57
55
  close_plan: Mark as done
58
56
  edit_plan: Edit
57
+ export_budgets: Convert to projects
59
58
  new: Submit new plan
60
59
  reopen_plan: Open for editing
61
60
  sections: Sections
@@ -63,6 +62,14 @@ sv:
63
62
  admin:
64
63
  actions:
65
64
  preview: Preview
65
+ budgets_exports:
66
+ create:
67
+ invalid: There's been a problem exporting the items into budgeting projects
68
+ success: "%{number} items successfully exported into budgeting projects"
69
+ new:
70
+ create: Export to projects
71
+ no_components: There are no other budgets components in this participatory space to export the items into projects.
72
+ select_component: Please select a component
66
73
  exports:
67
74
  plans: Plans
68
75
  plan_answers:
@@ -113,15 +120,11 @@ sv:
113
120
  plans: Plans
114
121
  admin_log:
115
122
  plan:
116
- answer: "%{user_name} answered %{resource_name} on the %{space_name}
117
- space."
118
- create: "%{user_name} created %{resource_name} on the %{space_name}
119
- space."
120
- update: "%{user_name} updated %{resource_name} on the %{space_name}
121
- space."
123
+ answer: "%{user_name} answered %{resource_name} on the %{space_name} space."
124
+ create: "%{user_name} created %{resource_name} on the %{space_name} space."
125
+ update: "%{user_name} updated %{resource_name} on the %{space_name} space."
122
126
  plan_note:
123
- create: "%{user_name} left a private note on %{resource_name} on the
124
- %{space_name} space."
127
+ create: "%{user_name} left a private note on %{resource_name} on the %{space_name} space."
125
128
  answers:
126
129
  accepted: Accepted
127
130
  evaluating: Evaluating
@@ -236,14 +239,12 @@ sv:
236
239
  show:
237
240
  back: Back
238
241
  close: Mark as done
239
- close_confirm: Are you sure you want to mark this item done? After
240
- marking done, the item can no longer be edited.
242
+ close_confirm: Are you sure you want to mark this item done? After marking done, the item can no longer be edited.
241
243
  edit: Edit
242
244
  hidden_authors_count:
243
245
  one: and %{count} more person
244
246
  other: and %{count} more people
245
- info-message: You can participate either by submitting a comment or by
246
- asking for a permission to edit content directly.
247
+ info-message: You can participate either by submitting a comment or by asking for a permission to edit content directly.
247
248
  of_versions: "(of %{number})"
248
249
  plan_accepted_reason: 'This plan has been accepted because:'
249
250
  plan_in_evaluation_reason: This plan is being evaluated
@@ -17,6 +17,9 @@ module Decidim
17
17
  post :close
18
18
  post :reopen
19
19
  end
20
+ collection do
21
+ resource :budgets_export, only: [:new, :create]
22
+ end
20
23
  end
21
24
  resources :sections, only: [:index, :new, :create, :edit, :update]
22
25
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Decidim
4
4
  module Plans
5
- VERSION = "0.16.1"
5
+ VERSION = "0.16.2"
6
6
  DECIDIM_VERSION = "~> 0.16.0"
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: decidim-plans
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.1
4
+ version: 0.16.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Antti Hukkanen
@@ -148,6 +148,7 @@ files:
148
148
  - app/commands/decidim/plans/accept_access_to_plan.rb
149
149
  - app/commands/decidim/plans/admin/answer_plan.rb
150
150
  - app/commands/decidim/plans/admin/create_plan.rb
151
+ - app/commands/decidim/plans/admin/export_plans_to_budgets.rb
151
152
  - app/commands/decidim/plans/admin/update_plan.rb
152
153
  - app/commands/decidim/plans/admin/update_sections.rb
153
154
  - app/commands/decidim/plans/attachment_methods.rb
@@ -164,6 +165,7 @@ files:
164
165
  - app/commands/decidim/plans/withdraw_plan.rb
165
166
  - app/controllers/concerns/decidim/plans/orderable.rb
166
167
  - app/controllers/decidim/plans/admin/application_controller.rb
168
+ - app/controllers/decidim/plans/admin/budgets_exports_controller.rb
167
169
  - app/controllers/decidim/plans/admin/plan_answers_controller.rb
168
170
  - app/controllers/decidim/plans/admin/plans_controller.rb
169
171
  - app/controllers/decidim/plans/admin/sections_controller.rb
@@ -185,6 +187,7 @@ files:
185
187
  - app/forms/decidim/plans/accept_access_to_plan_form.rb
186
188
  - app/forms/decidim/plans/access_to_plan_form.rb
187
189
  - app/forms/decidim/plans/admin/plan_answer_form.rb
190
+ - app/forms/decidim/plans/admin/plan_export_budgets_form.rb
188
191
  - app/forms/decidim/plans/admin/plan_form.rb
189
192
  - app/forms/decidim/plans/admin/plan_sections_form.rb
190
193
  - app/forms/decidim/plans/admin/section_form.rb
@@ -229,6 +232,7 @@ files:
229
232
  - app/services/decidim/plans/plan_builder.rb
230
233
  - app/services/decidim/plans/plan_search.rb
231
234
  - app/services/decidim/plans/tracer.rb
235
+ - app/views/decidim/plans/admin/budgets_exports/new.html.erb
232
236
  - app/views/decidim/plans/admin/plan_answers/edit.html.erb
233
237
  - app/views/decidim/plans/admin/plans/_bulk-actions.html.erb
234
238
  - app/views/decidim/plans/admin/plans/_form.html.erb