Class: Report::CampaignsReport::CampaignsReport

Inherits:
Object
  • Object
show all
Defined in:
app/services/report/campaigns_report/campaigns_report.rb

Defined Under Namespace

Classes: Result

Class Method Summary collapse

Class Method Details

.campaigns_revenue(start_date, end_date, campaign_ids, list_months) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'app/services/report/campaigns_report/campaigns_report.rb', line 78

def self.campaigns_revenue(start_date,end_date,campaign_ids,list_months)
  prev_start_date = start_date.years_ago(1)
  prev_end_date = end_date.years_ago(1)

  if campaign_ids.count == 1
    campaign_ids_sql = campaign_ids.empty? ? ' ' : " and coalesce(c.id,c2.id) = #{campaign_ids.first.to_i} "
    sql = <<-SQL
      select coalesce(c.id,c2.id) as campaign_id,coalesce(c.name,c2.name) as campaign_name,
            sum(case when gl_date between '#{start_date}' and '#{end_date}' then quantity * discounted_price * consolidated_exchange_rate else 0 end) as cur_sales_amount,
            sum(case when gl_date between '#{prev_start_date}' and '#{prev_end_date}' then quantity * discounted_price * consolidated_exchange_rate else 0 end) as prev_sales_amount,
            dt.month
      from view_sales_facts vsf
      inner join analytic_date_time_dimensions dt on vsf.gl_date = dt.date
      left join campaigns c on vsf.source_id = c.source_id and c.state = 'active'
      left join campaigns c2 on vsf.source_parent_id = c2.source_id and c2.state = 'active'
      where coalesce(c.name,c2.name) is not null
      and (gl_date between '#{prev_start_date}' and '#{prev_end_date}' or gl_date between '#{start_date}' and '#{end_date}')
      #{campaign_ids_sql}
      group by coalesce(c.id,c2.id),coalesce(c.name,c2.name),dt.month
    SQL
  else
    campaign_ids_sql = campaign_ids.empty? ? ' ' : " and coalesce(c.id,c2.id) in (#{campaign_ids.map{ |c| c.to_i}.join(",")}) "
    sql = <<-SQL
      select coalesce(c.id,c2.id) as campaign_id,coalesce(c.name,c2.name) as campaign_name,sum(quantity * discounted_price * consolidated_exchange_rate) as cur_sales_amount,dt.month
      from view_sales_facts vsf
      inner join analytic_date_time_dimensions dt on vsf.gl_date = dt.date
      left join campaigns c on vsf.source_id = c.source_id and c.state = 'active'
      left join campaigns c2 on vsf.source_parent_id = c2.source_id and c2.state = 'active'
      where coalesce(c.name,c2.name) is not null
      and gl_date between '#{start_date}' and '#{end_date}'
      #{campaign_ids_sql}
      group by coalesce(c.id,c2.id),coalesce(c.name,c2.name),dt.month
    SQL
  end


  results = ActiveRecord::Base.connection.execute(sql).to_a.map{ |r| r.symbolize_keys }

  campaign_sales = []
  if results.present?
    list_campaigns = results.map{ |r| r[:campaign_name] }.compact.uniq
    list_campaigns.each do |c|
      monthly_sales = []
      prev_monthly_sales = []
      list_months.each do |m|
        sales = 0
        prev_sales = 0
        results.map{ |r| sales += r[:cur_sales_amount] if c == r[:campaign_name] && m == r[:month]}
        results.map{ |r| prev_sales += r[:prev_sales_amount] if c == r[:campaign_name] && m == r[:month]} if campaign_ids.count == 1
        monthly_sales << sales.to_f.round
        prev_monthly_sales << prev_sales.to_f.round if campaign_ids.count == 1
      end
      campaign_sales << [c,monthly_sales,prev_monthly_sales]
    end
  else
    monthly_sales = []
    prev_monthly_sales = []
    list_months.each do |m|
      monthly_sales << 0
      prev_monthly_sales << 0 if campaign_ids.count == 1
    end
    campaign_sales << ['',monthly_sales,prev_monthly_sales]
  end

  return campaign_sales
end

.campaigns_revenue_and_num_customers_by_reps(start_date, end_date, campaign_ids) ⇒ Object



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'app/services/report/campaigns_report/campaigns_report.rb', line 145

