decidim-initiatives 0.21.0 → 0.22.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +22 -0
- data/app/assets/images/decidim/gamification/badges/initiatives.svg +1 -87
- data/app/assets/images/decidim/initiatives/icon.svg +1 -3
- data/app/assets/stylesheet/decidim/initiatives/initiatives-votes.css.scss +0 -1
- data/app/assets/stylesheet/decidim/initiatives/initiatives.scss +0 -8
- data/app/assets/stylesheet/decidim/initiatives/popularity_item.css.scss +0 -1
- data/app/assets/stylesheet/decidim/initiatives/print-initiative.css.scss +0 -3
- data/app/cells/decidim/initiatives/content_blocks/highlighted_initiatives/show.erb +4 -3
- data/app/cells/decidim/initiatives/initiative_m_cell.rb +11 -0
- data/app/commands/decidim/initiatives/admin/create_initiative_type.rb +3 -0
- data/app/commands/decidim/initiatives/admin/send_initiative_to_technical_validation.rb +17 -0
- data/app/commands/decidim/initiatives/admin/update_initiative.rb +29 -10
- data/app/commands/decidim/initiatives/admin/update_initiative_type.rb +3 -0
- data/app/commands/decidim/initiatives/attachment_methods.rb +33 -0
- data/app/commands/decidim/initiatives/create_initiative.rb +23 -1
- data/app/commands/decidim/initiatives/vote_initiative.rb +16 -0
- data/app/controllers/concerns/decidim/initiatives/admin/filterable.rb +18 -4
- data/app/controllers/concerns/decidim/initiatives/orderable.rb +3 -1
- data/app/controllers/concerns/decidim/initiatives/single_initiative_type.rb +26 -0
- data/app/controllers/decidim/initiatives/admin/initiatives_controller.rb +20 -1
- data/app/controllers/decidim/initiatives/create_initiative_controller.rb +35 -5
- data/app/controllers/decidim/initiatives/initiatives_controller.rb +17 -3
- data/app/controllers/decidim/initiatives/versions_controller.rb +20 -0
- data/app/events/decidim/initiatives/admin/initiative_sent_to_technical_validation_event.rb +21 -0
- data/app/events/decidim/initiatives/admin/support_threshold_reached_event.rb +13 -0
- data/app/forms/decidim/initiatives/admin/initiative_form.rb +31 -0
- data/app/forms/decidim/initiatives/admin/initiative_type_form.rb +5 -1
- data/app/forms/decidim/initiatives/initiative_form.rb +34 -0
- data/app/forms/decidim/initiatives/vote_form.rb +3 -1
- data/app/helpers/decidim/initiatives/application_helper.rb +104 -0
- data/app/helpers/decidim/initiatives/initiative_helper.rb +13 -0
- data/app/helpers/decidim/initiatives/initiatives_helper.rb +10 -0
- data/app/jobs/decidim/initiatives/export_initiatives_job.rb +25 -0
- data/app/mailers/decidim/initiatives/initiatives_mailer.rb +0 -21
- data/app/models/concerns/decidim/initiatives/has_area.rb +30 -0
- data/app/models/decidim/initiative.rb +62 -10
- data/app/permissions/decidim/initiatives/admin/permissions.rb +7 -0
- data/app/permissions/decidim/initiatives/permissions.rb +35 -10
- data/app/serializers/decidim/initiatives/initiative_serializer.rb +32 -0
- data/app/services/decidim/initiatives/diff_renderer.rb +18 -0
- data/app/services/decidim/initiatives/initiative_search.rb +59 -15
- data/app/services/decidim/initiatives/status_change_notifier.rb +4 -5
- data/app/views/decidim/initiatives/admin/exports/_dropdown.html.erb +8 -0
- data/app/views/decidim/initiatives/admin/initiatives/_form.html.erb +24 -1
- data/app/views/decidim/initiatives/admin/initiatives/_initiative_attachments.erb +43 -0
- data/app/views/decidim/initiatives/admin/initiatives/index.html.erb +8 -3
- data/app/views/decidim/initiatives/admin/initiatives_types/_form.html.erb +12 -0
- data/app/views/decidim/initiatives/create_initiative/fill_data.html.erb +44 -10
- data/app/views/decidim/initiatives/create_initiative/finish.html.erb +17 -10
- data/app/views/decidim/initiatives/create_initiative/previous_form.html.erb +2 -1
- data/app/views/decidim/initiatives/create_initiative/promotal_committee.html.erb +1 -1
- data/app/views/decidim/initiatives/create_initiative/select_initiative_type.html.erb +1 -2
- data/app/views/decidim/initiatives/create_initiative/show_similar_initiatives.html.erb +1 -1
- data/app/views/decidim/initiatives/initiative_signatures/fill_personal_data.html.erb +1 -0
- data/app/views/decidim/initiatives/initiatives/_author.html.erb +1 -1
- data/app/views/decidim/initiatives/initiatives/_filters.html.erb +16 -28
- data/app/views/decidim/initiatives/initiatives/_index_header.html.erb +3 -3
- data/app/views/decidim/initiatives/initiatives/_initiatives.html.erb +1 -1
- data/app/views/decidim/initiatives/initiatives/_interactions.html.erb +2 -3
- data/app/views/decidim/initiatives/initiatives/_tags.html.erb +3 -0
- data/app/views/decidim/initiatives/initiatives/index.html.erb +1 -1
- data/app/views/decidim/initiatives/initiatives/show.html.erb +1 -0
- data/app/views/decidim/initiatives/versions/index.html.erb +8 -0
- data/app/views/decidim/initiatives/versions/show.html.erb +10 -0
- data/app/views/layouts/decidim/_initiative_creation_header.html.erb +2 -1
- data/app/views/layouts/decidim/_initiative_header.html.erb +2 -1
- data/app/views/layouts/decidim/_initiative_signature_creation_header.html.erb +1 -1
- data/app/views/layouts/decidim/initiative_creation.html.erb +1 -2
- data/app/views/layouts/decidim/initiative_signature_creation.html.erb +2 -2
- data/config/locales/ar.yml +12 -19
- data/config/locales/bg-BG.yml +13 -0
- data/config/locales/ca.yml +79 -17
- data/config/locales/cs.yml +88 -26
- data/config/locales/da-DK.yml +1 -0
- data/config/locales/de.yml +67 -16
- data/config/locales/el.yml +528 -0
- data/config/locales/en.yml +82 -20
- data/config/locales/es-MX.yml +79 -17
- data/config/locales/es-PY.yml +79 -17
- data/config/locales/es.yml +81 -19
- data/config/locales/et-EE.yml +1 -0
- data/config/locales/eu.yml +4 -7
- data/config/locales/fi-plain.yml +79 -17
- data/config/locales/fi.yml +97 -35
- data/config/locales/fr-CA.yml +529 -0
- data/config/locales/fr.yml +66 -16
- data/config/locales/ga-IE.yml +1 -0
- data/config/locales/gl.yml +4 -7
- data/config/locales/hr-HR.yml +1 -0
- data/config/locales/hu.yml +21 -18
- data/config/locales/id-ID.yml +4 -7
- data/config/locales/is-IS.yml +4 -7
- data/config/locales/it.yml +105 -57
- data/config/locales/ja-JP.yml +535 -0
- data/config/locales/lt-LT.yml +1 -0
- data/config/locales/lv-LV.yml +529 -0
- data/config/locales/mt-MT.yml +1 -0
- data/config/locales/nl.yml +66 -16
- data/config/locales/no.yml +14 -29
- data/config/locales/pl.yml +241 -176
- data/config/locales/pt-BR.yml +5 -8
- data/config/locales/pt.yml +227 -176
- data/config/locales/ro-RO.yml +532 -0
- data/config/locales/ru.yml +4 -7
- data/config/locales/sk-SK.yml +468 -0
- data/config/locales/sk.yml +462 -0
- data/config/locales/sl.yml +18 -0
- data/config/locales/sr-CS.yml +8 -0
- data/config/locales/sv.yml +77 -26
- data/config/locales/tr-TR.yml +4 -7
- data/config/locales/uk.yml +4 -7
- data/db/migrate/20200320105920_index_foreign_keys_in_decidim_initiatives.rb +8 -0
- data/db/migrate/20200320105921_index_foreign_keys_in_decidim_initiatives_votes.rb +8 -0
- data/db/migrate/20200417120551_add_custom_signature_end_time_option.rb +7 -0
- data/db/migrate/20200424110930_add_attachments_enabled_option.rb +7 -0
- data/db/migrate/20200514085422_add_area_to_initiatives.rb +7 -0
- data/db/migrate/20200514102631_add_area_enabled_option_to_initiatives.rb +7 -0
- data/db/seeds/city2.jpeg +0 -0
- data/lib/decidim/initiatives/admin_engine.rb +4 -0
- data/lib/decidim/initiatives/engine.rb +1 -0
- data/lib/decidim/initiatives/participatory_space.rb +9 -1
- data/lib/decidim/initiatives/test/factories.rb +30 -1
- data/lib/decidim/initiatives/version.rb +1 -1
- metadata +55 -15
- data/app/views/decidim/initiatives/initiatives_mailer/notify_validating_request.html.erb +0 -3
@@ -32,6 +32,7 @@ module Decidim
|
|
32
32
|
percentage_after = @initiative.reload.percentage
|
33
33
|
|
34
34
|
notify_percentage_change(percentage_before, percentage_after)
|
35
|
+
notify_support_threshold_reached(percentage_after)
|
35
36
|
|
36
37
|
broadcast(:ok, vote)
|
37
38
|
end
|
@@ -92,6 +93,21 @@ module Decidim
|
|
92
93
|
}
|
93
94
|
)
|
94
95
|
end
|
96
|
+
|
97
|
+
def notify_support_threshold_reached(percentage)
|
98
|
+
return unless percentage >= 100
|
99
|
+
|
100
|
+
Decidim::EventsManager.publish(
|
101
|
+
event: "decidim.events.initiatives.support_threshold_reached",
|
102
|
+
event_class: Decidim::Initiatives::Admin::SupportThresholdReachedEvent,
|
103
|
+
resource: @initiative,
|
104
|
+
followers: organization_admins
|
105
|
+
)
|
106
|
+
end
|
107
|
+
|
108
|
+
def organization_admins
|
109
|
+
Decidim::User.where(organization: @initiative.organization, admin: true)
|
110
|
+
end
|
95
111
|
end
|
96
112
|
end
|
97
113
|
end
|
@@ -14,22 +14,36 @@ module Decidim
|
|
14
14
|
private
|
15
15
|
|
16
16
|
def base_query
|
17
|
-
collection
|
17
|
+
collection.joins(:scoped_type).left_joins(:area).joins("JOIN decidim_users ON decidim_users.id = decidim_initiatives.decidim_author_id")
|
18
18
|
end
|
19
19
|
|
20
20
|
def search_field_predicate
|
21
|
-
:
|
21
|
+
:title_or_description_or_id_string_or_author_name_or_author_nickname_cont
|
22
22
|
end
|
23
23
|
|
24
24
|
def filters
|
25
|
-
[:state_eq]
|
25
|
+
[:state_eq, :type_id_eq, :decidim_area_id_eq]
|
26
26
|
end
|
27
27
|
|
28
28
|
def filters_with_values
|
29
29
|
{
|
30
|
-
state_eq: Initiative.states.keys
|
30
|
+
state_eq: Initiative.states.keys,
|
31
|
+
type_id_eq: InitiativesType.where(organization: current_organization).pluck(:id),
|
32
|
+
decidim_area_id_eq: current_organization.areas.pluck(:id)
|
31
33
|
}
|
32
34
|
end
|
35
|
+
|
36
|
+
def dynamically_translated_filters
|
37
|
+
[:type_id_eq, :decidim_area_id_eq]
|
38
|
+
end
|
39
|
+
|
40
|
+
def translated_type_id_eq(id)
|
41
|
+
translated_attribute(Decidim::InitiativesType.find_by(id: id).title[I18n.locale.to_s])
|
42
|
+
end
|
43
|
+
|
44
|
+
def translated_decidim_area_id_eq(id)
|
45
|
+
translated_attribute(Decidim::Area.find_by(id: id).name[I18n.locale.to_s])
|
46
|
+
end
|
33
47
|
end
|
34
48
|
end
|
35
49
|
end
|
@@ -14,7 +14,7 @@ module Decidim
|
|
14
14
|
# Available orders based on enabled settings
|
15
15
|
def available_orders
|
16
16
|
@available_orders ||= begin
|
17
|
-
available_orders = %w(random recent most_voted most_commented)
|
17
|
+
available_orders = %w(random recent most_voted most_commented recently_published)
|
18
18
|
available_orders
|
19
19
|
end
|
20
20
|
end
|
@@ -31,6 +31,8 @@ module Decidim
|
|
31
31
|
initiatives.order_by_most_commented
|
32
32
|
when "recent"
|
33
33
|
initiatives.order_by_most_recent
|
34
|
+
when "recently_published"
|
35
|
+
initiatives.order_by_most_recently_published
|
34
36
|
else
|
35
37
|
initiatives.order_randomly(random_seed)
|
36
38
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/concern"
|
4
|
+
|
5
|
+
module Decidim
|
6
|
+
module Initiatives
|
7
|
+
# Common methods for elements that need specific behaviour when there is only one initiative type.
|
8
|
+
module SingleInitiativeType
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
included do
|
12
|
+
helper_method :single_initiative_type?
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def current_organization_initiatives_type
|
17
|
+
Decidim::InitiativesType.where(organization: current_organization)
|
18
|
+
end
|
19
|
+
|
20
|
+
def single_initiative_type?
|
21
|
+
current_organization_initiatives_type.count == 1
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -8,6 +8,7 @@ module Decidim
|
|
8
8
|
# Controller used to manage the initiatives
|
9
9
|
class InitiativesController < Decidim::Initiatives::Admin::ApplicationController
|
10
10
|
include Decidim::Initiatives::NeedsInitiative
|
11
|
+
include Decidim::Initiatives::SingleInitiativeType
|
11
12
|
include Decidim::Initiatives::TypeSelectorOptions
|
12
13
|
include Decidim::Initiatives::Admin::Filterable
|
13
14
|
|
@@ -28,11 +29,14 @@ module Decidim
|
|
28
29
|
# GET /admin/initiatives/:id/edit
|
29
30
|
def edit
|
30
31
|
enforce_permission_to :edit, :initiative, initiative: current_initiative
|
32
|
+
|
33
|
+
form_attachment_model = form(AttachmentForm).from_model(current_initiative.attachments.first)
|
31
34
|
@form = form(Decidim::Initiatives::Admin::InitiativeForm)
|
32
35
|
.from_model(
|
33
36
|
current_initiative,
|
34
37
|
initiative: current_initiative
|
35
38
|
)
|
39
|
+
@form.attachment = form_attachment_model
|
36
40
|
|
37
41
|
render layout: "decidim/admin/initiative"
|
38
42
|
end
|
@@ -107,7 +111,7 @@ module Decidim
|
|
107
111
|
|
108
112
|
SendInitiativeToTechnicalValidation.call(current_initiative, current_user) do
|
109
113
|
on(:ok) do
|
110
|
-
redirect_to
|
114
|
+
redirect_to EngineRouter.main_proxy(current_initiative).initiatives_path(initiative_slug: nil), flash: {
|
111
115
|
notice: I18n.t(
|
112
116
|
"success",
|
113
117
|
scope: %w(decidim initiatives admin initiatives edit)
|
@@ -117,6 +121,17 @@ module Decidim
|
|
117
121
|
end
|
118
122
|
end
|
119
123
|
|
124
|
+
# GET /admin/initiatives/export
|
125
|
+
def export
|
126
|
+
enforce_permission_to :export, :initiatives
|
127
|
+
|
128
|
+
Decidim::Initiatives::ExportInitiativesJob.perform_later(current_user, params[:format] || default_format)
|
129
|
+
|
130
|
+
flash[:notice] = t("decidim.admin.exports.notice")
|
131
|
+
|
132
|
+
redirect_back(fallback_location: initiatives_path)
|
133
|
+
end
|
134
|
+
|
120
135
|
# GET /admin/initiatives/:id/export_votes
|
121
136
|
def export_votes
|
122
137
|
enforce_permission_to :export_votes, :initiative, initiative: current_initiative
|
@@ -162,6 +177,10 @@ module Decidim
|
|
162
177
|
def pdf_signature_service
|
163
178
|
@pdf_signature_service ||= Decidim.pdf_signature_service.to_s.safe_constantize
|
164
179
|
end
|
180
|
+
|
181
|
+
def default_format
|
182
|
+
"json"
|
183
|
+
end
|
165
184
|
end
|
166
185
|
end
|
167
186
|
end
|
@@ -12,11 +12,13 @@ module Decidim
|
|
12
12
|
include Decidim::FormFactory
|
13
13
|
include InitiativeHelper
|
14
14
|
include TypeSelectorOptions
|
15
|
+
include SingleInitiativeType
|
15
16
|
|
16
17
|
helper Decidim::Admin::IconLinkHelper
|
17
18
|
helper InitiativeHelper
|
18
19
|
helper_method :similar_initiatives
|
19
20
|
helper_method :scopes
|
21
|
+
helper_method :areas
|
20
22
|
helper_method :current_initiative
|
21
23
|
helper_method :initiative_type
|
22
24
|
helper_method :promotal_committee_required?
|
@@ -43,7 +45,14 @@ module Decidim
|
|
43
45
|
def select_initiative_type_step(_parameters)
|
44
46
|
@form = form(Decidim::Initiatives::SelectInitiativeTypeForm).instance
|
45
47
|
session[:initiative] = {}
|
46
|
-
|
48
|
+
|
49
|
+
if single_initiative_type?
|
50
|
+
redirect_to next_wizard_path
|
51
|
+
return
|
52
|
+
end
|
53
|
+
|
54
|
+
@form = form(Decidim::Initiatives::SelectInitiativeTypeForm).instance
|
55
|
+
render_wizard unless performed?
|
47
56
|
end
|
48
57
|
|
49
58
|
def previous_form_step(parameters)
|
@@ -68,10 +77,18 @@ module Decidim
|
|
68
77
|
|
69
78
|
def fill_data_step(parameters)
|
70
79
|
@form = build_form(Decidim::Initiatives::InitiativeForm, parameters)
|
80
|
+
@form.attachment = form(AttachmentForm).from_params({})
|
81
|
+
|
71
82
|
render_wizard
|
72
83
|
end
|
73
84
|
|
74
85
|
def promotal_committee_step(parameters)
|
86
|
+
@form = build_form(Decidim::Initiatives::InitiativeForm, parameters)
|
87
|
+
unless @form.valid?
|
88
|
+
redirect_to previous_wizard_path(validate_form: true)
|
89
|
+
return
|
90
|
+
end
|
91
|
+
|
75
92
|
skip_step unless promotal_committee_required?
|
76
93
|
|
77
94
|
if session_initiative.has_key?(:id)
|
@@ -79,8 +96,6 @@ module Decidim
|
|
79
96
|
return
|
80
97
|
end
|
81
98
|
|
82
|
-
@form = build_form(Decidim::Initiatives::InitiativeForm, parameters)
|
83
|
-
|
84
99
|
CreateInitiative.call(@form, current_user) do
|
85
100
|
on(:ok) do |initiative|
|
86
101
|
session[:initiative][:id] = initiative.id
|
@@ -109,7 +124,12 @@ module Decidim
|
|
109
124
|
end
|
110
125
|
|
111
126
|
def build_form(klass, parameters)
|
112
|
-
@form =
|
127
|
+
@form = if single_initiative_type?
|
128
|
+
form(klass).from_params(parameters.merge(type_id: current_organization_initiatives_type.first.id), extra_context)
|
129
|
+
else
|
130
|
+
form(klass).from_params(parameters, extra_context)
|
131
|
+
end
|
132
|
+
|
113
133
|
attributes = @form.attributes_with_values
|
114
134
|
session[:initiative] = session_initiative.merge(attributes)
|
115
135
|
@form.valid? if params[:validate_form]
|
@@ -117,6 +137,12 @@ module Decidim
|
|
117
137
|
@form
|
118
138
|
end
|
119
139
|
|
140
|
+
def extra_context
|
141
|
+
return {} unless initiative_type_id
|
142
|
+
|
143
|
+
{ initiative_type: initiative_type }
|
144
|
+
end
|
145
|
+
|
120
146
|
def scopes
|
121
147
|
@scopes ||= InitiativesTypeScope.where(decidim_initiatives_types_id: @form.type_id)
|
122
148
|
end
|
@@ -126,7 +152,11 @@ module Decidim
|
|
126
152
|
end
|
127
153
|
|
128
154
|
def initiative_type
|
129
|
-
@initiative_type ||= InitiativesType.find(
|
155
|
+
@initiative_type ||= InitiativesType.find(initiative_type_id)
|
156
|
+
end
|
157
|
+
|
158
|
+
def initiative_type_id
|
159
|
+
session_initiative[:type_id] || @form&.type_id
|
130
160
|
end
|
131
161
|
|
132
162
|
def session_initiative
|
@@ -25,6 +25,7 @@ module Decidim
|
|
25
25
|
include Decidim::Initiatives::Orderable
|
26
26
|
include TypeSelectorOptions
|
27
27
|
include NeedsInitiative
|
28
|
+
include SingleInitiativeType
|
28
29
|
|
29
30
|
helper_method :collection, :initiatives, :filter, :stats
|
30
31
|
|
@@ -70,13 +71,26 @@ module Decidim
|
|
70
71
|
def default_filter_params
|
71
72
|
{
|
72
73
|
search_text: "",
|
73
|
-
state: "open",
|
74
|
-
|
74
|
+
state: ["open"],
|
75
|
+
type_id: default_filter_type_params,
|
75
76
|
author: "any",
|
76
|
-
scope_id:
|
77
|
+
scope_id: default_filter_scope_params,
|
78
|
+
area_id: default_filter_area_params
|
77
79
|
}
|
78
80
|
end
|
79
81
|
|
82
|
+
def default_filter_type_params
|
83
|
+
%w(all) + Decidim::InitiativesType.where(organization: current_organization).pluck(:id).map(&:to_s)
|
84
|
+
end
|
85
|
+
|
86
|
+
def default_filter_scope_params
|
87
|
+
%w(all global) + current_organization.scopes.pluck(:id).map(&:to_s)
|
88
|
+
end
|
89
|
+
|
90
|
+
def default_filter_area_params
|
91
|
+
%w(all) + current_organization.areas.pluck(:id).map(&:to_s)
|
92
|
+
end
|
93
|
+
|
80
94
|
def context_params
|
81
95
|
{
|
82
96
|
organization: current_organization,
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Initiatives
|
5
|
+
# Exposes Initiatives versions so users can see how an Initiative
|
6
|
+
# has been updated through time.
|
7
|
+
class VersionsController < Decidim::Initiatives::ApplicationController
|
8
|
+
include ParticipatorySpaceContext
|
9
|
+
participatory_space_layout
|
10
|
+
helper InitiativeHelper
|
11
|
+
|
12
|
+
include NeedsInitiative
|
13
|
+
include Decidim::ResourceVersionsConcern
|
14
|
+
|
15
|
+
def versioned_resource
|
16
|
+
current_initiative
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen-string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Initiatives
|
5
|
+
module Admin
|
6
|
+
class InitiativeSentToTechnicalValidationEvent < Decidim::Events::SimpleEvent
|
7
|
+
include Rails.application.routes.mounted_helpers
|
8
|
+
|
9
|
+
i18n_attributes :admin_initiative_url, :admin_initiative_path
|
10
|
+
|
11
|
+
def admin_initiative_path
|
12
|
+
ResourceLocatorPresenter.new(resource).edit
|
13
|
+
end
|
14
|
+
|
15
|
+
def admin_initiative_url
|
16
|
+
decidim_admin_initiatives.edit_initiative_url(resource, resource.mounted_params)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -14,20 +14,26 @@ module Decidim
|
|
14
14
|
translatable_attribute :description, String
|
15
15
|
attribute :type_id, Integer
|
16
16
|
attribute :decidim_scope_id, Integer
|
17
|
+
attribute :area_id, Integer
|
17
18
|
attribute :signature_type, String
|
18
19
|
attribute :signature_start_date, Decidim::Attributes::LocalizedDate
|
19
20
|
attribute :signature_end_date, Decidim::Attributes::LocalizedDate
|
20
21
|
attribute :hashtag, String
|
21
22
|
attribute :offline_votes, Integer
|
22
23
|
attribute :state, String
|
24
|
+
attribute :attachment, AttachmentForm
|
23
25
|
|
24
26
|
validates :title, :description, presence: true
|
27
|
+
validates :area, presence: true, if: ->(form) { form.area_id.present? }
|
25
28
|
validates :signature_type, presence: true, if: :signature_type_updatable?
|
26
29
|
validates :signature_start_date, presence: true, if: ->(form) { form.context.initiative.published? }
|
27
30
|
validates :signature_end_date, presence: true, if: ->(form) { form.context.initiative.published? }
|
28
31
|
validates :signature_end_date, date: { after: :signature_start_date }, if: lambda { |form|
|
29
32
|
form.signature_start_date.present? && form.signature_end_date.present?
|
30
33
|
}
|
34
|
+
validates :signature_end_date, date: { after: Date.current }, if: lambda { |form|
|
35
|
+
form.signature_start_date.blank? && form.signature_end_date.present?
|
36
|
+
}
|
31
37
|
|
32
38
|
validates :offline_votes,
|
33
39
|
numericality: {
|
@@ -35,6 +41,9 @@ module Decidim
|
|
35
41
|
greater_than: 0
|
36
42
|
}, allow_blank: true
|
37
43
|
|
44
|
+
validate :notify_missing_attachment_if_errored
|
45
|
+
validate :area_is_not_removed
|
46
|
+
|
38
47
|
def map_model(model)
|
39
48
|
self.type_id = model.type.id
|
40
49
|
self.decidim_scope_id = model.scope&.id
|
@@ -51,17 +60,39 @@ module Decidim
|
|
51
60
|
false
|
52
61
|
end
|
53
62
|
|
63
|
+
def area_updatable?
|
64
|
+
@area_updatable ||= current_user.admin? || context.initiative.created?
|
65
|
+
end
|
66
|
+
|
54
67
|
def scoped_type_id
|
55
68
|
return unless type && decidim_scope_id
|
56
69
|
|
57
70
|
type.scopes.find_by!(decidim_scopes_id: decidim_scope_id).id
|
58
71
|
end
|
59
72
|
|
73
|
+
def area
|
74
|
+
@area ||= current_organization.areas.find_by(id: area_id)
|
75
|
+
end
|
76
|
+
|
60
77
|
private
|
61
78
|
|
62
79
|
def type
|
63
80
|
@type ||= type_id ? Decidim::InitiativesType.find(type_id) : context.initiative.type
|
64
81
|
end
|
82
|
+
|
83
|
+
# This method will add an error to the `attachment` field only if there's
|
84
|
+
# any error in any other field. This is needed because when the form has
|
85
|
+
# an error, the attachment is lost, so we need a way to inform the user of
|
86
|
+
# this problem.
|
87
|
+
def notify_missing_attachment_if_errored
|
88
|
+
errors.add(:attachment, :needs_to_be_reattached) if errors.any? && attachment.present?
|
89
|
+
end
|
90
|
+
|
91
|
+
def area_is_not_removed
|
92
|
+
return if context.initiative.decidim_area_id.blank? || context.initiative.created?
|
93
|
+
|
94
|
+
errors.add(:area_id, :blank) if area_id.blank?
|
95
|
+
end
|
65
96
|
end
|
66
97
|
end
|
67
98
|
end
|
@@ -14,6 +14,9 @@ module Decidim
|
|
14
14
|
attribute :banner_image, String
|
15
15
|
attribute :signature_type, String
|
16
16
|
attribute :undo_online_signatures_enabled, Boolean
|
17
|
+
attribute :attachments_enabled, Boolean
|
18
|
+
attribute :custom_signature_end_date_enabled, Boolean
|
19
|
+
attribute :area_enabled, Boolean
|
17
20
|
attribute :promoting_committee_enabled, Boolean
|
18
21
|
attribute :minimum_committee_members, Integer
|
19
22
|
attribute :collect_user_extra_fields, Boolean
|
@@ -22,7 +25,8 @@ module Decidim
|
|
22
25
|
attribute :document_number_authorization_handler, String
|
23
26
|
|
24
27
|
validates :title, :description, translatable_presence: true
|
25
|
-
validates :
|
28
|
+
validates :attachments_enabled, :undo_online_signatures_enabled, :custom_signature_end_date_enabled,
|
29
|
+
:area_enabled, :promoting_committee_enabled, inclusion: { in: [true, false] }
|
26
30
|
validates :minimum_committee_members, numericality: { only_integer: true }, allow_nil: true
|
27
31
|
validates :banner_image, presence: true, if: ->(form) { form.context.initiative_type.nil? }
|
28
32
|
|