Skip to content

Instantly share code, notes, and snippets.

@kopylovvlad
Last active May 16, 2017 18:44
Show Gist options
  • Save kopylovvlad/f3ec23d94b3ca9eee9bb77aa7f90cebb to your computer and use it in GitHub Desktop.
Save kopylovvlad/f3ec23d94b3ca9eee9bb77aa7f90cebb to your computer and use it in GitHub Desktop.
# app/controllers/statistics_controller.rb
class StatisticsController < ApplicationController
# ...
def weekly
@weekly = []
get_date.each do |date_obj|
day = date_obj[:start_day].strftime('%A %d-%m-%Y')
orders = get_orders(date_obj)
orders_sum = orders.map(&:price).reduce(:+)
pizza_count = orders
.map { |order| order.items.where(type: :pizza).count }
.reduce(:+)
pizza_arr = get_pizza_arr(orders)
users_arr = get_users_arr(orders)
@weekly.push(
day: day,
pizza_count: pizza_count,
orders_sum: orders_sum,
users: users_arr,
pizza: pizza_arr
)
end
end
private
##
# returns array
# like this
# [ { pizza: <Item>, count: 10},
# { pizza: <Item>, count: 8},
# { pizza: <Item>, count: 7},]
def get_pizza_arr(orders, pizza_count)
pizza_hash = Hash.new(0)
orders
.map { |order| order.items.where(type: :pizza) }
.reduce(:+).each { |item| pizza_hash[item.id] += 1 }
pizza_hash = pizza_hash.sort_by { |k, v| v }.reverse.to_h
Hash[pizza_hash.sort_by { |k,v| -v }[0..2]].map do |k,v|
{
pizza: Item.find(k),
count: v
}
end
end
##
# return array like this
# [ {user: <User>, sum: 1000},
# {user: <User>, sum: 900},
# {user: <User>, sum: 850}]
def get_users_arr(orders)
users_hash = Hash.new(0)
orders.each { |order| users_hash[order.user_id] += order.price }
users_hash = users_hash.sort_by { |k, v| v }.reverse.to_h
Hash[users_hash.sort_by { |k,v| -v }[0..2]].map do |k,v|
{
user: User.find(k),
sum: v
}
end
end
def get_orders(date_obj)
Order.preload(:user, :items).where(
'created_at >= :start_day AND created_at < :end_day',
start_day: date_obj[:start_day],
end_day: date_obj[:end_day]
)
end
##
# it returns something like this
# [ {start_day: Mon, 08 May 2017 00:00:00 +0300,
# end_day: Tue, 09 May 2017 00:00:00 +0300},
# {start_day: Tue, 09 May 2017 00:00:00 +0300,
# end_day: Wed, 10 May 2017 00:00:00 +0300},
# {start_day: Wed, 10 May 2017 00:00:00 +0300,
# end_day: Thu, 11 May 2017 00:00:00 +0300},
# {start_day: Thu, 11 May 2017 00:00:00 +0300,
# end_day: Fri, 12 May 2017 00:00:00 +0300},
# {start_day: Fri, 12 May 2017 00:00:00 +0300,
# end_day: Sat, 13 May 2017 00:00:00 +0300},
# {start_day: Sat, 13 May 2017 00:00:00 +0300,
# end_day: Sun, 14 May 2017 00:00:00 +0300},
# {start_day: Sun, 14 May 2017 00:00:00 +0300,
# end_day: Mon, 15 May 2017 00:00:00 +0300}]
def get_date
arr = []
start_day = nil
loop do
unless start_day.present?
start_day = DateTime.current.beginning_of_week
else
start_day += 1.day
end
end_day = start_day + 1.day
arr.push(
start_day: start_day,
end_day: end_day
)
break if end_day > DateTime.current.end_of_week
end
arr
end
# ...
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment