diff --git a/app/controllers/repp/v1/stats_controller.rb b/app/controllers/repp/v1/stats_controller.rb index a8fa1d077..2894de252 100644 --- a/app/controllers/repp/v1/stats_controller.rb +++ b/app/controllers/repp/v1/stats_controller.rb @@ -1,11 +1,14 @@ module Repp module V1 class StatsController < BaseController - api :get, '/repp/v1/stats/market_share' + api :get, '/repp/v1/stats/market_share_distribution' desc 'Get market share and distribution of registrars' - def market_share + 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) - registrars = registrars.where(from_condition).where(to_condition) + .where(from_condition).where(to_condition) grouped = registrars.group(:name).count result = grouped.map do |key, value| @@ -16,22 +19,67 @@ module Repp render_success(data: result) end + 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) + .where(from_condition) + + domains_by_registrar = registrars.where(to_condition).group(:name).count + prev_domains_by_registrar = registrars.where(compare_to_condition).group(:name).count + + set_zero_values!(domains_by_registrar, prev_domains_by_registrar) + + result = { prev_data: { name: search_params[:compare_to_date], + domains: serialize(prev_domains_by_registrar) }, + data: { name: search_params[:end_date], + domains: serialize(domains_by_registrar) } } + render_success(data: result) + end + private def search_params - params.permit(:q, q: %i[start_date end_date]).fetch(:q, {}) || {} + 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 >= '#{Date.strptime(search_params[:start_date], '%m.%y')}'" + "domains.created_at >= '#{to_date(search_params[:start_date])}'" end def to_condition return unless search_params[:end_date] - "domains.created_at <= '#{Date.strptime(search_params[:end_date], '%m.%y').end_of_month}'" + "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 end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 9021eff60..f15a8a55d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -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: diff --git a/config/locales/et.yml b/config/locales/et.yml index 84672ed3c..6da5860ff 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -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' diff --git a/config/routes.rb b/config/routes.rb index 22a4dc9c6..7ef8474f0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -101,7 +101,8 @@ Rails.application.routes.draw do resources :retained_domains, only: %i[index] resources :stats do collection do - get '/market_share', to: 'stats#market_share' + 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 diff --git a/test/fixtures/domains.yml b/test/fixtures/domains.yml index c8ea1bfce..01c43d644 100644 --- a/test/fixtures/domains.yml +++ b/test/fixtures/domains.yml @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/test/integration/repp/v1/stats/market_share_test.rb b/test/integration/repp/v1/stats/market_share_test.rb index 12f6c2ab8..614b5868d 100644 --- a/test/integration/repp/v1/stats/market_share_test.rb +++ b/test/integration/repp/v1/stats/market_share_test.rb @@ -7,10 +7,12 @@ class ReppV1StatsMarketShareTest < ActionDispatch::IntegrationTest token = "Basic #{token}" @auth_headers = { 'Authorization' => token } + @today = Time.zone.today.strftime('%m.%y') end - def test_shows_market_share_data - get '/repp/v1/stats/market_share', headers: @auth_headers + 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 @@ -22,4 +24,22 @@ class ReppV1StatsMarketShareTest < ActionDispatch::IntegrationTest 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 \ No newline at end of file