diff --git a/app/components/budgets/ballot/ballot_component.html.erb b/app/components/budgets/ballot/ballot_component.html.erb
index 6834a3059..5945b7f2b 100644
--- a/app/components/budgets/ballot/ballot_component.html.erb
+++ b/app/components/budgets/ballot/ballot_component.html.erb
@@ -36,9 +36,7 @@
<% end %>
- <%= render Budgets::Ballot::InvestmentComponent.with_collection(
- ballot.investments.by_group(group.id)
- ) %>
+ <%= render Budgets::Ballot::InvestmentComponent.with_collection(group_investments(group)) %>
diff --git a/app/components/budgets/ballot/ballot_component.rb b/app/components/budgets/ballot/ballot_component.rb
index fbb8b1d75..bb2057951 100644
--- a/app/components/budgets/ballot/ballot_component.rb
+++ b/app/components/budgets/ballot/ballot_component.rb
@@ -26,4 +26,8 @@ class Budgets::Ballot::BallotComponent < ApplicationComponent
budget_investments_path(budget, heading_id: group.headings.first)
end
end
+
+ def group_investments(group)
+ ballot.investments.by_group(group.id).sort_by_ballot_lines
+ end
end
diff --git a/app/components/budgets/ballot/investment_for_sidebar_component.rb b/app/components/budgets/ballot/investment_for_sidebar_component.rb
index cf56c8c6f..7ba38bc76 100644
--- a/app/components/budgets/ballot/investment_for_sidebar_component.rb
+++ b/app/components/budgets/ballot/investment_for_sidebar_component.rb
@@ -18,6 +18,6 @@ class Budgets::Ballot::InvestmentForSidebarComponent < Budgets::Ballot::Investme
end
def delete_path
- budget_ballot_line_path(id: investment.id, investments_ids: investment_ids)
+ budget_ballot_line_path(budget, id: investment.id, investments_ids: investment_ids)
end
end
diff --git a/app/components/budgets/investments/my_ballot_component.html.erb b/app/components/budgets/investments/my_ballot_component.html.erb
index 307be97cc..99ada7a05 100644
--- a/app/components/budgets/investments/my_ballot_component.html.erb
+++ b/app/components/budgets/investments/my_ballot_component.html.erb
@@ -3,7 +3,7 @@
<%= t("budgets.investments.index.sidebar.my_ballot") %>
- <% if ballot.investments.by_heading(heading.id).count > 0 %>
+ <% if investments.count > 0 %>
<%= sanitize(ballot.voted_info(heading)) %>
@@ -32,7 +32,7 @@
<% if heading %>
<%= render Budgets::Ballot::InvestmentForSidebarComponent.with_collection(
- ballot.investments.by_heading(heading.id),
+ investments,
investment_ids: investment_ids
) %>
<% end %>
diff --git a/app/components/budgets/investments/my_ballot_component.rb b/app/components/budgets/investments/my_ballot_component.rb
index 0f7ea5ff5..20ad0855a 100644
--- a/app/components/budgets/investments/my_ballot_component.rb
+++ b/app/components/budgets/investments/my_ballot_component.rb
@@ -18,4 +18,8 @@ class Budgets::Investments::MyBallotComponent < ApplicationComponent
def budget
ballot.budget
end
+
+ def investments
+ ballot.investments.by_heading(heading.id).sort_by_ballot_lines
+ end
end
diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb
index 1808d8033..5f323b27c 100644
--- a/app/models/budget/investment.rb
+++ b/app/models/budget/investment.rb
@@ -99,6 +99,7 @@ class Budget
scope :last_week, -> { where("created_at >= ?", 7.days.ago) }
scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) }
scope :sort_by_created_at, -> { reorder(created_at: :desc) }
+ scope :sort_by_ballot_lines, -> { order(:"budget_ballot_lines.created_at") }
scope :by_budget, ->(budget) { where(budget: budget) }
scope :by_group, ->(group_id) { where(group_id: group_id) }
diff --git a/spec/components/budgets/ballot/ballot_component_spec.rb b/spec/components/budgets/ballot/ballot_component_spec.rb
index 2daf54097..3ba9d4c8a 100644
--- a/spec/components/budgets/ballot/ballot_component_spec.rb
+++ b/spec/components/budgets/ballot/ballot_component_spec.rb
@@ -3,11 +3,11 @@ require "rails_helper"
describe Budgets::Ballot::BallotComponent do
include Rails.application.routes.url_helpers
before { vc_test_request.session[:ballot_referer] = "/" }
+ let(:budget) { create(:budget, :balloting) }
+ let(:ballot) { create(:budget_ballot, user: create(:user), budget: budget) }
describe "link to group" do
- let(:budget) { create(:budget, :balloting) }
let(:group) { create(:budget_group, budget: budget) }
- let(:ballot) { create(:budget_ballot, user: create(:user), budget: budget) }
context "group with a single heading" do
let!(:heading) { create(:budget_heading, group: group, price: 1000) }
@@ -50,4 +50,15 @@ describe Budgets::Ballot::BallotComponent do
end
end
end
+
+ it "sorts investments by ballot lines" do
+ ["B letter", "A letter", "C letter"].each do |title|
+ ballot.add_investment(create(:budget_investment, :selected, budget: budget, title: title))
+ end
+
+ render_inline Budgets::Ballot::BallotComponent.new(ballot)
+
+ expect("B letter").to appear_before "A letter"
+ expect("A letter").to appear_before "C letter"
+ end
end
diff --git a/spec/components/budgets/investments/my_ballot_component_spec.rb b/spec/components/budgets/investments/my_ballot_component_spec.rb
new file mode 100644
index 000000000..122ea4451
--- /dev/null
+++ b/spec/components/budgets/investments/my_ballot_component_spec.rb
@@ -0,0 +1,28 @@
+require "rails_helper"
+
+describe Budgets::Investments::MyBallotComponent do
+ let(:user) { create(:user, :level_two) }
+ let(:budget) { create(:budget, :balloting) }
+ let(:ballot) { create(:budget_ballot, user: user, budget: budget) }
+ let(:heading) { create(:budget_heading, budget: budget) }
+
+ before do
+ vc_test_request.session[:ballot_referer] = "/"
+ sign_in(user)
+ end
+
+ it "sorts investments by ballot lines" do
+ ["B letter", "A letter", "C letter"].each do |title|
+ ballot.add_investment(create(:budget_investment, :selected, heading: heading, title: title))
+ end
+
+ render_inline Budgets::Investments::MyBallotComponent.new(
+ ballot: ballot,
+ heading: heading,
+ investment_ids: []
+ )
+
+ expect("B letter").to appear_before "A letter"
+ expect("A letter").to appear_before "C letter"
+ end
+end
diff --git a/spec/models/budget/investment_spec.rb b/spec/models/budget/investment_spec.rb
index af55804c0..bc1cae621 100644
--- a/spec/models/budget/investment_spec.rb
+++ b/spec/models/budget/investment_spec.rb
@@ -758,6 +758,48 @@ describe Budget::Investment do
end
end
+ describe ".sort_by_ballot_lines" do
+ let(:budget) { create(:budget, :balloting) }
+ let(:ballot) { create(:budget_ballot, user: create(:user), budget: budget) }
+
+ it "adjusts results when investments are added and removed" do
+ letter_a = create(:budget_investment, :selected, budget: budget, title: "A letter")
+ letter_b = create(:budget_investment, :selected, budget: budget, title: "B letter")
+ letter_c = create(:budget_investment, :selected, budget: budget, title: "C letter")
+
+ ballot.add_investment(letter_b)
+ ballot.add_investment(letter_a)
+ ballot.add_investment(letter_c)
+
+ ballot.investments.delete(letter_a)
+ ballot.add_investment(letter_a)
+
+ ordered_investments = ballot.investments.sort_by_ballot_lines
+
+ expect(ordered_investments.map(&:title)).to eq ["B letter", "C letter", "A letter"]
+ end
+
+ it "does not sort alphabetically" do
+ ["B letter", "A letter", "C letter"].each do |title|
+ ballot.add_investment(create(:budget_investment, :selected, budget: budget, title: title))
+ end
+
+ ordered_investments = ballot.investments.sort_by_ballot_lines
+
+ expect(ordered_investments.map(&:title)).to eq ["B letter", "A letter", "C letter"]
+ end
+
+ it "does not sort by price" do
+ [2, 1, 3].each do |price|
+ ballot.add_investment(create(:budget_investment, :selected, budget: budget, price: price))
+ end
+
+ ordered_investments = ballot.investments.sort_by_ballot_lines
+
+ expect(ordered_investments.map(&:price)).to eq [2, 1, 3]
+ end
+ end
+
describe "search_by_title_or_id" do
it "does not return investments by description" do
create(:budget_investment, title: "Something", description: "Awesome")