diff --git a/lib/far_mar.rb b/lib/far_mar.rb index b0453783..5996c1f6 100644 --- a/lib/far_mar.rb +++ b/lib/far_mar.rb @@ -1,3 +1,4 @@ +require "pry" require "csv" require "time" require "./lib/far_mar/market" diff --git a/lib/far_mar/market.rb b/lib/far_mar/market.rb index 9f073ca7..751a6ebb 100644 --- a/lib/far_mar/market.rb +++ b/lib/far_mar/market.rb @@ -1,7 +1,106 @@ +require 'pry' + module FarMar class Market - def initialize + attr_accessor :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 + +#Creates a class variable to store csv values in order to save time reading while running the program multiple times. Method reads CSV file and uses .map to create a .new object for each line, returning the whole array of objects + def self.all + if @market_array.nil?|| @market_array.empty? + @market_array = CSV.read("support/markets.csv").map do |line| + Market.new( + id: line[0], + name: line[1], + address: line[2], + city: line[3], + county: line[4], + state: line[5], + zip: line[6]) + end + end + return @market_array + end + +#Find converts the csv file to an array, then uses .find to locate where the first value of each array in each line is equal to the id passed through as the argument. It then initializes an object with the values of the array on that idenitfied line. + def self.find(id) + market_array = CSV.read("support/markets.csv") + matched_line = market_array.find do |line| + line[0].to_i == id + end + return specific_market = Market.new( + id: matched_line[0], + name: matched_line[1], + address: matched_line[2], + city: matched_line[3], + county: matched_line[4], + state: matched_line[5], + zip: matched_line[6]) + end + +#Calls the .all method of Vendors and parses through each vendor (already instantiated via the all method), finding all vendors where the id of the market matches the market id of the vendor. + def vendors + possibilities = FarMar::Vendor.all + associated_vendors = possibilities.find_all do |each| + @id == each.market_id + end + return associated_vendors + end + +#Creates an array of all_products, then calls the vendor method on itself to return all the associated vendors. For each vendor, it calls the vendor product method which finds all the products sold by the vendor. For each product it checks if that product is already included on all_products. If it is not, it pushes the product to the mass array. The method return all_products, consisting of every product of every vendor at the market, with no duplicates. + def products + all_products = [] + self.vendors.each do |vendor| + vendor.products.each do |product| + all_products.push(product) if !all_products.include?(product) + end + end + return all_products + end + +#This creates an array of results, then goes through all the names of all the markets and vendors. If the name of either of those instances matches the search term (using regexp and /i for case insensitivity), if will push that instance to the results and return it. + def self.search(search_term) + results = [] + FarMar::Market.all.find_all do |market| + results.push(market) if market.name.match(/#{search_term}/i) + end + FarMar::Vendor.all.find_all do |vendor| + results.push(vendor.market) if vendor.name.match(/#{search_term}/i) + end + return results + end + +#This calls the vendor method on itself, returning all vendors associated with the market. Then it sorts the vendors least to greatest by their revenue, a method in the vendor class. Finally, the method returns the last vendor of that group, or the vendor with the greatest revenue. + def pref_vendor + return self.vendors.sort_by { |vendor| vendor.revenue}.last + end +#This method starts be going through each vendor of the market. For each vendor, it calls sales, which returns all sales associated with the vendor. Next, for every sale it checks if the purchase_time is equal to the date passed through as an argument. If it is, it calls amount on that sale and adds it to the variable revenue. After the loops cycling through adding the sales of each vendor on a certain date, the method compares to see if the revenue on that date calculated is greater than the max_revenue, which startes at 0. If it is, it sets itself as max revenue and the vendor in question as the max_vendor. Thus, for each vendor it compares their revenue with the max revenue and max vendor of all the vendors the loops has already iterated, returning the overall max_vendor. + def preferred_vendor(date) + max_rev = 0 + max_vendor = nil + self.vendors.each do |vendor| + rev = 0 + vendor.sales.each do |sale| + if sale.purchase_time.to_date == date + rev += sale.amount + end + end + #puts vendor + if rev > max_rev + max_rev = rev + max_vendor = vendor + end + end + return max_vendor end end end diff --git a/lib/far_mar/product.rb b/lib/far_mar/product.rb index e4d3b79a..71173ba2 100644 --- a/lib/far_mar/product.rb +++ b/lib/far_mar/product.rb @@ -1,7 +1,60 @@ module FarMar class Product - def initialize + attr_accessor :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 + +#Creates a class variable to store csv values in order to save time reading while running the program multiple times. Method reads CSV file and uses .map to create a .new object for each line, returning the whole array of objects + def self.all + if @product_array.nil? || @product_array.empty? + @product_array = CSV.read("support/products.csv").map do |line| + Product.new( + id: line[0], + name: line[1], + vendor_id: line[2]) + end + end + return @product_array + end + +#Find converts the csv file to an array, then uses .find to locate where the first value of each array in each line is equal to the id passed through as the argument. It then initializes an object with the values of the array on that idenitfied line. + def self.find(id) + product_array = CSV.read("support/products.csv") + matched_line = product_array.find do |line| + line[0].to_i == id + end + return specific_product = Product.new( + id: matched_line[0], + name: matched_line[1], + vendor_id: matched_line[2]) + end + +#Passes the vendor_id of the product to the vendor find method in order to return the vendor that sells this product. + def vendor + return FarMar::Vendor.find(@vendor_id) + end + +#Creates an array of all the sales in order to find every sale in which the id of the product matches the product id of the sale. Returns an array of all of those matches. + def sales + all_sales = FarMar::Sale.all.find_all do |each| + @id == each.product_id + end + return all_sales + end + +#Calls the sales method and calculates the length of that array, or how many sales are associated with this product. + def number_of_sales + self.sales.length + end +#Goes through an array of all the products to find where the vendor id of the product is equal to the vendor_id passed through as a parameter. + def self.by_vendor(vendor_id) + return FarMar::Product.all.find_all do |each| + vendor_id == each.vendor_id + end end end end diff --git a/lib/far_mar/sale.rb b/lib/far_mar/sale.rb index 5604747f..7ccda6ff 100644 --- a/lib/far_mar/sale.rb +++ b/lib/far_mar/sale.rb @@ -1,7 +1,62 @@ module FarMar class Sale - def initialize + attr_accessor :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 + +#Creates a class variable to store csv values in order to save time reading while running the program multiple times. Method reads CSV file and uses .map to create a .new object for each line, returning the whole array of objects + def self.all + if @sales_array.nil? || @sales_array.empty? + @sales_array = CSV.read("support/sales.csv").map do |line| + Sale.new( + id: line[0], + amount: line[1], + purchase_time: line[2], + vendor_id: line[3], + product_id: line[4]) + end + end + return @sales_array + end + +#Find converts the csv file to an array, then uses .find to locate where the first value of each array in each line is equal to the id passed through as the argument. It then initializes an object with the values of the array on that idenitfied line. + def self.find(id) + sales_array = CSV.read("support/sales.csv") + matched_line = sales_array.find do |line| + line[0].to_i == id + end + return Sale.new( + id: matched_line[0], + amount: matched_line[1], + purchase_time: matched_line[2], + vendor_id: matched_line[3], + product_id: matched_line[4]) + end + +#This passes the vendor_id of the sale as an argument to the vendor.find method in order to return the vendor to which the sale refers. + def vendor + return FarMar::Vendor.find(@vendor_id) + + end + +#This passes the product_id of the sale as an argument to the product find method in order to to return the product to which the sale refers. + def product + return FarMar::Product.find(@product_id) + end +#This method first tries to sanitize the arguments of time passed through; if they are strings it converts them to DateTimes. Next, it creates an array of all the sales and compares the purchase time of each sale to see if its value is between the values of the argument. It returns an array of all the sales that match that condition. + def self.between(beginning_time, end_time) + beginning_time = DateTime.parse(beginning_time) if beginning_time.class == String + end_time = DateTime.parse(end_time) if end_time.class == String + matched_sales = self.all.find_all do |each| + each.purchase_time >= beginning_time && each.purchase_time <= end_time + end + return matched_sales end end end diff --git a/lib/far_mar/vendor.rb b/lib/far_mar/vendor.rb index cbb4dcd0..7c229061 100644 --- a/lib/far_mar/vendor.rb +++ b/lib/far_mar/vendor.rb @@ -1,7 +1,77 @@ module FarMar class Vendor - def initialize + attr_accessor :id, :name, :employee_no, :market_id + def initialize(vendor_hash) + @id = vendor_hash[:id].to_i + @name = vendor_hash[:name] + @employee_no = vendor_hash[:employee_no].to_i + @market_id = vendor_hash[:market_id].to_i + end + +#Creates a class variable to store csv values in order to save time reading while running the program multiple times. Method reads CSV file and uses .map to create a .new object for each line, returning the whole array of objects + def self.all + if @vendor_array.nil? || @vendor_array.empty? + @vendor_array = CSV.read("support/vendors.csv").map do |line| + Vendor.new( + id: line[0], + name: line[1], + employee_no: line[2], + market_id: line[3]) + end + end + return @vendor_array + end + +#Goes through every line of the CSV file and compares the first value [0], the id, to the argument passed through the method, creating a new object with the data where those two valued are equivalent. + def self.find(id) + vendor_array = CSV.read("support/vendors.csv") + matched_line = vendor_array.find do |line| + line[0].to_i == id + end + return specific_vendor = Vendor.new( + id: matched_line[0], + name: matched_line[1], + employee_no: matched_line[2], + market_id: matched_line[3]) + end + +#Uses the Market find method passing the argument of the vendor's market id, which is in fact the id of the market. + def market + return FarMar::Market.find(@market_id) + end + +#Creates an array of all the products, then uses find all to identify when the id of the vendor matches the vendor id of the product. Returns an array of all such matches + def products + possibilities = FarMar::Product.all + associated_products = possibilities.find_all do |each| + @id == each.vendor_id + end + return associated_products + end + +#Creates an array of all sales, then uses find all to identify when the id of the vendor matches the vendor id of the sale. Returns an array of all such matches. + def sales + possibilities = FarMar::Sale.all + associated_sales = possibilities.find_all do |each| + @id == each.vendor_id + end + return associated_sales + end + +#Calls sales on the particular vendor, which returns an array of all sales the vendor has made. For each sale, it iterates through and adds the amount of that sale to the revenue variable. Then it returns the total revenue, or sum of every sale. + def revenue + revenue = 0 + self.sales.each do |sale| + revenue += sale.amount.to_i + end + return revenue + end +#Starts with an array of all vendors using the .all method, then employs find_all to find where the market id passes as an argument equals the market id of each vendor of every iteration. It returns an array of vendors of all of these matches. + def self.by_market(market_id) + return self.all.find_all do |each| + market_id == each.market_id + end end end end diff --git a/spec/far_mar/market_spec.rb b/spec/far_mar/market_spec.rb index 35814a4f..b41e82ee 100644 --- a/spec/far_mar/market_spec.rb +++ b/spec/far_mar/market_spec.rb @@ -1,9 +1,101 @@ require "spec_helper" describe FarMar::Market do + before :each do + @csv = CSV.read("support/markets.csv") + @market1 = 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) + @market13 = FarMar::Market.new(:id => 13, :name => "Otsiningo Park Farmers' Market", :address => "1 Bevier St,Binghamton", :city => "Binghamton", :county => "Broome", :state => "New York", :zip => 13905) + end + describe "initialize" do it "creates an instance of a market" do - expect(FarMar::Market.new).to be_an_instance_of FarMar::Market + expect(@market1).to be_an_instance_of FarMar::Market + expect(@market13.id).to eq 13 + end + end + + describe "self.all" do + it "returns an array of all the markets" do + expect(FarMar::Market.all.length).to eq @csv.length + end + + it "returns values correctly" do + expect(FarMar::Market.all()[24].state).to eq "Illinois" + end + end + + describe "self.find" do + + it "returns a market" do + expect(FarMar::Market.find(400)).to be_an_instance_of FarMar::Market + end + + it "returns a market given an id" do + expect(FarMar::Market.find(4).name).to eq "Preston Farmers’ Market" + end + + it "really does that" do + expect(FarMar::Market.find(13).id).to eq 13 + end + end + + describe "#vendors" do + it "returns an array" do + expect(@market1.vendors).to be_an Array + end + + it "returns an array of vendors" do + expect(@market1.vendors.first).to be_an_instance_of FarMar::Vendor + end + + end + + describe "#products" do + it "returns an array" do + expect(@market1.products).to be_an Array + end + + it "returns an array of products" do + expect(@market1.products.first).to be_an_instance_of FarMar::Product + end + + it "returns all the products associated with a market" do + expect(@market13.products.length).to eq 26 + end + end + + describe ".search()" do + before :each do + @search_test = FarMar::Market.search("School") + end + + it "returns an array" do + expect(@search_test).to be_an Array + end + + it "returns the correct number of items" do + expect(@search_test.length).to eq 3 + end + + it "returns Markets or Vendors" do + expect(@search_test.first).to be_an_instance_of FarMar::Market || FarMar::Vendor + end + end + + describe "#pref_vendor" do + it "returns a vendor object" do + expect(@market1.pref_vendor).to be_an_instance_of FarMar::Vendor + end + + it "returns a vendor with the highest revenue" do + expect(@market13.pref_vendor.id).to eq 54 + end + end + + describe "#preferred_vendor(date)"do + it "returns a vendor correctly" do + expect(@market2.preferred_vendor(Date.parse("2013-11-07")).id).to eq 7 end end end diff --git a/spec/far_mar/product_spec.rb b/spec/far_mar/product_spec.rb index f8ac3f84..29c30182 100644 --- a/spec/far_mar/product_spec.rb +++ b/spec/far_mar/product_spec.rb @@ -1,9 +1,81 @@ require "spec_helper" describe FarMar::Product do + before :each do + @csv = CSV.read("support/products.csv") + @product1 = FarMar::Product.new(:id => 1, :name => "Dry Beets", :vendor_id => 1) + @product2 = FarMar::Product.new(:id => 15, :name => "Comfortable Pretzel", :vendor_id => 8) + + end describe "initialize" do it "creates an instance of a product" do - expect(FarMar::Product.new).to be_an_instance_of FarMar::Product + expect(@product1).to be_an_instance_of FarMar::Product + end + + it "returns the correct values upon instantiation" do + expect(@product2.id).to eq 15 + end + end + + describe "self.all" do + it "returns an array or all the products" do + expect(FarMar::Product.all.length).to eq @csv.length + end + + it "returns an array of product objects" do + expect(FarMar::Product.all.first).to be_an_instance_of FarMar::Product + end + end + + describe "self.find" do + it "returns a product given an id" do + expect(FarMar::Product.find(4).name).to eq "Yummy Fruit" + end + end + + describe "#vendor" do + it "returns an instance of vendor" do + expect(@product1.vendor).to be_an_instance_of FarMar::Vendor + end + + it "returns the correct vendor" do + expect(@product2.vendor.id).to eq 8 + end + end + + describe "#sales" do + it "returns an array" do + expect(@product1.sales).to be_an Array + end + + it "returns an array of sale object" do + expect(@product1.sales.first).to be_an_instance_of FarMar::Sale + end + + it "returns all of the sales" do + expect(@product2.sales.length).to eq 2 + end + end + + describe "#number_of_sales" do + it "returns a number" do + expect(@product2.number_of_sales).to be_a Fixnum + end + + it "returns all of the sales" do + expect(@product1.sales.length).to eq 7 end end + + describe ".by_vendor" do + it "returns an array" do + expect(FarMar::Product.by_vendor(1)).to be_an Array + end + + it "returns an array of products" do + expect(FarMar::Product.by_vendor(1).first).to be_an_instance_of FarMar::Product + end + end + + end diff --git a/spec/far_mar/sale_spec.rb b/spec/far_mar/sale_spec.rb index d67b0c0c..526bdda4 100644 --- a/spec/far_mar/sale_spec.rb +++ b/spec/far_mar/sale_spec.rb @@ -1,9 +1,65 @@ require "spec_helper" describe FarMar::Sale do + before :each do + @csv = CSV.read("support/sales.csv") + @sale1 = FarMar::Sale.new(:id =>1, :amount =>9290, :purchase_time =>"2013-11-07 04:34:56 -0800", :vendor_id => 1, :product_id => 1) + @sale2 = FarMar::Sale.new(:id =>13, :amount =>3450, :purchase_time =>"2013-11-12 12:00:35 -0800", :vendor_id => 3, :product_id => 4) + end + describe "initialize" do - it "creates an instance of a market" do - expect(FarMar::Sale.new).to be_an_instance_of FarMar::Sale + it "creates an instance of a sale" do + expect(@sale1).to be_an_instance_of FarMar::Sale + end + + it "returns correct values" do + expect(@sale2.id).to eq 13 + end + end + + describe "self.all" do + it "returns an array of all the sales" do + expect(FarMar::Sale.all.length).to eq @csv.length + end + + it "has sale objects in the array" do + expect(FarMar::Sale.all.first).to be_an_instance_of FarMar::Sale + end + end + + describe "self.find" do + it "returns a sale given an id" do + expect(FarMar::Sale.find(4).amount).to eq 1634 + end + end + + describe "#vendor" do + it "returns a vendor" do + expect(@sale1.vendor).to be_an_instance_of FarMar::Vendor + end + + it "returns the correct vendor" do + expect(@sale2.vendor.id).to eq 3 + end + end + + describe "#product" do + it "returns a product" do + expect(@sale1.product).to be_an_instance_of FarMar::Product + end + + it "returns the correct product" do + expect(@sale2.product.id).to eq 4 + end + end + + describe ".between" do + it "returns all sale values between expansive dates" do + expect(FarMar::Sale.between("1900-11-08 12:21:41 -0800", "2050-11-08 12:21:41 -0800").length).to eq 12798 + end + + it "returns correct sales" do + expect(FarMar::Sale.between("2013-11-08 12:21:41 -0800", "2013-11-08 12:21:41 -0800",).length).to eq 1 end end end diff --git a/spec/far_mar/vendor_spec.rb b/spec/far_mar/vendor_spec.rb index 1fb2afc9..dcb6a424 100644 --- a/spec/far_mar/vendor_spec.rb +++ b/spec/far_mar/vendor_spec.rb @@ -1,9 +1,90 @@ require "spec_helper" describe FarMar::Vendor do + before :each do + @csv = CSV.read("support/vendors.csv") + @vendor2 = FarMar::Vendor.new(:id => 10, :name => "Kertzmann LLC", :employee_no => 11, :market_id => 3) + @vendor1 = FarMar::Vendor.new(:id => 1, :name => "Feil-Farrell", :employee_no => 8, :market_id => 1) + end + describe "initialize" do it "creates an instance of a market" do - expect(FarMar::Vendor.new).to be_an_instance_of FarMar::Vendor + expect(@vendor2).to be_an_instance_of FarMar::Vendor + expect(@vendor2.id).to eq 10 + end + end + + describe "self.all" do + it "returns an array or all the vendors" do + expect(FarMar::Vendor.all.length).to eq @csv.length + end + + it "interprets values in the array correctly" do + expect(FarMar::Vendor.all[11].market_id).to eq 3 + end + end + + describe ".find" do + it "returns a vendor object" do + expect(FarMar::Vendor.find(4)).to be_an_instance_of FarMar::Vendor + end + + it "returns the correct vendor given an id" do + expect(FarMar::Vendor.find(4).name).to eq "Kris and Sons" + end + end + + describe "#market" do + it "returns a market" do + expect(@vendor1.market).to be_an_instance_of FarMar::Market + end + + it "returns the market with a matching market id" do + expect(@vendor1.market.id).to eq @vendor1.market_id + end + end + + describe "#products" do + it "returns an array" do + expect(@vendor1.products).to be_an Array + end + + it "returns an array of products" do + expect(@vendor1.products.first).to be_an_instance_of FarMar::Product + end + + it "returns all products associated with a vendor" do + expect(@vendor2.products.length).to eq 5 + end + end + + describe "#sales" do + it "returns an array" do + expect(@vendor1.sales).to be_an Array + end + + it "returns an array of sales" do + expect(@vendor1.sales.first).to be_an_instance_of FarMar::Sale + end + end + + describe "#revenue" do + it "returns a number" do + expect(@vendor1.revenue).to be_a Fixnum + end + + it "returns a correct number" do + expect(@vendor2.revenue).to eq 32628 + end + end + + describe ".by_market" do + it "return an array" do + expect(FarMar::Vendor.by_market(1)).to be_an Array + end + + it "returns an array of vendors" do + expect(FarMar::Vendor.by_market(1).first).to be_an_instance_of FarMar::Vendor end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 03753ffe..2082b763 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -2,3 +2,7 @@ SimpleCov.start require "./lib/far_mar" + +RSpec.configure do |config| + config.order = 'random' +end