educode_sales 1.10.48 → 1.10.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/educode_sales/modules/easyeditor/easyeditor.css +130 -0
- data/app/assets/stylesheets/educode_sales/modules/easyeditor/fangge-style.css +4 -0
- data/app/controllers/educode_sales/application_controller.rb +12 -0
- data/app/controllers/educode_sales/business_courses_controller.rb +230 -0
- data/app/controllers/educode_sales/home_controller.rb +7 -0
- data/app/controllers/educode_sales/shixun_dectects_controller.rb +111 -0
- data/app/controllers/educode_sales/shixuns_controller.rb +157 -0
- data/app/controllers/educode_sales/subject_trends_controller.rb +937 -0
- data/app/controllers/educode_sales/subjects_controller.rb +202 -0
- data/app/helpers/educode_sales/application_helper.rb +8 -0
- data/app/helpers/educode_sales/business_courses_helper.rb +37 -0
- data/app/helpers/educode_sales/subject_helper.rb +29 -0
- data/app/models/educode_sales/business.rb +22 -0
- data/app/models/educode_sales/business_deliver_subject.rb +48 -0
- data/app/models/educode_sales/business_subject.rb +62 -0
- data/app/models/educode_sales/business_subject_shixun.rb +46 -0
- data/app/models/educode_sales/business_subject_staff.rb +35 -0
- data/app/models/educode_sales/permission.rb +2 -1
- data/app/models/educode_sales/shixun_dectect.rb +12 -0
- data/app/views/educode_sales/business_courses/edit.html.erb +148 -0
- data/app/views/educode_sales/business_courses/index.html.erb +312 -0
- data/app/views/educode_sales/business_courses/index.json.jbuilder +16 -0
- data/app/views/educode_sales/business_courses/list_shixuns.html.erb +224 -0
- data/app/views/educode_sales/business_courses/list_shixuns.json.jbuilder +17 -0
- data/app/views/educode_sales/business_courses/list_subjects.html.erb +217 -0
- data/app/views/educode_sales/business_courses/list_subjects.json.jbuilder +12 -0
- data/app/views/educode_sales/business_courses/new.html.erb +212 -0
- data/app/views/educode_sales/shixun_dectects/index.html.erb +466 -0
- data/app/views/educode_sales/shixun_dectects/index.json.jbuilder +22 -0
- data/app/views/educode_sales/shixun_dectects/markdown.html.erb +60 -0
- data/app/views/educode_sales/shixuns/edit.html.erb +186 -0
- data/app/views/educode_sales/shixuns/index.html.erb +513 -0
- data/app/views/educode_sales/shixuns/index.json.jbuilder +22 -0
- data/app/views/educode_sales/shixuns/new.html.erb +251 -0
- data/app/views/educode_sales/subject_trends/trends.html.erb +1074 -0
- data/app/views/educode_sales/subjects/edit.html.erb +86 -0
- data/app/views/educode_sales/subjects/index.html.erb +247 -0
- data/app/views/educode_sales/subjects/index.json.jbuilder +16 -0
- data/app/views/educode_sales/subjects/list_shixuns.html.erb +228 -0
- data/app/views/educode_sales/subjects/list_shixuns.json.jbuilder +17 -0
- data/app/views/educode_sales/subjects/new.html.erb +254 -0
- data/app/views/layouts/educode_sales/application.html.erb +38 -0
- data/config/routes.rb +37 -0
- data/lib/educode_sales/version.rb +1 -1
- metadata +37 -1
@@ -0,0 +1,937 @@
|
|
1
|
+
require_dependency "educode_sales/application_controller"
|
2
|
+
|
3
|
+
module EducodeSales
|
4
|
+
class SubjectTrendsController < ApplicationController
|
5
|
+
# authorize_resource class: false
|
6
|
+
include SaleTrendsHelper
|
7
|
+
include SaleTrendsCountHelper
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
def trends
|
12
|
+
@year = params[:year] ? params[:year] : Time.now.year
|
13
|
+
@month = params[:month] ? params[:month] : Time.now.month
|
14
|
+
@months = ['全部','1','2','3','4','5','6','7','8','9','10','11','12']
|
15
|
+
@years = ['全部'] + (1..(Time.now.year - 2014)).reverse_each.map { |d| 2014 + d }
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def trendss
|
23
|
+
# authorize! :trends, EducodeSales::SaleTrend
|
24
|
+
@year = params[:year] ? params[:year] : Time.now.year
|
25
|
+
@years = ['全部'] + (1..(Time.now.year - 2014)).reverse_each.map { |d| 2014 + d }
|
26
|
+
x = Common.find_by(extras: EducodeSales::Common::XTYPE)&.id
|
27
|
+
o = Common.find_by(extras: EducodeSales::Common::OTYPE)&.id
|
28
|
+
if (@year == '全部')
|
29
|
+
@business_amount = Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id != ? AND educode_sales_follow_ups.clazz_id != ?", x, o).sum(:budget_amount).round(2)
|
30
|
+
stage_ids = Common.where(clazz: '商机阶段', name: ['已中标', '已签单', '已验收', '回款中', '服务中', '已结束']).pluck(:id)
|
31
|
+
# 中标总金额, 已回款总金额
|
32
|
+
total_return = Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id != ?", x).where("educode_sales_follow_ups.stage_id IN (?)", stage_ids).select("sum(total_amount) AS total, sum(educode_sales_businesses.return_money) AS return_money")
|
33
|
+
@goal_amount = total_return[0]['total']&.round(2) || 0
|
34
|
+
|
35
|
+
@actual_goal_amount = Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id != ?", x).where("educode_sales_follow_ups.stage_id IN (?)", stage_ids).sum(:actual_amount).round(2)
|
36
|
+
s_stage_ids = Common.where(clazz: '商机阶段', name: ['已签单', '已验收', '回款中', '服务中', '已结束']).pluck(:id)
|
37
|
+
@service_amount = Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id != ?", x).where("educode_sales_follow_ups.stage_id IN (?)", s_stage_ids).sum(:total_amount).round(2)
|
38
|
+
@actual_service_amount = Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id != ?", x).where("educode_sales_follow_ups.stage_id IN (?)", s_stage_ids).sum(:actual_amount).round(2)
|
39
|
+
|
40
|
+
|
41
|
+
@return_amount = EducodeSales::MoneyPlanRecord.from("(
|
42
|
+
SELECT distinct(educode_sales_money_plan_records.id), educode_sales_money_plan_records.amount
|
43
|
+
FROM educode_sales_money_plan_records
|
44
|
+
JOIN educode_sales_money_plan_claims ON educode_sales_money_plan_claims.money_plan_record_id = educode_sales_money_plan_records.id
|
45
|
+
GROUP BY educode_sales_money_plan_records.id
|
46
|
+
) AS educode_sales_money_plan_records
|
47
|
+
").sum("amount").round(2)
|
48
|
+
# @return_amount = Business.joins(last_follow_up: :money_plans).where("educode_sales_follow_ups.clazz_id != ?", x).where.not("educode_sales_money_plans.clazz!= ?", 1).sum(:amount).round(2)
|
49
|
+
# # @return_amount = total_return[0]['return_money']&.round(2) || 0
|
50
|
+
# @receivable_amount = @goal_amount - @return_amount
|
51
|
+
|
52
|
+
@receivable_amount = Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id != ?", x).where("educode_sales_follow_ups.stage_id IN (?)", stage_ids).select("(SUM(educode_sales_follow_ups.actual_amount) - SUM(educode_sales_businesses.return_money)) AS num")
|
53
|
+
@receivable_amount = @receivable_amount.present? && @receivable_amount[0]['num'] ? @receivable_amount[0]['num'].round(2) : 0
|
54
|
+
|
55
|
+
a = Common.where(clazz: '商机类型', name: Common.find_by(extras: EducodeSales::Common::ATYPE)&.name).pluck(:id)
|
56
|
+
@a_amount = Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id IN (?)", a).sum(:budget_amount).round(2)
|
57
|
+
b = Common.where(clazz: '商机类型', name: Common.find_by(extras: EducodeSales::Common::BTYPE)&.name).pluck(:id)
|
58
|
+
@b_amount = Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id IN (?)", b).sum(:budget_amount).round(2)
|
59
|
+
else
|
60
|
+
year_time = "#{@year}-01-01 00:00:00"
|
61
|
+
year_over_time = "#{@year}-12-31 23:59:59"
|
62
|
+
|
63
|
+
@sale_trend = SaleTrend.find_or_create_by(year: @year)
|
64
|
+
@business_amount = Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id != ? AND educode_sales_follow_ups.clazz_id != ?", x, o).where("educode_sales_follow_ups.year <= ?", @year).sum(:budget_amount).round(2)
|
65
|
+
stage_ids = Common.where(clazz: '商机阶段', name: ['已中标', '已签单', '已验收', '回款中', '服务中', '已结束']).pluck(:id)
|
66
|
+
|
67
|
+
# 中标总金额, 已回款总金额
|
68
|
+
total_return = Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id != ?", x).where("educode_sales_follow_ups.bidded_date >= ? AND educode_sales_follow_ups.bidded_date <= ? AND educode_sales_follow_ups.stage_id IN (?)", "#{@year}-01-01", "#{@year}-12-31", stage_ids).select("sum(total_amount) AS total, sum(educode_sales_businesses.return_money) AS return_money")
|
69
|
+
@goal_amount = total_return[0]['total']&.round(2) || 0
|
70
|
+
|
71
|
+
@actual_goal_amount = Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id != ?", x).where("educode_sales_follow_ups.bidded_date >= ? AND educode_sales_follow_ups.bidded_date <= ? AND educode_sales_follow_ups.stage_id IN (?)", "#{@year}-01-01", "#{@year}-12-31", stage_ids).sum(:actual_amount).round(2)
|
72
|
+
s_stage_ids = Common.where(clazz: '商机阶段', name: ['已签单', '已验收', '回款中', '服务中', '已结束']).pluck(:id)
|
73
|
+
@service_amount = Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id != ?", x).where("educode_sales_follow_ups.signed_date >= ? AND educode_sales_follow_ups.signed_date <= ? AND educode_sales_follow_ups.stage_id IN (?)", "#{@year}-01-01", "#{@year}-12-31", s_stage_ids).sum(:total_amount).round(2)
|
74
|
+
@actual_service_amount = Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id != ?", x).where("educode_sales_follow_ups.signed_date >= ? AND educode_sales_follow_ups.signed_date <= ? AND educode_sales_follow_ups.stage_id IN (?)", "#{@year}-01-01", "#{@year}-12-31", s_stage_ids).sum(:actual_amount).round(2)
|
75
|
+
# @return_amount = Business.joins(last_follow_up: :money_plans).where("educode_sales_follow_ups.clazz_id != ?", x).where.not("educode_sales_money_plans.clazz!= ?", 1).where("educode_sales_money_plans.date_at >= ? AND educode_sales_money_plans.date_at <= ? ", year_time, year_over_time).sum(:amount).round(2)
|
76
|
+
|
77
|
+
@return_amount = EducodeSales::MoneyPlanRecord.from("(
|
78
|
+
SELECT distinct(educode_sales_money_plan_records.id), educode_sales_money_plan_records.amount, date_at
|
79
|
+
FROM educode_sales_money_plan_records
|
80
|
+
JOIN educode_sales_money_plan_claims ON educode_sales_money_plan_claims.money_plan_record_id = educode_sales_money_plan_records.id
|
81
|
+
GROUP BY educode_sales_money_plan_records.id
|
82
|
+
) AS educode_sales_money_plan_records
|
83
|
+
").where("educode_sales_money_plan_records.date_at >= ? AND educode_sales_money_plan_records.date_at <= ? ", year_time, year_over_time).sum(:amount).round(2)
|
84
|
+
# 往年累计已中标合同
|
85
|
+
# @former_goal_amount = Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id != ?", x).where("educode_sales_follow_ups.bidded_date <= ? AND educode_sales_follow_ups.stage_id IN (?)", "#{@year}-12-31", stage_ids).sum(:actual_amount).round(2)
|
86
|
+
# # 往年累计已回款
|
87
|
+
# @former_return_amount = Business.joins(last_follow_up: :money_plans).where("educode_sales_follow_ups.clazz_id != ?", x).where.not("educode_sales_money_plans.clazz!= ?", 1).where("educode_sales_money_plans.date_at <= ? ", year_over_time).sum(:amount).round(2)
|
88
|
+
# @receivable_amount = @former_goal_amount - @former_return_amount
|
89
|
+
|
90
|
+
@receivable_amount = Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id != ?", x).where("educode_sales_follow_ups.bidded_date <= ? AND educode_sales_follow_ups.stage_id IN (?)", "#{@year}-12-31", stage_ids).select("(SUM(educode_sales_follow_ups.actual_amount) - SUM(educode_sales_businesses.return_money)) AS num")
|
91
|
+
@receivable_amount = @receivable_amount.present? && @receivable_amount[0]['num'] ? @receivable_amount[0]['num'].round(2) : 0
|
92
|
+
|
93
|
+
a = Common.where(clazz: '商机类型', name: Common.find_by(extras: EducodeSales::Common::ATYPE)&.name).pluck(:id)
|
94
|
+
@a_amount = Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id IN (?)", a).where("educode_sales_follow_ups.year <= ?", @year).sum(:budget_amount).round(2)
|
95
|
+
b = Common.where(clazz: '商机类型', name: Common.find_by(extras: EducodeSales::Common::BTYPE)&.name).pluck(:id)
|
96
|
+
@b_amount = Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id IN (?)", b).where("educode_sales_follow_ups.year <= ?", @year).sum(:budget_amount).round(2)
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
def sale_trends
|
102
|
+
sale_trend = SaleTrend.find_by(year: params[:year])
|
103
|
+
if sale_trend.update(sale_trend_params)
|
104
|
+
render_success
|
105
|
+
else
|
106
|
+
render_failure sale_trend
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def operations
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
# 商机跟进数
|
115
|
+
def business_followup_analysis
|
116
|
+
common = EducodeSales::Common.find_by(clazz: 'staff_type', name: '销售')
|
117
|
+
names = EducodeSales::Staff.includes(:user).where(job_type: common.id).map { |d| [d.user.real_name, d.id, d.role_id] }
|
118
|
+
x = EducodeSales::Common.find_by(extras: EducodeSales::Common::XTYPE)&.id
|
119
|
+
x_business_ids = EducodeSales::Business.joins(last_follow_up: :clazz).where("educode_sales_commons.id = ?",x).pluck :id
|
120
|
+
|
121
|
+
@follow_count_range = params[:follow_count_range] || "week"
|
122
|
+
# 商机跟进数图表
|
123
|
+
respond_to do |format|
|
124
|
+
format.html do
|
125
|
+
|
126
|
+
end
|
127
|
+
format.js do
|
128
|
+
default_dates = (30.day.ago.to_date..Date.today).map { |d| d.strftime("%Y-%W") }.uniq #默认时间范围
|
129
|
+
@follow_count_data = business_followup_charts(default_dates, names, x_business_ids, SaleTrend::COLORS, [30.day.ago.to_date.beginning_of_week, Date.today], "%Y%u") do |default_dates|
|
130
|
+
default_dates.map { |date|
|
131
|
+
d = date.split("-")
|
132
|
+
year = d[0].to_i
|
133
|
+
week = d[1].to_i
|
134
|
+
if week == 0
|
135
|
+
0
|
136
|
+
else
|
137
|
+
month = Date.commercial(year, week).strftime("%m月%d日")
|
138
|
+
day = Date.commercial(year, week, 7).strftime("%m月%d日")
|
139
|
+
date.to_s + "(#{month}-#{day})"
|
140
|
+
end
|
141
|
+
} - [0]
|
142
|
+
end
|
143
|
+
end
|
144
|
+
format.json do
|
145
|
+
if params[:follow_count_range].present?
|
146
|
+
case params[:follow_count_range]
|
147
|
+
when "week" #按周
|
148
|
+
if params[:date_week].present?
|
149
|
+
date = params[:date_week].split(" - ")
|
150
|
+
# 年初第一天周数是0会导致周数重复计算
|
151
|
+
dates = (date[0].to_date..date[1].to_date).map { |d| d.strftime("%Y-%W") }.uniq.select { |d| d.split("-")[1] != '00' }
|
152
|
+
@follow_count_data = business_followup_charts(dates, names, x_business_ids, SaleTrend::COLORS, date, "%Y%u") do |dates|
|
153
|
+
dates.map { |date|
|
154
|
+
d = date.split("-")
|
155
|
+
year = d[0].to_i
|
156
|
+
week = d[1].to_i
|
157
|
+
if week == 0
|
158
|
+
0
|
159
|
+
else
|
160
|
+
month = Date.commercial(year, week).strftime("%m月%d日")
|
161
|
+
day = Date.commercial(year, week, 7).strftime("%m月%d日")
|
162
|
+
date.to_s + "(#{month}-#{day})"
|
163
|
+
end
|
164
|
+
} - [0]
|
165
|
+
end
|
166
|
+
else
|
167
|
+
return render json: {msg: '请选择时间范围', success: false }
|
168
|
+
end
|
169
|
+
when "month" #按月
|
170
|
+
if params[:date_month].present?
|
171
|
+
date = params[:date_month].split(" - ")
|
172
|
+
dates = ((date[0] + "-01").to_date..(date[1] + "-01").to_date).map { |d| d.strftime("%Y-%m") }.uniq
|
173
|
+
@follow_count_data = business_followup_charts(dates, names, x_business_ids, SaleTrend::COLORS, [(date[0] + "-01").to_date, (date[1] + "-01").to_date.end_of_month], '%Y%m')
|
174
|
+
else
|
175
|
+
return render json: {msg: '请选择时间范围', success: false }
|
176
|
+
end
|
177
|
+
when "year" #按年
|
178
|
+
if params[:date_year].present?
|
179
|
+
date = params[:date_year].split(" - ")
|
180
|
+
dates = (date[0]..date[1]).to_a.map { |d| d.to_s}
|
181
|
+
@follow_count_data = business_followup_charts(dates, names, x_business_ids, SaleTrend::COLORS, ["#{date[0]}-01-01".to_date.beginning_of_year, "#{date[1]}-01-01".to_date.end_of_year], '%Y')
|
182
|
+
else
|
183
|
+
return render json: {msg: '请选择时间范围', success: false }
|
184
|
+
end
|
185
|
+
else
|
186
|
+
#按天
|
187
|
+
if params[:date].present?
|
188
|
+
date = params[:date].split(" - ")
|
189
|
+
dates = (date[0].to_date..date[1].to_date).to_a.map { |d| d.to_s}
|
190
|
+
@follow_count_data = business_followup_charts(dates, names, x_business_ids, SaleTrend::COLORS, [date[0].to_date, date[1].to_date], '%Y%m%d')
|
191
|
+
else
|
192
|
+
return render json: {msg: '请选择时间范围', success: false }
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
render json: {data: @follow_count_data }
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
# 销售额分析
|
203
|
+
def sales_analysis
|
204
|
+
respond_to do |format|
|
205
|
+
format.html do
|
206
|
+
|
207
|
+
end
|
208
|
+
format.js do
|
209
|
+
x = EducodeSales::Common.find_by(extras: EducodeSales::Common::XTYPE)&.id
|
210
|
+
count_type = params[:count_type] || "actual_amount"
|
211
|
+
stage_ids = Common.where(clazz: '商机阶段', name: ['已中标', '已签单', '已验收', '回款中', '服务中', '已结束']).pluck(:id)
|
212
|
+
s_stage_ids = Common.where(clazz: '商机阶段', name: ['已签单', '已验收', '回款中', '服务中', '已结束']).pluck(:id)
|
213
|
+
@goal_count_range = params[:goal_count_range] || "month"
|
214
|
+
|
215
|
+
goal_default_dates = ("#{Time.now.year}-01-01".to_date.."#{Time.now.year}-#{Time.now.month}-01".to_date).map { |d| d.strftime("%Y-%m") }.uniq
|
216
|
+
sale_names = ['已中标', '已签单', '已回款']
|
217
|
+
|
218
|
+
common = Common.find_by(clazz: 'staff_type', name: '销售')
|
219
|
+
staffs = Staff.joins(:user).where(job_type: common.id).where.not(role_id: 11)
|
220
|
+
@staffs = staffs.map { |d| [d.user.real_name, d.id]}
|
221
|
+
|
222
|
+
if params[:goal_count_range].present?
|
223
|
+
case params[:goal_count_range]
|
224
|
+
when "week"
|
225
|
+
when "month" #按月
|
226
|
+
if params[:goal_date_month].present?
|
227
|
+
date = params[:goal_date_month].split(" - ")
|
228
|
+
date[0] = (date[0] + "-01").to_date.to_s
|
229
|
+
date[1] = (date[1] + "-01").to_date.end_of_month.to_s
|
230
|
+
|
231
|
+
dates = ((date[0] + "-01").to_date..(date[1] + "-01").to_date).map { |d| d.strftime("%Y-%m") }.uniq
|
232
|
+
@goal_count_data = month_sale_chart(dates, sale_names, SaleTrend::COLORS, x, stage_ids, s_stage_ids, count_type, date)
|
233
|
+
else
|
234
|
+
@goal_count_data = month_sale_chart(goal_default_dates, sale_names, SaleTrend::COLORS, x, stage_ids, s_stage_ids, count_type, ["#{Time.now.year}-01", "#{Time.now.year}-#{Time.now.month}"])
|
235
|
+
end
|
236
|
+
else
|
237
|
+
#按年
|
238
|
+
if params[:goal_date_year].present?
|
239
|
+
date = params[:goal_date_year].split(" - ")
|
240
|
+
dates = (date[0]..date[1]).to_a
|
241
|
+
@goal_count_data = year_sale_chart(dates, sale_names, SaleTrend::COLORS, x, stage_ids, s_stage_ids, count_type, date)
|
242
|
+
else
|
243
|
+
goal_default_dates = ("#{Time.now.year}-01-01".to_date.."#{Time.now.year}-#{Time.now.month}-01".to_date).map { |d| d.strftime("%Y") }.uniq
|
244
|
+
@goal_count_data = year_sale_chart(goal_default_dates, sale_names, SaleTrend::COLORS, x, stage_ids, s_stage_ids, count_type, ["#{Time.now.year}", "#{Time.now.year}"])
|
245
|
+
end
|
246
|
+
end
|
247
|
+
else
|
248
|
+
@goal_count_data = month_sale_chart(goal_default_dates, sale_names, SaleTrend::COLORS, x, stage_ids, s_stage_ids, count_type, ["#{Time.now.year}-01", "#{Time.now.year}-#{Time.now.month}"])
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
# 商机区域分布
|
255
|
+
def business_area
|
256
|
+
respond_to do |format|
|
257
|
+
format.html do
|
258
|
+
end
|
259
|
+
format.js do
|
260
|
+
@business_types = EducodeSales::Common.where(clazz: 'business_type').where.not(extras: "x_class").map { |d| {name: d.name, value: d.id } }
|
261
|
+
@select_business_type = params[:business_type].present? ? params[:business_type].split(",") : []
|
262
|
+
x = EducodeSales::Common.find_by(extras: EducodeSales::Common::XTYPE)&.id
|
263
|
+
o = Common.find_by(extras: EducodeSales::Common::OTYPE)&.id
|
264
|
+
provinces = EducodeSales::Common.where(clazz: 'area').pluck(:name)
|
265
|
+
if params[:business_count_type] == 'money' || params[:business_count_type].blank?
|
266
|
+
data = provinces.map { |province|
|
267
|
+
if params[:business_type].blank?
|
268
|
+
Business.joins(:last_follow_up).where("educode_sales_businesses.department_id in (?)", School.joins(:departments).where(province: province).pluck("departments.id")).where("educode_sales_follow_ups.clazz_id != ? AND educode_sales_follow_ups.clazz_id != ?", x, o).sum(:budget_amount).round(2)
|
269
|
+
else
|
270
|
+
Business.joins(:last_follow_up).where("educode_sales_businesses.department_id in (?)", School.joins(:departments).where(province: province).pluck("departments.id")).where("educode_sales_follow_ups.clazz_id in (?)", params[:business_type].split(",")).sum(:budget_amount).round(2)
|
271
|
+
end
|
272
|
+
}
|
273
|
+
if params[:sort_by].present?
|
274
|
+
data_hash = []
|
275
|
+
data.each_with_index do |d, i|
|
276
|
+
data_hash << {id: i, num: d}
|
277
|
+
end
|
278
|
+
|
279
|
+
data_hash.sort! { |a, b| params[:sort_by] == 'asc' ? a[:num] <=> b[:num] : b[:num] <=> a[:num] }
|
280
|
+
data = []
|
281
|
+
provinces_sort = []
|
282
|
+
data_hash.each_with_index do |d|
|
283
|
+
data << d[:num]
|
284
|
+
provinces_sort << provinces[d[:id]]
|
285
|
+
end
|
286
|
+
provinces = provinces_sort
|
287
|
+
end
|
288
|
+
@business_data = {
|
289
|
+
labels: provinces,
|
290
|
+
datasets: [
|
291
|
+
{
|
292
|
+
label: "商机总额",
|
293
|
+
data: data,
|
294
|
+
backgroundColor: SaleTrend::COLORS[0],
|
295
|
+
borderColor: SaleTrend::COLORS[0],
|
296
|
+
borderWidth: 1
|
297
|
+
}
|
298
|
+
]
|
299
|
+
}
|
300
|
+
else
|
301
|
+
data = provinces.map { |province|
|
302
|
+
if params[:business_type].blank?
|
303
|
+
Business.joins(:last_follow_up).where("educode_sales_businesses.department_id in (?)", School.joins(:departments).where(province: province).pluck("departments.id")).where("educode_sales_follow_ups.clazz_id != ? AND educode_sales_follow_ups.clazz_id != ?", x, o).count
|
304
|
+
else
|
305
|
+
Business.joins(:last_follow_up).where("educode_sales_businesses.department_id in (?)", School.joins(:departments).where(province: province).pluck("departments.id")).where("educode_sales_follow_ups.clazz_id in (?)", params[:business_type].split(",")).count
|
306
|
+
end
|
307
|
+
}
|
308
|
+
if params[:sort_by].present?
|
309
|
+
data_hash = []
|
310
|
+
data.each_Wit_index do |d, i|
|
311
|
+
data_hash << {id: i, num: d}
|
312
|
+
end
|
313
|
+
|
314
|
+
data_hash.sort! { |a, b| params[:sort_by] == 'asc' ? a[:num] <=> b[:num] : b[:num] <=> a[:num] }
|
315
|
+
data = []
|
316
|
+
provinces_sort = []
|
317
|
+
data_hash.each_with_index do |d|
|
318
|
+
data << d[:num]
|
319
|
+
provinces_sort << provinces[d[:id]]
|
320
|
+
end
|
321
|
+
provinces = provinces_sort
|
322
|
+
end
|
323
|
+
@business_data = {
|
324
|
+
labels: provinces,
|
325
|
+
datasets: [
|
326
|
+
{
|
327
|
+
label: "商机数量",
|
328
|
+
data: data,
|
329
|
+
backgroundColor: SaleTrend::COLORS[0],
|
330
|
+
borderColor: SaleTrend::COLORS[0],
|
331
|
+
borderWidth: 1
|
332
|
+
}
|
333
|
+
]
|
334
|
+
}
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
# 销售人员跟进分析
|
341
|
+
def sales_followup_analysis
|
342
|
+
respond_to do |format|
|
343
|
+
format.html do
|
344
|
+
|
345
|
+
end
|
346
|
+
format.js do
|
347
|
+
# 销售人员跟进分析
|
348
|
+
@goal_count_range = params[:goal_count_range] || "month"
|
349
|
+
begin_time = Time.now.at_beginning_of_year.to_s
|
350
|
+
end_time = Time.now.at_end_of_year.to_s
|
351
|
+
customer_time_range = params[:customer_time_range]
|
352
|
+
case customer_time_range
|
353
|
+
when 'last_week'
|
354
|
+
begin_time = (Time.now - 1.week).at_beginning_of_week.to_s
|
355
|
+
end_time = (Time.now - 1.week).at_end_of_week.to_s
|
356
|
+
when 'this_week'
|
357
|
+
begin_time = Time.now.at_beginning_of_week.to_s
|
358
|
+
end_time = Time.now.at_end_of_week.to_s
|
359
|
+
when 'last_month'
|
360
|
+
begin_time = (Time.now - 1.month).at_beginning_of_month.to_s
|
361
|
+
end_time = (Time.now - 1.month).at_end_of_month.to_s
|
362
|
+
when 'this_month'
|
363
|
+
begin_time = Time.now.at_beginning_of_month.to_s
|
364
|
+
end_time = Time.now.at_end_of_month.to_s
|
365
|
+
when 'last_year'
|
366
|
+
begin_time = (Time.now - 1.year).at_beginning_of_year.to_s
|
367
|
+
end_time = (Time.now - 1.year).at_end_of_year.to_s
|
368
|
+
when 'this_year'
|
369
|
+
begin_time = Time.now.at_beginning_of_year.to_s
|
370
|
+
end_time = Time.now.at_end_of_year.to_s
|
371
|
+
when 'all'
|
372
|
+
begin_time = (Time.now - 5.year).at_beginning_of_year.to_s
|
373
|
+
end_time = (Time.now + 5.year).at_end_of_year.to_s
|
374
|
+
when 'diy'
|
375
|
+
if params[:customer_date].present?
|
376
|
+
date = params[:customer_date].split(" - ")
|
377
|
+
begin_time = date[0] + " 00:00:00"
|
378
|
+
end_time = date[1] + " 23:59:59"
|
379
|
+
end
|
380
|
+
end
|
381
|
+
common = Common.find_by(clazz: 'staff_type', name: '销售')
|
382
|
+
staff_names = Staff.joins(:user).where(job_type: common.id).map { |d| d.user.real_name }
|
383
|
+
staff_ids = Staff.joins(:user).where(job_type: common.id).pluck(:id)
|
384
|
+
if params[:customer_count_type] == 'money' || params[:customer_count_type].blank?
|
385
|
+
@customer_data = {
|
386
|
+
labels: staff_names,
|
387
|
+
datasets: [
|
388
|
+
{
|
389
|
+
label: "跟进客户数",
|
390
|
+
data: staff_ids.map { |staff_id|
|
391
|
+
(EducodeSales::CustomerFollow.where(staff_id: staff_id).where("created_at >= ? AND created_at <= ?", begin_time, end_time).pluck(:school_id) + EducodeSales::Business.where(id: EducodeSales::FollowUp.where(staff_id: staff_id).where("created_at >= ? AND created_at <= ?", begin_time, end_time).pluck(:business_id).uniq).pluck(:school_id)).uniq.size
|
392
|
+
},
|
393
|
+
backgroundColor: SaleTrend::COLORS[0],
|
394
|
+
borderColor: SaleTrend::COLORS[0],
|
395
|
+
borderWidth: 1
|
396
|
+
}
|
397
|
+
]
|
398
|
+
}
|
399
|
+
else
|
400
|
+
@customer_data = {
|
401
|
+
labels: staff_names,
|
402
|
+
datasets: [
|
403
|
+
{
|
404
|
+
label: "跟进客户次数",
|
405
|
+
data: staff_ids.map { |staff_id|
|
406
|
+
EducodeSales::CustomerFollow.where(staff_id: staff_id).where("created_at >= ? AND created_at <= ?", begin_time, end_time).size + EducodeSales::FollowUp.where(staff_id: staff_id).where("created_at >= ? AND created_at <= ?", begin_time, end_time).size
|
407
|
+
},
|
408
|
+
backgroundColor: SaleTrend::COLORS[0],
|
409
|
+
borderColor: SaleTrend::COLORS[0],
|
410
|
+
borderWidth: 1
|
411
|
+
}
|
412
|
+
]
|
413
|
+
}
|
414
|
+
end
|
415
|
+
end
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
def goal_forecast
|
420
|
+
respond_to do |format|
|
421
|
+
format.html do
|
422
|
+
end
|
423
|
+
format.js do
|
424
|
+
if params[:forecast_type].blank? || params[:forecast_type] == "money"
|
425
|
+
p "按金额"
|
426
|
+
goal_forecast_money
|
427
|
+
else
|
428
|
+
p "按数量"
|
429
|
+
goal_forecast_count
|
430
|
+
end
|
431
|
+
end
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
def user_stat
|
436
|
+
respond_to do |format|
|
437
|
+
format.html do
|
438
|
+
|
439
|
+
end
|
440
|
+
format.js do
|
441
|
+
user_stat = EducodeSales::UserStatService.new
|
442
|
+
gon.table_1 = user_stat.table_1
|
443
|
+
gon.table_2 = user_stat.table_2(1)
|
444
|
+
gon.table_3 = user_stat.table_3
|
445
|
+
end
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
#拜访分析
|
450
|
+
def visit_analysis
|
451
|
+
sort_by = params[:sort_by].present? ? params[:sort_by] : "desc"
|
452
|
+
user_name = params[:user_name]
|
453
|
+
visit_type = params[:visit_type].present? ? params[:visit_type].split(",") : ""
|
454
|
+
title_names = %w[本年拜访数 本季拜访数 本月拜访数 本周拜访数]
|
455
|
+
respond_to do |format|
|
456
|
+
format.js do
|
457
|
+
@user_names = EducodeSales::Attendance.pluck(:name).uniq.map{|d| {name: d, value: d}}
|
458
|
+
@visit_types = SaleTrend::VISIT_TYPE.map {|d| {name: d[0], value: d[1]}}
|
459
|
+
sql = "SELECT name, count(*) as name_count FROM `educode_sales_attendances` WHERE (attendance_date >= '#{Time.now.beginning_of_year}' and attendance_date <= '#{Time.now.end_of_year}') group by name order by name_count desc limit 30"
|
460
|
+
visit_count = EducodeSales::Attendance.find_by_sql(sql).map{|d| [d.name, d.name_count]}
|
461
|
+
#年拜访量前30的用户名
|
462
|
+
top_thirty_username = visit_count.map{ |d| d[0]}
|
463
|
+
@visit_count_data = visit_user_type_name(top_thirty_username, sort_by, visit_type, title_names)
|
464
|
+
end
|
465
|
+
format.json do
|
466
|
+
if params[:user_type].present? && params[:user_type] == "name"
|
467
|
+
if user_name.present?
|
468
|
+
sql_by_name = "SELECT name, count(*) as name_count FROM `educode_sales_attendances` WHERE (attendance_date >= '#{Time.now.beginning_of_year}' and attendance_date <= '#{Time.now.end_of_year}') and name like '%#{user_name}%' group by name"
|
469
|
+
else
|
470
|
+
sql_by_name = "SELECT name, count(*) as name_count FROM `educode_sales_attendances` WHERE (attendance_date >= '#{Time.now.beginning_of_year}' and attendance_date <= '#{Time.now.end_of_year}') group by name order by name_count desc limit 30"
|
471
|
+
end
|
472
|
+
visit_count = EducodeSales::Attendance.find_by_sql(sql_by_name).map{|d| [d.name, d.name_count]}
|
473
|
+
#年拜访量前30的用户名
|
474
|
+
top_thirty_username = visit_count.map{ |d| d[0]}
|
475
|
+
@visit_count_data = visit_user_type_name(top_thirty_username, sort_by, visit_type, title_names)
|
476
|
+
else
|
477
|
+
if user_name.present?
|
478
|
+
sql_by_customer = "SELECT name, customer, count(*) as customer_count FROM `educode_sales_attendances` WHERE (attendance_date >= '#{Time.now.beginning_of_year}' and attendance_date <= '#{Time.now.end_of_year}') and name like '%#{user_name}%' group by customer order by customer_count desc limit 30"
|
479
|
+
else
|
480
|
+
sql_by_customer = "SELECT name, customer, count(*) as customer_count FROM `educode_sales_attendances` WHERE (attendance_date >= '#{Time.now.beginning_of_year}' and attendance_date <= '#{Time.now.end_of_year}') group by customer order by customer_count desc limit 30"
|
481
|
+
end
|
482
|
+
visit_count = EducodeSales::Attendance.find_by_sql(sql_by_customer).map{|d| [d.customer, d.customer_count]}
|
483
|
+
#年拜访量前30的用户名
|
484
|
+
top_thirty_customer = visit_count.map{ |d| d[0]}
|
485
|
+
@visit_count_data = visit_user_type_customer(top_thirty_customer, sort_by, visit_type, title_names)
|
486
|
+
end
|
487
|
+
render json: {data: @visit_count_data }
|
488
|
+
end
|
489
|
+
end
|
490
|
+
end
|
491
|
+
|
492
|
+
private
|
493
|
+
|
494
|
+
def sale_trend_params
|
495
|
+
params.permit(:chance_money, :ballot_money, :sign_money, :returned_money)
|
496
|
+
end
|
497
|
+
|
498
|
+
def business_followup_charts(dates, names, x_business_ids, colors, date, clazz)
|
499
|
+
not_business = x_business_ids.present? ? x_business_ids.join(',') : ''
|
500
|
+
staff_ids = names.present? ? names.map { |d| d[1] }.join(",") : ''
|
501
|
+
|
502
|
+
sql = "SELECT DATE_FORMAT(created_at, '#{clazz}') as week, count(*) as counts, staff_id
|
503
|
+
FROM educode_sales_follow_ups
|
504
|
+
WHERE date(created_at) >= '#{date[0]}' and date(created_at) <= '#{date[1]}'
|
505
|
+
AND business_id NOT IN (#{not_business}) and educode_sales_follow_ups.deleted_at IS NULL
|
506
|
+
AND staff_id IN (#{staff_ids})
|
507
|
+
GROUP BY DATE_FORMAT(created_at, '#{clazz}'), staff_id"
|
508
|
+
data = EducodeSales::FollowUp.find_by_sql(sql).group_by { |d| "#{d['staff_id']}-#{d['week']}" }
|
509
|
+
{
|
510
|
+
labels: block_given? ? yield(dates) : dates,
|
511
|
+
datasets: names.map.with_index do |name, i|
|
512
|
+
{
|
513
|
+
label: name[0],
|
514
|
+
hidden: name[2] == 11, #role_id:11 离职角色
|
515
|
+
data: dates.map { |date| data["#{name[1]}-#{ date.gsub("-", '')}"]&.[](0)&.[]('counts') || 0 },
|
516
|
+
backgroundColor: "#fff",
|
517
|
+
pointBorderColor: colors[i % 50 + 1],
|
518
|
+
borderColor: colors[i % 50 + 1],
|
519
|
+
pointBackgroundColor: colors[i % 50 + 1],
|
520
|
+
borderWidth: 2
|
521
|
+
}
|
522
|
+
end
|
523
|
+
}
|
524
|
+
end
|
525
|
+
|
526
|
+
|
527
|
+
def month_sale_chart(dates, names, colors, x, stage_ids, s_stage_ids, count_type, range)
|
528
|
+
begin_at = range[0]
|
529
|
+
end_at = range[1]
|
530
|
+
|
531
|
+
business = EducodeSales::Business.joins(:last_follow_up)
|
532
|
+
if params[:sales_staff_id].present?
|
533
|
+
# 销售经理
|
534
|
+
business = business.joins("LEFT JOIN educode_sales_assign_follow_ups ON educode_sales_assign_follow_ups.follow_up_id = educode_sales_businesses.last_follow_up_id").
|
535
|
+
where("(educode_sales_assign_follow_ups.id IS NOT NULL AND educode_sales_assign_follow_ups.staff_id = ?) OR (educode_sales_assign_follow_ups.id IS NULL AND educode_sales_businesses.staff_id = ?)", params[:sales_staff_id], params[:sales_staff_id])
|
536
|
+
|
537
|
+
end
|
538
|
+
|
539
|
+
if params[:property].present?
|
540
|
+
# 客户类型
|
541
|
+
business = business.joins(department: [school: :school_tags]).where("school_tags.id = ?", params[:property])
|
542
|
+
end
|
543
|
+
|
544
|
+
data_1 = business.
|
545
|
+
where("educode_sales_follow_ups.clazz_id != ?", x).
|
546
|
+
where("educode_sales_follow_ups.stage_id IN (?)", stage_ids).
|
547
|
+
where("educode_sales_follow_ups.bidded_date >= ? AND educode_sales_follow_ups.bidded_date <= ?", begin_at, end_at).
|
548
|
+
select("SUM(#{count_type}) AS count_type, DATE_FORMAT(bidded_date, '%Y-%m') AS month").
|
549
|
+
group("DATE_FORMAT(bidded_date, '%Y-%m')").
|
550
|
+
order("DATE_FORMAT(bidded_date, '%Y-%m')")
|
551
|
+
data_1_hash = {}
|
552
|
+
data_1_total_hash = {}
|
553
|
+
data_1.each do |d|
|
554
|
+
data_1_hash[d.month] = d.count_type.round(2)
|
555
|
+
end
|
556
|
+
|
557
|
+
last_month = 0
|
558
|
+
last_sum = 0
|
559
|
+
dates.each do |month|
|
560
|
+
# 只累计当前年份
|
561
|
+
if last_month != month.split("-")[0]
|
562
|
+
last_sum = 0
|
563
|
+
end
|
564
|
+
data_1_total_hash[month] = ((data_1_hash[month] || 0) + last_sum).round(2)
|
565
|
+
last_sum += data_1_hash[month] || 0
|
566
|
+
last_month = month.split("-")[0]
|
567
|
+
end
|
568
|
+
|
569
|
+
data_2 = business.
|
570
|
+
where("educode_sales_follow_ups.clazz_id != ?", x).
|
571
|
+
where("educode_sales_follow_ups.stage_id IN (?)", s_stage_ids).
|
572
|
+
where("educode_sales_follow_ups.signed_date >= ? AND educode_sales_follow_ups.signed_date <= ?", begin_at, end_at).
|
573
|
+
select("SUM(#{count_type}) AS count_type, DATE_FORMAT(signed_date, '%Y-%m') AS month").
|
574
|
+
group("DATE_FORMAT(signed_date, '%Y-%m')").
|
575
|
+
order("DATE_FORMAT(signed_date, '%Y-%m')")
|
576
|
+
data_2_hash = {}
|
577
|
+
data_2_total_hash = {}
|
578
|
+
data_2.each do |d|
|
579
|
+
data_2_hash[d.month] = d.count_type.round(2)
|
580
|
+
end
|
581
|
+
|
582
|
+
last_month = 0
|
583
|
+
last_sum = 0
|
584
|
+
dates.each do |month|
|
585
|
+
# 只累计当前年份
|
586
|
+
if last_month != month.split("-")[0]
|
587
|
+
last_sum = 0
|
588
|
+
end
|
589
|
+
data_2_total_hash[month] = ((data_2_hash[month] || 0) + last_sum).round(2)
|
590
|
+
last_sum += data_2_hash[month] || 0
|
591
|
+
last_month = month.split("-")[0]
|
592
|
+
end
|
593
|
+
|
594
|
+
data_3 = business.joins(last_follow_up: :money_plans).
|
595
|
+
where("educode_sales_follow_ups.clazz_id != ?", x).
|
596
|
+
where.not("educode_sales_money_plans.clazz!= ?", 1).
|
597
|
+
where("educode_sales_money_plans.date_at >= ? AND educode_sales_money_plans.date_at <= ?", begin_at, end_at).
|
598
|
+
select("SUM(amount) AS count_type, DATE_FORMAT(date_at, '%Y-%m') AS month").
|
599
|
+
group("DATE_FORMAT(date_at, '%Y-%m')").
|
600
|
+
order("DATE_FORMAT(date_at, '%Y-%m')")
|
601
|
+
data_3_hash = {}
|
602
|
+
data_3.each do |d|
|
603
|
+
data_3_hash[d.month] = d.count_type.round(2)
|
604
|
+
end
|
605
|
+
|
606
|
+
data_3_total_hash = {}
|
607
|
+
last_month = 0
|
608
|
+
last_sum = 0
|
609
|
+
dates.each do |month|
|
610
|
+
# 只累计当前年份
|
611
|
+
if last_month != month.split("-")[0]
|
612
|
+
last_sum = 0
|
613
|
+
end
|
614
|
+
data_3_total_hash[month] = ((data_3_hash[month] || 0) + last_sum).round(2)
|
615
|
+
last_sum += data_3_hash[month] || 0
|
616
|
+
last_month = month.split("-")[0]
|
617
|
+
end
|
618
|
+
|
619
|
+
|
620
|
+
{
|
621
|
+
labels: dates,
|
622
|
+
datasets: names.map.with_index do |name, i|
|
623
|
+
{
|
624
|
+
label: name,
|
625
|
+
data: dates.map { |d|
|
626
|
+
case i
|
627
|
+
when 0
|
628
|
+
data_1_hash[d] || 0
|
629
|
+
when 1
|
630
|
+
data_2_hash[d] || 0
|
631
|
+
else
|
632
|
+
data_3_hash[d] || 0
|
633
|
+
end
|
634
|
+
},
|
635
|
+
data1: dates.map { |d|
|
636
|
+
case i
|
637
|
+
when 0
|
638
|
+
data_1_total_hash[d] || 0
|
639
|
+
when 1
|
640
|
+
data_2_total_hash[d] || 0
|
641
|
+
else
|
642
|
+
data_3_total_hash[d] || 0
|
643
|
+
end
|
644
|
+
},
|
645
|
+
backgroundColor: colors[i],
|
646
|
+
borderColor: colors[i],
|
647
|
+
borderWidth: 1
|
648
|
+
}
|
649
|
+
end
|
650
|
+
}
|
651
|
+
end
|
652
|
+
|
653
|
+
def year_sale_chart(dates, names, colors, x, stage_ids, s_stage_ids, count_type, range)
|
654
|
+
begin_at = range[0].split("-")
|
655
|
+
end_at = range[1].split("-")
|
656
|
+
begin_at = DateTime.new(begin_at[0].to_i).beginning_of_year.to_date.to_s
|
657
|
+
end_at = DateTime.new(end_at[0].to_i).end_of_year.to_date.to_s
|
658
|
+
|
659
|
+
data_1 = EducodeSales::Business.joins(:last_follow_up).
|
660
|
+
where("educode_sales_follow_ups.clazz_id != ?", x).
|
661
|
+
where("educode_sales_follow_ups.stage_id IN (?)", stage_ids).
|
662
|
+
where("educode_sales_follow_ups.bidded_date >= ? AND educode_sales_follow_ups.bidded_date <= ?", begin_at, end_at).
|
663
|
+
select("SUM(#{count_type}) AS count_type, DATE_FORMAT(bidded_date, '%Y') AS year").
|
664
|
+
group("DATE_FORMAT(bidded_date, '%Y')").
|
665
|
+
order("DATE_FORMAT(bidded_date, '%Y')")
|
666
|
+
data_1_hash = {}
|
667
|
+
data_1.each do |d|
|
668
|
+
data_1_hash[d.year] = d.count_type.round(2)
|
669
|
+
end
|
670
|
+
|
671
|
+
data_1_total_hash = {}
|
672
|
+
last_month = 0
|
673
|
+
last_sum = 0
|
674
|
+
dates.each do |month|
|
675
|
+
# 只累计当前年份
|
676
|
+
if last_month != month.split("-")[0]
|
677
|
+
last_sum = 0
|
678
|
+
end
|
679
|
+
data_1_total_hash[month] = ((data_1_hash[month] || 0) + last_sum).round(2)
|
680
|
+
last_sum += data_1_hash[month] || 0
|
681
|
+
last_month = month.split("-")[0]
|
682
|
+
end
|
683
|
+
|
684
|
+
data_2 = EducodeSales::Business.joins(:last_follow_up).
|
685
|
+
where("educode_sales_follow_ups.clazz_id != ?", x).
|
686
|
+
where("educode_sales_follow_ups.stage_id IN (?)", s_stage_ids).
|
687
|
+
where("educode_sales_follow_ups.signed_date >= ? AND educode_sales_follow_ups.signed_date <= ?", begin_at, end_at).
|
688
|
+
select("SUM(#{count_type}) AS count_type, DATE_FORMAT(signed_date, '%Y') AS year").
|
689
|
+
group("DATE_FORMAT(signed_date, '%Y')").
|
690
|
+
order("DATE_FORMAT(signed_date, '%Y')")
|
691
|
+
data_2_hash = {}
|
692
|
+
data_2.each do |d|
|
693
|
+
data_2_hash[d.year] = d.count_type.round(2)
|
694
|
+
end
|
695
|
+
|
696
|
+
data_2_total_hash = {}
|
697
|
+
last_month = 0
|
698
|
+
last_sum = 0
|
699
|
+
dates.each do |month|
|
700
|
+
# 只累计当前年份
|
701
|
+
if last_month != month.split("-")[0]
|
702
|
+
last_sum = 0
|
703
|
+
end
|
704
|
+
data_2_total_hash[month] = ((data_2_hash[month] || 0) + last_sum).round(2)
|
705
|
+
last_sum += data_2_hash[month] || 0
|
706
|
+
last_month = month.split("-")[0]
|
707
|
+
end
|
708
|
+
|
709
|
+
data_3 = EducodeSales::Business.joins(last_follow_up: :money_plans).
|
710
|
+
where("educode_sales_follow_ups.clazz_id != ?", x).
|
711
|
+
where.not("educode_sales_money_plans.clazz!= ?", 1).
|
712
|
+
where("educode_sales_money_plans.date_at >= ? AND educode_sales_money_plans.date_at <= ?", begin_at, end_at).
|
713
|
+
select("SUM(amount) AS count_type, DATE_FORMAT(date_at, '%Y') AS year").
|
714
|
+
group("DATE_FORMAT(date_at, '%Y')").
|
715
|
+
order("DATE_FORMAT(date_at, '%Y')")
|
716
|
+
data_3_hash = {}
|
717
|
+
data_3.each do |d|
|
718
|
+
data_3_hash[d.year] = d.count_type.round(2)
|
719
|
+
end
|
720
|
+
|
721
|
+
data_3_total_hash = {}
|
722
|
+
last_month = 0
|
723
|
+
last_sum = 0
|
724
|
+
dates.each do |month|
|
725
|
+
# 只累计当前年份
|
726
|
+
if last_month != month.split("-")[0]
|
727
|
+
last_sum = 0
|
728
|
+
end
|
729
|
+
|
730
|
+
data_3_total_hash[month] = ((data_3_hash[month] || 0) + last_sum).round(2)
|
731
|
+
last_sum += data_3_hash[month] || 0
|
732
|
+
last_month = month.split("-")[0]
|
733
|
+
end
|
734
|
+
|
735
|
+
|
736
|
+
|
737
|
+
{
|
738
|
+
labels: dates,
|
739
|
+
datasets: names.map.with_index do |name, i|
|
740
|
+
{
|
741
|
+
label: name,
|
742
|
+
data: dates.map { |d|
|
743
|
+
case i
|
744
|
+
when 0
|
745
|
+
data_1_hash[d] || 0
|
746
|
+
when 1
|
747
|
+
data_2_hash[d] || 0
|
748
|
+
else
|
749
|
+
data_3_hash[d]|| 0
|
750
|
+
end },
|
751
|
+
data1: dates.map { |d|
|
752
|
+
case i
|
753
|
+
when 0
|
754
|
+
data_1_total_hash[d] || 0
|
755
|
+
when 1
|
756
|
+
data_2_total_hash[d] || 0
|
757
|
+
else
|
758
|
+
data_3_total_hash[d] || 0
|
759
|
+
end
|
760
|
+
},
|
761
|
+
backgroundColor: colors[i],
|
762
|
+
borderColor: colors[i],
|
763
|
+
borderWidth: 1
|
764
|
+
}
|
765
|
+
end
|
766
|
+
}
|
767
|
+
end
|
768
|
+
|
769
|
+
def goal_forecast_money
|
770
|
+
property = params[:property] || nil
|
771
|
+
staff_id = params[:staff_id] || nil
|
772
|
+
@forecast_count_range = params[:forecast_count_range] || "month"
|
773
|
+
forecast_default_dates = ("#{Time.now.year}-01-01".to_date.."#{Time.now.year}-#{Time.now.month}-01".to_date).map { |d| d.strftime("%Y-%m") }.uniq
|
774
|
+
sale_names = %w[计划投标额 计划投标额累计 实际中标额 实际中标额累计]
|
775
|
+
case @forecast_count_range
|
776
|
+
when "week"
|
777
|
+
# 年初第一天周数是0会导致周数重复计算
|
778
|
+
if params[:forecast_date_day].present?
|
779
|
+
date = params[:forecast_date_day].split(" - ")
|
780
|
+
dates = (date[0].to_date..date[1].to_date).map { |d| d.strftime("%Y-%W") }.uniq.select { |d| d.split("-")[1] != '00' }
|
781
|
+
@forecast_count_data = goal_forecast_week(dates, sale_names, staff_id, property)
|
782
|
+
else
|
783
|
+
forecast_default_dates = ("#{Time.now.year}-01-01".to_date.."#{Time.now.year}-#{Time.now.month}-01".to_date).map { |d| d.strftime("%Y-%W") }.uniq.select { |d| d.split("-")[1] != '00' }
|
784
|
+
@forecast_count_data = goal_forecast_week(forecast_default_dates, sale_names, staff_id, property)
|
785
|
+
end
|
786
|
+
when "quarter"
|
787
|
+
# 按年
|
788
|
+
if params[:forecast_date_year].present?
|
789
|
+
date = params[:forecast_date_year].split(" - ")
|
790
|
+
dates = (date[0]..date[1]).to_a
|
791
|
+
dates = dates.map { |d| [d.to_s + "-" + "1", d.to_s + "-" + "2", d.to_s + "-" + "3", d.to_s + "-" + "4"] }.flatten
|
792
|
+
@forecast_count_data = goal_forecast_quarter(dates, sale_names, staff_id, property)
|
793
|
+
else
|
794
|
+
forecast_default_dates = ("#{Time.now.year}-01-01".to_date.."#{Time.now.year}-#{Time.now.month}-01".to_date).map { |d| d.strftime("%Y") }.uniq
|
795
|
+
forecast_default_dates = forecast_default_dates.map { |d| [d.to_s + "-" + "1", d.to_s + "-" + "2", d.to_s + "-" + "3", d.to_s + "-" + "4"] }.flatten
|
796
|
+
@forecast_count_data = goal_forecast_quarter(forecast_default_dates, sale_names, staff_id, property)
|
797
|
+
end
|
798
|
+
when "month" # 按月
|
799
|
+
if params[:forecast_date_month].present?
|
800
|
+
date = params[:forecast_date_month].split(" - ")
|
801
|
+
date[0] = (date[0] + "-01").to_date.to_s
|
802
|
+
date[1] = (date[1] + "-01").to_date.end_of_month.to_s
|
803
|
+
dates = ((date[0] + "-01").to_date..(date[1] + "-01").to_date).map { |d| d.strftime("%Y-%m") }.uniq
|
804
|
+
@forecast_count_data = goal_forecast_month(dates, sale_names, staff_id, property)
|
805
|
+
else
|
806
|
+
@forecast_count_data = goal_forecast_month(forecast_default_dates, sale_names, staff_id, property)
|
807
|
+
end
|
808
|
+
else
|
809
|
+
# 按年
|
810
|
+
if params[:forecast_date_year].present?
|
811
|
+
date = params[:forecast_date_year].split(" - ")
|
812
|
+
dates = (date[0]..date[1]).to_a
|
813
|
+
@forecast_count_data = goal_forecast_year(dates, sale_names, staff_id, property)
|
814
|
+
else
|
815
|
+
forecast_default_dates = ("#{Time.now.year}-01-01".to_date.."#{Time.now.year}-#{Time.now.month}-01".to_date).map { |d| d.strftime("%Y") }.uniq
|
816
|
+
@forecast_count_data = goal_forecast_year(forecast_default_dates, sale_names, staff_id, property)
|
817
|
+
end
|
818
|
+
end
|
819
|
+
@forecast_count_data_0 = @forecast_count_data[0]
|
820
|
+
@forecast_count_data_1 = @forecast_count_data[1]
|
821
|
+
end
|
822
|
+
|
823
|
+
def goal_forecast_count
|
824
|
+
property = params[:property] || nil
|
825
|
+
staff_id = params[:staff_id] || nil
|
826
|
+
@forecast_count_range = params[:forecast_count_range] || "month"
|
827
|
+
forecast_default_dates = ("#{Time.now.year}-01-01".to_date.."#{Time.now.year}-#{Time.now.month}-01".to_date).map { |d| d.strftime("%Y-%m") }.uniq
|
828
|
+
sale_names = %w[计划投标额 计划投标额累计 实际中标额 实际中标额累计]
|
829
|
+
case @forecast_count_range
|
830
|
+
when "week"
|
831
|
+
# 年初第一天周数是0会导致周数重复计算
|
832
|
+
if params[:forecast_date_day].present?
|
833
|
+
date = params[:forecast_date_day].split(" - ")
|
834
|
+
dates = (date[0].to_date..date[1].to_date).map { |d| d.strftime("%Y-%W") }.uniq.select { |d| d.split("-")[1] != '00' }
|
835
|
+
@forecast_count_data = goal_forecast_week_count(dates, sale_names, staff_id, property)
|
836
|
+
else
|
837
|
+
forecast_default_dates = ("#{Time.now.year}-01-01".to_date.."#{Time.now.year}-#{Time.now.month}-01".to_date).map { |d| d.strftime("%Y-%W") }.uniq.select { |d| d.split("-")[1] != '00' }
|
838
|
+
@forecast_count_data = goal_forecast_week_count(forecast_default_dates, sale_names, staff_id, property)
|
839
|
+
end
|
840
|
+
when "quarter"
|
841
|
+
# 按年
|
842
|
+
if params[:forecast_date_year].present?
|
843
|
+
date = params[:forecast_date_year].split(" - ")
|
844
|
+
dates = (date[0]..date[1]).to_a
|
845
|
+
dates = dates.map { |d| [d.to_s + "-" + "1", d.to_s + "-" + "2", d.to_s + "-" + "3", d.to_s + "-" + "4"] }.flatten
|
846
|
+
@forecast_count_data = goal_forecast_quarter_count(dates, sale_names, staff_id, property)
|
847
|
+
else
|
848
|
+
forecast_default_dates = ("#{Time.now.year}-01-01".to_date.."#{Time.now.year}-#{Time.now.month}-01".to_date).map { |d| d.strftime("%Y") }.uniq
|
849
|
+
forecast_default_dates = forecast_default_dates.map { |d| [d.to_s + "-" + "1", d.to_s + "-" + "2", d.to_s + "-" + "3", d.to_s + "-" + "4"] }.flatten
|
850
|
+
@forecast_count_data = goal_forecast_quarter_count(forecast_default_dates, sale_names, staff_id, property)
|
851
|
+
end
|
852
|
+
when "month" # 按月
|
853
|
+
if params[:forecast_date_month].present?
|
854
|
+
date = params[:forecast_date_month].split(" - ")
|
855
|
+
date[0] = (date[0] + "-01").to_date.to_s
|
856
|
+
date[1] = (date[1] + "-01").to_date.end_of_month.to_s
|
857
|
+
dates = ((date[0] + "-01").to_date..(date[1] + "-01").to_date).map { |d| d.strftime("%Y-%m") }.uniq
|
858
|
+
@forecast_count_data = goal_forecast_month_count(dates, sale_names, staff_id, property)
|
859
|
+
else
|
860
|
+
@forecast_count_data = goal_forecast_month_count(forecast_default_dates, sale_names, staff_id, property)
|
861
|
+
end
|
862
|
+
else
|
863
|
+
# 按年
|
864
|
+
if params[:forecast_date_year].present?
|
865
|
+
date = params[:forecast_date_year].split(" - ")
|
866
|
+
dates = (date[0]..date[1]).to_a
|
867
|
+
@forecast_count_data = goal_forecast_year_count(dates, sale_names, staff_id, property)
|
868
|
+
else
|
869
|
+
forecast_default_dates = ("#{Time.now.year}-01-01".to_date.."#{Time.now.year}-#{Time.now.month}-01".to_date).map { |d| d.strftime("%Y") }.uniq
|
870
|
+
@forecast_count_data = goal_forecast_year_count(forecast_default_dates, sale_names, staff_id, property)
|
871
|
+
end
|
872
|
+
end
|
873
|
+
@forecast_count_data_0 = @forecast_count_data[0]
|
874
|
+
@forecast_count_data_1 = @forecast_count_data[1]
|
875
|
+
end
|
876
|
+
|
877
|
+
def visit_user_type_name(top_thirty_username, sort_by, visit_type, title_names)
|
878
|
+
#本年拜访数
|
879
|
+
visit_count_year = EducodeSales::Attendance.where("name in (?)", top_thirty_username)
|
880
|
+
.where(" attendance_date >= '#{Time.now.beginning_of_year}' and attendance_date <= '#{Time.now.end_of_year}' ")
|
881
|
+
.group(:name).select("name, count(*) name_count").order("name_count #{sort_by}")&.map{ |d| [d.name, d.name_count]}
|
882
|
+
|
883
|
+
#本季拜访数
|
884
|
+
current_year = Time.now.year
|
885
|
+
current_month = Time.now.month
|
886
|
+
start_month = (current_month - 1) / 3 * 3 + 1
|
887
|
+
end_month = start_month + 2
|
888
|
+
start_date = Date.new(current_year, start_month, 1).strftime("%Y-%m-%d") + " 00:00:00"
|
889
|
+
end_date = Date.new(current_year, end_month, -1).strftime("%Y-%m-%d") + " 23:59:59"
|
890
|
+
visit_count_season = EducodeSales::Attendance.where("name in (?)", top_thirty_username)
|
891
|
+
.where("attendance_date >= '#{start_date}' and attendance_date <= '#{end_date}'")
|
892
|
+
.group(:name).select("name, count(*) name_count").order("name_count #{sort_by}")&.map{ |d| [d.name, d.name_count]}
|
893
|
+
|
894
|
+
#本月拜访数
|
895
|
+
visit_count_month = EducodeSales::Attendance.where("name in (?)", top_thirty_username)
|
896
|
+
.where("attendance_date >= '#{Time.now.beginning_of_month}' and attendance_date <= '#{Time.now.end_of_month}'")
|
897
|
+
.group(:name).select("name, count(*) name_count").order("name_count #{sort_by}")&.map{ |d| [d.name, d.name_count]}
|
898
|
+
|
899
|
+
#本周拜访数
|
900
|
+
visit_count_week = EducodeSales::Attendance.where("name in (?)", top_thirty_username)
|
901
|
+
.where("attendance_date >= '#{Time.now.beginning_of_week}' and attendance_date <= '#{Time.now.end_of_week}'")
|
902
|
+
.group(:name).select("name, count(*) name_count").order("name_count #{sort_by}")&.map{ |d| [d.name, d.name_count]}
|
903
|
+
|
904
|
+
visit_analysis_charts(visit_count_year, visit_count_season, visit_count_month, visit_count_week, visit_type, title_names)
|
905
|
+
end
|
906
|
+
|
907
|
+
def visit_user_type_customer(top_thirty_customer, sort_by, visit_type, title_names)
|
908
|
+
#本年拜访数
|
909
|
+
visit_count_year = EducodeSales::Attendance.where("customer in (?)", top_thirty_customer)
|
910
|
+
.where(" attendance_date >= '#{Time.now.beginning_of_year}' and attendance_date <= '#{Time.now.end_of_year}' ")
|
911
|
+
.group(:customer).select("customer, count(*) customer_count").order("customer_count #{sort_by}")&.map{ |d| [d.customer, d.customer_count]}
|
912
|
+
|
913
|
+
#本季拜访数
|
914
|
+
current_year = Time.now.year
|
915
|
+
current_month = Time.now.month
|
916
|
+
start_month = (current_month - 1) / 3 * 3 + 1
|
917
|
+
end_month = start_month + 2
|
918
|
+
start_date = Date.new(current_year, start_month, 1).strftime("%Y-%m-%d") + " 00:00:00"
|
919
|
+
end_date = Date.new(current_year, end_month, -1).strftime("%Y-%m-%d") + " 23:59:59"
|
920
|
+
visit_count_season = EducodeSales::Attendance.where("customer in (?)", top_thirty_customer)
|
921
|
+
.where("attendance_date >= '#{start_date}' and attendance_date <= '#{end_date}'")
|
922
|
+
.group(:customer).select("customer, count(*) customer_count").order("customer_count #{sort_by}")&.map{ |d| [d.customer, d.customer_count]}
|
923
|
+
|
924
|
+
#本月拜访数
|
925
|
+
visit_count_month = EducodeSales::Attendance.where("customer in (?)", top_thirty_customer)
|
926
|
+
.where("attendance_date >= '#{Time.now.beginning_of_month}' and attendance_date <= '#{Time.now.end_of_month}'")
|
927
|
+
.group(:customer).select("customer, count(*) customer_count").order("customer_count #{sort_by}")&.map{ |d| [d.customer, d.customer_count]}
|
928
|
+
|
929
|
+
#本周拜访数
|
930
|
+
visit_count_week = EducodeSales::Attendance.where("customer in (?)", top_thirty_customer)
|
931
|
+
.where("attendance_date >= '#{Time.now.beginning_of_week}' and attendance_date <= '#{Time.now.end_of_week}'")
|
932
|
+
.group(:customer).select("customer, count(*) customer_count").order("customer_count #{sort_by}")&.map{ |d| [d.customer, d.customer_count]}
|
933
|
+
|
934
|
+
visit_analysis_charts(visit_count_year, visit_count_season, visit_count_month, visit_count_week, visit_type, title_names)
|
935
|
+
end
|
936
|
+
end
|
937
|
+
end
|