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
|