app/helpers/policies_helper.rb
# frozen_string_literal: true
module PoliciesHelper
def quote(word)
"“#{word}”"
end
def policy_version_sentence(version)
changes = []
case version.event
when "create"
name = version.changeset["name"].second
description = version.changeset["description"].second
result = "Created"
result += version.changeset["private"].second == 2 ? " draft " : " "
result += "policy #{quote(name)} with description #{quote(description)}."
changes << result
when "update"
if version.changeset.key?("name")
name1 = version.changeset["name"].first
name2 = version.changeset["name"].second
changes << "Name changed from #{quote(name1)} to #{quote(name2)}."
end
if version.changeset.key?("description")
description1 = version.changeset["description"].first
description2 = version.changeset["description"].second
changes << "Description changed from #{quote(description1)} to #{quote(description2)}."
end
if version.changeset.key?("private")
case version.changeset["private"].second
when 0, "published"
changes << "Changed status to not draft."
when 2, "provisional"
changes << "Changed status to draft."
else
raise "Unexpected value for private: #{version.changeset['private'].second}"
end
end
else
raise
end
safe_join(changes.map { |change| content_tag(:p, change, class: "change-action") })
end
def policy_version_sentence_text(version)
case version.event
when "create"
name = version.changeset["name"].second
description = version.changeset["description"].second
result = "Created"
result += version.changeset["private"].second == 2 ? " draft " : " "
result += "policy #{quote(name)} with description #{quote(description)}"
result += "."
when "update"
changes = []
if version.changeset.key?("name")
name1 = version.changeset["name"].first
name2 = version.changeset["name"].second
changes << "name from #{quote(name1)} to #{quote(name2)}"
end
if version.changeset.key?("description")
description1 = version.changeset["description"].first
description2 = version.changeset["description"].second
changes << "description from #{quote(description1)} to #{quote(description2)}"
end
if version.changeset.key?("private")
case version.changeset["private"].second
when 0, "published"
changes << "status to not draft"
when 2, "provisional"
changes << "status to draft"
else
raise
end
end
result = changes.map do |change|
"* Changed #{change}."
end.join("\n")
else
raise
end
result
end
def policy_division_version_vote(version)
case version.event
when "create"
policy_vote_display_with_class(version.changeset["vote"].second)
when "destroy"
policy_vote_display_with_class(version.reify.vote)
when "update"
text = policy_vote_display_with_class(version.changeset["vote"].first)
text += " to ".html_safe
text += policy_vote_display_with_class(version.changeset["vote"].second)
text
end
end
def policy_division_version_vote_text(version)
case version.event
when "create"
vote_display(version.changeset["vote"].second)
when "destroy"
vote_display(version.reify.vote)
when "update"
"#{vote_display(version.changeset['vote'].first)} to #{vote_display(version.changeset['vote'].second)}"
end
end
def policy_division_version_division(version)
id = version.event == "create" ? version.changeset["division_id"].second : version.reify.division_id
Division.find(id)
end
# This helper is both used in the main application as well as the mailer. Therefore the links
# need to be full URLs including the host
def policy_division_version_sentence(version)
vote = policy_division_version_vote(version)
division = policy_division_version_division(version)
division_link = content_tag(:em, link_to(division.name, division_url_simple(division)))
out = []
case version.event
when "update"
out << "Changed vote from "
out << vote
out << " on division "
out << division_link
when "create"
out = []
out << "Added division "
out << division_link
out << ". Policy vote set to "
out << vote
when "destroy"
out = []
out << "Removed division "
out << division_link
out << ". Policy vote was "
out << vote
else
raise
end
out << "."
safe_join(out)
end
def policy_division_version_sentence_text(version)
actions = { "create" => "Added", "destroy" => "Removed", "update" => "Changed" }
vote = policy_division_version_vote_text(version)
division = policy_division_version_division(version)
case version.event
when "update"
"#{actions[version.event]} vote from #{vote} on division #{division.name}.\n#{division_url_simple(division)}"
when "create", "destroy"
tense = if version.event == "create"
"set to "
else
"was "
end
"#{actions[version.event]} division #{division.name}. Policy vote #{tense}#{vote}.\n#{division_url_simple(division)}"
else
raise
end
end
def version_policy(version)
Policy.find(version.policy_id)
end
# TODO: Remove duplication between version_sentence and version_sentence_text and methods they call
# This helper is both used in the main application as well as the mailer. Therefore the links
# need to be full URLs including the host
def version_sentence(version)
case version.item_type
when "Policy"
policy_version_sentence(version)
when "PolicyDivision"
content_tag(:p, policy_division_version_sentence(version), class: "change-action")
end
end
def version_sentence_text(version)
case version.item_type
when "Policy"
policy_version_sentence_text(version)
when "PolicyDivision"
policy_division_version_sentence_text(version)
end
end
def version_author(version)
if version.is_a?(WikiMotion)
version.user
else
User.find(version.whodunnit)
end
end
def version_attribution_text(version)
user = version_author(version)
"By #{user.name} at #{version.created_at.strftime('%I:%M%p - %d %b %Y')}\n#{user_url(user, only_path: false)}"
end
def capitalise_initial_character(text)
text[0].upcase + text[1..]
end
# This finds all people who can vote on a policy and orders them randomly but picking one from each category
# at a time so that each category is roughly evenly represented throughout in the final list
def randomise_people_voting_on_policy(policy)
distances = policy.policy_person_distances.currently_in_parliament.includes(:person, person: :members)
# Insert people into each category
people_category_table = {}
distances.each do |ppd|
category = ppd.category
people_category_table[category] ||= []
people_category_table[category] << ppd.person
end
# Randomly shuffle the members within each category
people_category_table.each_key do |category|
people_category_table[category] = people_category_table[category].shuffle
end
# Put the categories themselves in a random order
category_order = people_category_table.keys.shuffle
people = []
# Go through and pick one from each category until we've picked them all
while people.length < distances.length
category_order.each do |category|
people << people_category_table[category].shift unless people_category_table[category].empty?
end
end
people
end
def shortened_randomised_people_voting_on_policy(policy, max_people:)
people = randomise_people_voting_on_policy(policy)
chosen_people = people[0..(max_people - 1)]
# return the chosen people and the number of people not included
[chosen_people, people.length - chosen_people.length]
end
def people_under_policy_category(policy, category)
distances = policy.policy_person_distances.currently_in_parliament
# Insert people into each category
rep = []
distances.each do |ppd|
rep << ppd.person if ppd.category.to_s == category
end
rep
end
def card_title_from_category(policy, category)
case category.to_sym
when :not_enough
"We can't say anything concrete about how they voted on #{policy.name}"
else
"See who #{category_words_sentence(category.to_sym)}"
end
end
def policy_member_category(policy, category, max_person:)
rep = people_under_policy_category(policy, category)
chosen_rep = rep[0..(max_person - 1)]
card_title = card_title_from_category(policy, category)
[card_title, chosen_rep, rep.length - chosen_rep.length]
end
end