Created
August 8, 2014 07:29
-
-
Save bogdan/ce9716d61927b9c40964 to your computer and use it in GitHub Desktop.
This file contains 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
class SummaryGrid < CurebitDatagrid | |
attr_accessor :site, :campaigns_filter | |
include Rails.application.routes.url_helpers | |
scope { Array.new } | |
filter(:referral_status, :enum, select: Referral::STATUSES, multiple: true, | |
default: [Referral::PENDING, Referral::APPROVED], dummy: true) | |
# These are not actual filters, I'm just abusing the feature to render date pickers | |
filter(:column1, :date, header: 'Column #1: Your Newest Date Range (ex: last week)', | |
range: true, default: ->{ [1.week.ago, Time.now] }) do |period, scope| | |
scope << period | |
end | |
filter(:column2, :date, header: 'Column #2: Your Older Date Range (ex: previous week)', | |
range: true, default: ->{ [2.weeks.ago, 8.days.ago] }) do |period, scope| | |
scope << period | |
end | |
filter(:current_user_id, dummy: true) | |
def self.smart_range_column(name, options = {}, &block) | |
column(name, options) do |period, grid| | |
grid.instance_exec(grid.core_metrics(period), &block) | |
end | |
end | |
def core_metrics(period) | |
@core_metrics ||= {} | |
period = (period.first || site.created_at).beginning_of_day..(period.last || Time.now).end_of_day | |
@core_metrics[period] ||= CoreMetrics.new(period: period, site: site, campaigns: campaigns_filter.campaigns) | |
end | |
# Very hacky approach I am not entirely satisfied with, but I have no other choice | |
def difference(column) | |
val1, val2 = assets.map {|date| data_value(column, date) } | |
diff = [val1, val2].map do |data| | |
data = data.to_s.delete('$%') | |
data = data.delete(site.currency_settings[:format][:delimiter]). | |
gsub(site.currency_settings[:format][:separator], ?.) if column.options[:type] == :money | |
data = data.delete(?,) if column.options[:type] == :plain | |
data.to_f | |
end.reduce(:-) # smiley! | |
diff = diff.to_i if diff == diff.to_i # round float to int if whole number, i.e. 42.0 => 42 | |
case column.options[:type] | |
when :percentage | |
'%.1f%' % diff | |
when :money | |
currency_value(diff) | |
when :plain | |
number_with_delimeter(diff) | |
end | |
end | |
smart_range_column(:sales_from_curebit_links, type: :money, | |
header: 'Sales from Curebit Links', | |
description: 'Sum of all purchases made from Curebit Links in given period (that have rewards associated with reason "referred")', | |
) do |core_metrics| | |
format_currency_link( | |
core_metrics.total_new_sales_sum, | |
site_purchases_path(site) | |
) | |
end | |
smart_range_column(:total_sales, type: :money, | |
header: 'Total Purchases', | |
) do |core_metrics| | |
format_currency_link( | |
core_metrics.total_sales_sum, | |
site_purchases_path(site) | |
) | |
end | |
smart_range_column(:revenue_percentage, type: :percentage, | |
header: '% of Revenue', | |
) do |core_metrics| | |
'%.1f%' % core_metrics.revenue_percentage | |
end | |
smart_range_column(:rewards_given_to_referrers, type: :money, | |
header: 'Rewards Given to Referrers', | |
description: 'Sum of all rewards given to referrers in given period (rewards that have reason "referrer")', | |
) do |core_metrics| | |
format_currency_link( | |
rewards_given(core_metrics.period), | |
site_referrals_path(site) | |
) | |
end | |
smart_range_column(:customers, type: :plain, | |
header: 'Unique Customers', | |
description: 'Number of new customers in given period (people who have made their first purchase)', | |
) do |core_metrics| | |
format_link( | |
number_with_delimeter(core_metrics.customers), | |
site_people_path(site) | |
) | |
end | |
smart_range_column(:new_customers, type: :plain, | |
header: 'New Customers', | |
) do |core_metrics| | |
number_with_delimeter core_metrics.new_customers | |
end | |
smart_range_column(:lift_in_sales, type: :percentage, | |
header: 'Lift in Sales', | |
description: 'Sum of all purchases made from Curebit Links in given period divided by sum of all purchases made through other than Curebit channels', | |
) do |core_metrics| | |
self.class.format_percentage(core_metrics.lift_in_sales) | |
end | |
smart_range_column(:share_percentage, type: :percentage, | |
# header: 'Share rate', | |
header: '% of Customers Who Have Shared', | |
description: 'Number of sharers among new customers in given period divided by total number of new customers', | |
) do |core_metrics| | |
self.class.format_percentage(core_metrics.share_percentage) | |
end | |
smart_range_column(:orders, type: :plain, | |
header: 'Orders', | |
) do |core_metrics| | |
number_with_delimeter core_metrics.orders | |
end | |
smart_range_column(:average_order_value, type: :money, | |
header: 'A.O.V.', | |
description: 'Average Order Value', | |
) do |core_metrics| | |
currency_value core_metrics.average_order_value | |
end | |
smart_range_column(:sharers, type: :plain, | |
header: 'People Who Have Shared', | |
) do |core_metrics| | |
number_with_delimeter core_metrics.sharers | |
end | |
smart_range_column(:email_gated, type: :plain, | |
header: 'Number of Emails Collected', | |
description: 'Emails collected on Offer Signup and Offer Claim pages', | |
) do |core_metrics| | |
number_with_delimeter core_metrics.email_gated | |
end | |
smart_range_column(:site_traffic, type: :plain, | |
header: 'Site Traffic (Clicks)', | |
description: 'Number of clicks on Curebit links in given period', | |
) do |core_metrics| | |
number_with_delimeter core_metrics.clicks | |
end | |
smart_range_column(:shares_facebook, type: :plain, | |
header: 'Facebook Posts', | |
description: 'Number of Shares on Facebook', | |
) do |core_metrics| | |
number_with_delimeter core_metrics.with_sharing_channel('facebook').shares | |
end | |
smart_range_column(:shares_email, type: :plain, | |
header: 'Number of Emails Sent to Friends', | |
) do |core_metrics| | |
number_with_delimeter core_metrics.with_sharing_channel('email').shares | |
end | |
smart_range_column(:other_shares, type: :plain, | |
header: 'Other Share Actions', | |
description: 'Total Number of Link / Twitter Shares', | |
) do |core_metrics| | |
number_with_delimeter core_metrics.with_sharing_channel(['other', 'twitter']).shares | |
end | |
smart_range_column(:first_time_sales_from_curebit_links, type: :money, | |
header: 'First Time Sales from Curebit Links', | |
description: 'Sum of all purchases made from Curebit Links in given period by first time buyers', | |
if: :admin?, | |
) do |core_metrics| | |
currency_value referred_curebit_sales(core_metrics.period) | |
end | |
smart_range_column(:rewards_given_for_first_time_sales, type: :money, | |
header: 'Rewards for First Time Sales from Curebit Links', | |
description: 'Sum of all rewards given to referrers for first time buyers in given period', | |
if: :admin?, | |
) do |core_metrics| | |
currency_value rewards_given(core_metrics.period, true) | |
end | |
protected | |
def referred_curebit_sales(period) | |
scope = site.purchases.referred_with_status(referral_status). | |
by_dates(period).by_campaigns(campaigns_filter.campaigns).new_only | |
scope.sum(:subtotal) | |
end | |
def rewards_given(period, first_time=false) | |
scope = site.referral_rewards.referrer.with_referral_status(referral_status). | |
by_dates(period).by_campaign(campaigns_filter.campaigns) | |
if first_time | |
purchase_ids = site.purchases.new_only.by_dates(period).referred_with_status(referral_status).select('origins.id') | |
scope = scope.where(target_type: 'Referral', target_id: Referral.select(:id).where(referred_origin_id: purchase_ids)) | |
end | |
scope.sum(:amount) | |
end | |
def format_currency_link(value, path) | |
format_link(currency_value(value), path) | |
end | |
def currency_value(value) | |
site.number_to_current_currency(value) | |
end | |
def number_with_delimeter(number) | |
ActionController::Base.helpers.number_with_delimiter(number) | |
end | |
def format_link(value, path) | |
self.class.format(value.to_s) do | |
link_to(value.to_s, path) | |
end | |
end | |
def current_user | |
@current_user ||= User.find(current_user_id) | |
end | |
def admin? | |
current_user.try(:admin?) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment