diff --git a/app/controllers/budgets/executions_controller.rb b/app/controllers/budgets/executions_controller.rb index 0d4c25134..63f74717e 100644 --- a/app/controllers/budgets/executions_controller.rb +++ b/app/controllers/budgets/executions_controller.rb @@ -12,15 +12,15 @@ module Budgets private def investments_by_heading + base = @budget.investments.winners + base = base.joins(milestones: :translations).includes(:milestones) + base = base.tagged_with(params[:milestone_tag]) if params[:milestone_tag].present? + if params[:status].present? - @budget.investments.winners - .with_milestone_status_id(params[:status]) - .uniq - .group_by(&:heading) + base = base.with_milestone_status_id(params[:status]) + base.uniq.group_by(&:heading) else - @budget.investments.winners - .joins(milestones: :translations) - .distinct.group_by(&:heading) + base.distinct.group_by(&:heading) end end diff --git a/app/helpers/budget_executions_helper.rb b/app/helpers/budget_executions_helper.rb index 90d0744b0..d8f20936f 100644 --- a/app/helpers/budget_executions_helper.rb +++ b/app/helpers/budget_executions_helper.rb @@ -4,6 +4,12 @@ module BudgetExecutionsHelper @budget.investments.winners.with_milestone_status_id(status).count end + def options_for_milestone_tags + @budget.milestone_tags.map do |tag| + ["#{tag} (#{@budget.investments.winners.tagged_with(tag).count})", tag] + end + end + def first_milestone_with_image(investment) investment.milestones.order_by_publication_date .select{ |milestone| milestone.image.present? }.last diff --git a/app/models/budget.rb b/app/models/budget.rb index b31f08ed5..3797be797 100644 --- a/app/models/budget.rb +++ b/app/models/budget.rb @@ -195,6 +195,10 @@ class Budget < ApplicationRecord investments.winners.any? end + def milestone_tags + investments.winners.map(&:milestone_tag_list).flatten.uniq.sort + end + private def sanitize_descriptions diff --git a/app/views/admin/budget_investments/edit.html.erb b/app/views/admin/budget_investments/edit.html.erb index f930dbf06..81c4a6895 100644 --- a/app/views/admin/budget_investments/edit.html.erb +++ b/app/views/admin/budget_investments/edit.html.erb @@ -106,10 +106,9 @@
- <%= f.label :milestone_tag_list, t("admin.budget_investments.edit.milestone_tags") %> <%= f.text_field :milestone_tag_list, value: @investment.milestone_tag_list.sort.join(", "), - label: false %> + label: t("admin.budget_investments.edit.milestone_tags") %>
diff --git a/app/views/admin/milestones/_milestones.html.erb b/app/views/admin/milestones/_milestones.html.erb index 0b587fb6a..bcbf61885 100644 --- a/app/views/admin/milestones/_milestones.html.erb +++ b/app/views/admin/milestones/_milestones.html.erb @@ -6,7 +6,9 @@ <% if milestoneable.milestone_tag_list.any? %>
- <%= t("admin.milestones.index.milestone_tags") %>: <%= milestoneable.milestone_tag_list.sort.join(", ") %> + + <%= t("admin.milestones.index.milestone_tags") %>: + <%= milestoneable.milestone_tag_list.sort.join(", ") %>
<% end %> diff --git a/app/views/budgets/executions/show.html.erb b/app/views/budgets/executions/show.html.erb index acab50de4..f9410fdc8 100644 --- a/app/views/budgets/executions/show.html.erb +++ b/app/views/budgets/executions/show.html.erb @@ -44,13 +44,24 @@
<%= form_tag(budget_executions_path(@budget), method: :get) do %>
- <%= label_tag :status, t("budgets.executions.filters.label") %> + <%= label_tag :milestone_tag, t("budgets.executions.filters.milestone_tag.label") %> + <%= select_tag :milestone_tag, + options_for_select( + options_for_milestone_tags, + params[:milestone_tag] + ), + class: "js-submit-on-change", + prompt: t("budgets.executions.filters.milestone_tag.all", + count: @budget.investments.winners.with_milestones.count) %> +
+
+ <%= label_tag :status, t("budgets.executions.filters.status.label") %> <%= select_tag :status, options_from_collection_for_select(@statuses, :id, lambda { |s| "#{s.name} (#{filters_select_counts(s.id)})" }, params[:status]), class: "js-submit-on-change", - prompt: t("budgets.executions.filters.all", + prompt: t("budgets.executions.filters.status.all", count: @budget.investments.winners.with_milestones.count) %>
<% end %> diff --git a/config/locales/ar/budgets.yml b/config/locales/ar/budgets.yml index 63c1b6322..7b5c4a0d1 100644 --- a/config/locales/ar/budgets.yml +++ b/config/locales/ar/budgets.yml @@ -168,8 +168,9 @@ ar: heading_selection_title: "جسب المنطقة" no_winner_investments: "لا يوجد استثمارات فائزة" filters: - label: "حالة المشروع الحالية" - all: "الكل (%{count})" + status: + label: "حالة المشروع الحالية" + all: "الكل (%{count})" phases: errors: dates_range_invalid: "تاريخ البدأ لا يمكن ان يكون مساو او يتجاوز تاريخ الانتهاء" diff --git a/config/locales/de-DE/budgets.yml b/config/locales/de-DE/budgets.yml index 30bb6305e..d69d70fd2 100644 --- a/config/locales/de-DE/budgets.yml +++ b/config/locales/de-DE/budgets.yml @@ -182,8 +182,9 @@ de: heading_selection_title: "Nach Bezirk" no_winner_investments: "Keine erfolgreichen Ausgabenvorschläge in diesem Status" filters: - label: "Aktueller Stand des Projekts" - all: "Alle (%{count})" + status: + label: "Aktueller Stand des Projekts" + all: "Alle (%{count})" phases: errors: dates_range_invalid: "Das Anfangsdatum kann nicht gleich oder später als das Enddatum sein" diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 78b667712..fd472c7f1 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -298,6 +298,7 @@ en: documents: "Documents" milestone: Milestone new_milestone: Create new milestone + milestone_tags: Milestone Tags form: admin_statuses: Manage statuses no_statuses_defined: There are no defined statuses yet diff --git a/config/locales/en/budgets.yml b/config/locales/en/budgets.yml index 5f49b1d41..c209d4d2c 100644 --- a/config/locales/en/budgets.yml +++ b/config/locales/en/budgets.yml @@ -184,8 +184,12 @@ en: heading_selection_title: "By district" no_winner_investments: "No winner investments in this state" filters: - label: "Project's current state" - all: "All (%{count})" + status: + label: "Project's current state" + all: "All (%{count})" + milestone_tag: + label: "Milestone tag" + all: "All (%{count})" phases: errors: dates_range_invalid: "Start date can't be equal or later than End date" diff --git a/config/locales/en/milestones.yml b/config/locales/en/milestones.yml index dfb035afe..79e38f6c6 100644 --- a/config/locales/en/milestones.yml +++ b/config/locales/en/milestones.yml @@ -3,7 +3,6 @@ en: index: no_milestones: Don't have defined milestones progress: Progress - milestone_tags: Milestone Tags show: publication_date: "Published %{publication_date}" status_changed: Status changed to diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 3d3388b27..907fc15c7 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -298,6 +298,7 @@ es: documents: "Documentos" milestone: Seguimiento new_milestone: Crear nuevo hito + milestone_tags: Etiquetas de Seguimiento form: admin_statuses: Gestionar estados no_statuses_defined: No hay estados definidos diff --git a/config/locales/es/budgets.yml b/config/locales/es/budgets.yml index cac1f50bd..855598a0d 100644 --- a/config/locales/es/budgets.yml +++ b/config/locales/es/budgets.yml @@ -184,8 +184,12 @@ es: heading_selection_title: "Ámbito de actuación" no_winner_investments: "No hay proyectos de gasto ganadores en este estado" filters: - label: "Estado actual del proyecto" - all: "Todos (%{count})" + status: + label: "Estado actual del proyecto" + all: "Todos (%{count})" + milestone_tag: + label: "Etiquetas de Seguimiento" + all: "Todos (%{count})" phases: errors: dates_range_invalid: "La fecha de comienzo no puede ser igual o superior a la de finalización" diff --git a/config/locales/es/milestones.yml b/config/locales/es/milestones.yml index dc3098319..3e5432519 100644 --- a/config/locales/es/milestones.yml +++ b/config/locales/es/milestones.yml @@ -3,7 +3,6 @@ es: index: no_milestones: No hay hitos definidos progress: Progreso - milestone_tags: Etiquetas de Seguimiento show: publication_date: "Publicado el %{publication_date}" status_changed: El proyecto ha cambiado al estado diff --git a/config/locales/fi-FI/budgets.yml b/config/locales/fi-FI/budgets.yml index 80cdcbf29..4a956a286 100644 --- a/config/locales/fi-FI/budgets.yml +++ b/config/locales/fi-FI/budgets.yml @@ -50,4 +50,5 @@ fi: link: "Tavoitteet" page_title: "%{budget} - Tavoitteet" filters: - all: "Kaikki (%{count})" + status: + all: "Kaikki (%{count})" diff --git a/config/locales/gl/budgets.yml b/config/locales/gl/budgets.yml index e578b008f..f9df44e6c 100644 --- a/config/locales/gl/budgets.yml +++ b/config/locales/gl/budgets.yml @@ -182,8 +182,9 @@ gl: heading_selection_title: "Por ámbito de actuación" no_winner_investments: "Non hai investimentos gañadores neste estado" filters: - label: "Estado actual do proxecto" - all: "Todo (%{count})" + status: + label: "Estado actual do proxecto" + all: "Todo (%{count})" phases: errors: dates_range_invalid: "A data de comezo non pode ser igual ou superior á de remate" diff --git a/config/locales/it/budgets.yml b/config/locales/it/budgets.yml index 74df6ac9d..d2ae6a3ac 100644 --- a/config/locales/it/budgets.yml +++ b/config/locales/it/budgets.yml @@ -176,7 +176,8 @@ it: link: "Traguardi" heading_selection_title: "Per circoscrizione" filters: - all: "Tutto (%{count})" + status: + all: "Tutto (%{count})" phases: errors: dates_range_invalid: "La Data di inizio non può essere uguale o successiva alla Data finale" diff --git a/config/locales/nl/budgets.yml b/config/locales/nl/budgets.yml index 166c5419b..22bd22417 100644 --- a/config/locales/nl/budgets.yml +++ b/config/locales/nl/budgets.yml @@ -184,8 +184,9 @@ nl: heading_selection_title: "Per wijk" no_winner_investments: "Geen geaccepteerde investeringen in deze status" filters: - label: "Status van het project" - all: "Alle (%{count})" + status: + label: "Status van het project" + all: "Alle (%{count})" phases: errors: dates_range_invalid: "De begindatum dient kleiner te zijn dan de einddatum" diff --git a/config/locales/so-SO/budgets.yml b/config/locales/so-SO/budgets.yml index d47a4e51e..dbcf21d0c 100644 --- a/config/locales/so-SO/budgets.yml +++ b/config/locales/so-SO/budgets.yml @@ -181,8 +181,9 @@ so: heading_selection_title: "Degmo ahaan" no_winner_investments: "Mana jiraan maalgalin ku guuleysta gobolkan" filters: - label: "Mashruca hada gobolka kasocda" - all: "Dhaman%{count}" + status: + label: "Mashruca hada gobolka kasocda" + all: "Dhaman%{count}" phases: errors: dates_range_invalid: "Taariikhda bilowga ma noqon karto mid siman ama ka dambeysa taariikhda dhammaadka" diff --git a/config/locales/sq-AL/budgets.yml b/config/locales/sq-AL/budgets.yml index cb376b4f8..6d3cecdc6 100644 --- a/config/locales/sq-AL/budgets.yml +++ b/config/locales/sq-AL/budgets.yml @@ -49,7 +49,7 @@ sq: all_phases: Shihni të gjitha fazat all_phases: Fazat e investimeve buxhetore map: Propozimet e investimeve buxhetore të vendosura gjeografikisht - investment_proyects: Lista e të gjitha projekteve të investimeve + investment_proyects: Lista e të gjitha projekteve të investimeve unfeasible_investment_proyects: Lista e të gjitha projekteve të investimeve të papranueshme not_selected_investment_proyects: Lista e të gjitha projekteve të investimeve të pa zgjedhur për votim finished_budgets: Përfunduan buxhetet pjesëmarrëse. @@ -171,7 +171,7 @@ sq: accepted: "Propozimi i pranuar i shpenzimeve:" discarded: "Propozimi i hedhur poshtë i shpenzimeve:" incompatibles: I papajtueshëm - investment_proyects: Lista e të gjitha projekteve të investimeve + investment_proyects: Lista e të gjitha projekteve të investimeve unfeasible_investment_proyects: Lista e të gjitha projekteve të investimeve të papranueshme not_selected_investment_proyects: Lista e të gjitha projekteve të investimeve të pa zgjedhur për votim executions: @@ -181,8 +181,9 @@ sq: heading_selection_title: "Nga rrethi" no_winner_investments: "Asnjë investim fitues në këtë gjendje" filters: - label: "Gjendja aktuale e projektit" - all: "Të gjitha (%{count})" + status: + label: "Gjendja aktuale e projektit" + all: "Të gjitha (%{count})" phases: errors: dates_range_invalid: "Data e fillimit nuk mund të jetë e barabartë ose më vonë se data e përfundimit" diff --git a/config/locales/val/budgets.yml b/config/locales/val/budgets.yml index 1e2cd7bcb..2cd0e9207 100644 --- a/config/locales/val/budgets.yml +++ b/config/locales/val/budgets.yml @@ -182,8 +182,9 @@ val: heading_selection_title: "Àmbit d'actuació" no_winner_investments: "No hi ha propostes en aquest estat" filters: - label: "Estat actual del projecte" - all: "Tots (%{count})" + status: + label: "Estat actual del projecte" + all: "Tots (%{count})" phases: errors: dates_range_invalid: "La data d'inici no ha de ser igual o posterior a la data de fi" diff --git a/config/locales/zh-CN/budgets.yml b/config/locales/zh-CN/budgets.yml index f3588eb3a..5ac40d396 100644 --- a/config/locales/zh-CN/budgets.yml +++ b/config/locales/zh-CN/budgets.yml @@ -176,8 +176,9 @@ zh-CN: heading_selection_title: "按区域" no_winner_investments: "这个州里没有胜出的投资" filters: - label: "项目的当前状态" - all: "所有(%{count})" + status: + label: "项目的当前状态" + all: "所有(%{count})" phases: errors: dates_range_invalid: "开始日期不能等于或晚于结束日期" diff --git a/spec/factories/proposals.rb b/spec/factories/proposals.rb index 8fcb7bf76..92a925627 100644 --- a/spec/factories/proposals.rb +++ b/spec/factories/proposals.rb @@ -66,6 +66,7 @@ FactoryBot.define do trait :published do published_at { Time.current } + end trait :with_milestone_tags do after(:create) { |proposal| proposal.milestone_tags << create(:tag, :milestone) } diff --git a/spec/features/admin/budget_investments_spec.rb b/spec/features/admin/budget_investments_spec.rb index 11fc94037..8e870fa5a 100644 --- a/spec/features/admin/budget_investments_spec.rb +++ b/spec/features/admin/budget_investments_spec.rb @@ -1335,6 +1335,7 @@ describe "Admin budget investments" do budget_investment = create(:budget_investment) visit admin_budget_budget_investment_path(budget_investment.budget, budget_investment) + expect(page).not_to have_content("Milestone Tags:") click_link "Edit classification" diff --git a/spec/features/budgets/executions_spec.rb b/spec/features/budgets/executions_spec.rb index 3083d1eca..579b7d038 100644 --- a/spec/features/budgets/executions_spec.rb +++ b/spec/features/budgets/executions_spec.rb @@ -235,6 +235,52 @@ describe "Executions" do select "Bidding (0)", from: "status" expect(page).not_to have_content(investment1.title) end + + scenario "by milestone tag, only display tags for winner investments", :js do + create(:milestone, milestoneable: investment1, status: status1) + create(:milestone, milestoneable: investment2, status: status2) + create(:milestone, milestoneable: investment3, status: status2) + investment1.milestone_tag_list.add("tag1", "tag2") + investment1.save + investment2.milestone_tag_list.add("tag2") + investment2.save + investment3.milestone_tag_list.add("tag2") + investment3.save + + visit budget_path(budget) + + click_link "See results" + click_link "Milestones" + + expect(page).to have_content(investment1.title) + expect(page).to have_content(investment2.title) + + select "tag2 (2)", from: "milestone_tag" + + expect(page).to have_content(investment1.title) + expect(page).to have_content(investment2.title) + + select "Studying the project (1)", from: "status" + + expect(page).to have_content(investment1.title) + expect(page).not_to have_content(investment2.title) + + select "Bidding (1)", from: "status" + + expect(page).not_to have_content(investment1.title) + expect(page).to have_content(investment2.title) + + select "tag1 (1)", from: "milestone_tag" + + expect(page).not_to have_content(investment1.title) + expect(page).not_to have_content(investment2.title) + + select "All (2)", from: "milestone_tag" + + expect(page).not_to have_content(investment1.title) + expect(page).to have_content(investment2.title) + end + end context "Heading Order" do diff --git a/spec/models/budget/investment_spec.rb b/spec/models/budget/investment_spec.rb index 797845b9b..439938eff 100644 --- a/spec/models/budget/investment_spec.rb +++ b/spec/models/budget/investment_spec.rb @@ -1274,17 +1274,22 @@ describe Budget::Investment do describe "milestone_tags" do context "without milestone_tags" do let(:investment) {create(:budget_investment)} + it "do not have milestone_tags" do expect(investment.milestone_tag_list).to eq([]) expect(investment.milestone_tags).to eq([]) end + it "add a new milestone_tag" do investment.milestone_tag_list = "tag1,tag2" + expect(investment.milestone_tag_list).to eq(["tag1", "tag2"]) end end + context "with milestone_tags" do let(:investment) {create(:budget_investment, :with_milestone_tags)} + it "has milestone_tags" do expect(investment.milestone_tag_list.count).to eq(1) end diff --git a/spec/models/budget_spec.rb b/spec/models/budget_spec.rb index 123035732..851d6076a 100644 --- a/spec/models/budget_spec.rb +++ b/spec/models/budget_spec.rb @@ -306,4 +306,46 @@ describe Budget do expect(budget.formatted_amount(1000.00)).to eq ("€1,000") end end + + describe "#milestone_tags" do + let(:investment1) { build(:budget_investment, :winner) } + let(:investment2) { build(:budget_investment, :winner) } + let(:investment3) { build(:budget_investment) } + + it "returns an empty array if not investments milestone_tags" do + budget.investments << investment1 + + expect(budget.milestone_tags).to eq([]) + end + + it "returns array of investments milestone_tags" do + investment1.milestone_tag_list = "tag1" + investment1.save + budget.investments << investment1 + + expect(budget.milestone_tags).to eq(["tag1"]) + end + + it "returns uniq list of investments milestone_tags" do + investment1.milestone_tag_list = "tag1" + investment1.save + investment2.milestone_tag_list = "tag1" + investment2.save + budget.investments << investment1 + budget.investments << investment2 + + expect(budget.milestone_tags).to eq(["tag1"]) + end + + it "returns tags only for winner investments" do + investment1.milestone_tag_list = "tag1" + investment1.save + investment3.milestone_tag_list = "tag2" + investment3.save + budget.investments << investment1 + budget.investments << investment3 + + expect(budget.milestone_tags).to eq(["tag1"]) + end + end end diff --git a/spec/models/legislation/process_spec.rb b/spec/models/legislation/process_spec.rb index 389ccff6a..0813b6064 100644 --- a/spec/models/legislation/process_spec.rb +++ b/spec/models/legislation/process_spec.rb @@ -197,21 +197,28 @@ describe Legislation::Process do describe "milestone_tags" do context "without milestone_tags" do let(:process) {create(:legislation_process)} + it "do not have milestone_tags" do expect(process.milestone_tag_list).to eq([]) expect(process.milestone_tags).to eq([]) end + it "add a new milestone_tag" do process.milestone_tag_list = "tag1,tag2" + expect(process.milestone_tag_list).to eq(["tag1", "tag2"]) end end + context "with milestone_tags" do + let(:process) {create(:legislation_process, :with_milestone_tags)} + it "has milestone_tags" do expect(process.milestone_tag_list.count).to eq(1) end end + end end