From c98e8a004f76134ed050ccdd9b743efe8bb68192 Mon Sep 17 00:00:00 2001 From: decabeza Date: Wed, 26 Jan 2022 10:54:32 +0100 Subject: [PATCH 01/10] Add new 'hide_money' column to the budgets' table We will use this field to show/hide all price references in the Budgets with the final voting style: Approval. --- db/migrate/20210311110036_add_hide_money_to_budgets.rb | 5 +++++ db/schema.rb | 1 + 2 files changed, 6 insertions(+) create mode 100644 db/migrate/20210311110036_add_hide_money_to_budgets.rb diff --git a/db/migrate/20210311110036_add_hide_money_to_budgets.rb b/db/migrate/20210311110036_add_hide_money_to_budgets.rb new file mode 100644 index 000000000..636c70d4a --- /dev/null +++ b/db/migrate/20210311110036_add_hide_money_to_budgets.rb @@ -0,0 +1,5 @@ +class AddHideMoneyToBudgets < ActiveRecord::Migration[5.1] + def change + add_column :budgets, :hide_money, :boolean, default: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 050cb482f..9b9355562 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -394,6 +394,7 @@ ActiveRecord::Schema.define(version: 2021_11_03_112944) do t.text "description_informing" t.string "voting_style", default: "knapsack" t.boolean "published" + t.boolean "hide_money", default: false end create_table "campaigns", id: :serial, force: :cascade do |t| From 80e64590b78812374342d00b0c2194e70cac99a5 Mon Sep 17 00:00:00 2001 From: decabeza Date: Wed, 2 Feb 2022 13:12:03 +0100 Subject: [PATCH 02/10] Allow enable 'hide_money' check on admin budget form Add new 'hide_money' field to admin budget form. Only display new field 'hide_money' when voting style is 'approval' --- app/assets/javascripts/application.js | 2 + app/assets/javascripts/budget_hide_money.js | 17 +++ .../admin/budgets/form_component.html.erb | 8 + .../admin/budgets/form_component.rb | 4 + app/controllers/admin/budgets_controller.rb | 1 + .../budgets_wizard/budgets_controller.rb | 2 +- config/locales/en/activerecord.yml | 1 + config/locales/en/admin.yml | 2 + config/locales/es/activerecord.yml | 1 + config/locales/es/admin.yml | 2 + spec/factories/budgets.rb | 4 + spec/system/admin/budgets_spec.rb | 140 ++++++++++++++++++ 12 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 app/assets/javascripts/budget_hide_money.js diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 6f6203f6e..0918ffb1d 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -110,6 +110,7 @@ //= require cookies //= require columns_selector //= require budget_edit_associations +//= require budget_hide_money //= require datepicker //= require_tree ./admin //= require_tree ./sdg @@ -166,6 +167,7 @@ var initialize_modules = function() { App.AdminBudgetsWizardCreationStep.initialize(); App.AdminMachineLearningScripts.initialize(); App.BudgetEditAssociations.initialize(); + App.BudgetHideMoney.initialize(); App.Datepicker.initialize(); App.SDGRelatedListSelector.initialize(); App.SDGManagementRelationSearch.initialize(); diff --git a/app/assets/javascripts/budget_hide_money.js b/app/assets/javascripts/budget_hide_money.js new file mode 100644 index 000000000..2c433ac9b --- /dev/null +++ b/app/assets/javascripts/budget_hide_money.js @@ -0,0 +1,17 @@ +(function() { + "use strict"; + App.BudgetHideMoney = { + initialize: function() { + $("#budget_voting_style").on({ + change: function() { + if ($(this).val() === "approval") { + $("#hide_money").removeClass("hide"); + } else { + $("#budget_hide_money").prop("checked", false); + $("#hide_money").addClass("hide"); + } + } + }); + } + }; +}).call(this); diff --git a/app/components/admin/budgets/form_component.html.erb b/app/components/admin/budgets/form_component.html.erb index 5df2e0e92..dd9bbddc9 100644 --- a/app/components/admin/budgets/form_component.html.erb +++ b/app/components/admin/budgets/form_component.html.erb @@ -39,6 +39,14 @@ +
+
+

<%= t("admin.budgets.edit.hide_money") %>

+

<%= t("admin.budgets.edit.hide_money_help_text") %>

