Last active
May 16, 2017 18:43
-
-
Save kopylovvlad/5bd63bb27962f43429db2857bfd066b3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # app/model/weekly_day.rb | |
| WeeklyDay = Struct.new(:start_day, :end_day) do | |
| def start_day_string | |
| start_day.strftime('%A %d-%m-%Y') | |
| end | |
| end | |
| # app/model/daily_statistic.rb | |
| DailyStatistic = Struct.new(:day_string, :orders) do | |
| def day | |
| day_string | |
| end | |
| def orders_sum | |
| @orders_sum ||= orders.map(&:price).reduce(:+) | |
| end | |
| def pizza_count | |
| @pizza_count ||= orders | |
| .map { |order| order.items.where(type: :pizza).count } | |
| .reduce(:+) | |
| end | |
| def users | |
| @users ||= get_users_arr | |
| end | |
| def pizza | |
| @pizza ||= get_pizza_arr | |
| end | |
| private | |
| ## | |
| # returns array | |
| # like this | |
| # [ { pizza: <Item>, count: 10}, | |
| # { pizza: <Item>, count: 8}, | |
| # { pizza: <Item>, count: 7},] | |
| def get_pizza_arr | |
| 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 | |
| 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 | |
| end | |
| # app/models/weekly_statistic.rb | |
| class WeeklyStatistic | |
| def perform | |
| date.map do |weekly_day| | |
| DailyStatistic.new( | |
| weekly_day.start_day_string, | |
| get_orders(weekly_day) | |
| ) | |
| end | |
| end | |
| def date | |
| @date ||= get_date | |
| end | |
| private | |
| ## | |
| # it returns something like this | |
| # [ <WeeklyDay>, <WeeklyDay>, <WeeklyDay> ] | |
| 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(WeeklyDay.new(start_day, end_day)) | |
| break if end_day > DateTime.current.end_of_week | |
| end | |
| arr | |
| 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 | |
| end | |
| # app/controllers/statistics_controller.rb | |
| class StatisticsController < ApplicationController | |
| # ... | |
| def weekly | |
| @weekly = WeeklyStatistic.new.perform | |
| end | |
| # ... | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment