diff --git a/lib/attendee.rb b/lib/attendee.rb index 690e5c9..4fbaf8b 100644 --- a/lib/attendee.rb +++ b/lib/attendee.rb @@ -3,6 +3,10 @@ class Attendee def initialize(info) @name = info[:name] - @budget = info[:budget] + @budget = info[:budget].split("$")[1].to_i + end + + def spend(cost) + @budget -= cost end end \ No newline at end of file diff --git a/lib/auction.rb b/lib/auction.rb index 4d53f20..ad1ae3a 100644 --- a/lib/auction.rb +++ b/lib/auction.rb @@ -1,3 +1,5 @@ +require 'date' + class Auction attr_reader :items @@ -6,10 +8,106 @@ def initialize end def add_item(item) - @items.unshift(item) + @items << item end def item_names - raise NotImplementedError + @items.map do |item| + item.name + end + end + + def unpopular_items + unpopular = @items.select do |item| + item.bids.empty? + end + unpopular + end + + def potential_revenue + revenue = 0 + @items.each do |item| + if !unpopular_items.include?(item) + revenue += item.current_high_bid + end + end + revenue + end + + def bidders + bidders = list_bidder_objects + + return bidder_names = bidders.map do |bidder| + bidder.name + end + end + + def bidder_info + bidder_info = {} + bidder_objects = list_bidder_objects + + bidder_objects.each do |bidder| + @items.each do |item| + if item.bids.keys.include?(bidder) + if !bidder_info.keys.include?(bidder) + bidder_info[bidder] = {budget: bidder.budget, + items: [item]} + else + bidder_info[bidder][:items] << item + end + end + end + end + bidder_info end + + # def date + # Date.today.to_s + # end + + def close_auction + sales = {} + @items.each do |item| + item.close_bidding # Close bidding on all items + + if item.bids.empty? + sales[item] = 'Not Sold' + else + item.bids.select do |bidder, bid| + if bid == item.current_high_bid && can_afford(bidder, bid) + sales[item] = bidder + else + sales[item] = 'Not Sold' + end + end + end + end + sales + end + + # Helper Method that returns an array of the attendee objects that bid + def list_bidder_objects + bidder_objects = [] + + @items.each do |item| + item_bidders = item.bids.keys + + item_bidders.each do |bidder| + if !bidder_objects.include?(bidder) + bidder_objects << bidder + end + end + end + bidder_objects + end + + def can_afford(bidder, bid) + if bidder.budget >= bid + bidder.spend(bid) + true + else + false + end + end + end \ No newline at end of file diff --git a/lib/item.rb b/lib/item.rb index e198fd3..faa62c3 100644 --- a/lib/item.rb +++ b/lib/item.rb @@ -1,7 +1,30 @@ -class Items - attr_reader :name +class Item + attr_reader :name, :bids, :closed def initialize(name) - @name = "Chalkware Piggy Bank" + @name = name + @bids = {} + @closed = false + end + + def add_bid(attendee, bid) + if @closed == false + bids[attendee] = bid + else + return "Bidding Closed!" + end + end + + def current_high_bid + highest = @bids.max_by do |attendee, bid| + bid + end + highest[1] + end + + def close_bidding + @closed = true + + "Closed!" end end \ No newline at end of file diff --git a/spec/attendee_spec.rb b/spec/attendee_spec.rb index 563506f..9e9e321 100644 --- a/spec/attendee_spec.rb +++ b/spec/attendee_spec.rb @@ -13,4 +13,9 @@ expect(@attendee.name).to eq('Megan') expect(@attendee.budget).to eq(50) end + + it 'can spend budget' do + @attendee.spend(22) + expect(@attendee.budget).to eq(28) + end end \ No newline at end of file diff --git a/spec/auction_spec.rb b/spec/auction_spec.rb index 31d12e0..b95dd66 100644 --- a/spec/auction_spec.rb +++ b/spec/auction_spec.rb @@ -1,10 +1,18 @@ require './lib/item' +require './lib/attendee' require './lib/auction' RSpec.describe Auction do before(:each) do @item1 = Item.new('Chalkware Piggy Bank') @item2 = Item.new('Bamboo Picture Frame') + @item3 = Item.new('Homemade Chocolate Chip Cookies') + @item4 = Item.new('2 Days Dogsitting') + @item5 = Item.new('Forever Stamps') + + @attendee1 = Attendee.new({name: 'Megan', budget: '$50'}) + @attendee2 = Attendee.new({name: 'Bob', budget: '$75'}) + @attendee3 = Attendee.new({name: 'Mike', budget: '$100'}) @auction = Auction.new end @@ -29,4 +37,159 @@ expect(@auction.item_names).to eq(["Chalkware Piggy Bank", "Bamboo Picture Frame"]) end + + # Iteration 2 + + describe "#unpopular/revenue" do + before(:each) do + @auction.add_item(@item1) + @auction.add_item(@item2) + @auction.add_item(@item3) + @auction.add_item(@item4) + @auction.add_item(@item5) + end + + describe "#unpopular_items" do + it 'can return a list of unpopular items (no bids)' do + @item1.add_bid(@attendee2, 20) + @item1.add_bid(@attendee1, 22) + @item4.add_bid(@attendee3, 50) + + expect(@auction.unpopular_items).to eq([@item2, @item3, @item5]) + + @item3.add_bid(@attendee2, 15) + + expect(@auction.unpopular_items).to eq([@item2, @item5]) + end + end + + describe "#potential_revenue" do + it 'can calculate the auctions potential revenue' do + @item1.add_bid(@attendee2, 20) + @item1.add_bid(@attendee1, 22) # Will only count highest bid + @item4.add_bid(@attendee3, 50) + @item3.add_bid(@attendee2, 15) + + expect(@auction.potential_revenue).to eq(87) + end + end + end + + # Iteration 3 + describe "#bidders/bidder_info" do + before(:each) do + @auction.add_item(@item1) + @auction.add_item(@item2) + @auction.add_item(@item3) + @auction.add_item(@item4) + @auction.add_item(@item5) + + @item1.add_bid(@attendee2, 20) + @item1.add_bid(@attendee1, 22) + @item4.add_bid(@attendee3, 50) + @item3.add_bid(@attendee2, 15) + @item2.add_bid(@attendee1, 28) + end + + describe "#bidders" do + it 'can return an Array of bidders names' do + expect(@auction.bidders).to eq(["Bob", "Megan", "Mike"]) + end + + describe "#list_bidder_objects" do + it 'can return a list of attendee objects that bid' do + expect(@auction.list_bidder_objects).to eq([@attendee2, @attendee1, @attendee3]) + end + end + end + + describe "#bidder_info" do + it 'can return a hash of bidders info' do + expect(@auction.bidder_info).to eq({ + @attendee1 => { + budget: 50, + items: [@item1, @item2] + }, + @attendee2 => { + budget: 75, + items: [@item1, @item3] + }, + @attendee3 => { + budget: 100, + items: [@item4] + } + }) + end + end + end + + # Iteration 4 + + # describe "#date" do + # it 'can return the date of the auction' do + # test_date = double("any date") + + # allow(test_date).to receive(:date).and_return("24/02/2020") + # expect(@auction.date).to eq("24/02/2020") + # end + # end + + describe "#close_auction" do + before(:each) do + @auction.add_item(@item1) + @auction.add_item(@item2) + @auction.add_item(@item3) + @auction.add_item(@item4) + @auction.add_item(@item5) + + @item1.add_bid(@attendee2, 20) + @item1.add_bid(@attendee1, 22) + @item4.add_bid(@attendee3, 50) + @item3.add_bid(@attendee2, 15) + @item2.add_bid(@attendee1, 28) + end + + it 'can close bidding on all items' do + @auction.close_auction + + expect(@item1.closed).to eq true + expect(@item2.closed).to eq true + expect(@item3.closed).to eq true + expect(@item4.closed).to eq true + expect(@item5.closed).to eq true + end + + it 'can return a hash of sold items' do + expect(@auction.close_auction).to eq({ + @item1 => @attendee1, + @item2 => @attendee1, + @item3 => @attendee2, + @item4 => @attendee3, + @item5 => 'Not Sold' + }) + end + + it 'can only sell items if an attendee can afford the bid' do + @item5.add_bid(@attendee1, 15) + + expect(@auction.close_auction).to eq({ + @item1 => @attendee1, + @item2 => @attendee1, + @item3 => @attendee2, + @item4 => @attendee3, + @item5 => 'Not Sold' + }) + end + + # helper method to determine if an attendee can afford the bid + describe "#can_afford" do + it 'can determine if an attendee can afford a bid' do + expect(@auction.can_afford(@attendee1, 22)).to be true + expect(@auction.can_afford(@attendee1, 28)).to be true + + @item5.add_bid(@attendee1, 15) + expect(@auction.can_afford(@attendee1, 15)).to be false + end + end + end end \ No newline at end of file diff --git a/spec/item_spec.rb b/spec/item_spec.rb index 4073cc4..a4d6a47 100644 --- a/spec/item_spec.rb +++ b/spec/item_spec.rb @@ -1,9 +1,14 @@ require './lib/item' +require './lib/attendee' RSpec.describe Item do before(:each) do @item1 = Item.new('Chalkware Piggy Bank') @item2 = Item.new('Bamboo Picture Frame') + + @attendee1 = Attendee.new({name: 'Megan', budget: '$50'}) + @attendee2 = Attendee.new({name: 'Bob', budget: '$75'}) + @attendee3 = Attendee.new({name: 'Mike', budget: '$100'}) end it 'exists' do @@ -14,4 +19,52 @@ expect(@item1.name).to eq("Chalkware Piggy Bank") expect(@item2.name).to eq("Bamboo Picture Frame") end + + # Iteration 2 + + it 'has a list of bids defaulted to an empty hash' do + expect(@item1.bids).to eq({}) + end + + it 'can be bid on' do + expect(@item1.bids).to eq({}) + + @item1.add_bid(@attendee2, 20) + @item1.add_bid(@attendee1, 22) + + expect(@item1.bids).to eq({ + @attendee2 => 20, + @attendee1 => 22 + }) + end + + it 'can determine the current highest bid' do + @item1.add_bid(@attendee2, 20) + @item1.add_bid(@attendee1, 22) + + expect(@item1.current_high_bid).to eq(22) + end + + # Iteration 3 + describe "#close_bidding" do + before(:each) do + @item1.add_bid(@attendee2, 20) + @item1.add_bid(@attendee1, 22) + end + + it 'has a closed attribute defaulted to false' do + expect(@item1.closed).to be false + end + + it 'can close bidding' do + expect(@item1.close_bidding).to eq("Closed!") + expect(@item1.closed).to be true + end + + it 'can no longer accept new bids after closed' do + @item1.close_bidding + + expect(@item1.add_bid(@attendee3, 24)).to eq("Bidding Closed!") + end + end end \ No newline at end of file