diff --git a/lib/far_mar.rb b/lib/far_mar.rb index f259ba84..b03a97e0 100644 --- a/lib/far_mar.rb +++ b/lib/far_mar.rb @@ -1,5 +1,6 @@ require 'csv' require 'time' +require 'pry' require './lib/far_mar/market' require './lib/far_mar/vendor' require './lib/far_mar/sale' diff --git a/lib/far_mar/market.rb b/lib/far_mar/market.rb index 1df3b33f..6757dad1 100644 --- a/lib/far_mar/market.rb +++ b/lib/far_mar/market.rb @@ -1,13 +1,121 @@ -# require './support/markets.csv' +# CSV.read('./support/markets.csv') module FarMar class Market + attr_reader :market_id, :name, :address, :city, :county, :state, :zip - def initialize - + def initialize(market_id, name, address, city, county, state, zip) + @market_id = market_id.to_i + @name = name + @address = address + @city = city + @county = county + @state = state + @zip = zip end - end + def self.all + @@market_array ||= [] + if @@market_array == [] + CSV.read('./support/markets.csv').each do |row| + market = FarMar::Market.new(row[0], row[1], row[2], row[3], row[4], row[5], row[6]) + @@market_array.push(market) + end + end + return @@market_array + end + + def self.find(id) + FarMar::Market.all.find {|mar| mar.market_id == id } + end + + def vendors + FarMar::Vendor.all.find_all {|ven| ven.market == market_id } + end + + def products + ven_array = self.vendors + prod_array = [] + ven_array.each do |ven| + prod_array.push(ven.products) + end + return prod_array.flatten + end + def self.search(search_term) + search_term = search_term.downcase + match_markets = [] + FarMar::Market.all.each do |market| + match_markets.push(market) if market.name.downcase.match(/#{search_term}/) + end + match_vendors = [] + FarMar::Vendor.all.each do |vendor| + match_vendors.push(vendor) if vendor.name.downcase.match(/#{search_term}/) + end + match_vendors.map! {|vendor| vendor.market} + match_vendors.each do |market_id| + market = FarMar::Market.find(market_id) + match_markets.push(market) + end + return match_markets + end + + def preferred_vendor(date = nil) + if date == nil + ven = self.vendors + preferred = ven.max_by{|ven| ven.revenue} + else + date = DateTime.strptime(date, "%Y-%m-%d").to_date + max_revenue = 0 + pref_vend = nil + total = 0 + self.vendors.each do |vendor_inst| + sales_array = [] + vendor_inst.sales.each do |sale_inst| + if sale_inst.purchase_time.to_date == date + sales_array.push(sale_inst.amount) + end + end + if sales_array.length > 0 + total = sales_array.inject(0, :+) + if total > max_revenue + max_revenue = total + pref_vend = vendor_inst + end + end + end + return pref_vend + end + end + + def worst_vendor(date = nil) + if date == nil + ven = self.vendors + worst = ven.min_by{|ven| ven.revenue} + else + date = DateTime.strptime(date, "%Y-%m-%d").to_date + min_revenue = Float::INFINITY + worst_ven = nil + total = 0 + self.vendors.each do |vendor_inst| + sales_array = [] + vendor_inst.sales.each do |sale_inst| + if sale_inst.purchase_time.to_date == date + sales_array.push(sale_inst.amount) + end + end + if sales_array.length > 0 + total = sales_array.inject(0, :+) + if total < min_revenue + min_revenue = total + worst_ven = vendor_inst + end + end + end + return worst_ven + end + end + + end end \ No newline at end of file diff --git a/lib/far_mar/product.rb b/lib/far_mar/product.rb index b1a44aba..7b1c2fc1 100644 --- a/lib/far_mar/product.rb +++ b/lib/far_mar/product.rb @@ -1,7 +1,48 @@ +# CSV.read("./support/products.csv") + module FarMar class Product + attr_reader :product_id, :name, :vendor_id + + def initialize(product_id, name, vendor_id) + @product_id = product_id.to_i + @name = name.to_s + @vendor_id = vendor_id.to_i + end + + def self.all + @@product_array ||= [] + if @@product_array == [] + CSV.read('./support/products.csv').each do |row| + product = FarMar::Product.new(row[0], row[1], row[2]) + @@product_array.push(product) + end + end + return @@product_array + end + + def self.find(id) + FarMar::Product.all.find {|pro| pro.product_id == id} + end + + def vendor + FarMar::Vendor.all.find{|ven| ven.vendor_id == @vendor_id} + end + + def sales + sales_hash = FarMar::Sale.sales_by_product + return sales_hash[@product_id] + end + + def number_of_sales + self.sales.length + end + + def self.by_vendor(vendor_id) + FarMar::Product.all.find_all{|prod| prod.vendor_id == vendor_id} + end end -end \ No newline at end of file +end diff --git a/lib/far_mar/sale.rb b/lib/far_mar/sale.rb index 0e1e3117..23fc3471 100644 --- a/lib/far_mar/sale.rb +++ b/lib/far_mar/sale.rb @@ -1,8 +1,73 @@ -# require "./support/sales.csv" +# CSV.read("./support/sales.csv") module FarMar class Sale + attr_reader :sale_id, :amount, :purchase_time, :vendor_id, :product_id + + def initialize(sale_id, amount, purchase_time, vendor_id, product_id) + @sale_id = sale_id.to_i + @amount = amount.to_i + purchase_time = purchase_time.to_s + @purchase_time = DateTime.strptime(purchase_time, "%Y-%m-%d %H:%M:%S %z") + @vendor_id = vendor_id.to_i + @product_id = product_id.to_i + end + + # def self.all + # @@sales_array ||= [] + # if @@sales_array = [] + # CSV.read('./support/sales.csv').each do |row| + # sale = FarMar::Sale.new(row[0], row[1], row[2], row[3], row[4]) + # @@sales_array.push(sale) + # end + # end + # return @@sales_array + # end + + def self.sales_init + @@sales_by_id = Hash.new + @@sales_by_product = Hash.new {|hash, key| hash[key] = []} + @@sales_by_vendor = Hash.new {|hash, key| hash[key] = []} + CSV.read('./support/sales.csv').each do |row| + new_sale = FarMar::Sale.new(row[0], row[1], row[2], row[3], row[4]) + @@sales_by_id[new_sale.sale_id] = new_sale + @@sales_by_product[new_sale.product_id].push(new_sale) + @@sales_by_vendor[new_sale.vendor_id].push(new_sale) + end + @@sales_all = sales_by_product.values.flatten + end + + def self.sales_by_product + return @@sales_by_product + end + + def self.sales_by_vendor + return @@sales_by_vendor + end + + def self.all + return @@sales_all + end + + def self.find(id) + #FarMar::Sale.all.find {|sale| sale.sale_id == id} + return @@sales_by_id[id] + end + + def vendor + FarMar::Vendor.all.find {|ven| ven.vendor_id == @vendor_id} + end + + def product + FarMar::Product.all.find {|pro| pro.product_id == @product_id} + end + + def self.between(beginning_time, ending_time) + FarMar::Sale.all.find_all do |sale| + sale.purchase_time.between?(beginning_time, ending_time) + end + end end diff --git a/lib/far_mar/vendor.rb b/lib/far_mar/vendor.rb index 02459c18..c5847a77 100644 --- a/lib/far_mar/vendor.rb +++ b/lib/far_mar/vendor.rb @@ -1,8 +1,86 @@ -# require './suport/vendors.csv' +# CSV.read('./support/vendors.csv') module FarMar class Vendor + attr_reader :vendor_id, :name, :employees, :market + + def initialize(vendor_id, name, employees, market) + @vendor_id = vendor_id.to_i + @name = name + @employees = employees + @market = market.to_i + end + + def self.all + @@vendor_array ||= [] + if @@vendor_array == [] + CSV.read('./support/vendors.csv').each do |row| + vendor = FarMar::Vendor.new(row[0], row[1], row[2], row[3]) + @@vendor_array.push(vendor) + end + end + return @@vendor_array + end + + def self.find(vendor_id) + FarMar::Vendor.all.find {|ven| ven.vendor_id == vendor_id} + end + + def products + FarMar::Product.all.find_all {|pro| pro.vendor_id == @vendor_id} + end + + def sales + sales_hash = FarMar::Sale.sales_by_vendor + return sales_hash[@vendor_id] + end + + def revenue + sales_array = self.sales + total = 0 + sales_array.each do |sale| + # binding.pry + total += sale.amount + end + return total + end + + def self.by_market(market_id) + FarMar::Vendor.all.find_all {|ven| ven.market == market_id } + end + + # Couldn't figure out how to rewrite this to get it to run in a decent amount of time + # def self.most_revenue(n) + # top_vendors = @@vendor_array.sort_by{|ven| ven.revenue} + # return top_vendors[0..n] + # end + + def self.most_items(n) + most_items = 0 + vendors_by_items = [] + vendor_array = @@vendor_array.dup + n.times do + vendor = vendor_array.max_by{|ven| ven.products.length} + vendors_by_items.push(vendor) + vendor_array.delete(vendor) + end + return vendors_by_items + end + + # This method is currently taking too long to run; I can't even get the tests to finish on it. Not sure if I'll have the time to retool it + # def self.revenue(date) + # date = DateTime.strptime(date, "%Y-%m-%d").to_date + # revenue = 0 + # FarMar::Vendor.all.each do |vendor_inst| + # vendor_inst.sales.each do |sale_inst| + # if sale_inst.purchase_time.to_date == date + # revenue += sale_inst.amount + # end + # end + # end + # return revenue + # end end diff --git a/spec/far_mar/market_spec.rb b/spec/far_mar/market_spec.rb index dc2bf4e6..0c88610b 100644 --- a/spec/far_mar/market_spec.rb +++ b/spec/far_mar/market_spec.rb @@ -1,12 +1,125 @@ require 'spec_helper' describe FarMar::Market do - before :each do - @market = FarMar::Market.new + + FarMar::Sale.sales_init + + describe '#initialize' do + before :each do + @market = FarMar::Market.new(1,"People's Co-op Farmers Market","30th and Burnside","Portland","Multnomah","Oregon",97202) + end + + it 'can create an instance of a FarMar::Market' do + expect(@market).to be_an_instance_of(FarMar::Market) + end + it 'can retrieve the name of the market instance' do + expect(@market.name).to eq ("People's Co-op Farmers Market") + end + it 'assigns the proper variable to state' do + expect(@market.state).to eq("Oregon") + end + end + + describe '.all' do + before :each do + @market_array = FarMar::Market.all + end + it 'returns an array' do + expect(@market_array).to be_an_instance_of(Array) + end + it 'contains only FarMar::Market instances' do + length = @market_array.length - 1 + expect(@market_array[rand(0..length)]).to be_an_instance_of(FarMar::Market) + end + it 'contains all data from CSV file' do + csv = CSV.read("support/markets.csv") + expect(@market_array.length).to eq(csv.length) + end + end + + describe '.find(id)' do + it 'returns a matching market instance' do + expect(FarMar::Market.find(16).zip).to eq("60546") + end + end + + describe 'vendors' do + before :each do + @market = FarMar::Market.new(7,"Petaluma Evening Farmers' Market","1 2nd Street","Petaluma","Sonoma","California",94952) + end + it 'returns an array' do + expect(@market.vendors).to be_an_instance_of(Array) + end + it 'returns all FarMar::Vendor instances for a market id' do + expect(@market.vendors.length).to eq(2) + end + end + + describe '#products' do + before :each do + @market = FarMar::Market.new(2,"Silverdale Farmers Market",98383,"Silverdale","Kitsap","Washington",98383) + end + it 'returns FarMar::Product instances' do + expect(@market.products[0]).to be_an_instance_of(FarMar::Product) + end + it 'returns an array' do + expect(@market.products).to be_an_instance_of(Array) + end + it 'returns all products sold at the Market' do + expect(@market.products.length).to eq(9) + end + end + + describe '.search(search_term)' do + before :each do + @search_return = FarMar::Market.search("school") + end + it 'returns an array' do + expect(@search_return).to be_an_instance_of(Array) + end + it 'contains Market Instances' do + expect(@search_return[0]).to be_an_instance_of(FarMar::Market) + end + it 'returns Markets w search_term in @name' do + expect(@search_return.length).to eq(3) + end + it 'returns Markets w search term in Vendor @name' do + @search = FarMar::Market.search("Donnelly") + expect(@search.length).to eq(18) + expect(@search[0].market_id).to eq(3) + end + end + + describe '#preferred_vendor(date)' do + before :each do + @market = FarMar::Market.new(2,"Silverdale Farmers Market",98383,"Silverdale","Kitsap","Washington",98383) + end + it 'returns a Vendor' do + expect(@market.preferred_vendor).to be_an_instance_of(FarMar::Vendor) + end + it 'returns Vendor with highest revenue' do + expect(@market.preferred_vendor.name).to eq("Stamm Inc") + end + it 'returns Vendor w highest revenue for date' do + @pref_vend = @market.preferred_vendor("2013-11-10") + expect(@pref_vend.vendor_id).to eq(7) + end end - it 'can create an instance of a FarMar::Market' do - expect(@market).to be_an_instance_of(FarMar::Market) + describe 'worst_vendor' do + before :each do + @market = FarMar::Market.new(2,"Silverdale Farmers Market",98383,"Silverdale","Kitsap","Washington",98383) + end + it 'returns a Vendor' do + expect(@market.worst_vendor).to be_an_instance_of(FarMar::Vendor) + end + it 'returns the Vendor with lowest revenue' do + expect(@market.worst_vendor.name).to eq("Quigley, Breitenberg and Schuster") + end + it 'returns Vendor w highest revenue for date' do + @worst_vend = @market.worst_vendor("2013-11-10") + expect(@worst_vend.vendor_id).to eq(8) + end end end \ No newline at end of file diff --git a/spec/far_mar/product_spec.rb b/spec/far_mar/product_spec.rb index ce78770c..49ec9526 100644 --- a/spec/far_mar/product_spec.rb +++ b/spec/far_mar/product_spec.rb @@ -1,9 +1,87 @@ -# require "./suport/products.csv" +require 'spec_helper' -module FarMar +describe FarMar::Product do - class Product + describe '#initialize' do + before :each do + @product = FarMar::Product.new(14,"Stupendous Carrots",7) + end + it 'creates an instance of a FarMar::Product' do + expect(@product).to be_an_instance_of(FarMar::Product) + end + it 'can access #product_id' do + expect(@product.product_id).to eq(14) + end + it 'can access the #vendor_id' do + expect(@product.vendor_id).to eq(7) + end + end + describe '.all' do + before :each do + @product_array = FarMar::Product.all + end + it 'returns an array' do + expect(@product_array).to be_an_instance_of(Array) + end + it 'contains only FarMar::Product instances' do + length = @product_array.length - 1 + expect(@product_array[rand(0..length)]).to be_an_instance_of(FarMar::Product) + end + it 'contains all products from CSV' do + csv = CSV.read("support/products.csv") + expect(@product_array.length).to eq csv.length + end end + describe '.find' do + it 'returns a matching product instance' do + expect(FarMar::Product.find(10).name).to eq("Black Apples") + end + end + + describe '#vendor' do + before :each do + @product = FarMar::Product.new(9,"Large Mushrooms",5) + end + it 'returns Vendor associated with Product' do + expect(@product.vendor.name).to eq("Reynolds, Schmitt and Klocko") + end + end + + describe '#sales' do + before :each do + @product = FarMar::Product.new(9,"Large Mushrooms",5) + end + it 'returns an array' do + expect(@product.sales).to be_an_instance_of(Array) + end + it 'returns all sales of product' do + product1 = FarMar::Product.new(165,"Striped Apples",51) + expect(product1.sales.length).to eq(0) + expect(@product.sales.length).to eq(3) + end + it 'returns Sales instances' do + expect(@product.sales[rand(0..2)]).to be_an_instance_of(FarMar::Sale) + end + end + + describe 'number_of_sales' do + before :each do + @product = FarMar::Product.new(6,"Smooth Mushrooms",4) + end + it 'returns the number of times Product has been sold' do + expect(@product.number_of_sales).to eq(1) + end + it 'works if product has not been sold' do + @product1 = FarMar::Product.new(165,"Striped Apples",51) + expect(@product1.number_of_sales).to eq(0) + end + + describe '.by_vendor(vendor_id)'do + it 'returns products sold with same vendor_id' do + expect(FarMar::Product.by_vendor(6).length).to eq(3) + end + end + end end \ No newline at end of file diff --git a/spec/far_mar/sale_spec.rb b/spec/far_mar/sale_spec.rb index 9271f030..9b890bf6 100644 --- a/spec/far_mar/sale_spec.rb +++ b/spec/far_mar/sale_spec.rb @@ -1,12 +1,59 @@ require 'spec_helper' describe FarMar::Sale do - before :each do - @sale = FarMar::Sale.new - end + + describe '#initialize' do + before :each do + @sale = FarMar::Sale.new(5,4440,"2013-11-10 05:19:05 -0800",1,1) + end + it 'can create an instance of a FarMar::Sale' do + expect(@sale).to be_an_instance_of(FarMar::Sale) + end + end - it 'can create an instance of a FarMar::Sale' do - expect(@sale).to be_an_instance_of(FarMar::Sale) - end + describe '.all' do + before :each do + @sale_array = FarMar::Sale.all + end + it 'returns an array' do + expect(@sale_array).to be_an_instance_of(Array) + end + it 'contains all sales from CSV' do + csv = CSV.read("support/sales.csv") + expect(@sale_array.length).to eq csv.length + + end + end + + describe '.find' do + it 'returns a matching sale instance' do + expect(FarMar::Sale.find(15).amount).to eq(8924) + end + end + + describe '#vendor' do + it 'returns Vendor that is associated with Sale' do + sale = FarMar::Sale.new(14,4978,"2013-11-10 01:51:24 -0800",3,4) + expect(sale.vendor.name).to eq("Breitenberg Inc") + end + end + + describe 'product' do + it 'returns Product associated with the Sale' do + sale = FarMar::Sale.new(14,4978,"2013-11-10 01:51:24 -0800",3,4) + expect(sale.product.name).to eq("Yummy Fruit") + end + end + + describe 'self.between(beginning_time, end_time)' do + before :each do + @beg_time1 = DateTime.strptime("2013-11-06 08:35:40 -08:00", "%Y-%m-%d %H:%M:%S %z") + @end_time1 = DateTime.strptime("2013-11-13 08:35:16 -0800", "%Y-%m-%d %H:%M:%S %z") + end + it 'returns Sales between two purchase times' do + sales = FarMar::Sale.between(@beg_time1, @end_time1) + expect(sales.length).to eq(12798) + end + end end \ No newline at end of file diff --git a/spec/far_mar/vendor_spec.rb b/spec/far_mar/vendor_spec.rb index ec39f260..4b0222a3 100644 --- a/spec/far_mar/vendor_spec.rb +++ b/spec/far_mar/vendor_spec.rb @@ -1,12 +1,119 @@ require 'spec_helper' describe FarMar::Vendor do - before :each do - @vendor = FarMar::Vendor.new + + FarMar::Sale.sales_init + + + describe '#initialize' do + before :each do + @vendor = FarMar::Vendor.new(30,"Koelpin, Koelpin and Wintheiser",10,9) + end + it 'can create an instance of a FarMar::Vendor' do + expect(@vendor).to be_an_instance_of(FarMar::Vendor) + end + it 'can retrieve the id of a given instance' do + expect(@vendor.vendor_id).to eq(30) + end + end + + describe '.all' do + before :each do + @vendor_array = FarMar::Vendor.all + end + it 'returns an array' do + expect(@vendor_array).to be_an_instance_of(Array) + end + it 'contains same number of vendors as orginal file' do + csv = CSV.read("support/vendors.csv") + expect(@vendor_array.length).to eq(csv.length) + end + it 'only contains FarMar::Vendor instances' do + length = @vendor_array.length - 1 + expect(@vendor_array[rand(0..length)]).to be_an_instance_of(FarMar::Vendor) + end + end + + describe '.find(id)' do + it 'returns a vendor instance' do + expect(FarMar::Vendor.find(10).name).to eq("Kertzmann LLC") + end + end + + describe '#market' do + vendor = FarMar::Vendor.new(5,"Reynolds, Schmitt and Klocko",3,1) + it 'returns the market associated with Vendor instance' do + expect(vendor.market).to eq(1) + end + end + + describe '#products' do + before :each do + @vendor = FarMar::Vendor.new(12,"Windler Inc",4,3) + end + it 'returns all products for a vendor' do + expect(@vendor.products.length).to eq(3) + end + # I feel like I could use let for the length variable, + # but I'm having trouble figure it out + it 'contains only Product instances'do + length = @vendor.products.length - 1 + expect(@vendor.products[0]).to be_an_instance_of(FarMar::Product) + end + end + + describe '#sales' do + before :each do + @vendor = FarMar::Vendor.new(12,"Windler Inc",4,3) + end + it 'returns an array' do + expect(@vendor.sales.class).to eq(Array) + end + it 'returns all sales per vendor' do + expect(@vendor.sales.length).to eq(3) + end + end + + describe '#revenue' do + it 'totals sales for Vendor' do + vendor = FarMar::Vendor.new(51,"Bernier Inc",1,12) + vendor1 = FarMar::Vendor.new(18,"Von-Hamill",10,5) + expect(vendor.revenue).to eq(0) + expect(vendor1.revenue).to eq(9749) + end end - it 'can create an instance of a FarMar::Vendor' do - expect(@vendor).to be_an_instance_of(FarMar::Vendor) + describe '.by_market(market_id)' do + it 'returns all Vendors for given market_id' do + expect(FarMar::Vendor.by_market(1).length).to eq(6) + end + it 'returns only instances of Vendors' do + expect(FarMar::Vendor.by_market(1)[rand(0..5)]).to be_an_instance_of(FarMar::Vendor) + end end + # Couldn't figure out how to get this to run without taking so long I have to just cancel it.. + # describe '.most_revenue(n)' do + # it 'returns top n Vendors by revenue' do + # top_vends = FarMar::Vendor.most_revenue(3) + # expect(top_vends[1].vendor_id).to eq() + # end + # end + + describe '.most_items(n)' do + it 'returns an Array' do + expect(FarMar::Vendor.most_items(3)).to be_an_instance_of(Array) + end + it 'returns top n Vendors by most items available for sale' do + expect(FarMar::Vendor.most_items(3)[0].vendor_id).to eq(10) + end + end + + # Another method that is taking way too long to run :/ + # describe 'self.revenue(date)' do + # it 'returns total revenue for a given date' do + # expect(FarMar::Vendor.revenue("2013-11-07")).to eq(9060582) + # end + # end + end \ No newline at end of file diff --git a/spec/product_spec.rb b/spec/product_spec.rb deleted file mode 100644 index b953106d..00000000 --- a/spec/product_spec.rb +++ /dev/null @@ -1,12 +0,0 @@ -require 'spec_helper' - -describe FarMar::Product do - before :each do - @product = FarMar::Product.new - end - - it 'can create an instance of a FarMar::Product' do - expect(@product).to be_an_instance_of(FarMar::Product) - end - -end \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 07cee4c8..8c932869 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,4 +1,5 @@ require 'simplecov' SimpleCov.start -require './lib/far_mar' \ No newline at end of file +require './lib/far_mar' +