refactors investment adding to ballots

This commit is contained in:
Juanjo Bazán
2016-06-14 14:03:21 +02:00
parent 56a358a638
commit 4fcf138045
4 changed files with 61 additions and 39 deletions

View File

@@ -7,6 +7,10 @@ class Budget
has_many :lines, dependent: :destroy
has_many :investments, through: :lines
def add_investment(investment)
lines.create!(budget: budget, investment: investment, heading: investment.heading, group_id: investment.heading.group_id)
end
def total_amount_spent
investments.sum(:price).to_i
end
@@ -18,5 +22,15 @@ class Budget
def amount_available(heading)
budget.heading_price(heading) - amount_spent(heading.id)
end
def valid_heading?(heading)
group = heading.group
return false if group.budget_id != budget_id
line = lines.where(heading_id: group.heading_ids).first
return false if line.present? && line.heading_id != heading.id
true
end
end
end

View File

@@ -21,6 +21,7 @@ class Budget
validates :title, presence: true
validates :author, presence: true
validates :description, presence: true
validates :heading_id, presence: true
validates_presence_of :unfeasibility_explanation, if: :unfeasibility_explanation_required?
validates :title, length: { in: 4 .. Budget::Investment.title_max_length }
@@ -152,7 +153,7 @@ class Budget
def reason_for_not_being_ballotable_by(user, ballot)
return permission_problem(user) if permission_problem?(user)
return :no_ballots_allowed unless budget.balloting?
return :different_heading_assigned unless heading_id.blank? || ballot.blank? || heading_id == ballot.heading_id || ballot.heading_id.nil?
return :different_heading_assigned unless ballot.valid_heading?(heading)
return :not_enough_money if ballot.present? && !enough_money?(ballot)
end

View File

@@ -4,32 +4,38 @@ describe Budget::Ballot do
describe "#amount_spent" do
it "returns the total amount spent in investments" do
inv1 = create(:budget_investment, :feasible, price: 10000)
inv2 = create(:budget_investment, :feasible, price: 20000)
budget = create(:budget)
group1 = create(:budget_group, budget: budget)
group2 = create(:budget_group, budget: budget)
heading1 = create(:budget_heading, group: group1, price: 100000)
heading2 = create(:budget_heading, group: group2, price: 200000)
inv1 = create(:budget_investment, :feasible, price: 10000, heading: heading1)
inv2 = create(:budget_investment, :feasible, price: 20000, heading: heading2)
ballot = create(:budget_ballot)
ballot.investments << inv1
ballot = create(:budget_ballot, budget: budget)
ballot.add_investment inv1
expect(ballot.total_amount_spent).to eq 10000
ballot.investments << inv2
ballot.add_investment inv2
expect(ballot.total_amount_spent).to eq 30000
end
it "returns the amount spent on all investments assigned to a specific heading" do
heading = create(:budget_heading)
budget = heading.group.budget
inv1 = create(:budget_investment, :feasible, price: 10000, heading: heading)
inv2 = create(:budget_investment, :feasible, price: 20000, heading: create(:budget_heading))
inv2 = create(:budget_investment, :feasible, price: 20000, heading: create(:budget_heading, group: heading.group))
inv3 = create(:budget_investment, :feasible, price: 40000, heading: heading)
ballot = create(:budget_ballot)
ballot.investments << inv1
ballot.investments << inv2
ballot = create(:budget_ballot, budget: budget)
ballot.add_investment inv1
ballot.add_investment inv2
expect(ballot.amount_spent(heading.id)).to eq 10000
ballot.investments << inv3
ballot.add_investment inv3
expect(ballot.amount_spent(heading.id)).to eq 50000
end
@@ -45,12 +51,12 @@ describe Budget::Ballot do
inv3 = create(:budget_investment, :feasible, price: 400, heading: heading)
ballot = create(:budget_ballot, budget: budget)
ballot.investments << inv1
ballot.investments << inv2
ballot.add_investment inv1
ballot.add_investment inv2
expect(ballot.amount_available(heading)).to eq 900
ballot.investments << inv3
ballot.add_investment inv3
expect(ballot.amount_available(heading)).to eq 500
end

View File

