decidim-plans 0.16.1 → 0.16.2

Sign up to get free protection for your applications and to get access to all the features.
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