decidim-reporting_proposals 0.2.0 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.eslintrc.json +1 -0
- data/.github/workflows/lint.yml +1 -0
- data/.github/workflows/test_integration.yml +5 -1
- data/.github/workflows/test_unit.yml +5 -1
- data/Gemfile +1 -0
- data/Gemfile.lock +269 -227
- data/README.md +108 -16
- data/app/cells/concerns/decidim/reporting_proposals/proposals_picker_cell_override.rb +24 -0
- data/app/commands/concerns/decidim/admin/hide_resource_override.rb +34 -0
- data/app/commands/concerns/decidim/proposals/admin/answer_proposal_override.rb +41 -0
- data/app/commands/concerns/decidim/proposals/admin/assign_proposals_to_valuator_override.rb +30 -0
- data/app/commands/concerns/decidim/proposals/publish_proposal_override.rb +72 -0
- data/app/commands/concerns/decidim/reporting_proposals/admin/create_answer_override.rb +17 -0
- data/app/commands/concerns/decidim/reporting_proposals/admin/create_result_override.rb +17 -0
- data/app/commands/concerns/decidim/reporting_proposals/admin/update_result_override.rb +34 -0
- data/app/commands/concerns/decidim/reporting_proposals/close_meeting_override.rb +15 -0
- data/app/commands/concerns/decidim/reporting_proposals/create_project_override.rb +15 -0
- data/app/commands/concerns/decidim/templates/admin/copy_questionnaire_template_override.rb +32 -0
- data/app/commands/concerns/decidim/templates/admin/create_questionnaire_template_override.rb +32 -0
- data/app/commands/decidim/templates/admin/copy_proposal_answer_template.rb +35 -0
- data/app/commands/decidim/templates/admin/create_proposal_answer_template.rb +48 -0
- data/app/commands/decidim/templates/admin/update_proposal_answer_template.rb +52 -0
- data/app/controllers/concerns/decidim/proposals/admin/valuation_assignments_controller_override.rb +35 -0
- data/app/controllers/concerns/decidim/templates/admin/application_controller_override.rb +20 -0
- data/app/controllers/decidim/reporting_proposals/admin/proposal_notes_controller.rb +4 -5
- data/app/controllers/decidim/templates/admin/proposal_answer_templates_controller.rb +181 -0
- data/app/events/concerns/decidim/proposals/publish_proposal_event_override.rb +35 -0
- data/app/forms/concerns/decidim/reporting_proposals/close_meeting_form_override.rb +28 -0
- data/app/forms/concerns/decidim/reporting_proposals/form_builder_override.rb +1 -3
- data/app/forms/concerns/decidim/reporting_proposals/map_included_proposals_for_form_override.rb +28 -0
- data/app/forms/concerns/decidim/reporting_proposals/map_related_proposals_for_form_override.rb +28 -0
- data/app/forms/decidim/templates/admin/proposal_answer_template_form.rb +21 -0
- data/app/helpers/concerns/decidim/reporting_proposals/resource_helper_override.rb +25 -0
- data/app/mailers/concerns/decidim/admin/hidden_resource_mailer.rb +28 -0
- data/app/mailers/concerns/decidim/proposals/admin/notification_answer_proposal_mailer.rb +25 -0
- data/app/mailers/concerns/decidim/proposals/admin/proposals_valuator_mailer.rb +30 -0
- data/app/mailers/concerns/decidim/proposals/notification_publish_proposal_mailer.rb +23 -0
- data/app/mailers/concerns/decidim/reported_mailer_override.rb +16 -0
- data/app/models/concerns/decidim/reporting_proposals/participatory_space_role_config/valuator_override.rb +4 -1
- data/app/overrides/decidim/proposals/admin/proposal_answers/_form/add_template_chooser.html.erb.deface +5 -0
- data/app/overrides/decidim/proposals/admin/proposals/show/add_address.html.erb.deface +3 -0
- data/app/overrides/decidim/proposals/admin/proposals/show/add_valuators_form.html.erb.deface +19 -0
- data/app/overrides/decidim/reported_mailer/report/add_link_to_admin.html.erb.deface +5 -0
- data/app/packs/entrypoints/decidim_templates_admin.js +1 -0
- data/app/packs/src/decidim/reporting_proposals/user_camera_inputs.js +37 -39
- data/app/packs/src/decidim/templates/admin/proposal_answer_template_chooser.js +27 -0
- data/app/packs/stylesheets/decidim/reporting_proposals/manage_component_admin.scss +31 -0
- data/app/presenters/concerns/decidim/resource_locator_presenter_override.rb +38 -0
- data/app/resources/concerns/decidim/resource_manifest_override.rb +14 -0
- data/app/views/decidim/admin/hidden_resource_mailer/notify_mail.html.erb +12 -0
- data/app/views/decidim/proposals/admin/notification_answer_proposal_mailer/notify_proposal_author.html.erb +7 -0
- data/app/views/decidim/proposals/admin/proposals/_address.html.erb +13 -0
- data/app/views/decidim/proposals/admin/proposals_valuator_mailer/notify_proposals_valuator.html.erb +17 -0
- data/app/views/decidim/proposals/notification_publish_proposal_mailer/notify_proposal_author.html.erb +7 -0
- data/app/views/decidim/proposals/proposals/index.js.erb +19 -0
- data/app/views/decidim/templates/admin/proposal_answer_templates/_form.html.erb +34 -0
- data/app/views/decidim/templates/admin/proposal_answer_templates/_template_chooser.html.erb +16 -0
- data/app/views/decidim/templates/admin/proposal_answer_templates/edit.html.erb +3 -0
- data/app/views/decidim/templates/admin/proposal_answer_templates/index.html.erb +52 -0
- data/app/views/decidim/templates/admin/proposal_answer_templates/new.html.erb +6 -0
- data/config/assets.rb +2 -1
- data/config/i18n-tasks.yml +3 -0
- data/config/locales/ca.yml +81 -7
- data/config/locales/de.yml +77 -3
- data/config/locales/en.yml +87 -0
- data/config/locales/es.yml +328 -254
- data/db/migrate/20230404103706_add_target_and_field_values_to_decidim_templates_templates.rb +12 -0
- data/db/migrate/20230404104741_migrate_templatable.rb +13 -0
- data/decidim-reporting_proposals.gemspec +5 -0
- data/lib/decidim/reporting_proposals/admin_engine.rb +16 -1
- data/lib/decidim/reporting_proposals/component.rb +1 -1
- data/lib/decidim/reporting_proposals/config.rb +10 -5
- data/lib/decidim/reporting_proposals/engine.rb +38 -1
- data/lib/decidim/reporting_proposals/test/factories.rb +10 -0
- data/lib/decidim/reporting_proposals/version.rb +2 -7
- metadata +152 -2
data/README.md
CHANGED
@@ -9,12 +9,18 @@
|
|
9
9
|
|
10
10
|
This module creates a new component to be used in participatory spaces that allows to create proposals orientated to manage geolocated issues in a city. For instance Damages or new ideas of improving a particular street or public good.
|
11
11
|
|
12
|
-
|
12
|
+
[👉 See features & screenshots](#features)
|
13
13
|
|
14
14
|
## Installation
|
15
15
|
|
16
16
|
Add this line to your application's Gemfile:
|
17
17
|
|
18
|
+
```ruby
|
19
|
+
gem 'decidim-reporting_proposals'
|
20
|
+
```
|
21
|
+
|
22
|
+
Or, if you want to stay up to date with the latest changes use this line instead:
|
23
|
+
|
18
24
|
```ruby
|
19
25
|
gem 'decidim-reporting_proposals', git: "https://github.com/openpoke/decidim-module-reporting_proposals"
|
20
26
|
```
|
@@ -27,17 +33,105 @@ And then execute:
|
|
27
33
|
bundle exec rails decidim_reporting_proposals:install:migrations
|
28
34
|
```
|
29
35
|
|
36
|
+
> **IMPORTANT:**
|
37
|
+
>
|
38
|
+
> This module makes use of the [Deface](https://github.com/spree/deface) gem.
|
39
|
+
> In conjunction with other modules (we know [Term Customizer](https://github.com/mainio/decidim-module-term_customizer/) is one of them) it might cause errors when precompiling assets for production sites. But only if during this process the compiling machine does not have access to the database.
|
40
|
+
>
|
41
|
+
> It is easy to overcome this problem. Just add the following line to your `config/environments/production.rb` file:
|
42
|
+
>
|
43
|
+
> ```ruby
|
44
|
+
> config.deface.enabled = ENV['DB_ADAPTER'].blank? || ENV['DB_ADAPTER'] == 'postgresql'
|
45
|
+
> ```
|
46
|
+
>
|
47
|
+
> Then precompile with these ENV enabled in your CI:
|
48
|
+
>
|
49
|
+
> ```bash
|
50
|
+
> DB_ADAPTER=nulldb RAILS_ENV=production rake assets:precompile
|
51
|
+
> ```
|
52
|
+
>
|
53
|
+
> Alternatively, use any other ENV var to set up the `config.deface.enabled` to `false` during the precompilation phase.
|
54
|
+
|
55
|
+
Depending on your Decidim version, you can choose the corresponding version to ensure compatibility:
|
56
|
+
|
57
|
+
| Version | Compatible Decidim versions |
|
58
|
+
|---|---|
|
59
|
+
| 0.5.x | 0.27.x |
|
60
|
+
| 0.4.x | 0.26.x |
|
61
|
+
|
30
62
|
## Usage
|
31
63
|
|
32
|
-
|
64
|
+
This module works very similarly as the Proposals module, in fact, it extends it to provide additional features and some different defaults.
|
65
|
+
|
66
|
+
It provides a new component called "Reporting Proposals" that can be added in addition or instead of the Proposals component in any participatory space.
|
67
|
+
|
68
|
+
### Features
|
69
|
+
|
70
|
+
This module provides the following features:
|
71
|
+
|
72
|
+
1. **Reporting Proposals Component**: A new component that can be added to any participatory space. It allows to create proposals in one-step form with some optimization for mobile devices. Users can add photos using the phone's camera directly and also use the device's GPS to establish a precise a geolocated address with one click. Some of the options can be used in the normal proposal's component too (but in this case they 2 steps behavior is maintained).
|
73
|
+
![Reporting proposal creationg](features/proposal.png)
|
74
|
+
|
75
|
+
2. **Comparison by proximity**: By default, reporting proposals are compared by proximity before publishing (as they are geolocated by default). This can be disabled in the component's settings.
|
76
|
+
![Compare by proximity](features/proximity.png)
|
77
|
+
|
78
|
+
3. **Automatic assignation of valuators**: When a proposal is created, admins usually have to assign valuators manually to it. This module allows admins to assign valuators to a category directly. This will automatically assign all valuators in that category to any proposal/reporting proposal created under it (and also existing proposals). This avoids the need of manually assign proposals to valuators. This behavior can be disabled in the component's settings.
|
79
|
+
![Valuators in categories](features/categories.png)
|
80
|
+
|
81
|
+
4. **Valuators empowerment**: A number of features allow valuators to have more control over the proposals they are evaluating. They can assign other valuators (instead of themselves) and they can change or add photos to a proposal. All of it is configurable. Also, valuators can be assigned directly in the proposal's answering page instead of using the bulk assignation feature. Additionally, privates note can be edited and links in it are clickable.
|
82
|
+
![Valuators empowerment](features/answering1.png)
|
83
|
+
|
84
|
+
5. **Overdue proposals**: This module allows to set a number of days after which a proposal is considered overdue. This is configurable and can be disabled. This feature affects the admin list of proposals, adding visual notes, color coded, to facilitate the identification of overdue proposals and preventing admins to leave unanswered proposals for a long time.
|
85
|
+
![Overdue proposals](features/overdues.png)
|
86
|
+
|
87
|
+
6. **Improved notifications**: Some notifications are added, and some existing ones are improved. For instance, valuators and admins can receive notifications after a proposal has been added and it's content includes a direct link to the proposal and its answering page.
|
88
|
+
|
89
|
+
7. **Hide proposals without reporting**: Administrators can hide proposals directly, without using the reporting process. Also, authors who's content has been hidden receive a notification.
|
90
|
+
|
91
|
+
8. **Proposal answers templates**: Administrators can create templates for the answers to proposals. This is useful to provide a standard answer to proposals that are similar. This feature requires to enable the `decidim-templates` official module.
|
92
|
+
![Templates for proposals answers](features/templates1.png)
|
93
|
+
![Applying a template](features/templates2.png)
|
94
|
+
|
95
|
+
### Customization
|
96
|
+
|
97
|
+
Almost all the features of this module can be customized/disabled through an initializer.
|
98
|
+
|
99
|
+
For instance, you can create an initializer an change some of the available options as follows (**This is optional, you don't need to do this, by default all options are enabled**):
|
33
100
|
|
34
101
|
```ruby
|
35
102
|
# config/initializers/reporting_proposals.rb
|
36
103
|
|
37
104
|
Decidim::ReportingProposals.configure do |config|
|
105
|
+
# Public Setting that defines after how many days a not-answered proposal is overdue
|
106
|
+
# Set it to 0 (zero) if you don't want to use this feature
|
107
|
+
config.unanswered_proposals_overdue = 7
|
108
|
+
|
109
|
+
# Public Setting that defines after how many days an evaluating-state proposal is overdue
|
110
|
+
# Set it to 0 (zero) if you don't want to use this feature
|
111
|
+
config.evaluating_proposals_overdue = 3
|
112
|
+
|
113
|
+
# Public Setting that defines whether the administrator is allowed to hide the proposals.
|
114
|
+
# Set to false if you do not want to use this feature
|
115
|
+
config.allow_admins_to_hide_proposals =true
|
116
|
+
|
117
|
+
# Public Setting that allows to configure which component will have "Use my location" button
|
118
|
+
# in a geocoded address field. Accepts an array of component manifest names
|
119
|
+
config.show_my_location_button = [:proposals, :meetings, :reporting_proposals]
|
120
|
+
|
121
|
+
# Public Setting that adds a button next to the "add image" input[type=file] to open the camera directly
|
122
|
+
config.use_camera_button = [:proposals, :reporting_proposals]
|
123
|
+
|
124
|
+
# Public setting to prevent valuators or admins to modify the photos attached to a proposal
|
125
|
+
# otherwise can be configured at the component level
|
126
|
+
config.allow_proposal_photo_editing = true
|
127
|
+
|
128
|
+
# Public setting to allow to assign other valuators
|
129
|
+
config.valuators_assign_other_valuators = true
|
38
130
|
end
|
39
131
|
```
|
40
132
|
|
133
|
+
Find all the available options in the [config.rb](lib/decidim/reporting_proposals/config.rb) file.
|
134
|
+
|
41
135
|
## Contributing
|
42
136
|
|
43
137
|
Bug reports and pull requests are welcome on GitHub at https://github.com/openpoke/decidim-module-reporting_proposals.
|
@@ -57,8 +151,8 @@ You can create the development app by running the following commands after
|
|
57
151
|
cloning this project:
|
58
152
|
|
59
153
|
```bash
|
60
|
-
|
61
|
-
|
154
|
+
bundle
|
155
|
+
DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bundle exec rake development_app
|
62
156
|
```
|
63
157
|
|
64
158
|
Note that the database user has to have rights to create and drop a database in
|
@@ -67,10 +161,10 @@ order to create the dummy test app database.
|
|
67
161
|
Then to test how the module works in Decidim, start the development server:
|
68
162
|
|
69
163
|
```bash
|
70
|
-
|
164
|
+
DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bin/rails s
|
71
165
|
```
|
72
166
|
|
73
|
-
Note that `bin/rails` is a
|
167
|
+
Note that `bin/rails` is a convenient wrapper around the command `cd development_app; bundle exec rails`.
|
74
168
|
|
75
169
|
In case you are using [rbenv](https://github.com/rbenv/rbenv) and have the
|
76
170
|
[rbenv-vars](https://github.com/rbenv/rbenv-vars) plugin installed for it, you
|
@@ -87,7 +181,7 @@ speed up the process.
|
|
87
181
|
|
88
182
|
To do that, start in a separate terminal than the one with `bin/rails s`, and BEFORE it, the following command:
|
89
183
|
|
90
|
-
```
|
184
|
+
```bash
|
91
185
|
bin/webpack-dev-server
|
92
186
|
```
|
93
187
|
|
@@ -102,14 +196,13 @@ project is set to follow the same rules that Decidim itself follows.
|
|
102
196
|
You can run the code styling checks by running the following commands from the
|
103
197
|
console:
|
104
198
|
|
105
|
-
```
|
106
|
-
|
199
|
+
```bash
|
200
|
+
bundle exec rubocop
|
107
201
|
```
|
108
202
|
|
109
203
|
To ease up following the style guide, you should install the plugin to your
|
110
204
|
favorite editor, such as:
|
111
205
|
|
112
|
-
- Atom - [linter-rubocop](https://atom.io/packages/linter-rubocop)
|
113
206
|
- Sublime Text - [Sublime RuboCop](https://github.com/pderichs/sublime_rubocop)
|
114
207
|
- Visual Studio Code - [Rubocop for Visual Studio Code](https://github.com/misogi/vscode-ruby-rubocop)
|
115
208
|
|
@@ -128,9 +221,9 @@ run the following commands:
|
|
128
221
|
To run the tests run the following in the gem development path:
|
129
222
|
|
130
223
|
```bash
|
131
|
-
|
132
|
-
|
133
|
-
|
224
|
+
bundle
|
225
|
+
DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bundle exec rake test_app
|
226
|
+
DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bundle exec rspec
|
134
227
|
```
|
135
228
|
|
136
229
|
Note that the database user has to have rights to create and drop a database in
|
@@ -144,11 +237,10 @@ commands shown above.
|
|
144
237
|
|
145
238
|
### Test code coverage
|
146
239
|
|
147
|
-
|
148
|
-
the `SIMPLECOV=1` environment variable in the rspec command as follows:
|
240
|
+
Running tests automatically generates a code coverage report. To generate the complete report run all the tests using this command:
|
149
241
|
|
150
242
|
```bash
|
151
|
-
|
243
|
+
bundle exec rspec
|
152
244
|
```
|
153
245
|
|
154
246
|
This will generate a folder named `coverage` in the project root which contains
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module ReportingProposals
|
5
|
+
# Exposes the proposal resource so users can view and create them.
|
6
|
+
module ProposalsPickerCellOverride
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
def proposals
|
11
|
+
@proposals ||= begin
|
12
|
+
proposals_query = Decidim.find_resource_manifest(:proposals).try(:resource_scope, component)
|
13
|
+
reporting_proposals_query = Decidim.find_resource_manifest(:reporting_proposals).try(:resource_scope, component)
|
14
|
+
(reporting_proposals_query ? proposals_query.or(reporting_proposals_query) : proposals_query)
|
15
|
+
&.includes(:component)
|
16
|
+
&.published
|
17
|
+
&.not_hidden
|
18
|
+
&.order(id: :asc)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Admin
|
5
|
+
module HideResourceOverride
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
def call
|
10
|
+
return broadcast(:invalid) unless hideable?
|
11
|
+
|
12
|
+
hide!
|
13
|
+
|
14
|
+
send_hide_notification_to_author
|
15
|
+
send_hide_email_to_author
|
16
|
+
|
17
|
+
broadcast(:ok, @reportable)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def send_hide_email_to_author
|
23
|
+
Decidim::Admin::HiddenResourceMailer.notify_mail(
|
24
|
+
@reportable, resource_authors, report_reasons
|
25
|
+
).deliver_later
|
26
|
+
end
|
27
|
+
|
28
|
+
def resource_authors
|
29
|
+
@reportable.try(:authors) || [@reportable.try(:author)]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Proposals
|
5
|
+
module Admin
|
6
|
+
module AnswerProposalOverride
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
def call
|
11
|
+
return broadcast(:invalid) if form.invalid?
|
12
|
+
|
13
|
+
store_initial_proposal_state
|
14
|
+
|
15
|
+
transaction do
|
16
|
+
answer_proposal
|
17
|
+
notify_proposal_answer
|
18
|
+
send_email_to_author
|
19
|
+
end
|
20
|
+
|
21
|
+
broadcast(:ok)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def send_email_to_author
|
27
|
+
return unless Decidim::ReportingProposals.notify_authors_on_answering.include?(proposal.component.manifest_name.to_sym)
|
28
|
+
|
29
|
+
affected_users.each do |user|
|
30
|
+
Decidim::Proposals::Admin::NotificationAnswerProposalMailer.notify_proposal_author(proposal, user).deliver_later
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def affected_users
|
35
|
+
proposal.notifiable_identities
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Proposals
|
5
|
+
module Admin
|
6
|
+
module AssignProposalsToValuatorOverride
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
def call
|
11
|
+
return broadcast(:invalid) unless form.valid?
|
12
|
+
|
13
|
+
assign_proposals
|
14
|
+
send_email
|
15
|
+
|
16
|
+
broadcast(:ok)
|
17
|
+
rescue ActiveRecord::RecordInvalid
|
18
|
+
broadcast(:invalid)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def send_email
|
24
|
+
ProposalsValuatorMailer.notify_proposals_valuator(form.valuator_role.user, form.current_user, form.proposals).deliver_later
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Proposals
|
5
|
+
module PublishProposalOverride
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
def call
|
10
|
+
return broadcast(:invalid) unless @proposal.authored_by?(@current_user)
|
11
|
+
|
12
|
+
transaction do
|
13
|
+
publish_proposal
|
14
|
+
increment_scores
|
15
|
+
send_notification
|
16
|
+
send_email_to_author
|
17
|
+
send_notification_to_participatory_space
|
18
|
+
end
|
19
|
+
|
20
|
+
broadcast(:ok, @proposal)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def send_notification_to_participatory_space
|
26
|
+
Decidim::EventsManager.publish(
|
27
|
+
event: "decidim.events.proposals.proposal_published",
|
28
|
+
event_class: Decidim::Proposals::PublishProposalEvent,
|
29
|
+
resource: @proposal,
|
30
|
+
followers: @proposal.participatory_space.followers - coauthors_followers - admins_followers,
|
31
|
+
extra: {
|
32
|
+
participatory_space: true
|
33
|
+
}
|
34
|
+
)
|
35
|
+
# put here to avoid override the call method
|
36
|
+
send_notification_to_admins
|
37
|
+
end
|
38
|
+
|
39
|
+
def send_notification_to_admins
|
40
|
+
return if admins_followers.empty?
|
41
|
+
|
42
|
+
Decidim::EventsManager.publish(
|
43
|
+
event: "decidim.events.proposals.proposal_published",
|
44
|
+
event_class: Decidim::Proposals::PublishProposalEvent,
|
45
|
+
resource: @proposal,
|
46
|
+
followers: admins_followers,
|
47
|
+
extra: {
|
48
|
+
type: "admin",
|
49
|
+
participatory_space: true
|
50
|
+
}
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
def admins_followers
|
55
|
+
@proposal.followers.where(admin: true).uniq
|
56
|
+
end
|
57
|
+
|
58
|
+
def send_email_to_author
|
59
|
+
return unless Decidim::ReportingProposals.notify_authors_on_publish.include?(@proposal.component.manifest_name.to_sym)
|
60
|
+
|
61
|
+
affected_users.each do |user|
|
62
|
+
Decidim::Proposals::NotificationPublishProposalMailer.notify_proposal_author(@proposal, user).deliver_later
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def affected_users
|
67
|
+
@proposal.notifiable_identities
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module ReportingProposals
|
5
|
+
module Admin
|
6
|
+
module CreateAnswerOverride
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
def proposals
|
11
|
+
@proposals ||= answer.sibling_scope(:proposals).where(id: @form.proposal_ids) + answer.sibling_scope(:reporting_proposals).where(id: @form.proposal_ids)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module ReportingProposals
|
5
|
+
module Admin
|
6
|
+
module CreateResultOverride
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
def proposals
|
11
|
+
@proposals ||= result.sibling_scope(:proposals).where(id: @form.proposal_ids) + result.sibling_scope(:reporting_proposals).where(id: @form.proposal_ids)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module ReportingProposals
|
5
|
+
module Admin
|
6
|
+
module UpdateResultOverride
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
def proposals
|
11
|
+
@proposals ||= result.sibling_scope(:proposals).where(id: form.proposal_ids) + result.sibling_scope(:reporting_proposals).where(id: form.proposal_ids)
|
12
|
+
end
|
13
|
+
|
14
|
+
def send_notifications
|
15
|
+
all = result.linked_resources(:proposals, "included_proposals") + result.linked_resources(:reporting_proposals, "included_proposals")
|
16
|
+
all.each do |proposal|
|
17
|
+
Decidim::EventsManager.publish(
|
18
|
+
event: "decidim.events.accountability.result_progress_updated",
|
19
|
+
event_class: Decidim::Accountability::ResultProgressUpdatedEvent,
|
20
|
+
resource: result,
|
21
|
+
affected_users: proposal.notifiable_identities,
|
22
|
+
followers: proposal.followers - proposal.notifiable_identities,
|
23
|
+
extra: {
|
24
|
+
progress: result.progress,
|
25
|
+
proposal_id: proposal.id
|
26
|
+
}
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module ReportingProposals
|
5
|
+
module CloseMeetingOverride
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
def proposals
|
10
|
+
@proposals ||= meeting.sibling_scope(:proposals).where(id: @form.proposal_ids) + meeting.sibling_scope(:reporting_proposals).where(id: form.proposal_ids)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module ReportingProposals
|
5
|
+
module CreateProjectOverride
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
def proposals
|
10
|
+
@proposals ||= project.sibling_scope(:proposals).where(id: @form.proposal_ids) + project.sibling_scope(:reporting_proposals).where(id: form.proposal_ids)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Templates
|
5
|
+
# A command with all the business logic when duplicating a questionnaire template
|
6
|
+
module Admin
|
7
|
+
module CopyQuestionnaireTemplateOverride
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
private
|
12
|
+
|
13
|
+
def copy_template
|
14
|
+
@copied_template = Template.create!(
|
15
|
+
organization: @template.organization,
|
16
|
+
name: @template.name,
|
17
|
+
description: @template.description,
|
18
|
+
target: :questionnaire
|
19
|
+
)
|
20
|
+
@resource = Decidim::Forms::Questionnaire.create!(
|
21
|
+
@template.templatable.dup.attributes.merge(
|
22
|
+
questionnaire_for: @copied_template
|
23
|
+
)
|
24
|
+
)
|
25
|
+
|
26
|
+
@copied_template.update!(templatable: @resource)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Templates
|
5
|
+
# A command with all the business logic when duplicating a questionnaire template
|
6
|
+
module Admin
|
7
|
+
module CreateQuestionnaireTemplateOverride
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
def call
|
12
|
+
return broadcast(:invalid) unless @form.valid?
|
13
|
+
|
14
|
+
@template = Decidim.traceability.create!(
|
15
|
+
Template,
|
16
|
+
@form.current_user,
|
17
|
+
name: @form.name,
|
18
|
+
description: @form.description,
|
19
|
+
organization: @form.current_organization,
|
20
|
+
target: :questionnaire
|
21
|
+
)
|
22
|
+
|
23
|
+
@questionnaire = Decidim::Forms::Questionnaire.create!(questionnaire_for: @template)
|
24
|
+
@template.update!(templatable: @questionnaire)
|
25
|
+
|
26
|
+
broadcast(:ok, @template)
|
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 Templates
|
5
|
+
# A command with all the business logic when duplicating a proposal's answer template
|
6
|
+
module Admin
|
7
|
+
class CopyProposalAnswerTemplate < Rectify::Command
|
8
|
+
def initialize(template)
|
9
|
+
@template = template
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
return broadcast(:invalid) unless @template.valid?
|
14
|
+
|
15
|
+
Template.transaction do
|
16
|
+
copy_template
|
17
|
+
end
|
18
|
+
|
19
|
+
broadcast(:ok, @copied_template)
|
20
|
+
end
|
21
|
+
|
22
|
+
def copy_template
|
23
|
+
@copied_template = Template.create!(
|
24
|
+
organization: @template.organization,
|
25
|
+
name: @template.name,
|
26
|
+
description: @template.description,
|
27
|
+
target: :proposal_answer,
|
28
|
+
field_values: @template.field_values,
|
29
|
+
templatable: @template.templatable
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Templates
|
5
|
+
module Admin
|
6
|
+
class CreateProposalAnswerTemplate < Rectify::Command
|
7
|
+
# Initializes the command.
|
8
|
+
#
|
9
|
+
# form - The source for this ProposalAnswerTemplate.
|
10
|
+
def initialize(form)
|
11
|
+
@form = form
|
12
|
+
end
|
13
|
+
|
14
|
+
def call
|
15
|
+
return broadcast(:invalid) unless @form.valid?
|
16
|
+
|
17
|
+
@template = Decidim.traceability.create!(
|
18
|
+
Template,
|
19
|
+
@form.current_user,
|
20
|
+
name: @form.name,
|
21
|
+
description: @form.description,
|
22
|
+
organization: @form.current_organization,
|
23
|
+
field_values: { internal_state: @form.internal_state },
|
24
|
+
target: :proposal_answer
|
25
|
+
)
|
26
|
+
|
27
|
+
resource = identify_templateable_resource
|
28
|
+
@template.update!(templatable: resource)
|
29
|
+
|
30
|
+
broadcast(:ok, @template)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def identify_templateable_resource
|
36
|
+
resource = @form.scope_for_availability.split("-")
|
37
|
+
case resource.first
|
38
|
+
when "organizations"
|
39
|
+
@form.current_organization
|
40
|
+
when "components"
|
41
|
+
component = Decidim::Component.find_by(id: resource.last)
|
42
|
+
component&.participatory_space&.decidim_organization_id == @form.current_organization.id ? component : nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|