decidim-action_delegator 0.8.2 → 0.9.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 (194) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +104 -58
  3. data/Rakefile +2 -2
  4. data/app/commands/decidim/action_delegator/admin/create_delegation.rb +1 -3
  5. data/app/commands/decidim/action_delegator/admin/create_setting.rb +5 -2
  6. data/app/commands/decidim/action_delegator/admin/update_setting.rb +4 -2
  7. data/app/controllers/concerns/decidim/action_delegator/devise/sessions_controller_override.rb +1 -1
  8. data/app/controllers/concerns/decidim/action_delegator/election_per_question_votes_controller_override.rb +65 -0
  9. data/app/controllers/concerns/decidim/action_delegator/election_votes_controller_override.rb +38 -0
  10. data/app/controllers/concerns/decidim/action_delegator/votes_controller_methods.rb +46 -0
  11. data/app/controllers/decidim/action_delegator/admin/application_controller.rb +11 -5
  12. data/app/controllers/decidim/action_delegator/admin/delegations_controller.rb +2 -10
  13. data/app/controllers/decidim/action_delegator/admin/invite_participants_controller.rb +0 -8
  14. data/app/controllers/decidim/action_delegator/admin/manage_delegations_controller.rb +13 -20
  15. data/app/controllers/decidim/action_delegator/admin/manage_participants_controller.rb +11 -19
  16. data/app/controllers/decidim/action_delegator/admin/participants_controller.rb +1 -9
  17. data/app/controllers/decidim/action_delegator/admin/permissions_controller.rb +1 -24
  18. data/app/controllers/decidim/action_delegator/admin/ponderations_controller.rb +0 -8
  19. data/app/controllers/decidim/action_delegator/admin/settings_controller.rb +12 -12
  20. data/app/controllers/decidim/action_delegator/application_controller.rb +3 -3
  21. data/app/controllers/decidim/action_delegator/elections/admin/results_controller.rb +58 -0
  22. data/app/controllers/decidim/action_delegator/elections/results_controller.rb +36 -0
  23. data/app/controllers/decidim/action_delegator/user_delegations_controller.rb +1 -1
  24. data/app/controllers/decidim/action_delegator/verifications/delegations_verifier/authorizations_controller.rb +14 -18
  25. data/app/forms/decidim/action_delegator/admin/action_delegator_census_form.rb +44 -0
  26. data/app/forms/decidim/action_delegator/admin/csv_import_form.rb +17 -0
  27. data/app/forms/decidim/action_delegator/admin/ponderation_form.rb +2 -1
  28. data/app/forms/decidim/action_delegator/admin/setting_form.rb +16 -10
  29. data/app/forms/decidim/action_delegator/censuses/internal_users_form.rb +32 -0
  30. data/app/forms/decidim/action_delegator/verifications/delegations_verifier_form.rb +41 -25
  31. data/app/helpers/decidim/action_delegator/admin/{delegation_helper.rb → settings_helper.rb} +3 -16
  32. data/app/helpers/decidim/action_delegator/settings_helper.rb +124 -0
  33. data/app/jobs/decidim/action_delegator/admin/invite_participants_job.rb +1 -1
  34. data/app/jobs/decidim/action_delegator/send_sms_job.rb +2 -2
  35. data/app/jobs/decidim/action_delegator/twilio_send_sms_job.rb +2 -2
  36. data/app/models/decidim/action_delegator/delegation.rb +15 -14
  37. data/app/models/decidim/action_delegator/participant.rb +7 -10
  38. data/app/models/decidim/action_delegator/ponderation.rb +0 -2
  39. data/app/models/decidim/action_delegator/setting.rb +14 -32
  40. data/app/overrides/decidim/elections/admin/dashboard/_results/_add_results_contents.html.erb.deface +10 -0
  41. data/app/overrides/decidim/elections/admin/dashboard/_results/_add_results_tabs.html.erb.deface +3 -0
  42. data/app/overrides/decidim/elections/elections/_election_aside/add_delegation_buttons.html.erb.deface +3 -0
  43. data/app/overrides/decidim/elections/elections/_vote_results/replace_results_div.html.erb.deface +8 -0
  44. data/app/overrides/decidim/elections/per_question_votes/show/add_delegation_hidden_input.html.erb.deface +3 -0
  45. data/app/overrides/decidim/elections/per_question_votes/show/add_delegation_id_to_links.html.erb.deface +3 -0
  46. data/app/overrides/decidim/elections/per_question_votes/waiting/add_delegation_buttons.html.erb.deface +3 -0
  47. data/app/overrides/decidim/elections/votes/receipt/add_delegation_buttons.html.erb.deface +3 -0
  48. data/app/packs/entrypoints/decidim_action_delegator_elections.js +1 -0
  49. data/app/packs/src/decidim/action_delegator/elections_live_results.js +160 -0
  50. data/app/permissions/decidim/action_delegator/admin/permissions.rb +29 -0
  51. data/app/permissions/decidim/action_delegator/permissions.rb +6 -30
  52. data/app/presenters/decidim/action_delegator/setting_presenter.rb +33 -0
  53. data/app/queries/decidim/action_delegator/action_delegator_census_users.rb +51 -0
  54. data/app/queries/decidim/action_delegator/authorized_resources.rb +28 -0
  55. data/app/queries/decidim/action_delegator/election_settings.rb +23 -0
  56. data/app/queries/decidim/action_delegator/{delegated_votes_versions.rb → elections_delegated_votes_versions.rb} +8 -8
  57. data/app/queries/decidim/action_delegator/elections_question_responses_by_type.rb +33 -0
  58. data/app/queries/decidim/action_delegator/elections_question_weighted_responses.rb +28 -0
  59. data/app/queries/decidim/action_delegator/elections_votes_with_ponderations.rb +62 -0
  60. data/app/services/decidim/action_delegator/participants_csv_importer.rb +1 -1
  61. data/app/services/decidim/action_delegator/sms_gateway.rb +2 -2
  62. data/app/views/decidim/action_delegator/admin/censuses/_action_delegator_census_form.html.erb +44 -0
  63. data/app/views/decidim/action_delegator/admin/censuses/_action_delegator_census_options_form.html.erb +25 -0
  64. data/app/views/decidim/action_delegator/admin/delegations/index.html.erb +12 -13
  65. data/app/views/decidim/action_delegator/admin/delegations/new.html.erb +29 -27
  66. data/app/views/decidim/action_delegator/admin/manage_delegations/new.html.erb +36 -24
  67. data/app/views/decidim/action_delegator/admin/manage_participants/new.html.erb +47 -33
  68. data/app/views/decidim/action_delegator/admin/participants/_form.html.erb +14 -8
  69. data/app/views/decidim/action_delegator/admin/participants/edit.html.erb +11 -13
  70. data/app/views/decidim/action_delegator/admin/participants/index.html.erb +20 -25
  71. data/app/views/decidim/action_delegator/admin/participants/new.html.erb +11 -13
  72. data/app/views/decidim/action_delegator/admin/ponderations/_form.html.erb +13 -7
  73. data/app/views/decidim/action_delegator/admin/ponderations/edit.html.erb +11 -13
  74. data/app/views/decidim/action_delegator/admin/ponderations/index.html.erb +8 -11
  75. data/app/views/decidim/action_delegator/admin/ponderations/new.html.erb +11 -13
  76. data/app/views/decidim/action_delegator/admin/settings/_form.html.erb +26 -12
  77. data/app/views/decidim/action_delegator/admin/settings/_participants_sync_check.html.erb +1 -1
  78. data/app/views/decidim/action_delegator/admin/settings/_setting_checks.html.erb +11 -16
  79. data/app/views/decidim/action_delegator/admin/settings/edit.html.erb +11 -12
  80. data/app/views/decidim/action_delegator/admin/settings/index.html.erb +22 -19
  81. data/app/views/decidim/action_delegator/admin/settings/new.html.erb +11 -12
  82. data/app/views/decidim/action_delegator/admin/shared/_tabs_menu.html.erb +15 -0
  83. data/app/views/decidim/action_delegator/censuses/_internal_users_form.html.erb +61 -0
  84. data/app/views/decidim/action_delegator/elections/_delegation_buttons.html.erb +10 -0
  85. data/app/views/decidim/action_delegator/elections/_normal_election_buttons.html.erb +13 -0
  86. data/app/views/decidim/action_delegator/elections/_per_question_buttons.html.erb +9 -0
  87. data/app/views/decidim/action_delegator/elections/_per_question_waiting_buttons.html.erb +19 -0
  88. data/app/views/decidim/action_delegator/elections/_vote_results.html.erb +10 -0
  89. data/app/views/decidim/action_delegator/elections/_vote_results_question.html.erb +13 -0
  90. data/app/views/decidim/action_delegator/elections/admin/dashboard/_by_type_and_weight.html.erb +45 -0
  91. data/app/views/decidim/action_delegator/elections/admin/dashboard/_results_tabs.html.erb +5 -0
  92. data/app/views/decidim/action_delegator/elections/admin/dashboard/_results_type_info.html.erb +4 -0
  93. data/app/views/decidim/action_delegator/elections/admin/dashboard/_sum_of_weights.html.erb +43 -0
  94. data/app/views/decidim/action_delegator/elections/admin/dashboard/_totals.html.erb +27 -0
  95. data/app/views/decidim/action_delegator/user_delegations/index.html.erb +13 -14
  96. data/app/views/decidim/action_delegator/verifications/delegations_verifier/authorizations/edit.html.erb +19 -29
  97. data/app/views/decidim/action_delegator/verifications/delegations_verifier/authorizations/new.html.erb +42 -40
  98. data/config/assets.rb +3 -36
  99. data/config/i18n-tasks.yml +27 -5
  100. data/config/locales/ca.yml +103 -146
  101. data/config/locales/cs.yml +161 -145
  102. data/config/locales/en.yml +110 -75
  103. data/config/locales/es.yml +108 -154
  104. data/db/migrate/20200824113801_create_settings.rb +1 -1
  105. data/db/migrate/20250729104037_add_title_to_action_delegator_settings.rb +31 -0
  106. data/lib/decidim/action_delegator/admin_engine.rb +72 -45
  107. data/lib/decidim/action_delegator/common_rake.rb +13 -0
  108. data/lib/decidim/action_delegator/engine.rb +48 -19
  109. data/lib/decidim/action_delegator/test/delegation_examples.rb +144 -0
  110. data/lib/decidim/action_delegator/test/factories.rb +11 -6
  111. data/lib/decidim/action_delegator/verifications/delegations_authorizer.rb +80 -47
  112. data/lib/decidim/action_delegator/version.rb +3 -3
  113. data/lib/decidim/action_delegator.rb +8 -26
  114. data/lib/tasks/migrate_consultations.rake +382 -0
  115. data/lib/tasks/upgrade_tasks.rake +5 -0
  116. data/package.json +10 -27
  117. metadata +72 -122
  118. data/app/commands/concerns/decidim/action_delegator/consultations/multiple_vote_question_override.rb +0 -31
  119. data/app/commands/concerns/decidim/action_delegator/consultations/vote_question_override.rb +0 -44
  120. data/app/commands/decidim/action_delegator/admin/fix_resource_permissions.rb +0 -46
  121. data/app/commands/decidim/action_delegator/vote_delegation.rb +0 -28
  122. data/app/controllers/concerns/decidim/action_delegator/consultations/consultations_controller_override.rb +0 -16
  123. data/app/controllers/concerns/decidim/action_delegator/consultations/question_multiple_votes_controller_override.rb +0 -29
  124. data/app/controllers/concerns/decidim/action_delegator/consultations/question_votes_controller_override.rb +0 -57
  125. data/app/controllers/concerns/decidim/action_delegator/consultations/questions_controller_override.rb +0 -16
  126. data/app/controllers/concerns/decidim/action_delegator/needs_consultation_styles.rb +0 -24
  127. data/app/controllers/decidim/action_delegator/admin/consultations/exports_controller.rb +0 -27
  128. data/app/controllers/decidim/action_delegator/admin/consultations_controller.rb +0 -47
  129. data/app/controllers/decidim/action_delegator/admin/exports/_sum_of_weights_controller.rb +0 -15
  130. data/app/controllers/decidim/action_delegator/questions_summary_controller.rb +0 -14
  131. data/app/forms/concerns/decidim/action_delegator/consultations/vote_form_override.rb +0 -15
  132. data/app/helpers/decidim/action_delegator/delegation_helper.rb +0 -13
  133. data/app/jobs/decidim/action_delegator/export_consultation_results_job.rb +0 -51
  134. data/app/models/concerns/decidim/action_delegator/consultations/question_override.rb +0 -36
  135. data/app/models/concerns/decidim/action_delegator/consultations/vote_override.rb +0 -15
  136. data/app/models/decidim/action_delegator/unversioned_vote.rb +0 -19
  137. data/app/models/decidim/action_delegator/whodunnit_vote.rb +0 -28
  138. data/app/overrides/decidim/consultations/admin/consultations/results/add_ongoing_warning.html.erb.deface +0 -3
  139. data/app/overrides/decidim/consultations/consultations/_question/add_delegation_link.html.erb.deface +0 -3
  140. data/app/overrides/decidim/consultations/consultations/_question/replace_vote_info.html.erb.deface +0 -4
  141. data/app/overrides/decidim/consultations/consultations/_regular_questions/prevent_empty_questions.html.erb.deface +0 -10
  142. data/app/overrides/decidim/consultations/consultations/_regular_questions/remove_highlighted_scopes.html.erb.deface +0 -5
  143. data/app/overrides/decidim/consultations/question_multiple_votes/_form/add_delegation_notice.html.erb.deface +0 -8
  144. data/app/overrides/decidim/consultations/questions/_results/replace_results.html.erb.deface +0 -3
  145. data/app/overrides/decidim/consultations/questions/_vote_button/add_delegations_link.html.erb.deface +0 -3
  146. data/app/overrides/decidim/consultations/questions/_vote_button/add_modal.html.erb.deface +0 -3
  147. data/app/overrides/decidim/consultations/questions/_vote_button/add_modal_javascript.html.erb.deface +0 -3
  148. data/app/overrides/decidim/consultations/questions/_vote_button/replace_delegation_to_multivote_link.html.erb.deface +0 -8
  149. data/app/overrides/decidim/consultations/questions/_vote_modal/add_delegation_callout.html.erb.deface +0 -3
  150. data/app/overrides/decidim/consultations/questions/_vote_modal_confirm/add_delegation_callout.html.erb.deface +0 -3
  151. data/app/overrides/decidim/consultations/questions/_vote_modal_confirm/add_hidden_field.html.erb.deface +0 -3
  152. data/app/overrides/layouts/decidim/_consultation_header/add_consultation_callout.html.erb.deface +0 -9
  153. data/app/overrides/layouts/decidim/_question_header/add_consultation_callout.html.erb.deface +0 -9
  154. data/app/overrides/layouts/decidim/admin/remove_deprecation.rb +0 -10
  155. data/app/packs/entrypoints/decidim_action_delegator.scss +0 -1
  156. data/app/packs/entrypoints/decidim_action_delegator_questions.js +0 -5
  157. data/app/packs/entrypoints/decidim_action_delegator_questions_summary.js +0 -1
  158. data/app/packs/src/decidim/action_delegator/questions.js +0 -33
  159. data/app/packs/src/decidim/action_delegator/summary.js +0 -24
  160. data/app/packs/stylesheets/decidim/action_delegator/questions.scss +0 -26
  161. data/app/permissions/concerns/decidim/action_delegator/consultations/permissions_override.rb +0 -35
  162. data/app/presenters/decidim/action_delegator/question_with_totals.rb +0 -24
  163. data/app/queries/decidim/action_delegator/consultation_delegations.rb +0 -25
  164. data/app/queries/decidim/action_delegator/delegates_votes_by_consultation.rb +0 -24
  165. data/app/queries/decidim/action_delegator/delegates_votes_by_question.rb +0 -26
  166. data/app/queries/decidim/action_delegator/delegation_votes.rb +0 -30
  167. data/app/queries/decidim/action_delegator/grantee_delegations.rb +0 -24
  168. data/app/queries/decidim/action_delegator/organization_delegations.rb +0 -26
  169. data/app/queries/decidim/action_delegator/organization_settings.rb +0 -31
  170. data/app/queries/decidim/action_delegator/responses.rb +0 -24
  171. data/app/queries/decidim/action_delegator/responses_by_membership.rb +0 -58
  172. data/app/queries/decidim/action_delegator/scrutiny.rb +0 -87
  173. data/app/queries/decidim/action_delegator/setting_delegations.rb +0 -19
  174. data/app/queries/decidim/action_delegator/sum_of_membership_weight.rb +0 -44
  175. data/app/queries/decidim/action_delegator/sum_of_weights.rb +0 -25
  176. data/app/queries/decidim/action_delegator/type_and_weight.rb +0 -26
  177. data/app/queries/decidim/action_delegator/voted_with_ponderations.rb +0 -30
  178. data/app/queries/decidim/action_delegator/votes_count_aggregation.rb +0 -34
  179. data/app/serializers/decidim/action_delegator/consultation_results_serializer.rb +0 -19
  180. data/app/views/decidim/action_delegator/admin/consultations/_ongoing_consultation_warning.html.erb +0 -3
  181. data/app/views/decidim/action_delegator/admin/consultations/results.html.erb +0 -65
  182. data/app/views/decidim/action_delegator/admin/consultations/weighted_results.html.erb +0 -66
  183. data/app/views/decidim/action_delegator/consultations/_link_to_question.html.erb +0 -11
  184. data/app/views/decidim/action_delegator/consultations/_link_with_results.html.erb +0 -11
  185. data/app/views/decidim/action_delegator/consultations/questions/_callout.html.erb +0 -5
  186. data/app/views/decidim/action_delegator/consultations/questions/_delegations_modal.html.erb +0 -34
  187. data/app/views/decidim/action_delegator/consultations/questions/_link_to_delegations.html.erb +0 -15
  188. data/app/views/decidim/action_delegator/consultations/questions/_vote_delegated_active.html.erb +0 -32
  189. data/app/views/decidim/action_delegator/consultations/questions/_vote_delegated_finished.html.erb +0 -9
  190. data/app/views/decidim/action_delegator/consultations/questions/_vote_delegated_upcoming.html.erb +0 -8
  191. data/app/views/decidim/action_delegator/consultations/questions/_weight_results.html.erb +0 -8
  192. data/app/views/decidim/consultations/question_votes/_callout.html.erb +0 -47
  193. data/app/views/decidim/consultations/question_votes/update_vote_button.js.erb +0 -82
  194. data/lib/tasks/import_direct_verification.rake +0 -30
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decidim
4
- module ActionDelegator
5
- # This query object replaces the ActiveRecord association we would have between the Vote and
6
- # Delegation models. Unfortunately we can't use custom foreign keys on both ends of the
7
- # association so this aims to replace `delegation.votes`.
8
- class DelegationVotes < Decidim::Query
9
- def query
10
- Delegation.joins(
11
- delegations.join(votes).on(vote_author_eq_granter).join_sources
12
- )
13
- end
14
-
15
- private
16
-
17
- def votes
18
- Decidim::Consultations::Vote.arel_table
19
- end
20
-
21
- def delegations
22
- Delegation.arel_table
23
- end
24
-
25
- def vote_author_eq_granter
26
- votes[:decidim_author_id].eq(delegations[:granter_id])
27
- end
28
- end
29
- end
30
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decidim
4
- module ActionDelegator
5
- class GranteeDelegations
6
- def self.for(consultation, user)
7
- new(consultation, user).query
8
- end
9
-
10
- def initialize(consultation, user)
11
- @consultation = consultation
12
- @user = user
13
- end
14
-
15
- def query
16
- ConsultationDelegations.for(consultation).where(grantee_id: user.id)
17
- end
18
-
19
- private
20
-
21
- attr_reader :consultation, :user
22
- end
23
- end
24
- end
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decidim
4
- module ActionDelegator
5
- class OrganizationDelegations < Decidim::Query
6
- def initialize(organization)
7
- @organization = organization
8
- end
9
-
10
- def query
11
- Delegation
12
- .joins(setting: :consultation)
13
- .merge(organization_consultations)
14
- .includes(:grantee, :granter)
15
- end
16
-
17
- private
18
-
19
- attr_reader :organization
20
-
21
- def organization_consultations
22
- Decidim::Consultations::OrganizationConsultations.new(organization).query
23
- end
24
- end
25
- end
26
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decidim
4
- module ActionDelegator
5
- class OrganizationSettings < Decidim::Query
6
- def initialize(organization)
7
- @organization = organization
8
- end
9
-
10
- def query
11
- Setting
12
- .joins(:consultation)
13
- .merge(organization_consultations)
14
- end
15
-
16
- def active
17
- Setting
18
- .joins(:consultation)
19
- .merge(organization_consultations.active)
20
- end
21
-
22
- private
23
-
24
- attr_reader :organization
25
-
26
- def organization_consultations
27
- Decidim::Consultations::OrganizationConsultations.new(organization).query
28
- end
29
- end
30
- end
31
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decidim
4
- module ActionDelegator
5
- class Responses < Decidim::Query
6
- def initialize(consultation)
7
- @consultation = consultation
8
- end
9
-
10
- # The Question's default_scope, `order(order: :asc)`, messes up the ordering in our queries so
11
- # we have to explicitly remove the ORDER BY close using `#reorder`.
12
- def query
13
- Decidim::Consultations::Response
14
- .joins(question: :consultation)
15
- .where(decidim_consultations_questions: { decidim_consultation_id: consultation.id })
16
- .where.not(decidim_consultations_questions: { published_at: nil })
17
- end
18
-
19
- private
20
-
21
- attr_reader :consultation
22
- end
23
- end
24
- end
@@ -1,58 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decidim
4
- module ActionDelegator
5
- # Returns total votes of each response by memberships' type and weight.
6
- class ResponsesByMembership < Decidim::Query
7
- DEFAULT_METADATA = I18n.t("decidim.admin.consultations.results.default_metadata")
8
-
9
- def initialize(relation)
10
- @relation = relation
11
- end
12
-
13
- def query
14
- relation
15
- .select(
16
- responses[:decidim_consultations_questions_id],
17
- responses[:title],
18
- coalesce(Ponderation.arel_table[:name], default_metadata).as("membership_type"),
19
- coalesce(Ponderation.arel_table[:weight], 1).as("membership_weight"),
20
- votes_count
21
- )
22
- .group(
23
- responses[:decidim_consultations_questions_id],
24
- responses[:title],
25
- sql(:membership_type),
26
- sql(:membership_weight)
27
- )
28
- .order(:title, :membership_type, { membership_weight: :desc }, "votes_count DESC")
29
- end
30
-
31
- private
32
-
33
- attr_reader :relation
34
-
35
- def default_metadata
36
- sql(ActiveRecord::Base.sanitize_sql(["?", DEFAULT_METADATA]))
37
- end
38
-
39
- def votes_count
40
- sql("COUNT(*)").as(sql(:votes_count))
41
- end
42
-
43
- def responses
44
- Decidim::Consultations::Response.arel_table
45
- end
46
-
47
- def sql(name)
48
- Arel.sql(name.to_s)
49
- end
50
-
51
- # This method comes with Rails 6. See:
52
- # https://github.com/rails/rails/commit/e5190acacd1088211cfe6f128b782af216aa6570
53
- def coalesce(*exprs)
54
- Arel::Nodes::NamedFunction.new("COALESCE", exprs)
55
- end
56
- end
57
- end
58
- end
@@ -1,87 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decidim
4
- module ActionDelegator
5
- class QuestionStats
6
- attr_reader :total_delegates, :total_participants
7
-
8
- def initialize(total_delegates, total_participants)
9
- @total_delegates = total_delegates
10
- @total_participants = total_participants
11
- end
12
- end
13
-
14
- class Scrutiny
15
- def initialize(consultation)
16
- @consultation = consultation
17
- @question_votes_by_id = questions_query.group_by(&:id)
18
- end
19
-
20
- def questions
21
- questions_cache = build_questions_cache
22
-
23
- question_votes_by_id.map do |_id, question_votes|
24
- # They are all the same question so we can pick any
25
- question = question_votes.first
26
- QuestionWithTotals.new(question, questions_cache)
27
- end
28
- end
29
-
30
- private
31
-
32
- attr_reader :consultation, :questions_cache, :question_votes_by_id
33
-
34
- # Returns a hash where the key is the question id and the value is an object that wraps some
35
- # question's counts displayed in the view.
36
- def build_questions_cache
37
- question_votes_by_id.each_with_object({}) do |(id, question_votes), memo|
38
- total_delegations = delegations_count(question_votes)
39
- total_participants = participants_count(question_votes)
40
-
41
- memo[id] = QuestionStats.new(total_delegations, total_participants)
42
- end
43
- end
44
-
45
- # Computes the count of delegated votes out of rows returned by `#questions_query`, named
46
- # `question_votes`.
47
- def delegations_count(question_votes)
48
- question_votes.count { |question| question.granter_id.present? }
49
- end
50
-
51
- # Computes the count of participants out of rows returned by `#questions_query`, named
52
- # `question_votes`.
53
- def participants_count(question_votes)
54
- question_votes.map(&:decidim_author_id).uniq.compact.size
55
- end
56
-
57
- # Returns questions joined with their votes and delegations so that we can aggregate the data
58
- # in Ruby in different ways but reaching out to DB just once.
59
- def questions_query
60
- @questions_query ||= Decidim::Consultations::Question
61
- .includes(:responses)
62
- .select(
63
- '"decidim_consultations_questions".*',
64
- '"decidim_consultations_votes"."decidim_author_id"',
65
- '"decidim_action_delegator_delegations"."granter_id"'
66
- )
67
- .from(questions_joined_votes_and_delegations)
68
- .where(decidim_consultation_id: consultation.id)
69
- .merge(Decidim::Consultations::Question.published)
70
- end
71
-
72
- def questions_joined_votes_and_delegations
73
- <<-SQL.squish
74
- "decidim_consultations_questions"
75
- LEFT OUTER JOIN "decidim_consultations_votes"
76
- ON "decidim_consultations_votes"."decidim_consultation_question_id" = "decidim_consultations_questions"."id"
77
- LEFT JOIN "decidim_action_delegator_delegations"
78
- ON "decidim_consultations_votes"."decidim_author_id" = "decidim_action_delegator_delegations"."granter_id"
79
- LEFT JOIN "decidim_action_delegator_settings"
80
- ON "decidim_action_delegator_settings"."id" = "decidim_action_delegator_delegations"."decidim_action_delegator_setting_id"
81
- LEFT JOIN "decidim_consultations"
82
- ON "decidim_consultations"."id" = "decidim_action_delegator_settings"."decidim_consultation_id"
83
- SQL
84
- end
85
- end
86
- end
87
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decidim
4
- module ActionDelegator
5
- class SettingDelegations < Decidim::Query
6
- def initialize(setting)
7
- @setting = setting
8
- end
9
-
10
- def query
11
- Delegation.where(setting: setting)
12
- end
13
-
14
- private
15
-
16
- attr_reader :setting
17
- end
18
- end
19
- end
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decidim
4
- module ActionDelegator
5
- class SumOfMembershipWeight < Decidim::Query
6
- def initialize(relation)
7
- @relation = relation
8
- end
9
-
10
- def query
11
- relation
12
- .select(
13
- questions[:id].as("question_id"),
14
- questions[:title].as("question_title"),
15
- responses[:title],
16
- votes_count
17
- )
18
- .group(
19
- questions[:id],
20
- questions[:title],
21
- responses[:title]
22
- )
23
- .order(responses[:title])
24
- end
25
-
26
- private
27
-
28
- attr_reader :relation
29
-
30
- def questions
31
- Decidim::Consultations::Question.arel_table
32
- end
33
-
34
- def responses
35
- Decidim::Consultations::Response.arel_table
36
- end
37
-
38
- def votes_count
39
- field = Ponderation.arel_table[:weight]
40
- VotesCountAggregation.new(field, "votes_count").to_sql
41
- end
42
- end
43
- end
44
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decidim
4
- module ActionDelegator
5
- class SumOfWeights < Decidim::Query
6
- def initialize(consultation)
7
- @consultation = consultation
8
- end
9
-
10
- def query
11
- SumOfMembershipWeight.new(published_questions_responses).query
12
- end
13
-
14
- private
15
-
16
- attr_reader :consultation
17
-
18
- def published_questions_responses
19
- VotedWithPonderations.new(
20
- Responses.new(consultation).query
21
- ).query
22
- end
23
- end
24
- end
25
- end
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decidim
4
- module ActionDelegator
5
- class TypeAndWeight < Decidim::Query
6
- def initialize(consultation)
7
- @consultation = consultation
8
- end
9
-
10
- def query
11
- relation = VotedWithPonderations.new(published_questions_responses).query
12
- ResponsesByMembership.new(relation).query
13
- end
14
-
15
- private
16
-
17
- attr_reader :consultation
18
-
19
- # Returns the published questions' responses of the given consultation as an ActiveRecord
20
- # Relation. Note this enables us to the chain it with other AR Relation objects.
21
- def published_questions_responses
22
- Responses.new(consultation).query
23
- end
24
- end
25
- end
26
- end
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decidim
4
- module ActionDelegator
5
- class VotedWithPonderations < Decidim::Query
6
- def initialize(relation)
7
- @relation = relation
8
- end
9
-
10
- def query
11
- relation
12
- .joins(:votes)
13
- .joins(ponderation_sql)
14
- end
15
-
16
- private
17
-
18
- attr_reader :relation
19
-
20
- def ponderation_sql
21
- <<~SQL.squish
22
- LEFT OUTER JOIN "decidim_action_delegator_settings" ON "decidim_action_delegator_settings"."decidim_consultation_id" = "decidim_consultations_questions"."decidim_consultation_id"
23
- LEFT OUTER JOIN "decidim_action_delegator_participants" ON "decidim_action_delegator_participants"."decidim_action_delegator_setting_id" = "decidim_action_delegator_settings"."id"
24
- AND "decidim_action_delegator_participants"."decidim_user_id" = "decidim_consultations_votes"."decidim_author_id"
25
- LEFT OUTER JOIN "decidim_action_delegator_ponderations" ON "decidim_action_delegator_ponderations"."id" = "decidim_action_delegator_participants"."decidim_action_delegator_ponderation_id"
26
- SQL
27
- end
28
- end
29
- end
30
- end
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decidim
4
- module ActionDelegator
5
- class VotesCountAggregation
6
- def initialize(field, aliaz)
7
- @field = field
8
- @aliaz = aliaz
9
- end
10
-
11
- def to_sql
12
- int_field = cast(field, :integer)
13
- int_field = coalesce(int_field, 1)
14
- Arel::Nodes::Sum.new([int_field], aliaz).to_sql
15
- end
16
-
17
- private
18
-
19
- attr_reader :field, :aliaz
20
-
21
- # Returns the equivalent of `CAST ((<exprs>) AS <type>)` in Arel
22
- def cast(*exprs, type)
23
- Arel::Nodes::NamedFunction.new(
24
- "CAST",
25
- [Arel::Nodes::As.new(Arel::Nodes::Grouping.new(exprs), Arel.sql(type.to_s.upcase))]
26
- )
27
- end
28
-
29
- def coalesce(*exprs)
30
- Arel::Nodes::NamedFunction.new("COALESCE", exprs)
31
- end
32
- end
33
- end
34
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decidim
4
- module ActionDelegator
5
- class ConsultationResultsSerializer < Decidim::Exporters::Serializer
6
- include Decidim::TranslationsHelper
7
-
8
- def serialize
9
- {
10
- question: translated_attribute(resource.question.title),
11
- response: translated_attribute(resource.title),
12
- membership_type: resource.membership_type,
13
- membership_weight: resource.membership_weight,
14
- votes_count: resource.votes_count
15
- }
16
- end
17
- end
18
- end
19
- end
@@ -1,3 +0,0 @@
1
- <% if Decidim::ActionDelegator.admin_preview_results && !consultation.finished? %>
2
- <div class="callout warning"><%= t "ongoing_consultation", scope: "decidim.action_delegator.admin.consultations.results" %></div>
3
- <% end %>
@@ -1,65 +0,0 @@
1
- <div class="card" id="consultations">
2
- <div class="card-divider">
3
- <h2 class="card-title">
4
- <%= t ".title" %>
5
- <span class="label button--title">
6
- <%= t "decidim.admin.consultations.results.total_votes", count: current_consultation.total_votes %>
7
- /
8
- <%= t "decidim.admin.consultations.results.total_delegates", count: total_delegates %>
9
- /
10
- <%= t "decidim.admin.consultations.results.participants", count: current_consultation.total_participants %>
11
- </span>
12
- <span id="export-consultation-results" class="button--title">
13
- <% if allowed_to?(:export_consultation_results, :consultation, consultation: current_consultation) %>
14
- <%= link_to t("decidim.admin.consultations.results.export"), decidim_admin_action_delegator.consultation_exports_path(current_consultation), method: :post, class: "button tiny button--title" %>
15
- <% else %>
16
- <span class="button tiny button--title disabled"><%= t("decidim.admin.consultations.results.export") %></span>
17
- <% end %>
18
- </span>
19
- </h2>
20
- </div>
21
- <div class="card-section">
22
-
23
- <%= render "ongoing_consultation_warning", consultation: current_consultation %>
24
-
25
- <table class="table-list">
26
- <% questions.each do |question| %>
27
- <% unless question.external_voting %>
28
- <thead>
29
- <tr>
30
- <th><%= strip_tags translated_attribute question.title %></th>
31
- <th><%= I18n.t("decidim.admin.consultations.results.membership_type") %></th>
32
- <th><%= I18n.t("decidim.admin.consultations.results.membership_weight") %></th>
33
- <th class="table-list__actions">
34
- <%= t "decidim.admin.consultations.results.total_votes", count: question.total_votes %>
35
- /
36
- <%= t "decidim.admin.consultations.results.total_delegates", count: question.total_delegates %>
37
- /
38
- <%= t "decidim.admin.consultations.results.participants", count: question.total_participants %>
39
- </th>
40
- </tr>
41
- </thead>
42
- <tbody>
43
- <% if question.publishable_results? %>
44
- <% responses_by_membership.fetch(question.id, []).each do |row| %>
45
- <tr>
46
- <td class="response-title"><%= strip_tags translated_attribute row.title %></td>
47
- <td class="membership-type"><%= row.membership_type %></td>
48
- <td class="membership-weight"><%= row.membership_weight %></td>
49
- <td class="votes-count"><%= row.votes_count %></td>
50
- </tr>
51
- <% end %>
52
- <% else %>
53
- <tr>
54
- <td><em><%= t "decidim.admin.consultations.results.not_visible" %></em></td>
55
- <td>&nbsp;</td>
56
- <td>&nbsp;</td>
57
- <td>&nbsp;</td>
58
- </tr>
59
- <% end %>
60
- </tbody>
61
- <% end %>
62
- <% end %>
63
- </table>
64
- </div>
65
- </div>
@@ -1,66 +0,0 @@
1
- <div class="card" id="consultations">
2
- <div class="card-divider">
3
- <h2 class="card-title">
4
- <%= t ".title" %>
5
- <span class="label button--title">
6
- <%= t "decidim.admin.consultations.results.total_votes", count: current_consultation.total_votes %>
7
- /
8
- <%= t "decidim.admin.consultations.results.total_delegates", count: total_delegates %>
9
- /
10
- <%= t "decidim.admin.consultations.results.participants", count: current_consultation.total_participants %>
11
- </span>
12
- <span id="export-consultation-results" class="button--title">
13
- <% if allowed_to?(:export_consultation_results, :consultation, consultation: current_consultation) %>
14
- <%= link_to(
15
- t("decidim.admin.consultations.results.export"),
16
- decidim_admin_action_delegator.consultation_exports_sum_of_weights_path(current_consultation),
17
- method: :post,
18
- class: "button tiny button--title"
19
- ) %>
20
- <% else %>
21
- <span class="button tiny button--title disabled"><%= t("decidim.admin.consultations.results.export") %></span>
22
- <% end %>
23
- </span>
24
- </h2>
25
- </div>
26
- <div class="card-section">
27
-
28
- <%= render "ongoing_consultation_warning", consultation: current_consultation %>
29
-
30
- <table id="results" class="table-list">
31
- <% questions.each do |question| %>
32
- <% unless question.external_voting %>
33
- <thead>
34
- <tr>
35
- <th><%= strip_tags translated_attribute question.title %></th>
36
- <th class="table-list__actions">
37
- <%= t "decidim.admin.consultations.results.total_votes", count: question.total_votes %>
38
- /
39
- <%= t "decidim.admin.consultations.results.total_delegates", count: question.total_delegates %>
40
- /
41
- <%= t "decidim.admin.consultations.results.participants", count: question.total_participants %>
42
- </th>
43
- </tr>
44
- </thead>
45
- <tbody>
46
- <% if question.publishable_results? %>
47
- <% responses_by_weight.fetch(question.id, []).each do |row| %>
48
- <tr>
49
- <td class="response-title"><%= strip_tags translated_attribute row.title %></td>
50
- <td class="votes-count"><%= row.votes_count %></td>
51
- </tr>
52
- <% end %>
53
- <% else %>
54
- <tr>
55
- <td><em><%= t "decidim.admin.consultations.results.not_visible" %></em></td>
56
- <td>&nbsp;</td>
57
- <td>&nbsp;</td>
58
- <td>&nbsp;</td>
59
- </tr>
60
- <% end %>
61
- </tbody>
62
- <% end %>
63
- <% end %>
64
- </table>
65
- </div>
66
- </div>
@@ -1,11 +0,0 @@
1
- <% if signed_in? && Decidim::ActionDelegator::Delegation.granted_to?(current_user, question.consultation) %>
2
- <% if has_any_delegate_vote?(question) %>
3
- <div class="delegations-notice">
4
- <%= link_to t("action_delegator.delegations.has_delegations", scope: "decidim"), decidim_consultations.question_path(question) %>
5
- </div>
6
- <% else %>
7
- <div class="delegations-notice">
8
- <%= link_to t("action_delegator.delegations.link", scope: "decidim"), decidim_consultations.question_path(question) %>
9
- </div>
10
- <% end %>
11
- <% end %>
@@ -1,11 +0,0 @@
1
- <%= link_to decidim_consultations.question_path(question), class: "button expanded button--sc" do %>
2
- <%= t "consultations.question.view_results", scope: "decidim" %>
3
- <% if question.most_weighted_voted_response.present? %>
4
- <span class="button__info"><%= translated_attribute question.most_weighted_voted_response.title %></span>
5
- <span class="button__info">
6
- <%= question.most_weighted_voted_response.votes_count %>
7
- <%= t "consultations.question.votes_out_of", scope: "decidim", count: question.most_weighted_voted_response.votes_count %>
8
- <%= question.total_weighted_votes %>
9
- </span>
10
- <% end %>
11
- <% end %>
@@ -1,5 +0,0 @@
1
- <% if signed_in? && Decidim::ActionDelegator::Delegation.granted_to?(current_user, consultation) %>
2
- <div class="delegation-callout callout warning is-hidden">
3
- <p><%= t "action_delegator.delegations_modal.callout", scope: "decidim" %> <span class="delegation-callout-message"></span></p>
4
- </div>
5
- <% end %>