Class: Report::OpportunitiesVsLogistics::OpportunitiesVsLogistics

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

Defined Under Namespace

Classes: Result

Class Method Summary collapse

Class Method Details

.opps_data(start_date, end_date, product_lines_ids, report_type, display) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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
77
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
# File 'app/services/report/opportunities_vs_logistics/opportunities_vs_logistics.rb', line 24

def self.opps_data(start_date,end_date,product_lines_ids,report_type,display)
  product_lines_ids_sql = " and g.grouping_id in (#{product_lines_ids.map{|pl| "'#{pl}'" }.join(',')})" if product_lines_ids.present?
  table_select_sql = " select * from table_result order by result asc" if report_type == 1
  table_select_sql = " select * from chart_result" if report_type == 2

  sql = <<-SQL
    with opps as (
        select op.id,customer_id,state,timezone('America/Chicago', timestamptz(created_at))::date as created_at,close_date,reference_number
        from opportunities op
        where state in ('follow_up','promised')
        and timezone('America/Chicago', timestamptz(created_at))::date between '#{start_date}' and '#{end_date}'

    ), last_quote as (
        select opportunity_id,max(quotes.id) as quote_id
        from quotes
        inner join opps on quotes.opportunity_id = opps.id
        where quotes.id not in (select distinct quote_id from item_demand_forecast_additions where quote_id is not null)
        group by opportunity_id
        order by opportunity_id

    ), grouping as (
        select id,grouping,
        case when grouping = 'Floor Heating' then 1
             when grouping = 'Snow Melting' then 2
             when grouping = 'Roof & Gutter Deicing' then 3
             when grouping = 'Pipe Freeze Protection' then 4 else 0 end as grouping_id
        from (
            select id,trim(split_part(lineage_expanded,'>',1)) as grouping
            from product_lines
            where trim(split_part(lineage_expanded,'>',1)) in ('Floor Heating','Snow Melting','Roof & Gutter Deicing','Pipe Freeze Protection')
        )a

    ), line_items_by_quote as (
        select quote_id,quantity,item_id,sku,grouping_id
        from line_items li
        inner join last_quote lq on li.resource_type = 'Quote' and li.resource_id = lq.quote_id
        inner join items i on li.item_id = i.id
        inner join grouping g on i.primary_product_line_id = g.id
        where li.id not in (select distinct line_item_id from inventory_commits)
        #{product_lines_ids_sql}

    ), in_stock as (
        select item_id,(sum(qty_on_hand) - sum(qty_committed)) as qty_available
        from store_items
        where store_id in (1,2)
        and location = 'AVAILABLE'
        group by item_id

    ), on_order as (
        select item_id,sum(poi.quantity)as qty_ordered,max(pos.promised_delivery_date) as eta_shipment
        from purchase_order_items poi
        inner join shipment_items si on poi.id = si.purchase_order_item_id
        inner join purchase_order_shipments pos on si.purchase_order_shipment_id = pos.id
        where poi.state in ('not_receipted','partially_receipted')
        group by item_id

    ), opportunity_items as (
        select opportunity_id,customer_id,lq.quote_id,state,created_at,op.reference_number,grouping_id,quantity as qty,liq.item_id,sku,(created_at + 30) as hw_estimated_conv,
              close_date as promised_date,quantity as opp_pipeline
        from opps op
        inner join last_quote lq on op.id = lq.opportunity_id
        inner join line_items_by_quote liq on lq.quote_id = liq.quote_id

    ), opps_items_sum as (
        --select opportunity_id,customer_id,quote_id,state,created_at,reference_number,grouping_id,sum(qty) as qty,item_id,sku,hw_estimated_conv,promised_date,sum(opp_pipeline) as opp_pipeline
        select item_id,sku,sum(qty) as qty,created_at,hw_estimated_conv,promised_date,sum(opp_pipeline) as opp_pipeline,count(distinct opportunity_id) as num_opps
        from opportunity_items
        group by item_id,sku,created_at,hw_estimated_conv,promised_date

    ), table_result as (
        select op.item_id,sku,qty,hw_estimated_conv,promised_date,reorder_date_combined as inventory_planing_date,opp_pipeline,
              qty_available as current_stock_level,coalesce(reorder_amount_combined,0) as inventory_planing,coalesce(qty_ordered,0) as on_order,
              eta_shipment,
              case when (coalesce(qty_available,0) + coalesce(reorder_amount_combined,0) + coalesce(qty_ordered,0)) < opp_pipeline
                    then (coalesce(qty_available,0) + coalesce(reorder_amount_combined,0) + coalesce(qty_ordered,0) - opp_pipeline)
                    else (coalesce(qty_available,0) + coalesce(reorder_amount_combined,0) + coalesce(qty_ordered,0)) end as result
        from opps_items_sum op
        left join in_stock st on op.item_id = st.item_id
        left join view_inventory_plans vip on op.item_id = vip.item_id
        left join on_order oo on op.item_id = oo.item_id

    ), stock as (
          select detail,sum(current_stock_level) as on_stock,sum(on_order) as on_order,sum(inventory_planing) as inventory_planing
          from (
              select distinct #{display} as detail,oi.item_id,st.qty_available as current_stock_level,coalesce(vip.reorder_amount_combined,0) as inventory_planing,coalesce(oo.qty_ordered,0) as on_order
              from opportunity_items oi
              inner join analytic_date_time_dimensions dt on oi.created_at = date
              left join in_stock st on oi.item_id = st.item_id
              left join view_inventory_plans vip on oi.item_id = vip.item_id
              left join on_order oo on oi.item_id = oo.item_id
          )a
          group by detail

    ), opps_by as (
          select #{display} as detail,count(distinct opportunity_id) as num_opps
          from opportunity_items oi
          inner join analytic_date_time_dimensions dt on oi.created_at = date
          group by #{display}

    ), chart_result as (
          select ob.detail,num_opps,on_stock,on_order,inventory_planing
          from opps_by ob
          inner join stock s on ob.detail = s.detail
          order by 1
    )
    #{table_select_sql};
  SQL

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

.results(options = {}) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'app/services/report/opportunities_vs_logistics/opportunities_vs_logistics.rb', line 8

def self.results(options = {})
  start_date = options[:period1_gteq]
  end_date = options[:period1_lteq]
  product_lines_ids = options[:product_lines]
  display = options[:displays][0]

  opps_data_table = opps_data(start_date,end_date,product_lines_ids,1,display)
  opps_data_chart = opps_data(start_date,end_date,product_lines_ids,2,display)

  Result.new(success: true,
             data_table: opps_data_table,
             data_chart: opps_data_chart,
             display: display
  )
end