@@ -66,7 +66,7 @@ describe Budget::Investment do
end
describe "by_admin" do
it "should return spending investments assigned to specific administrator" do
it "should return investments assigned to specific administrator" do
investment1 = create(:budget_investment, administrator_id: 33)
create(:budget_investment)
@@ -78,7 +78,7 @@ describe Budget::Investment do
end
describe "by_valuator" do
it "should return spending proposals assigned to specific valuator" do
it "should return investments assigned to specific valuator" do
investment1 = create(:budget_investment)
investment2 = create(:budget_investment)
investment3 = create(:budget_investment)
@@ -99,7 +99,7 @@ describe Budget::Investment do
describe "scopes" do
describe "valuation_open" do
it "should return all spending proposals with false valuation_finished" do
it "should return all investments with false valuation_finished" do
investment1 = create(:budget_investment, valuation_finished: true)
investment2 = create(:budget_investment)
@@ -111,7 +111,7 @@ describe Budget::Investment do
end
describe "without_admin" do
it "should return all open spending proposals without assigned admin" do
it "should return all open investments without assigned admin" do
investment1 = create(:budget_investment, valuation_finished: true)
investment2 = create(:budget_investment, administrator: create(:administrator))
investment3 = create(:budget_investment)
@@ -124,7 +124,7 @@ describe Budget::Investment do
end
describe "managed" do
it "should return all open spending proposals with assigned admin but without assigned valuators" do
it "should return all open investments with assigned admin but without assigned valuators" do
investment1 = create(:budget_investment, administrator: create(:administrator))
investment2 = create(:budget_investment, administrator: create(:administrator), valuation_finished: true)
investment3 = create(:budget_investment, administrator: create(:administrator))
@@ -138,7 +138,7 @@ describe Budget::Investment do
end
describe "valuating" do
it "should return all spending proposals with assigned valuator but valuation not finished" do
it "should return all investments with assigned valuator but valuation not finished" do
investment1 = create(:budget_investment)
investment2 = create(:budget_investment)
investment3 = create(:budget_investment, valuation_finished: true)
@@ -154,7 +154,7 @@ describe Budget::Investment do
end
describe "valuation_finished" do
it "should return all spending proposals with valuation finished" do
it "should return all investments with valuation finished" do
investment1 = create(:budget_investment)
investment2 = create(:budget_investment)
investment3 = create(:budget_investment, valuation_finished: true)
@@ -170,7 +170,7 @@ describe Budget::Investment do
end
describe "feasible" do
it "should return all feasible spending proposals" do
it "should return all feasible investments" do
feasible_investment = create(:budget_investment, :feasible)
create(:budget_investment)
@@ -179,7 +179,7 @@ describe Budget::Investment do
end
describe "unfeasible" do
it "should return all unfeasible spending proposals" do
it "should return all unfeasible investments" do
unfeasible_investment = create(:budget_investment, :unfeasible)
create(:budget_investment, :feasible)
@@ -283,12 +283,12 @@ describe Budget::Investment do
describe "#with_supports" do
it "should return proposals with supports" do
sp1 = create(:budget_investment)
sp2 = create(:budget_investment)
create(:vote, votable: sp1)
inv1 = create(:budget_investment)
inv2 = create(:budget_investment)
create(:vote, votable: inv1)
expect(Budget::Investment.with_supports).to include(sp1)
expect(Budget::Investment.with_supports).to_not include(sp2)
expect(Budget::Investment.with_supports).to include(inv1)
expect(Budget::Investment.with_supports).to_not include(inv2)
end
end
@@ -327,11 +327,9 @@ describe Budget::Investment do
expect(investment.reason_for_not_being_ballotable_by(user, ballot)).to be_nil
end
it "accepts valid district selections" do
it "accepts valid selections" do
budget.phase = "selecting"
expect(investment.reason_for_not_being_selectable_by(user)).to be_nil
ballot.heading_id = heading.id
expect(investment.reason_for_not_being_selectable_by(user)).to be_nil
end
it "rejects users with different headings" do
@@ -340,22 +338,25 @@ describe Budget::Investment do
california = create(:budget_heading, group: group)
new_york = create(:budget_heading, group: group)
sp1 = create(:budget_investment, :feasible, heading: california)
sp2 = create(:budget_investment, :feasible, heading: new_york)
b = create(:budget_ballot, user: user, heading: california, investments: [sp1])
inv1 = create(:budget_investment, :feasible, heading: california)
inv2 = create(:budget_investment, :feasible, heading: new_york)
b = create(:budget_ballot, user: user, budget: budget)
b.add_investment inv1
expect(sp2.reason_for_not_being_ballotable_by(user, b)).to eq(:different_heading_assigned)
expect(inv2.reason_for_not_being_ballotable_by(user, b)).to eq(:different_heading_assigned)
end
it "rejects proposals with price higher than current available money" do
budget.phase = "balloting"
distritos = create(:budget_group, budget: budget)
carabanchel = create(:budget_heading, group: distritos, price: 35)
sp1 = create(:budget_investment, :feasible, heading: carabanchel, price: 30)
sp2 = create(:budget_investment, :feasible, heading: carabanchel, price: 10)
ballot = create(:budget_ballot, user: user, heading: carabanchel, investments: [sp1])
inv1 = create(:budget_investment, :feasible, heading: carabanchel, price: 30)
inv2 = create(:budget_investment, :feasible, heading: carabanchel, price: 10)
expect(sp2.reason_for_not_being_ballotable_by(user, ballot)).to eq(:not_enough_money)
ballot = create(:budget_ballot, user: user, budget: budget)
ballot.add_investment inv1
expect(inv2.reason_for_not_being_ballotable_by(user, ballot)).to eq(:not_enough_money)
end
end