diff --git a/lib/far_mar/market.rb b/lib/far_mar/market.rb index 5be343e9..2d0c1fc7 100644 --- a/lib/far_mar/market.rb +++ b/lib/far_mar/market.rb @@ -1,4 +1,86 @@ module FarMar class Market + attr_reader :id, :name, :address, :city, :county, :state, :zip + + def initialize(market_hash) + @id = market_hash[:id].to_i + @name = market_hash[:name] + @address = market_hash[:address] + @city = market_hash[:city] + @county = market_hash[:county] + @state = market_hash[:state] + @zip = market_hash[:zip] + end + + def self.all + # if @@all_markets is nil, reads the csv and creates the array + # otherwise uses array already in memory + @@all_markets ||= CSV.read('./support/markets.csv').map do |col| + FarMar::Market.new({ + id: col[0], + name: col[1], + address: col[2], + city: col[3], + county: col[4], + state: col[5], + zip: col[6] + }) + end + end + + def self.find(id) + # can use all without self (all.find instead of self.all.find) because already in the class scope + all.find {|market| market.id == id} + end + + def vendors + # returns a collection of FarMar::Vendor instances + # that are associated with the market by the market_id field. + FarMar::Vendor.all.find_all do |vendor| + vendor.market_id == @id + end + end + + def products + # if just .map, this would give back an array of an array of instances + # .flat_map is like calling .flatten on the .map array + vendors.flat_map{|vendor| vendor.products } + end + + def self.search(search_term) + all.find_all do |market| + market.name.downcase.include?(search_term.downcase) || + market.vendors.any?{|vendor| vendor.name.downcase.include?(search_term.downcase)} + end + end + + # This was my def preferred_vendor code before refactoring: + # highest_rev = 0 + # pref_vendor = nil + # vendors.each do |vendor| + # if vendor.revenue > highest_rev + # highest_rev = vendor.revenue + # pref_vendor = vendor + # end + # end + # return pref_vendor + + def preferred_vendor(date = nil) + if date == nil + vendors.max_by{|vendor|vendor.revenue} + else + vendors.max_by {|vendor| vendor.revenue(date)} + end + end + + def worst_vendor(date = nil) + if date == nil + vendors.min_by{|vendor|vendor.revenue} + else + vendors.min_by{|vendor|vendor.revenue(date)} + end + end + + end end diff --git a/lib/far_mar/product.rb b/lib/far_mar/product.rb index 67d6716d..484e0629 100644 --- a/lib/far_mar/product.rb +++ b/lib/far_mar/product.rb @@ -1,4 +1,41 @@ module FarMar class Product + attr_reader :id, :name, :vendor_id + + def initialize(product_hash) + @id = product_hash[:id].to_i + @name = product_hash[:name] + @vendor_id = product_hash[:vendor_id].to_i + end + + def self.all + @@all_products ||= CSV.read('./support/products.csv').map do |col| + FarMar::Product.new({ + id: col[0], + name: col[1], + vendor_id: col[2] + }) + end + end + + def self.find(id) + all.find{|product| product.id == id} + end + + def vendor + FarMar::Vendor.all.find {|vendor| vendor.id == @vendor_id} + end + + def sales + FarMar::Sale.all.find_all {|sale| sale.product_id == @id} + end + + def number_of_sales + sales.length + end + + def self.by_vendor(vendor_id) + all.find_all{|product| product.vendor_id == vendor_id} + end end end diff --git a/lib/far_mar/sale.rb b/lib/far_mar/sale.rb index 10e3780e..2f8d6caa 100644 --- a/lib/far_mar/sale.rb +++ b/lib/far_mar/sale.rb @@ -1,4 +1,48 @@ module FarMar class Sale + attr_reader :id, :amount, :purchase_time, :vendor_id, :product_id + + def initialize(sale_hash) + @id = sale_hash[:id].to_i + @amount = sale_hash[:amount].to_i + @purchase_time = DateTime.parse(sale_hash[:purchase_time]) + @vendor_id = sale_hash[:vendor_id].to_i + @product_id = sale_hash[:product_id].to_i + end + + def self.all + @@all_sales ||= CSV.read('./support/sales.csv').map do |col| + FarMar::Sale.new({ + id: col[0], + amount: col[1], + purchase_time: col[2], + vendor_id: col[3], + product_id: col[4] + }) + end + end + + def self.find(id) + all.find{|sale| sale.id == id} + end + + def vendor + FarMar::Vendor.all.find do |vendor| + vendor.id == @vendor_id + end + end + + def product + FarMar::Product.all.find do |product| + product.id == @product_id + end + end + + def self.between(beginning_time, end_time) + all.find_all do |sale| + sale.purchase_time.between?(beginning_time, end_time) + end + end + end end diff --git a/lib/far_mar/vendor.rb b/lib/far_mar/vendor.rb index 43c213b6..1ceac8fa 100644 --- a/lib/far_mar/vendor.rb +++ b/lib/far_mar/vendor.rb @@ -1,4 +1,75 @@ module FarMar class Vendor + attr_reader :id, :name, :employees, :market_id + + def initialize(vendor_hash) + @id = vendor_hash[:id].to_i + @name = vendor_hash[:name] + @employees = vendor_hash[:employees].to_i + @market_id = vendor_hash[:market_id].to_i + end + + def self.all + @@all_vendors ||= CSV.read('./support/vendors.csv').map do |col| + FarMar::Vendor.new({ + id: col[0], + name: col[1], + employees: col[2], + market_id: col[3] + }) + end + end + + def self.find(id) + all.find{|vendor| vendor.id == id} + end + + def market + #returns the FarMar::Market instance that is associated + #with this vendor using the FarMar::Vendor market_id field + FarMar::Market.all.find do |market| + @market_id == market.id + end + end + + def products + FarMar::Product.all.find_all do |product| + product.vendor_id == @id + end + end + + def sales + FarMar::Sale.all.find_all do |sale| + sale.vendor_id == @id + end + end + + # def revenue + # total_revenue = 0 + # sales.each do |sale| + # total_revenue += sale.amount + # end + # return total_revenue + # end + + def revenue(date=nil) + if date == nil + sales.reduce(0) {|sum, sale| sum + sale.amount} + else + date = DateTime.parse(date) + total_revenue = 0 + sales.each do |sale| + if sale.purchase_time.to_date == date + total_revenue += sale.amount + end + end + return total_revenue + end + end + + def self.by_market(market_id) + #returns all of the vendors with the given market id + all.find_all{|vendor| vendor.market_id == market_id} + end end end diff --git a/spec/far_mar/market_spec.rb b/spec/far_mar/market_spec.rb index 8d545726..fa2456a8 100644 --- a/spec/far_mar/market_spec.rb +++ b/spec/far_mar/market_spec.rb @@ -2,7 +2,24 @@ describe FarMar::Market do before :each do - @market = FarMar::Market.new + @market = FarMar::Market.new({ + id: "1", + name: "People's Co-op Farmers Market", + address: "30th and Burnside", + city: "Portland", + county: "Multnomah", + state: "Oregon", + zip: "97202" + }) + @market2 = FarMar::Market.new({ + id: "2", + name: "Silverdale Farmers Market", + address: "98383", + city: "Silverdale", + county: "Kitsap", + state: "Washington", + zip: "98383" + }) end describe ".new" do @@ -11,4 +28,70 @@ end end + describe "#all" do + all_markets = FarMar::Market.all + it "returns a collection of all market instances in the csv" do + #test that its an array + expect(all_markets.class).to eq Array + #test that some are instances of Market + expect(all_markets[0]).to be_an_instance_of FarMar::Market + expect(all_markets[-1]).to be_an_instance_of FarMar::Market + #test length of array + csv = CSV.read("support/markets.csv") + expect(all_markets.length).to eq csv.length + end + end + + describe "#find" do + it "returns the instance of Market matching the input id" do + expect(FarMar::Market.find(1)).to be_an_instance_of FarMar::Market + expect(FarMar::Market.find(1).name).to eq "People's Co-op Farmers Market" + end + end + + describe ".vendors" do + it "returns a collection of vendor instances associated with the specific market" do + expect(@market.vendors).to be_an Array + expect(@market.vendors.length).to eq 6 + end + end + + describe ".products" do + it "returns a collection of product instances associated with the market" do + expect(@market.products).to be_an Array + expect(@market.products.length).to eq 13 + end + end + + describe "#search(search_term)" do + it "returns a collection of Market instances where the market or vendor name contain the search term" do + expect(FarMar::Market.search("school")).to be_an Array + expect(FarMar::Market.search("school").length).to eq 3 + expect(FarMar::Market.search("schmitt").length).to eq 15 + end + end + + describe ".preferred_vendor" do + it "returns the vendor with the highest revenue, if no date given" do + expect(@market2.preferred_vendor).to be_an_instance_of FarMar::Vendor + expect(@market2.preferred_vendor.id).to eq 8 + end + it "returns the vendor with the highest revenue for the given date, when given a date" do + expect(@market2.preferred_vendor("2013-11-07")).to be_an_instance_of FarMar::Vendor + expect(@market2.preferred_vendor("2013-11-07").id).to eq 7 + end + end + + describe ".worst_vendor" do + it "returns the vendor with the lowest revenue, if no date given" do + expect(@market2.worst_vendor).to be_an_instance_of FarMar::Vendor + expect(@market2.worst_vendor.id).to eq 9 + end + it "returns the vendor revenue for the given date, when given date" do + expect(@market2.worst_vendor("2013-11-07")).to be_an_instance_of FarMar::Vendor + expect(@market2.worst_vendor("2013-11-07").id).to eq 9 + end + end + + end diff --git a/spec/far_mar/product_spec.rb b/spec/far_mar/product_spec.rb index 073d3512..3c700e08 100644 --- a/spec/far_mar/product_spec.rb +++ b/spec/far_mar/product_spec.rb @@ -2,7 +2,11 @@ describe FarMar::Product do before :each do - @product = FarMar::Product.new + @product = FarMar::Product.new({ + id: "56", + name: "Nom nom Beef", + vendor_id: "19" + }) end describe ".new" do @@ -11,4 +15,50 @@ end end + describe "#all" do + all_products = FarMar::Product.all + it "returns a collection of all product instances in the csv" do + expect(all_products.class).to eq Array + expect(all_products[0]).to be_an_instance_of FarMar::Product + expect(all_products[-1]).to be_an_instance_of FarMar::Product + csv = CSV.read("support/products.csv") + expect(all_products.length).to eq csv.length + end + end + + describe "#find" do + it "returns the instance of Product matching the input id" do + expect(FarMar::Product.find(1)).to be_an_instance_of FarMar::Product + expect(FarMar::Product.find(3).name).to eq "Heavy Chicken" + end + end + + describe ".vendor" do + it "returns the Vendor instance that is associated with this product" do + expect(@product.vendor).to be_an_instance_of FarMar::Vendor + expect(@product.vendor.name).to eq "Labadie-Tremblay" + end + end + + describe ".sales" do + it "returns a collection of sales instances associated with this product" do + expect(@product.sales).to be_an Array + expect(@product.sales.length).to eq 2 + end + end + + describe ".number_of_sales" do + it "returns the number of times this product has been sold" do + expect(@product.number_of_sales).to be_an Integer + expect(@product.number_of_sales).to eq 2 + end + end + + describe "#by_vendor" do + it "returns all of the products with the given vendor_id" do + expect(FarMar::Product.by_vendor(1)).to be_an Array + expect(FarMar::Product.by_vendor(1).length).to eq 1 + end + end + end diff --git a/spec/far_mar/sale_spec.rb b/spec/far_mar/sale_spec.rb index b711bbe1..731c793e 100644 --- a/spec/far_mar/sale_spec.rb +++ b/spec/far_mar/sale_spec.rb @@ -2,7 +2,13 @@ describe FarMar::Sale do before :each do - @sale = FarMar::Sale.new + @sale = FarMar::Sale.new({ + id: "1", + amount: "9290", + purchase_time: "2013-11-07 04:34:56 -0800", + vendor_id: "1", + product_id:"1" + }) end describe ".new" do @@ -11,4 +17,45 @@ end end + describe "#all" do + all_sales = FarMar::Sale.all + it "returns a collection of all sale instances in the csv" do + expect(all_sales.class).to eq Array + expect(all_sales[0]).to be_an_instance_of FarMar::Sale + expect(all_sales[-1]).to be_an_instance_of FarMar::Sale + csv = CSV.read("support/sales.csv") + expect(all_sales.length).to eq csv.length + end + end + + describe "#find" do + it "returns the instance of Sale matching the input id" do + expect(FarMar::Sale.find(1)).to be_an_instance_of FarMar::Sale + expect(FarMar::Sale.find(2).amount).to eq 2262 + end + end + + describe ".vendor" do + it "returns the Vendor instance associated with the sale" do + expect(@sale.vendor).to be_an_instance_of FarMar::Vendor + expect(@sale.vendor.name).to eq "Feil-Farrell" + end + end + + describe ".product" do + it "returns the Product instance associated with the sale" do + expect(@sale.product).to be_an_instance_of FarMar::Product + expect(@sale.product.name).to eq "Dry Beets" + end + end + + describe "#between" do + it "returns a collection of Sale instances where the purchase time is between the two times given." do + @begin = DateTime.parse("2013-11-12 06:03:50 -0800") + @end = DateTime.parse("2013-11-13 01:48:19 -0800") + expect(FarMar::Sale.between(@begin, @end)).to be_an Array + expect(FarMar::Sale.between(@begin, @end).first).to be_an_instance_of FarMar::Sale + end + end + end diff --git a/spec/far_mar/vendor_spec.rb b/spec/far_mar/vendor_spec.rb index e24eb1bc..88706c80 100644 --- a/spec/far_mar/vendor_spec.rb +++ b/spec/far_mar/vendor_spec.rb @@ -2,7 +2,12 @@ describe FarMar::Vendor do before :each do - @vendor = FarMar::Vendor.new + @vendor = FarMar::Vendor.new({ + id: "1", + name: "Feil-Farrell", + employees: "8", + market_id: "1" + }) end describe ".new" do @@ -11,4 +16,67 @@ end end + describe "#all" do + all_vendors = FarMar::Vendor.all + it "returns a collection of all vendor instances in the csv" do + expect(all_vendors.class).to eq Array + expect(all_vendors[0]).to be_an_instance_of FarMar::Vendor + expect(all_vendors[-1]).to be_an_instance_of FarMar::Vendor + csv = CSV.read("support/vendors.csv") + expect(all_vendors.length).to eq csv.length + end + end + + describe "#find" do + it "returns the instance of Vendor matching the input id" do + expect(FarMar::Vendor.find(1)).to be_an_instance_of FarMar::Vendor + expect(FarMar::Vendor.find(2).name).to eq "Hamill, Kilback and Pfeffer" + end + end + + describe ".market" do + it "returns the Market instance from the csv that is associated with this vendor" do + expect(@vendor.market).to be_an_instance_of FarMar::Market + expect(@vendor.market.name).to eq "People's Co-op Farmers Market" + end + end + + describe ".products" do + it "returns a collection of the product instances associated with the vendor" do + expect(@vendor.products).to be_an Array + expect(@vendor.products.first).to be_a FarMar::Product + expect(@vendor.products.first.name).to eq "Dry Beets" + end + end + + describe ".sales" do + it "returns a collection of the sale instances associated with the vendor" do + expect(@vendor.sales).to be_an Array + expect(@vendor.sales.first.id).to eq 1 + end + end + + describe ".revenue" do + it "returns the sum of all of the vendor's sales, in cents" do + expect(@vendor.revenue).to be_an Integer + expect(@vendor.revenue).to eq 38259 + end + it "returns the amount of the vendor's sale in cents, if only one sale" do + @vendor2 = FarMar::Vendor.new({ + id: "2", + name: "Hamill, Kilback and Pfeffer", + employees: "5", + market_id: "1" + }) + expect(@vendor2.revenue).to be_an Integer + expect(@vendor2.revenue).to eq 5727 + end + end + + describe "#by_market" do + it "returns all of the vendors with the given market id" do + expect(FarMar::Vendor.by_market(1)).to be_an Array + expect(FarMar::Vendor.by_market(1).length).to eq 6 + end + end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 03753ffe..b69b2cb0 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,4 +1,9 @@ require "simplecov" SimpleCov.start - +require "pry" require "./lib/far_mar" + +# randomize running of specs +RSpec.configure do |config| + config.order = 'random' +end