def self.campaigns_revenue_and_num_customers_by_reps(start_date,end_date,campaign_ids)
  prev_start_date = start_date.years_ago(1)
  prev_end_date = end_date.years_ago(1)
  campaign_ids_sql = campaign_ids.empty? ? ' ' : " and coalesce(c.id,c2.id) in (#{campaign_ids.map{ |c| c.to_i}.join(",")}) "

  sql = <<-SQL
    select vsf.primary_sr_id,r.full_name,
          sum(case when gl_date between '#{start_date}' and '#{end_date}' then quantity * discounted_price * consolidated_exchange_rate else 0 end) as cur_sales_amount,
          count(distinct case when gl_date between '#{start_date}' and '#{end_date}' then vsf.customer_id else null end) as cur_num_customers,
          sum(case when gl_date between '#{prev_start_date}' and '#{prev_end_date}' then quantity * discounted_price * consolidated_exchange_rate else 0 end) as prev_sales_amount,
          count(distinct case when gl_date between '#{prev_start_date}' and '#{prev_end_date}' then vsf.customer_id else null end) as prev_num_customers
    from view_sales_facts vsf
    inner join analytic_date_time_dimensions dt on vsf.gl_date = dt.date
    inner join parties r on vsf.primary_sr_id = r.id and r.inactive = false
    left join campaigns c on vsf.source_id = c.source_id and c.state = 'active'
    left join campaigns c2 on vsf.source_parent_id = c2.source_id and c2.state = 'active'
    where coalesce(c.name,c2.name) is not null
    and (primary_sr_id is not null and primary_sr_id not in (92,85))
    and (gl_date between '#{prev_start_date}' and '#{prev_end_date}' or gl_date between '#{start_date}' and '#{end_date}')
    #{campaign_ids_sql}
    group by vsf.primary_sr_id,r.full_name
  SQL

  results = ActiveRecord::Base.connection.execute(sql).to_a.map{ |r| r.symbolize_keys }
end

.campaigns_revenue_by_report_grouping(start_date, end_date, campaign_ids) ⇒ Object



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'app/services/report/campaigns_report/campaigns_report.rb', line 171

def self.campaigns_revenue_by_report_grouping(start_date,end_date,campaign_ids)
  prev_start_date = start_date.years_ago(1)
  prev_end_date = end_date.years_ago(1)
  campaign_ids_sql = campaign_ids.empty? ? ' ' : " and coalesce(c.id,c2.id) in (#{campaign_ids.map{ |c| c.to_i}.join(",")}) "

  sql = <<-SQL
    with months as (
        select distinct month,year
        from analytic_date_time_dimensions
        where (date between '#{prev_start_date}' and '#{prev_end_date}' or date between '#{start_date}' and '#{end_date}')
    ), sales as (
        select vsf.report_grouping,sum(quantity * discounted_price * consolidated_exchange_rate) as sales_amount,dt.month,dt.year
        from view_sales_facts vsf
        inner join analytic_date_time_dimensions dt on vsf.gl_date = dt.date
        left join campaigns c on vsf.source_id = c.source_id and c.state = 'active'
        left join campaigns c2 on vsf.source_parent_id = c2.source_id and c2.state = 'active'
        where coalesce(c.name,c2.name) is not null
        and (primary_sr_id is not null and primary_sr_id not in (92,85))
        and (gl_date between '#{prev_start_date}' and '#{prev_end_date}' or gl_date between '#{start_date}' and '#{end_date}')
        #{campaign_ids_sql}
        group by vsf.report_grouping,dt.month,dt.year
    ), sales_reps as (
        select distinct report_grouping
        from sales
    ), sales_reps_by_month as (
        select *
        from sales_reps,months
    )
    select rm.report_grouping,coalesce(sales_amount,0) as sales_amount,rm.month,rm.year
    from sales_reps_by_month rm
    left join sales s on rm.report_grouping = s.report_grouping and rm.month = s.month and rm.year = s.year
  SQL

  results = ActiveRecord::Base.connection.execute(sql).to_a.map{ |r| r.symbolize_keys }
end

.campaigns_revenue_by_report_grouping_for_chart(start_date, end_date, campaign_ids) ⇒ Object



207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'app/services/report/campaigns_report/campaigns_report.rb', line 207

def self.campaigns_revenue_by_report_grouping_for_chart(start_date,end_date,campaign_ids)
  campaign_ids_sql = campaign_ids.empty? ? ' ' : " and coalesce(c.id,c2.id) in (#{campaign_ids.map{ |c| c.to_i}.join(",")}) "
  sql = <<-SQL
    select vsf.report_grouping,sum(quantity * discounted_price * consolidated_exchange_rate) as sales_amount
    from view_sales_facts vsf
    inner join analytic_date_time_dimensions dt on vsf.gl_date = dt.date
    left join campaigns c on vsf.source_id = c.source_id and c.state = 'active'
    left join campaigns c2 on vsf.source_parent_id = c2.source_id and c2.state = 'active'
    where coalesce(c.name,c2.name) is not null
    and (primary_sr_id is not null and primary_sr_id not in (92,85))
    and gl_date between '#{start_date}' and '#{end_date}'
    #{campaign_ids_sql}
    group by vsf.report_grouping
  SQL

  results = ActiveRecord::Base.connection.execute(sql).to_a.map{ |r| r.symbolize_keys }