+ <%= f.check_box :hide_money %> +
+
+ <% unless wizard? %>
<%= f.select :phase, phases_select_options %> diff --git a/app/components/admin/budgets/form_component.rb b/app/components/admin/budgets/form_component.rb index d57457e7a..4b598e3b6 100644 --- a/app/components/admin/budgets/form_component.rb +++ b/app/components/admin/budgets/form_component.rb @@ -34,4 +34,8 @@ class Admin::Budgets::FormComponent < ApplicationComponent def valuators @valuators ||= Valuator.includes(:user).order(description: :asc).order("users.email ASC") end + + def hide_money_style + "hide" if budget.voting_style == "knapsack" + end end diff --git a/app/controllers/admin/budgets_controller.rb b/app/controllers/admin/budgets_controller.rb index 00d238260..139abde34 100644 --- a/app/controllers/admin/budgets_controller.rb +++ b/app/controllers/admin/budgets_controller.rb @@ -59,6 +59,7 @@ class Admin::BudgetsController < Admin::BaseController valid_attributes = [:phase, :currency_symbol, :voting_style, + :hide_money, administrator_ids: [], valuator_ids: [], image_attributes: image_attributes diff --git a/app/controllers/admin/budgets_wizard/budgets_controller.rb b/app/controllers/admin/budgets_wizard/budgets_controller.rb index 92003fe5a..90f188f60 100644 --- a/app/controllers/admin/budgets_wizard/budgets_controller.rb +++ b/app/controllers/admin/budgets_wizard/budgets_controller.rb @@ -37,7 +37,7 @@ class Admin::BudgetsWizard::BudgetsController < Admin::BudgetsWizard::BaseContro end def allowed_params - valid_attributes = [:currency_symbol, :voting_style, administrator_ids: [], + valid_attributes = [:currency_symbol, :voting_style, :hide_money, administrator_ids: [], valuator_ids: [], image_attributes: image_attributes] valid_attributes + [translation_params(Budget)] diff --git a/config/locales/en/activerecord.yml b/config/locales/en/activerecord.yml index 973455a05..d02d6499c 100644 --- a/config/locales/en/activerecord.yml +++ b/config/locales/en/activerecord.yml @@ -160,6 +160,7 @@ en: voting_style: "Final voting style" voting_style_knapsack: "Knapsack" voting_style_approval: "Approval" + hide_money: "Hide money amount for this budget" budget/translation: main_link_text: "Text on the link" main_link_url: "The link takes you to (add a link)" diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index a740a897a..e26670d17 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -136,6 +136,8 @@ en: info: budget_settings: "General participatory budget settings" staff_settings: "Administrators and Valuators assigned to the budget" + hide_money: "Hide money" + hide_money_help_text: "If this option is checked, all fields showing the amount of money will be hidden throughout the process." destroy: success_notice: Budget deleted successfully unable_notice: You cannot delete a budget that has associated investments diff --git a/config/locales/es/activerecord.yml b/config/locales/es/activerecord.yml index 82c682edf..b7cf2fc07 100644 --- a/config/locales/es/activerecord.yml +++ b/config/locales/es/activerecord.yml @@ -160,6 +160,7 @@ es: voting_style: "Estilo de la votación final" voting_style_knapsack: Bolsa de dinero voting_style_approval: Por aprobación + hide_money: "Ocultar la cantidad de dinero para este presupuesto" budget/translation: main_link_text: "Texto del enlace" main_link_url: "El enlace te lleva a (añade un enlace)" diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 9ff38ec50..fd7a0d28c 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -136,6 +136,8 @@ es: info: budget_settings: "Configuración genérica del presupuesto participativo" staff_settings: "Administradores y Evaluadores asigandos al presupuesto" + hide_money: "Ocultar dinero" + hide_money_help_text: "Si esta opción está marcada, todos los campos que muestran la cantidad de dinero se ocultarán durante todo el proceso." destroy: success_notice: Presupuesto eliminado correctamente unable_notice: No se puede eliminar un presupuesto con proyectos asociados diff --git a/spec/factories/budgets.rb b/spec/factories/budgets.rb index 81f2089ec..59ae4b977 100644 --- a/spec/factories/budgets.rb +++ b/spec/factories/budgets.rb @@ -68,6 +68,10 @@ FactoryBot.define do trait :with_winner do after(:create) { |budget| create(:budget_investment, :winner, budget: budget) } end + + trait :hide_money do + hide_money { true } + end end factory :budget_group, class: "Budget::Group" do diff --git a/spec/system/admin/budgets_spec.rb b/spec/system/admin/budgets_spec.rb index db39f419f..ede90d9c9 100644 --- a/spec/system/admin/budgets_spec.rb +++ b/spec/system/admin/budgets_spec.rb @@ -94,6 +94,76 @@ describe "Admin budgets", :admin do end end + context "Create" do + scenario "Create budget - Approval voting with hide money" do + visit admin_budgets_path + click_button "Create new budget" + click_link "Create multiple headings budget" + + expect(page).to have_select("Final voting style", selected: "Knapsack") + expect(page).not_to have_selector("#budget_hide_money") + + fill_in "Name", with: "Budget hide money" + select "Approval", from: "Final voting style" + check "Hide money amount for this budget" + click_button "Continue to groups" + + expect(page).to have_content "New participatory budget created successfully!" + expect(page).to have_content "Budget hide money" + + click_link "Go back to edit budget" + + expect(page).to have_select("Final voting style", selected: "Approval") + expect(page).to have_field "Hide money amount for this budget", checked: true + end + + scenario "Create a budget with hide money by steps" do + visit admin_budgets_path + click_button "Create new budget" + click_link "Create multiple headings budget" + + fill_in "Name", with: "Multiple headings budget with hide money" + select "Approval", from: "Final voting style" + check "Hide money amount for this budget" + click_button "Continue to groups" + + expect(page).to have_content "New participatory budget created successfully!" + expect(page).to have_content "There are no groups." + + click_button "Add new group" + fill_in "Group name", with: "All city" + click_button "Create new group" + + expect(page).to have_content "Group created successfully!" + + click_button "Add new group" + fill_in "Group name", with: "District A" + click_button "Create new group" + + expect(page).to have_content "Group created successfully!" + + within("table") do + expect(page).to have_content "All city" + expect(page).to have_content "District A" + end + expect(page).not_to have_content "There are no groups." + + click_link "Continue to headings" + + expect(page).to have_content "Showing headings from the All city group." + expect(page).to have_link "Manage headings from the District A group." + + click_button "Add new heading" + fill_in "Heading name", with: "All city" + click_button "Create new heading" + + expect(page).to have_content "Heading created successfully!" + expect(page).to have_content "All city" + expect(page).to have_link "Continue to phases" + expect(page).not_to have_content "There are no headings." + end + end + context "Publish" do let(:budget) { create(:budget, :drafting) } @@ -260,6 +330,76 @@ describe "Admin budgets", :admin do expect(page).to have_content "New English Name" end + + scenario "Hide money active" do + budget_hide_money = create(:budget, :approval, :hide_money) + group = create(:budget_group, budget: budget_hide_money) + heading = create(:budget_heading, group: group) + heading_2 = create(:budget_heading, group: group) + + visit admin_budget_path(budget_hide_money) + + expect(page).to have_content heading.name + expect(page).to have_content heading_2.name + + visit edit_admin_budget_path(budget_hide_money) + + expect(page).to have_field "Hide money amount for this budget", checked: true + expect(page).to have_select("Final voting style", selected: "Approval") + end + + scenario "Change voting style uncheck hide money" do + budget_hide_money = create(:budget, :approval, :hide_money) + hide_money_help_text = "If this option is checked, all fields showing the amount of money "\ + "will be hidden throughout the process." + + visit edit_admin_budget_path(budget_hide_money) + + expect(page).to have_field "Hide money amount for this budget", checked: true + expect(page).to have_content hide_money_help_text + + select "Knapsack", from: "Final voting style" + + expect(page).not_to have_field "Hide money amount for this budget" + expect(page).not_to have_content hide_money_help_text + + select "Approval", from: "Final voting style" + + expect(page).to have_field "Hide money amount for this budget", checked: false + expect(page).to have_content hide_money_help_text + end + + scenario "Edit knapsack budget do not show hide money info" do + budget = create(:budget, :knapsack) + hide_money_help_text = "If this option is checked, all fields showing the amount of money "\ + "will be hidden throughout the process." + + visit edit_admin_budget_path(budget) + + expect(page).not_to have_field "Hide money amount for this budget" + expect(page).not_to have_content hide_money_help_text + + select "Approval", from: "Final voting style" + + expect(page).to have_field "Hide money amount for this budget", checked: false + expect(page).to have_content hide_money_help_text + end + + scenario "Edit approval budget show hide money info" do + budget = create(:budget, :approval) + hide_money_help_text = "If this option is checked, all fields showing the amount of money "\ + "will be hidden throughout the process." + + visit edit_admin_budget_path(budget) + + expect(page).to have_field "Hide money amount for this budget", checked: false + expect(page).to have_content hide_money_help_text + + select "Knapsack", from: "Final voting style" + + expect(page).not_to have_field "Hide money amount for this budget" + expect(page).not_to have_content hide_money_help_text + end end context "Update" do From 9fb5019f0f4c8fee574b4d27702e0c3fc2d03fcd Mon Sep 17 00:00:00 2001 From: decabeza Date: Wed, 2 Feb 2022 13:19:08 +0100 Subject: [PATCH 03/10] Manage the render of the price field on admin budget headings Avoid displaying the price in admin budget headings section and avoid fill the field 'price' in admin budget headings form when the budget has been checked with hide_money field. --- .../budget_headings/headings_component.html.erb | 8 ++++++-- app/models/budget.rb | 4 ++++ app/views/admin/budget_headings/_form.html.erb | 6 +++++- spec/models/budget/heading_spec.rb | 6 ++++++ spec/system/admin/budget_headings_spec.rb | 13 +++++++++++++ spec/system/admin/budgets_spec.rb | 4 ++++ 6 files changed, 38 insertions(+), 3 deletions(-) diff --git a/app/components/admin/budget_headings/headings_component.html.erb b/app/components/admin/budget_headings/headings_component.html.erb index cde24117b..d8ba48040 100644 --- a/app/components/admin/budget_headings/headings_component.html.erb +++ b/app/components/admin/budget_headings/headings_component.html.erb @@ -4,7 +4,9 @@ <%= Budget::Heading.human_attribute_name(:name) %> - <%= Budget::Heading.human_attribute_name(:price) %> + <% if budget.show_money? %> + <%= Budget::Heading.human_attribute_name(:price) %> + <% end %> <% if budget.approval_voting? %> <%= Budget::Heading.human_attribute_name(:max_ballot_lines) %> <% end %> @@ -15,7 +17,9 @@ <% headings.each do |heading| %> <%= heading.name %> - <%= budget.formatted_heading_price(heading) %> + <% if budget.show_money? %> + <%= budget.formatted_heading_price(heading) %> + <% end %> <% if budget.approval_voting? %> <%= heading.max_ballot_lines %> <% end %> diff --git a/app/models/budget.rb b/app/models/budget.rb index 1f7c7dc2b..c7a6c8c0c 100644 --- a/app/models/budget.rb +++ b/app/models/budget.rb @@ -230,6 +230,10 @@ class Budget < ApplicationRecord voting_style == "approval" end + def show_money? + !hide_money? + end + private def generate_phases diff --git a/app/views/admin/budget_headings/_form.html.erb b/app/views/admin/budget_headings/_form.html.erb index be0c3059c..c51d55f18 100644 --- a/app/views/admin/budget_headings/_form.html.erb +++ b/app/views/admin/budget_headings/_form.html.erb @@ -12,7 +12,11 @@ <% end %>
- <%= f.text_field :price, maxlength: 8 %> + <% if @budget.show_money? %> + <%= f.text_field :price, maxlength: 8 %> + <% else %> + <%= f.hidden_field :price, value: 0 %> + <% end %> <% if heading.budget.approval_voting? %> <%= f.number_field :max_ballot_lines, diff --git a/spec/models/budget/heading_spec.rb b/spec/models/budget/heading_spec.rb index a5cc098b4..185b88084 100644 --- a/spec/models/budget/heading_spec.rb +++ b/spec/models/budget/heading_spec.rb @@ -333,6 +333,12 @@ describe Budget::Heading do end end + describe "price" do + it "can't be blank" do + expect(build(:budget_heading, group: group, price: nil)).not_to be_valid + end + end + describe "#name_scoped_by_group" do it "returns heading name in budgets with a single heading" do heading = create(:budget_heading, group: group, name: "One and only") diff --git a/spec/system/admin/budget_headings_spec.rb b/spec/system/admin/budget_headings_spec.rb index 9adff8ed1..f6076f574 100644 --- a/spec/system/admin/budget_headings_spec.rb +++ b/spec/system/admin/budget_headings_spec.rb @@ -123,6 +123,19 @@ describe "Admin budget headings", :admin do expect(page).to have_content "can't be blank" end + scenario "Heading money field is hidden if hide money is true" do + budget_hide_money = create(:budget, :hide_money) + group = create(:budget_group, budget: budget_hide_money) + + visit new_admin_budget_group_heading_path(budget_hide_money, group) + + fill_in "Heading name", with: "Heading without money" + click_button "Create new heading" + + expect(page).to have_content "Heading created successfully!" + expect(page).not_to have_content "Money amount" + end + describe "Max votes is optional" do scenario "do no show max_ballot_lines field for knapsack budgets" do visit new_admin_budget_group_heading_path(budget, group) diff --git a/spec/system/admin/budgets_spec.rb b/spec/system/admin/budgets_spec.rb index ede90d9c9..207d40a0e 100644 --- a/spec/system/admin/budgets_spec.rb +++ b/spec/system/admin/budgets_spec.rb @@ -161,6 +161,8 @@ describe "Admin budgets", :admin do expect(page).to have_content "All city" expect(page).to have_link "Continue to phases" expect(page).not_to have_content "There are no headings." + expect(page).not_to have_content "Money amount" + expect(page).not_to have_content "€" end end @@ -341,6 +343,8 @@ describe "Admin budgets", :admin do expect(page).to have_content heading.name expect(page).to have_content heading_2.name + expect(page).not_to have_content "Money amount" + expect(page).not_to have_content "€" visit edit_admin_budget_path(budget_hide_money) From 2c16bac5f8e96f8a031181f6e1eeaaff50f092ff Mon Sep 17 00:00:00 2001 From: decabeza Date: Wed, 2 Feb 2022 13:20:39 +0100 Subject: [PATCH 04/10] Manage the render of the price field on public budget headings --- .../budgets/groups_and_headings_component.rb | 2 +- .../budgets/single_heading_component.html.erb | 2 +- .../budgets/single_heading_component.rb | 2 +- spec/system/budgets/budgets_spec.rb | 28 +++++++++++++++++++ 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/app/components/budgets/groups_and_headings_component.rb b/app/components/budgets/groups_and_headings_component.rb index b16357e4b..115695034 100644 --- a/app/components/budgets/groups_and_headings_component.rb +++ b/app/components/budgets/groups_and_headings_component.rb @@ -8,6 +8,6 @@ class Budgets::GroupsAndHeadingsComponent < ApplicationComponent private def price(heading) - tag.span(budget.formatted_heading_price(heading)) + tag.span(budget.formatted_heading_price(heading)) if budget.show_money? end end diff --git a/app/components/budgets/single_heading_component.html.erb b/app/components/budgets/single_heading_component.html.erb index 05fb1898d..a8550e402 100644 --- a/app/components/budgets/single_heading_component.html.erb +++ b/app/components/budgets/single_heading_component.html.erb @@ -1,4 +1,4 @@

<%= title %>

-

<%= price %>

+ <%= price %>
diff --git a/app/components/budgets/single_heading_component.rb b/app/components/budgets/single_heading_component.rb index d9711775a..c35068694 100644 --- a/app/components/budgets/single_heading_component.rb +++ b/app/components/budgets/single_heading_component.rb @@ -16,6 +16,6 @@ class Budgets::SingleHeadingComponent < ApplicationComponent end def price - budget.formatted_heading_price(heading) + tag.p budget.formatted_heading_price(heading) if budget.show_money? end end diff --git a/spec/system/budgets/budgets_spec.rb b/spec/system/budgets/budgets_spec.rb index 3e49b59c9..b0a8ce7f9 100644 --- a/spec/system/budgets/budgets_spec.rb +++ b/spec/system/budgets/budgets_spec.rb @@ -119,6 +119,34 @@ describe "Budgets" do end end + scenario "Hide money on single heading budget" do + budget = create(:budget, :finished, :hide_money) + heading = create(:budget_heading, budget: budget) + + visit budgets_path + + within("#budget_info") do + expect(page).to have_content heading.name + expect(page).not_to have_content "€" + end + end + + scenario "Hide money on multiple headings budget" do + budget = create(:budget, :finished, :hide_money) + heading1 = create(:budget_heading, budget: budget) + heading2 = create(:budget_heading, budget: budget) + heading3 = create(:budget_heading, budget: budget) + + visit budgets_path + + within("#budget_info") do + expect(page).to have_content heading1.name + expect(page).to have_content heading2.name + expect(page).to have_content heading3.name + expect(page).not_to have_content "€" + end + end + scenario "No budgets" do Budget.destroy_all From 40bdd1f03a0e960c04d6041dd8795babdba84c04 Mon Sep 17 00:00:00 2001 From: decabeza Date: Wed, 2 Feb 2022 13:36:08 +0100 Subject: [PATCH 05/10] Manage the render of the price field on admin investments section --- .../admin/budget_investments/_investments.html.erb | 4 +++- .../budget_investments/_select_investment.html.erb | 8 +++++--- spec/system/admin/budget_investments_spec.rb | 13 +++++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/app/views/admin/budget_investments/_investments.html.erb b/app/views/admin/budget_investments/_investments.html.erb index 15bbdc216..e5a79becb 100644 --- a/app/views/admin/budget_investments/_investments.html.erb +++ b/app/views/admin/budget_investments/_investments.html.erb @@ -30,7 +30,9 @@ <%= t("admin.budget_investments.index.list.geozone") %> <%= t("admin.budget_investments.index.list.feasibility") %> - <%= t("admin.budget_investments.index.list.price") %> + <% if @budget.show_money? %> + <%= t("admin.budget_investments.index.list.price") %> + <% end %> <%= t("admin.budget_investments.index.list.valuation_finished") %> diff --git a/app/views/admin/budget_investments/_select_investment.html.erb b/app/views/admin/budget_investments/_select_investment.html.erb index 320abc579..9753b35f9 100644 --- a/app/views/admin/budget_investments/_select_investment.html.erb +++ b/app/views/admin/budget_investments/_select_investment.html.erb @@ -42,9 +42,11 @@ <%= t("admin.budget_investments.index.feasibility.#{investment.feasibility}") %> - - <%= investment.formatted_price %> - +<% if @budget.show_money? %> + + <%= investment.formatted_price %> + +<% end %> <%= investment.valuation_finished? ? t("shared.yes") : t("shared.no") %> diff --git a/spec/system/admin/budget_investments_spec.rb b/spec/system/admin/budget_investments_spec.rb index 333ea691d..fd0d8779e 100644 --- a/spec/system/admin/budget_investments_spec.rb +++ b/spec/system/admin/budget_investments_spec.rb @@ -30,6 +30,19 @@ describe "Admin budget investments", :admin do expect(page).to have_content(budget_investment.total_votes) end + scenario "Do not show price column on budgets with hide money" do + budget_hide_money = create(:budget, :hide_money) + budget_investment = create(:budget_investment, budget: budget_hide_money) + + visit admin_budget_budget_investments_path(budget_hide_money) + + expect(page).to have_content(budget_investment.title) + expect(page).to have_content(budget_investment.heading.name) + expect(page).to have_content(budget_investment.id) + expect(page).not_to have_content("Price") + expect(page).not_to have_content("€") + end + scenario "If budget is finished do not show 'Selected' button" do finished_budget = create(:budget, :finished) budget_investment = create(:budget_investment, budget: finished_budget, cached_votes_up: 77) From abc4e9dca1b577e0a3583864ac9efd11b97a4179 Mon Sep 17 00:00:00 2001 From: decabeza Date: Wed, 2 Feb 2022 14:52:48 +0100 Subject: [PATCH 06/10] Manage the render of the price field on public investment section --- app/components/budgets/investments/new_component.rb | 6 +++++- app/models/budget/investment.rb | 4 ++-- config/locales/en/budgets.yml | 1 + config/locales/es/budgets.yml | 1 + spec/models/budget/investment_spec.rb | 6 ++++++ spec/system/budgets/investments_spec.rb | 13 +++++++++++++ 6 files changed, 28 insertions(+), 3 deletions(-) diff --git a/app/components/budgets/investments/new_component.rb b/app/components/budgets/investments/new_component.rb index f893a2ad9..ff16bf257 100644 --- a/app/components/budgets/investments/new_component.rb +++ b/app/components/budgets/investments/new_component.rb @@ -17,10 +17,14 @@ class Budgets::Investments::NewComponent < ApplicationComponent end def subtitle - if budget.single_heading? + return unless budget.single_heading? + + if budget.show_money? tag.span t("budgets.investments.form.subtitle", heading: budget.headings.first.name, price: budget.formatted_heading_price(budget.headings.first)) + else + tag.span t("budgets.investments.form.subtitle_without_price", heading: budget.headings.first.name) end end end diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index 50a403eba..76fe714f4 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -233,7 +233,7 @@ class Budget end def price_required? - feasible? && valuation_finished? + feasible? && valuation_finished? && budget.show_money? end def unfeasible_email_pending? @@ -333,7 +333,7 @@ class Budget end def should_show_price? - selected? && price.present? && budget.published_prices? + selected? && price.present? && budget.published_prices? && budget.show_money? end def should_show_price_explanation? diff --git a/config/locales/en/budgets.yml b/config/locales/en/budgets.yml index 99a49af9a..1e3c6b41a 100644 --- a/config/locales/en/budgets.yml +++ b/config/locales/en/budgets.yml @@ -75,6 +75,7 @@ en: form: title: "Create a budget investment" subtitle: "%{heading} (%{price})" + subtitle_without_price: "%{heading}" tag_category_label: "Categories" tags_instructions: "Tag this proposal. You can choose from proposed categories or add your own" tags_label: Tags diff --git a/config/locales/es/budgets.yml b/config/locales/es/budgets.yml index 1fea405b4..5cf78e3d4 100644 --- a/config/locales/es/budgets.yml +++ b/config/locales/es/budgets.yml @@ -75,6 +75,7 @@ es: form: title: "Crear nuevo proyecto" subtitle: "%{heading} (%{price})" + subtitle_without_price: "%{heading}" tag_category_label: "Categorías" tags_instructions: "Etiqueta este proyecto. Puedes elegir entre las categorías propuestas o introducir las que desees" tags_label: Etiquetas diff --git a/spec/models/budget/investment_spec.rb b/spec/models/budget/investment_spec.rb index 854bb1d9c..fa8bb73f8 100644 --- a/spec/models/budget/investment_spec.rb +++ b/spec/models/budget/investment_spec.rb @@ -245,6 +245,12 @@ describe Budget::Investment do expect(investment.should_show_price?).to eq(false) end + + it "returns false if budget hide money is active" do + budget.update!(hide_money: true) + + expect(investment.should_show_price?).to eq(false) + end end describe "#should_show_price_explanation?" do diff --git a/spec/system/budgets/investments_spec.rb b/spec/system/budgets/investments_spec.rb index a48bbb1f2..0dec3fd34 100644 --- a/spec/system/budgets/investments_spec.rb +++ b/spec/system/budgets/investments_spec.rb @@ -598,6 +598,19 @@ describe "Budget Investments" do expect(page).to have_content "Build a skyscraper" end + scenario "Create with single heading and hidden money" do + budget_hide_money = create(:budget, :hide_money) + group = create(:budget_group, budget: budget_hide_money) + create(:budget_heading, name: "Heading without money", group: group) + + login_as(author) + + visit new_budget_investment_path(budget_hide_money) + + expect(page).to have_content "Heading without money" + expect(page).not_to have_content "€" + end + scenario "Create with single group and multiple headings" do create(:budget_heading, group: group, name: "Medical supplies") create(:budget_heading, group: group, name: "Even more hospitals") From 5d475e64014147a3260671f85cc1009c7db03548 Mon Sep 17 00:00:00 2001 From: decabeza Date: Wed, 2 Feb 2022 14:59:18 +0100 Subject: [PATCH 07/10] Manage the render of the price field on budgets ballot section --- .../budgets/ballot/investment_component.rb | 2 +- spec/system/budgets/ballots_spec.rb | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/app/components/budgets/ballot/investment_component.rb b/app/components/budgets/ballot/investment_component.rb index 31352ccfe..18387e11a 100644 --- a/app/components/budgets/ballot/investment_component.rb +++ b/app/components/budgets/ballot/investment_component.rb @@ -20,7 +20,7 @@ class Budgets::Ballot::InvestmentComponent < ApplicationComponent end def investment_price - tag.span investment.formatted_price, class: "ballot-list-price" + tag.span investment.formatted_price, class: "ballot-list-price" if budget.show_money? end def delete_path diff --git a/spec/system/budgets/ballots_spec.rb b/spec/system/budgets/ballots_spec.rb index f824ef956..872ced135 100644 --- a/spec/system/budgets/ballots_spec.rb +++ b/spec/system/budgets/ballots_spec.rb @@ -659,4 +659,33 @@ describe "Ballots" do end end end + + context "Hide money" do + scenario "Do not show prices on sidebar or ballot show" do + budget_hide_money = create(:budget, :balloting, :approval, :hide_money) + group_no_price = create(:budget_group, budget: budget_hide_money) + heading_no_price = create(:budget_heading, group: group_no_price, max_ballot_lines: 2) + investment_1 = create(:budget_investment, :selected, heading: heading_no_price, price: 3000) + investment_2 = create(:budget_investment, :selected, heading: heading_no_price, price: 4000) + user = create(:user, :level_two, ballot_lines: [investment_1, investment_2]) + + login_as(user) + visit budget_investments_path(budget_hide_money, heading_id: heading_no_price.id) + + within("#sidebar") do + expect(page).to have_content investment_1.title + expect(page).to have_content investment_2.title + expect(page).not_to have_content investment_1.price + expect(page).not_to have_content investment_2.price + expect(page).not_to have_content "€" + click_link "Submit my ballot" + end + + expect(page).to have_content investment_1.title + expect(page).to have_content investment_2.title + expect(page).not_to have_content investment_1.price + expect(page).not_to have_content investment_2.price + expect(page).not_to have_content "€" + end + end end From 4c0499d53b909e5c827e50358db535a1c4610ea5 Mon Sep 17 00:00:00 2001 From: decabeza Date: Thu, 3 Feb 2022 10:48:50 +0100 Subject: [PATCH 08/10] Manage the render of the price field on budgets results section --- app/models/budget/result.rb | 10 ++++-- .../budgets/results/_results_table.html.erb | 34 ++++++++++-------- spec/system/budgets/results_spec.rb | 35 +++++++++++++++++++ 3 files changed, 61 insertions(+), 18 deletions(-) diff --git a/app/models/budget/result.rb b/app/models/budget/result.rb index 60a852547..661b0bd94 100644 --- a/app/models/budget/result.rb +++ b/app/models/budget/result.rb @@ -9,9 +9,13 @@ class Budget def calculate_winners reset_winners - investments.compatible.each do |investment| - @current_investment = investment - set_winner if inside_budget? + if @budget.hide_money? + investments.compatible.update_all(winner: true) + else + investments.compatible.each do |investment| + @current_investment = investment + set_winner if inside_budget? + end end end diff --git a/app/views/budgets/results/_results_table.html.erb b/app/views/budgets/results/_results_table.html.erb index 696ea2280..75adcbe9f 100644 --- a/app/views/budgets/results/_results_table.html.erb +++ b/app/views/budgets/results/_results_table.html.erb @@ -13,14 +13,16 @@ <%= t("budgets.results.ballot_lines_count") %> - - <%= t("budgets.results.price") %> - - <% if results_type == :compatible %> - - <%= t("budgets.results.amount_available") %>
- <%= @budget.formatted_amount(heading_price) %>
+ <% if @budget.show_money? %> + + <%= t("budgets.results.price") %> + <% if results_type == :compatible %> + + <%= t("budgets.results.amount_available") %>
+ <%= @budget.formatted_amount(heading_price) %>
+ + <% end %> <% end %> @@ -50,15 +52,17 @@ <%= investment.ballot_lines_count %> - - <%= @budget.formatted_amount(investment.price) %> - - <% if results_type == :compatible %> - - <%= @budget.formatted_amount(amount_available - investment.price) %> - <% amount_available -= investment.price if investment.winner? %> + <% if @budget.show_money? %> + + <%= @budget.formatted_amount(investment.price) %> + <% if results_type == :compatible %> + + <%= @budget.formatted_amount(amount_available - investment.price) %> + <% amount_available -= investment.price if investment.winner? %> + + <% end %> <% end %> <% end %> diff --git a/spec/system/budgets/results_spec.rb b/spec/system/budgets/results_spec.rb index 41d84fbf1..7c6b5f1c1 100644 --- a/spec/system/budgets/results_spec.rb +++ b/spec/system/budgets/results_spec.rb @@ -67,6 +67,41 @@ describe "Results" do end end + scenario "Does not show price and available budget when hide money" do + budget.update!(voting_style: "approval", hide_money: true) + visit budget_path(budget) + click_link "See results" + + expect(page).to have_content investment1.title + expect(page).to have_content investment2.title + expect(page).not_to have_content investment1.price + expect(page).not_to have_content investment2.price + expect(page).not_to have_content "Price" + expect(page).not_to have_content "Available budget" + expect(page).not_to have_content "€" + end + + scenario "Does not have in account the price on hide money budgets" do + budget.update!(voting_style: "approval", hide_money: true) + heading.update!(price: 0) + + inv1 = create(:budget_investment, :selected, heading: heading, price: 2000, ballot_lines_count: 1000) + inv2 = create(:budget_investment, :selected, heading: heading, price: 5000, ballot_lines_count: 1000) + + Budget::Result.new(budget, heading).calculate_winners + + visit budget_path(budget) + click_link "See results" + + expect(page).to have_content inv1.title + expect(page).to have_content inv2.title + expect(page).not_to have_content inv1.price + expect(page).not_to have_content inv2.price + expect(page).not_to have_content "Price" + expect(page).not_to have_content "Available budget" + expect(page).not_to have_content "€" + end + scenario "Does not raise error if budget (slug or id) is not found" do visit budget_results_path("wrong budget") From 8c3b222c9820a1bb6890ab469133210720c8f2df Mon Sep 17 00:00:00 2001 From: decabeza Date: Thu, 3 Feb 2022 10:49:41 +0100 Subject: [PATCH 09/10] Manage the render of the price field on valuation investments section --- .../budget_investments/_dossier.html.erb | 46 ++++++++++--------- .../budget_investments/_dossier_form.html.erb | 36 ++++++++------- .../valuation/budget_investments_spec.rb | 29 ++++++++++++ 3 files changed, 73 insertions(+), 38 deletions(-) diff --git a/app/views/valuation/budget_investments/_dossier.html.erb b/app/views/valuation/budget_investments/_dossier.html.erb index db18ab04a..e1d5c351a 100644 --- a/app/views/valuation/budget_investments/_dossier.html.erb +++ b/app/views/valuation/budget_investments/_dossier.html.erb @@ -1,27 +1,29 @@ -

- - <%= t("valuation.budget_investments.show.price") %> - (<%= t("valuation.budget_investments.show.currency") %>): - - <% if @investment.price.present? %> - <%= @investment.price %> - <% else %> - <%= t("valuation.budget_investments.show.undefined") %> - <% end %> -

+<% if @budget.show_money? %> +

+ + <%= t("valuation.budget_investments.show.price") %> + (<%= t("valuation.budget_investments.show.currency") %>): + + <% if @investment.price.present? %> + <%= @investment.price %> + <% else %> + <%= t("valuation.budget_investments.show.undefined") %> + <% end %> +

-

- - <%= t("valuation.budget_investments.show.price_first_year") %> - (<%= t("valuation.budget_investments.show.currency") %>): - +

+ + <%= t("valuation.budget_investments.show.price_first_year") %> + (<%= t("valuation.budget_investments.show.currency") %>): + - <% if @investment.price_first_year.present? %> - <%= @investment.price_first_year %> - <% else %> - <%= t("valuation.budget_investments.show.undefined") %> - <% end %> -

+ <% if @investment.price_first_year.present? %> + <%= @investment.price_first_year %> + <% else %> + <%= t("valuation.budget_investments.show.undefined") %> + <% end %> +

+<% end %> <%= explanation_field @investment.price_explanation %> diff --git a/app/views/valuation/budget_investments/_dossier_form.html.erb b/app/views/valuation/budget_investments/_dossier_form.html.erb index 56460f0ed..243d9f147 100644 --- a/app/views/valuation/budget_investments/_dossier_form.html.erb +++ b/app/views/valuation/budget_investments/_dossier_form.html.erb @@ -38,25 +38,29 @@
-
-
- <%= f.number_field :price, - label: t("valuation.budget_investments.edit.price", currency: budget.currency_symbol), - max: 1000000000000000 %> + <% if budget.show_money? %> +
+
+ <%= f.number_field :price, + label: t("valuation.budget_investments.edit.price", currency: budget.currency_symbol), + max: 1000000000000000 %> +
+ +
+ <%= f.number_field :price_first_year, + label: t("valuation.budget_investments.edit.price_first_year", currency: budget.currency_symbol), + max: 1000000000000000 %> +
-
- <%= f.number_field :price_first_year, - label: t("valuation.budget_investments.edit.price_first_year", currency: budget.currency_symbol), - max: 1000000000000000 %> +
+
+ <%= f.text_area :price_explanation, rows: 3 %> +
-
- -
-
- <%= f.text_area :price_explanation, rows: 3 %> -
-
+ <% else %> + <%= f.hidden_field :price, value: 0 %> + <% end %>
diff --git a/spec/system/valuation/budget_investments_spec.rb b/spec/system/valuation/budget_investments_spec.rb index 0bfc0bb51..69a5188d0 100644 --- a/spec/system/valuation/budget_investments_spec.rb +++ b/spec/system/valuation/budget_investments_spec.rb @@ -381,6 +381,35 @@ describe "Valuation budget investments" do end end + scenario "Dossier hide price on hide money budgets" do + budget = create(:budget, :valuating, :hide_money) + investment = create(:budget_investment, budget: budget, administrator: admin, valuators: [valuator]) + investment.update!(visible_to_valuators: true) + + visit valuation_budget_budget_investments_path(budget) + within("#budget_investment_#{investment.id}") do + click_link "Edit dossier" + end + + expect(page).not_to have_content "Price (€)" + expect(page).not_to have_content "Cost during the first year (€)" + expect(page).not_to have_content "Price explanation" + + choose "budget_investment_feasibility_feasible" + fill_in "budget_investment_duration", with: "12 months" + click_button "Save changes" + + expect(page).to have_content "Dossier updated" + + visit valuation_budget_budget_investments_path(budget) + click_link investment.title + + within("#duration") { expect(page).to have_content("12 months") } + within("#feasibility") { expect(page).to have_content("Feasible") } + expect(page).not_to have_selector "#price" + expect(page).not_to have_selector "#price_first_year" + end + scenario "Finish valuation" do investment.update!(visible_to_valuators: true) From 50e00a096b970b596313a0ea45c1e7c56d1bf254 Mon Sep 17 00:00:00 2001 From: decabeza Date: Thu, 3 Feb 2022 10:52:17 +0100 Subject: [PATCH 10/10] Update investments order when hide_money is active --- app/models/budget.rb | 2 +- spec/models/budget_spec.rb | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/models/budget.rb b/app/models/budget.rb index c7a6c8c0c..1f3af0373 100644 --- a/app/models/budget.rb +++ b/app/models/budget.rb @@ -190,7 +190,7 @@ class Budget < ApplicationRecord when "accepting", "reviewing", "finished" %w[random] when "publishing_prices", "balloting", "reviewing_ballots" - %w[random price] + hide_money? ? %w[random] : %w[random price] else %w[random confidence_score] end diff --git a/spec/models/budget_spec.rb b/spec/models/budget_spec.rb index 41e827e31..630131fdf 100644 --- a/spec/models/budget_spec.rb +++ b/spec/models/budget_spec.rb @@ -277,6 +277,16 @@ describe Budget do expect(budget.investments_orders).to eq(["random", "price"]) end + it "is random when ballotting and reviewing ballots if hide money" do + budget.update!(voting_style: "approval", hide_money: true) + budget.phase = "publishing_prices" + expect(budget.investments_orders).to eq(["random"]) + budget.phase = "balloting" + expect(budget.investments_orders).to eq(["random"]) + budget.phase = "reviewing_ballots" + expect(budget.investments_orders).to eq(["random"]) + end + it "is random and confidence_score in all other cases" do budget.phase = "selecting" expect(budget.investments_orders).to eq(["random", "confidence_score"])