Skip to content

Instantly share code, notes, and snippets.

@bogdan
Created August 8, 2014 07:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bogdan/ce9716d61927b9c40964 to your computer and use it in GitHub Desktop.
Save bogdan/ce9716d61927b9c40964 to your computer and use it in GitHub Desktop.
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