end

.campaigns_revenue_by_reps(start_date, end_date, campaign_ids) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'app/services/report/campaigns_report/campaigns_report.rb', line 41

def self.campaigns_revenue_by_reps(start_date,end_date,campaign_ids)
  prev_start_date = start_date.years_ago(1)
  prev_end_date = end_date.years_ago(1)
  campaign_ids_sql = campaign_ids.empty? ? ' ' : " and coalesce(c.id,c2.id) in (#{campaign_ids.map{ |c| c.to_i}.join(",")}) "

  sql = <<-SQL
    with months as (
        select distinct month,year
        from analytic_date_time_dimensions
        where (date between '#{prev_start_date}' and '#{prev_end_date}' or date between '#{start_date}' and '#{end_date}')
    ), sales as (
        select vsf.primary_sr_id,sum(quantity * discounted_price * consolidated_exchange_rate) as sales_amount,count(distinct customer_id) as num_customers,dt.month,dt.year
        from view_sales_facts vsf
        inner join analytic_date_time_dimensions dt on vsf.gl_date = dt.date
        left join campaigns c on vsf.source_id = c.source_id and c.state = 'active'
        left join campaigns c2 on vsf.source_parent_id = c2.source_id and c2.state = 'active'
        where coalesce(c.name,c2.name) is not null
        and (primary_sr_id is not null and primary_sr_id not in (92,85))
        and (gl_date between '#{prev_start_date}' and '#{prev_end_date}' or gl_date between '#{start_date}' and '#{end_date}')
        #{campaign_ids_sql}
        group by vsf.primary_sr_id,dt.month,dt.year
    ), sales_reps as (
        select distinct primary_sr_id,full_name
        from sales sr
        inner join parties r on sr.primary_sr_id = r.id and r.inactive = false
    ), sales_reps_by_month as (
        select *
        from sales_reps,months
    )
    select rm.primary_sr_id,rm.full_name,coalesce(sales_amount,0) as sales_amount,coalesce(num_customers,0) as num_customers,rm.month,rm.year
    from sales_reps_by_month rm
    left join sales s on rm.primary_sr_id = s.primary_sr_id and rm.month = s.month and rm.year = s.year
  SQL

  results = ActiveRecord::Base.connection.execute(sql).to_a.map{ |r| r.symbolize_keys }
end

.result(options = {}) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'app/services/report/campaigns_report/campaigns_report.rb', line 8

def self.result(options = {})
  start_date = options[:period1_gteq]
  end_date = options[:period1_lteq]
  campaign_ids = options[:campaign_ids].map(&:presence).compact
  list_months = (1..12).map{ |m| m }
  list_months = list_months.delete_if{ |m| m > end_date.month }

  data_campaigns_revenue_by_reps = campaigns_revenue_by_reps(start_date,end_date,campaign_ids)
  list_reps = data_campaigns_revenue_by_reps.map{ |r| { rep_id: r[:primary_sr_id], rep_name: r[:full_name]} }.compact.uniq
  data_campaigns_revenue_for_chart = campaigns_revenue(start_date,end_date,campaign_ids,list_months)
  data_campaigns_revenue_and_num_customers_by_reps_for_chart = campaigns_revenue_and_num_customers_by_reps(start_date,end_date,campaign_ids)

  data_campaigns_revenue_by_report_grouping = campaigns_revenue_by_report_grouping(start_date,end_date,campaign_ids)
  list_report_grouping = data_campaigns_revenue_by_report_grouping.map{ |r| r[:report_grouping] }.compact.uniq
  data_campaigns_revenue_by_report_grouping_for_chart = campaigns_revenue_by_report_grouping_for_chart(start_date,end_date,campaign_ids)

  Result.new(success: true,
             start_date: start_date,
             end_date: end_date,
             campaign_ids: campaign_ids,
             list_months: list_months,
             current_year: end_date.year,
             prev_year: end_date.years_ago(1).year,
             revenue_data_table: data_campaigns_revenue_by_reps,
             revenue_data_chart: data_campaigns_revenue_for_chart,
             revenue_and_num_customers_data_chart: data_campaigns_revenue_and_num_customers_by_reps_for_chart,
             list_reps: list_reps,
             report_grouping_data_table: data_campaigns_revenue_by_report_grouping,
             list_report_grouping: list_report_grouping,
             report_grouping_data_chart: data_campaigns_revenue_by_report_grouping_for_chart
  )
end