diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..3d036d9 --- /dev/null +++ b/.rspec @@ -0,0 +1 @@ +--format documentation \ No newline at end of file diff --git a/lib/item.rb b/lib/item.rb index 85bb5fd..0f644b0 100644 --- a/lib/item.rb +++ b/lib/item.rb @@ -1,3 +1,13 @@ class Item + attr_reader :name, + :price + def initialize(attributes) + @name = attributes[:name] + @price = float_price(attributes[:price]) + end + + def float_price(string_price) + string_price.delete('$').to_f + end end diff --git a/lib/market.rb b/lib/market.rb index 0286ac1..62be840 100644 --- a/lib/market.rb +++ b/lib/market.rb @@ -1,3 +1,60 @@ +require 'date' + class Market - + attr_reader :name, + :vendors, + :date + + def initialize(name, date = Date.today) + @name = name + @vendors = [] + @date = date + end + + def add_vendor(vendor) + @vendors << vendor + end + + def vendor_names + @vendors.map(&:name) + end + + def vendors_that_sell(item) + @vendors.select { |vendor| vendor.inventory[item] > 0 } + end + + def sorted_item_list + list_items = @vendors.flat_map do |vendor| + vendor.inventory.keys.map(&:name) + end + + list_items.uniq.sort + end + + def total_inventory + inventory_list = Hash.new { |hash, key| hash[key] = { quantity: 0, vendors: [] } } + + @vendors.each do |vendor| + vendor.inventory.each do |item, quantity| + inventory_list[item][:quantity] += quantity + inventory_list[item][:vendors] << vendor + end + end + + inventory_list + end + + def overstocked?(item_data) + item_data[:quantity] > 50 && item_data[:vendors].length > 1 + end + + def overstocked_items + total_inventory.each_with_object([]) do |(item, data), overstock| + overstock << item if overstocked?(data) + end + end + + def formatted_date + @date.strftime("%d/%m/%Y") + end end diff --git a/lib/vendor.rb b/lib/vendor.rb index 6f8cc8b..1ae73b5 100644 --- a/lib/vendor.rb +++ b/lib/vendor.rb @@ -1,3 +1,21 @@ class Vendor + attr_reader :name, + :inventory + + def initialize(name) + @name = name + @inventory = Hash.new(0) + end + def check_stock(item) + @inventory.has_key?(item) ? @inventory[item] : 0 + end + + def stock(item, quantity) + @inventory[item] += quantity + end + + def potential_revenue + @inventory.sum { |item, quantity| item.price * quantity} + end end diff --git a/spec/item_spec.rb b/spec/item_spec.rb index e69de29..6731dc9 100644 --- a/spec/item_spec.rb +++ b/spec/item_spec.rb @@ -0,0 +1,19 @@ +require './spec/spec_helper' + +RSpec.describe Item do + before(:each) do + @item1 = Item.new({name: 'Peach', price: "$0.75"}) + @item2 = Item.new({name: 'Tomato', price: '$0.50'}) + end + + describe '#item attributes' do + it 'exists' do + expect(@item1).to be_an_instance_of(Item) + end + + it 'has a name and price' do + expect(@item1.name).to eq('Peach') + expect(@item2.price).to eq(0.5) + end + end +end \ No newline at end of file diff --git a/spec/market_spec.rb b/spec/market_spec.rb new file mode 100644 index 0000000..cfae07b --- /dev/null +++ b/spec/market_spec.rb @@ -0,0 +1,85 @@ +require './spec/spec_helper' +require 'date' + +RSpec.describe Market do + before(:each) do + @market = Market.new("South Pearl Street Farmers Market") + @vendor1 = Vendor.new("Rocky Mountain Fresh") + @vendor2 = Vendor.new("Ba-Nom-a-Nom") + @vendor3 = Vendor.new("Palisade Peach Shack") + @item1 = Item.new({name: 'Peach', price: "$0.75"}) + @item2 = Item.new({name: 'Tomato', price: "$0.50"}) + @item3 = Item.new({name: "Peach-Raspberry Nice Cream", price: "$5.30"}) + @item4 = Item.new({name: "Banana Nice Cream", price: "$4.25"}) + end + + describe '#market attributes' do + it 'exits and has a name' do + expect(@market).to be_an_instance_of(Market) + expect(@market.name).to eq("South Pearl Street Farmers Market") + expect(@market.vendors.length).to eq(0) + end + end + + describe '#vendors with inventory' do + before(:each) do + @vendor1.stock(@item1, 35) + @vendor1.stock(@item2, 9) + @vendor3.stock(@item3, 13) + @vendor2.stock(@item4, 50) + @vendor3.stock(@item1, 65) + @market.add_vendor(@vendor1) + @market.add_vendor(@vendor2) + @market.add_vendor(@vendor3) + end + + it 'can add vendors' do + expect(@market.vendors.length).to eq(3) + end + + it 'has a hash of vendors' do + expect(@market.vendor_names).to eq (["Rocky Mountain Fresh", "Ba-Nom-a-Nom", "Palisade Peach Shack"]) + end + + it 'knows which vendors sell which items' do + expect(@market.vendors_that_sell(@item1)).to eq([@vendor1, @vendor3]) + expect(@market.vendors_that_sell(@item4)).to eq([@vendor2]) + end + + it 'return a sorted list of unique items' do + expect(@market.sorted_item_list).to eq(["Banana Nice Cream", "Peach", "Peach-Raspberry Nice Cream", "Tomato"]) + end + + it 'knows total market inventory' do + actual_inventory = { + @item1 => { quantity: 100, vendors: [@vendor1, @vendor3] }, + @item2 => { quantity: 9, vendors: [@vendor1] }, + @item3 => { quantity: 13, vendors: [@vendor3] }, + @item4 => { quantity: 50, vendors: [@vendor2] } + } + expect(@market.total_inventory).to eq(actual_inventory) + end + + it 'returns overstocked items' do + expect(@market.overstocked_items).to eq([@item1]) + end + + xit 'knows when not to sell item' do + expect(@market.sell(@item2, 25)).to be false + end + + xit 'sells the item to reduce stock' do + expect(@market.sell(@item1, 40)).to be true + expect(@vendor1.check_stock(@item1)).to eq(0) + expect(@vendor3.check_stock(@item1)).to eq(60) + end + end + + describe 'date can be any date but will default to current' do + it 'returns market creation date' do + allow(Date).to receive(:today).and_return(Date.new(1912, 5, 13)) + market1 = Market.new("Test Market") + expect(market1.formatted_date).to eq("13/05/1912") + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..eb37d22 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,3 @@ +require './lib/item' +require './lib/vendor' +require './lib/market' \ No newline at end of file diff --git a/spec/vendor_spec.rb b/spec/vendor_spec.rb new file mode 100644 index 0000000..8f9e99e --- /dev/null +++ b/spec/vendor_spec.rb @@ -0,0 +1,34 @@ +require './spec/spec_helper' + +RSpec.describe Vendor do + before(:each) do + @item1 = Item.new({name: 'Peach', price: "$0.75"}) + @item2 = Item.new({name: 'Tomato', price: '$0.50'}) + @vendor = Vendor.new("Rocky Mountain Fresh") + end + + describe '#vendor attributes' do + it 'exitst and has a name' do + expect(@vendor).to be_an_instance_of(Vendor) + expect(@vendor.name).to eq("Rocky Mountain Fresh") + end + + it 'starts with no inventory' do + expect(@vendor.inventory).to eq({}) + expect(@vendor.check_stock(@item1)).to eq(0) + end + end + + describe '#inventory process' do + it 'adds to inventory' do + @vendor.stock(@item1, 30) + expect(@vendor.check_stock(@item1)).to eq(30) + end + + it 'calculates potential revenue' do + @vendor.stock(@item1, 30) + @vendor.stock(@item2, 20) + expect(@vendor.potential_revenue).to eq(32.5) + end + end +end