Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Created market share chart data endpoint #2426

Merged
merged 8 commits into from
Sep 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions app/controllers/repp/v1/stats_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
module Repp
module V1
class StatsController < BaseController
api :get, '/repp/v1/stats/market_share_distribution'
desc 'Get market share and distribution of registrars'
param :q, Hash, required: true, desc: 'Period parameters for data' do
param :end_date, String, required: true, desc: 'Period end date'
end
def market_share_distribution
registrars = ::Registrar.where(test_registrar: false).joins(:domains)
.where(from_condition).where(to_condition)
grouped = registrars.group(:name).count

result = grouped.map do |key, value|
hash = { name: key.strip, y: value }
hash.merge!({ sliced: true, selected: true }) if current_user.registrar.name == key
hash
end
render_success(data: result)
end

# rubocop:disable Metrics/MethodLength
api :get, '/repp/v1/stats/market_share_growth_rate'
desc 'Get market share and growth rate of registrars'
param :q, Hash, required: true, desc: 'Period parameters for data' do
param :end_date, String, required: true, desc: 'Period end date'
param :compare_to_date, String, required: true, desc: 'Comparison date'
end
def market_share_growth_rate
registrars = ::Registrar.where(test_registrar: false).joins(:domains)

domains_by_rar = registrars.where(from_condition).where(to_condition).group(:name).count
prev_domains_by_rar = registrars.where(compare_to_condition).group(:name).count

set_zero_values!(domains_by_rar, prev_domains_by_rar)

market_share_by_rar = calculate_market_share(domains_by_rar)
prev_market_share_by_rar = calculate_market_share(prev_domains_by_rar)

result = { prev_data: { name: search_params[:compare_to_date],
domains: serialize(prev_domains_by_rar),
market_share: serialize(prev_market_share_by_rar) },
data: { name: search_params[:end_date],
domains: serialize(domains_by_rar),
market_share: serialize(market_share_by_rar) } }
render_success(data: result)
end
# rubocop:enable Metrics/MethodLength

private

def search_params
params.permit(:q, q: %i[start_date end_date compare_to_date])
.fetch(:q, {}) || {}
end

def from_condition
return unless search_params[:start_date]

"domains.created_at >= '#{to_date(search_params[:start_date])}'"
end

def to_condition
return unless search_params[:end_date]

"domains.created_at <= '#{to_date(search_params[:end_date]).end_of_month}'"
end

def compare_to_condition
return unless search_params[:compare_to_date]

"domains.created_at <= '#{to_date(search_params[:compare_to_date]).end_of_month}'"
end

def to_date(date_param)
Date.strptime(date_param, '%m.%y')
end

def serialize(rars)
rars.map { |key, value| [key, value] }
end

def set_zero_values!(cur, prev)
cur_dup = cur.dup
cur_dup.each_key do |k|
cur_dup[k] = prev[k] || 0
end
prev.clear.merge!(cur_dup)
end

def calculate_market_share(domains_by_rar)
sum = domains_by_rar.values.sum
domains_by_rar.transform_values do |v|
value = v.to_f / sum * 100.0
value < 0.1 ? value.round(3) : value.round(1)
end
end
end
end
end
3 changes: 3 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ en:
date_long: "%d. %B %Y"
filename: "%Y-%m-%d_%H.%M"
date:
month_names:
[~, January, February, March, April, May, June, July, August, September, October, November, December]
formats:
default: "%Y-%m-%d"
month_year: "%B, %Y"

activerecord:
errors:
Expand Down
7 changes: 5 additions & 2 deletions config/locales/et.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ et:
password: 'Parool'

date:
# Don't forget the nil at the beginning; there's no such thing as a 0th month
month_names: [~, Jaanuar, Veebruar, Märts, Aprill, Mai, Juuni, Juuli, August, September, Oktoober, November, Detsember]
month_names:
[~, Jaanuar, Veebruar, Märts, April, Mai, Juuni, Juuli, August, September, Oktoober, November, Detsember]
formats:
default: "%Y-%m-%d"
month_year: "%B, %Y"
emails: "Meillaadressid"
invoice:
title: 'Arve'
Expand Down
6 changes: 6 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@
end
resources :auctions, only: %i[index]
resources :retained_domains, only: %i[index]
resources :stats do
collection do
get '/market_share_distribution', to: 'stats#market_share_distribution'
get '/market_share_growth_rate', to: 'stats#market_share_growth_rate'
end
end
namespace :registrar do
resources :notifications, only: [:index, :show, :update] do
collection do
Expand Down
4 changes: 4 additions & 0 deletions test/fixtures/domains.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ shop:
period: 1
period_unit: m
uuid: 1b3ee442-e8fe-4922-9492-8fcb9dccc69c
created_at: <%= 2.days.ago.to_s :db %>

airport:
name: airport.test
Expand All @@ -24,6 +25,7 @@ airport:
period: 1
period_unit: m
uuid: 2df2c1a1-8f6a-490a-81be-8bdf29866880
created_at: <%= 2.days.ago.to_s :db %>

library:
name: library.test
Expand All @@ -36,6 +38,7 @@ library:
period: 1
period_unit: m
uuid: 647bcc48-8d5e-4a04-8ce5-2a3cd17b6eab
created_at: <%= 2.days.ago.to_s :db %>

metro:
name: metro.test
Expand All @@ -48,6 +51,7 @@ metro:
period: 1
period_unit: m
uuid: ef97cb80-333b-4893-b9df-163f2b452798
created_at: <%= 2.days.ago.to_s :db %>

hospital:
name: hospital.test
Expand Down
45 changes: 45 additions & 0 deletions test/integration/repp/v1/stats/market_share_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
require 'test_helper'

class ReppV1StatsMarketShareTest < ActionDispatch::IntegrationTest
def setup
@user = users(:api_bestnames)
token = Base64.encode64("#{@user.username}:#{@user.plain_text_password}")
token = "Basic #{token}"

@auth_headers = { 'Authorization' => token }
@today = Time.zone.today.strftime('%m.%y')
end

def test_shows_market_share_distribution_data
get '/repp/v1/stats/market_share_distribution', headers: @auth_headers,
params: { q: { end_date: @today } }
json = JSON.parse(response.body, symbolize_names: true)

assert_response :ok
assert_equal 1000, json[:code]
assert_equal 'Command completed successfully', json[:message]

assert json[:data].is_a? Array
assert json[:data][0].is_a? Hash
assert_equal json[:data][0][:name], 'Best Names'
assert json[:data][0][:selected]
end

def test_shows_market_share_growth_rate_data
prev_date = Time.zone.today.last_month.strftime('%m.%y')
get '/repp/v1/stats/market_share_growth_rate', headers: @auth_headers,
params: { q: { end_date: @today,
compare_to_date: prev_date } }
json = JSON.parse(response.body, symbolize_names: true)

assert_response :ok
assert_equal 1000, json[:code]
assert_equal 'Command completed successfully', json[:message]

data = json[:data]
assert data[:data].is_a? Hash
assert data[:prev_data].is_a? Hash
assert_equal data[:data][:name], @today
assert data[:data][:domains].is_a? Array
end
end