<%= 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 b854fc616..fd472c7f1 100644
--- a/config/locales/en/admin.yml
+++ b/config/locales/en/admin.yml
@@ -281,6 +281,7 @@ en:
tags_placeholder: "Write the tags you want separated by commas (,)"
undefined: Undefined
user_groups: "Groups"
+ milestone_tags: Milestone tags
search_unfeasible: Search unfeasible
milestones:
index:
@@ -297,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/es/admin.yml b/config/locales/es/admin.yml
index 934f45d37..907fc15c7 100644
--- a/config/locales/es/admin.yml
+++ b/config/locales/es/admin.yml
@@ -281,6 +281,7 @@ es:
tags_placeholder: "Escribe las etiquetas que desees separadas por comas (,)"
undefined: Sin definir
user_groups: "Grupos"
+ milestone_tags: Etiquetas de Seguimiento
search_unfeasible: Buscar inviables
milestones:
index:
@@ -297,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/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/budgets.rb b/spec/factories/budgets.rb
index fc60927cc..11645104f 100644
--- a/spec/factories/budgets.rb
+++ b/spec/factories/budgets.rb
@@ -166,6 +166,10 @@ FactoryBot.define do
trait :with_confirmed_hide do
confirmed_hide_at { Time.current }
end
+
+ trait :with_milestone_tags do
+ after(:create) { |investment| investment.milestone_tags << create(:tag, :milestone) }
+ end
end
factory :budget_phase, class: "Budget::Phase" do
diff --git a/spec/factories/classifications.rb b/spec/factories/classifications.rb
index e905ea3d4..e8721a50c 100644
--- a/spec/factories/classifications.rb
+++ b/spec/factories/classifications.rb
@@ -5,6 +5,10 @@ FactoryBot.define do
trait :category do
kind "category"
end
+
+ trait :milestone do
+ kind "milestone"
+ end
end
factory :tagging, class: "ActsAsTaggableOn::Tagging" do
diff --git a/spec/factories/legislations.rb b/spec/factories/legislations.rb
index ff149c905..d6ed4b20a 100644
--- a/spec/factories/legislations.rb
+++ b/spec/factories/legislations.rb
@@ -112,6 +112,10 @@ FactoryBot.define do
result_publication_enabled false
published true
end
+
+ trait :with_milestone_tags do
+ after(:create) { |legislation| legislation.milestone_tags << create(:tag, :milestone) }
+ end
end
factory :legislation_draft_version, class: "Legislation::DraftVersion" do
diff --git a/spec/factories/proposals.rb b/spec/factories/proposals.rb
index 7cbd44acb..92a925627 100644
--- a/spec/factories/proposals.rb
+++ b/spec/factories/proposals.rb
@@ -67,6 +67,10 @@ 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) }
+ end
end
factory :proposal_notification do
diff --git a/spec/features/admin/budget_investments_spec.rb b/spec/features/admin/budget_investments_spec.rb
index 073efa2d3..8e870fa5a 100644
--- a/spec/features/admin/budget_investments_spec.rb
+++ b/spec/features/admin/budget_investments_spec.rb
@@ -1331,6 +1331,23 @@ describe "Admin budget investments" do
expect(page).to have_content "can't be blank"
end
+ scenario "Add milestone tags" 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"
+
+ fill_in "budget_investment_milestone_tag_list", with: "tag1, tag2"
+
+ click_button "Update"
+
+ expect(page).to have_content "Investment project updated succesfully."
+ expect(page).to have_content("Milestone Tags: tag1, tag2")
+ end
+
end
context "Selecting" do
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 587c34ba2..439938eff 100644
--- a/spec/models/budget/investment_spec.rb
+++ b/spec/models/budget/investment_spec.rb
@@ -1267,6 +1267,32 @@ describe Budget::Investment do
investment.valuators << valuator
investment.administrator = administrator
expect(investment.admin_and_valuator_users_associated).to eq([valuator, administrator])
+
+ end
+ end
+
+ 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
end
end
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 c870a4049..0813b6064 100644
--- a/spec/models/legislation/process_spec.rb
+++ b/spec/models/legislation/process_spec.rb
@@ -194,4 +194,31 @@ describe Legislation::Process do
end
end
+ 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
diff --git a/spec/models/proposal_spec.rb b/spec/models/proposal_spec.rb
index b55cbba9f..7d5d8067c 100644
--- a/spec/models/proposal_spec.rb
+++ b/spec/models/proposal_spec.rb
@@ -1084,4 +1084,32 @@ describe Proposal do
end
+ describe "milestone_tags" do
+
+ context "without milestone_tags" do
+
+ let(:proposal) {create(:proposal)}
+
+ it "do not have milestone_tags" do
+ expect(proposal.milestone_tag_list).to eq([])
+ expect(proposal.milestone_tags).to eq([])
+ end
+
+ it "add a new milestone_tag" do
+ proposal.milestone_tag_list = "tag1,tag2"
+
+ expect(proposal.milestone_tag_list).to eq(["tag1", "tag2"])
+ end
+ end
+
+ context "with milestone_tags" do
+
+ let(:proposal) {create(:proposal, :with_milestone_tags)}
+
+ it "has milestone_tags" do
+ expect(proposal.milestone_tag_list.count).to eq(1)
+ end
+ end
+ end
+
end