educode_sales 0.9.71 → 0.9.73
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/images/educode_sales/indexlogo.png +0 -0
- data/app/controllers/educode_sales/businesses_controller.rb +27 -0
- data/app/controllers/educode_sales/follow_ups_controller.rb +20 -5
- data/app/controllers/educode_sales/project_charts_controller.rb +145 -0
- data/app/controllers/educode_sales/staffs_controller.rb +35 -0
- data/app/helpers/educode_sales/application_helper.rb +153 -6
- data/app/views/educode_sales/businesses/_follows.html.erb +11 -1
- data/app/views/educode_sales/businesses/edit_follow_record.html.erb +19 -0
- data/app/views/educode_sales/businesses/index.html.erb +40 -8
- data/app/views/educode_sales/businesses/index.json.jbuilder +3 -0
- data/app/views/educode_sales/businesses/key_person.html.erb +56 -0
- data/app/views/educode_sales/businesses/key_person.json.jbuilder +17 -0
- data/app/views/educode_sales/businesses/new_follow_record.html.erb +23 -9
- data/app/views/educode_sales/follow_ups/index.json.jbuilder +2 -0
- data/app/views/educode_sales/project_charts/_sales_analysis.html.erb +436 -0
- data/app/views/educode_sales/project_charts/sales_analysis.js.erb +1 -0
- data/app/views/educode_sales/project_charts/trends.html.erb +81 -0
- data/app/views/educode_sales/project_charts/trends.json.jbuilder +4 -0
- data/app/views/educode_sales/staffs/edit.html.erb +1 -1
- data/app/views/educode_sales/staffs/index.html.erb +20 -1
- data/app/views/educode_sales/staffs/list.html.erb +39 -0
- data/app/views/layouts/educode_sales/application.html.erb +3 -3
- data/config/routes.rb +14 -0
- data/db/migrate/20230428015007_add_deploy_time_follow_ups.rb +6 -0
- data/lib/educode_sales/version.rb +1 -1
- metadata +16 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd2b28526eb6deff3149781638110e6f86c717287996bf7740437727adfd2ee3
|
4
|
+
data.tar.gz: cd3c64540eed97347f0f5b640136cc2fab13d74635246d54d5ca1e95dc1b4a43
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f07f190aa90d48f53aa734204c86c77f7caa7fd3a374b71bd4b6a8080428542354d67b9eefd4037490da5b3784b3219fcc3286d1cba6dd1279489e6a3edabb3f
|
7
|
+
data.tar.gz: 27b899f64fe009157232ccaf573e83f4562a5496fbb69bdb5650105df89ca8599b26715c22e70af9aeff1bf355f75fcaab5ff8ef6768371ddf48ec35d85efab5
|
Binary file
|
@@ -299,6 +299,22 @@ module EducodeSales
|
|
299
299
|
@businesses = @businesses.joins("JOIN educode_sales_business_clazz_changes ON educode_sales_business_clazz_changes.business_id = educode_sales_businesses.id").where("educode_sales_business_clazz_changes.clazz_changed in (?)", clazz_changes)
|
300
300
|
end
|
301
301
|
|
302
|
+
if params[:q].present? && params[:q][:property].present?
|
303
|
+
# 客户类型
|
304
|
+
@businesses = @businesses.joins(department: [school: :school_tags]).where("school_tags.id = ?", params[:q][:property])
|
305
|
+
# @businesses = @businesses.joins("JOIN departments ON educode_sales_businesses.department_id = departments.id
|
306
|
+
# JOIN schools ON departments.school_id = schools.id").where("schools.school_property_id = ?", params[:q][:property])
|
307
|
+
end
|
308
|
+
|
309
|
+
if params[:q].present? && params[:q][:staff_manages].present?
|
310
|
+
# 销售经理
|
311
|
+
@businesses = @businesses.joins("LEFT JOIN educode_sales_follow_ups AS last_follow_up ON educode_sales_businesses.last_follow_up_id = last_follow_up.id AND last_follow_up.deleted_at IS NULL
|
312
|
+
LEFT JOIN educode_sales_assign_follow_ups ON educode_sales_assign_follow_ups.follow_up_id = last_follow_up.id").
|
313
|
+
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[:q][:staff_manages], params[:q][:staff_manages])
|
314
|
+
|
315
|
+
|
316
|
+
end
|
317
|
+
|
302
318
|
if params[:sort].present? && params[:sort][:field]
|
303
319
|
if params[:sort][:field] == "service_end_time"
|
304
320
|
@businesses = @businesses.order("service_time_long #{params[:sort][:order]}")
|
@@ -1188,6 +1204,17 @@ module EducodeSales
|
|
1188
1204
|
end
|
1189
1205
|
end
|
1190
1206
|
|
1207
|
+
def key_person
|
1208
|
+
respond_to do |format|
|
1209
|
+
format.html do
|
1210
|
+
render layout: false
|
1211
|
+
end
|
1212
|
+
format.json do
|
1213
|
+
@teachers = EducodeSales::KeyPerson.where(follow_up_id: params[:follow_up_id]).page(params[:page]).per(params[:limit])
|
1214
|
+
end
|
1215
|
+
end
|
1216
|
+
end
|
1217
|
+
|
1191
1218
|
private
|
1192
1219
|
|
1193
1220
|
def load_business
|
@@ -12,19 +12,34 @@ module EducodeSales
|
|
12
12
|
if @current_admin.is_admin?
|
13
13
|
@follow_ups = FollowUp.all
|
14
14
|
else
|
15
|
+
permissions = @current_admin.permissions.pluck(:name)
|
16
|
+
area_business_ids = []
|
17
|
+
if permissions.include?("专项管理商机")
|
18
|
+
# 按客户类型查看商机下跟进记录
|
19
|
+
school_tag_ids = EducodeSales::StaffSchoolTag.where(staff_id: 10009).pluck :school_tag_id
|
20
|
+
school_ids = SchoolTagMiddle.where(school_tag_id: school_tag_ids).pluck :school_id
|
21
|
+
area_business_ids = Business.joins("JOIN departments ON educode_sales_businesses.department_id = departments.id").where("departments.school_id in (?)", school_ids).pluck(:id)
|
22
|
+
end
|
23
|
+
|
15
24
|
level = @current_admin.role.role_areas.find_by(clazz: '商机管理').level
|
16
25
|
case level
|
17
26
|
when '自己'
|
27
|
+
if permissions.include?("区域管理商机")
|
28
|
+
# 按负责区域查看商机下跟进记录
|
29
|
+
school_ids = School.where(province: @current_admin.areas.pluck(:name)).pluck(:id)
|
30
|
+
area_business_ids += Business.joins("JOIN departments ON educode_sales_businesses.department_id = departments.id").where("departments.school_id in (?)", school_ids).pluck(:id)
|
31
|
+
end
|
32
|
+
|
18
33
|
business_ids = Business.joins(last_follow_up: :assign_follow_ups).where("educode_sales_assign_follow_ups.staff_id = ?", @current_admin.id).pluck(:id)
|
19
34
|
@businesses = Business.where("educode_sales_businesses.staff_id = ? OR educode_sales_businesses.id in (?)", @current_admin.id, business_ids)
|
20
35
|
business_ids = @businesses.pluck(:id)
|
21
|
-
@follow_ups = FollowUp.where(business_id: business_ids)
|
36
|
+
@follow_ups = FollowUp.where(business_id: business_ids + area_business_ids)
|
22
37
|
when '区域'
|
23
38
|
school_ids = School.where(province: @current_admin.areas.pluck(:name)).pluck(:id) + StaffSchool.where(staff_id: @current_admin.id).pluck(:school_id)
|
24
39
|
business_ids = Business.joins(last_follow_up: :assign_follow_ups).where("educode_sales_assign_follow_ups.staff_id = ?", @current_admin.id).pluck(:id)
|
25
40
|
@businesses = Business.joins("JOIN departments ON educode_sales_businesses.department_id = departments.id").where("departments.school_id in (?) OR educode_sales_businesses.staff_id = #{@current_admin.id} OR educode_sales_businesses.id in (?)", school_ids, business_ids)
|
26
41
|
business_ids = @businesses.pluck(:id)
|
27
|
-
@follow_ups = FollowUp.where(business_id: business_ids)
|
42
|
+
@follow_ups = FollowUp.where(business_id: business_ids + area_business_ids)
|
28
43
|
else
|
29
44
|
@follow_ups = FollowUp.all
|
30
45
|
end
|
@@ -110,7 +125,7 @@ module EducodeSales
|
|
110
125
|
end
|
111
126
|
|
112
127
|
end
|
113
|
-
@business.update(last_follow_up_id: follow_up.id, clazz_id: follow_up.clazz_id)
|
128
|
+
@business.update(last_follow_up_id: follow_up.id, clazz_id: follow_up.clazz_id, p_deploy_time: params[:deploy_time])
|
114
129
|
# 增加o商机编号
|
115
130
|
add_business_number
|
116
131
|
update_department
|
@@ -154,7 +169,7 @@ module EducodeSales
|
|
154
169
|
if follow_up.save
|
155
170
|
# 增加o类商机
|
156
171
|
@business = follow_up.business
|
157
|
-
@business.update(clazz_id: follow_up.clazz_id)
|
172
|
+
@business.update(clazz_id: follow_up.clazz_id, p_deploy_time: params[:deploy_time])
|
158
173
|
add_business_number
|
159
174
|
update_department
|
160
175
|
render_success
|
@@ -284,7 +299,7 @@ module EducodeSales
|
|
284
299
|
end
|
285
300
|
|
286
301
|
def follow_up_params
|
287
|
-
params.permit(:clazz_id, :stage_id, :invitation_at, :reception_at, :total_amount, :actual_amount, :divide_amount, :divide_rate, :budget_amount, :description, :advise, :place_id, :bidded_date, :signed_date, :year, :o_business_deployment)
|
302
|
+
params.permit(:clazz_id, :stage_id, :invitation_at, :reception_at, :total_amount, :actual_amount, :divide_amount, :divide_rate, :budget_amount, :description, :advise, :place_id, :bidded_date, :signed_date, :year, :o_business_deployment, :deploy_time, :rival)
|
288
303
|
end
|
289
304
|
|
290
305
|
# 更新部门和部门下老师用户的状态
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require_dependency "educode_sales/application_controller"
|
2
|
+
|
3
|
+
module EducodeSales
|
4
|
+
class ProjectChartsController < ApplicationController
|
5
|
+
# authorize_resource class: false
|
6
|
+
|
7
|
+
def trends
|
8
|
+
end
|
9
|
+
# 销售额分析
|
10
|
+
def sales_analysis
|
11
|
+
respond_to do |format|
|
12
|
+
format.html do
|
13
|
+
end
|
14
|
+
format.js do
|
15
|
+
x = EducodeSales::Common.find_by(extras: EducodeSales::Common::XTYPE)&.id
|
16
|
+
count_type = params[:count_type] || "actual_amount"
|
17
|
+
stage_ids = Common.where(clazz: '商机阶段', name: ['已中标', '已签单', '已验收', '回款中', '服务中', '已结束']).pluck(:id)
|
18
|
+
s_stage_ids = Common.where(clazz: '商机阶段', name: ['已签单', '已验收', '回款中', '服务中', '已结束']).pluck(:id)
|
19
|
+
@goal_count_range = params[:goal_count_range] || "month"
|
20
|
+
|
21
|
+
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
|
22
|
+
sale_names = ['已中标', '已签单', '已回款']
|
23
|
+
@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}"])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
def month_sale_chart(dates, names, colors, x, stage_ids, s_stage_ids, count_type, range)
|
33
|
+
begin_at = range[0]
|
34
|
+
end_at = range[1]
|
35
|
+
|
36
|
+
data_1 = EducodeSales::Business.joins(:last_follow_up).
|
37
|
+
where("educode_sales_follow_ups.clazz_id != ?", x).
|
38
|
+
where("educode_sales_follow_ups.stage_id IN (?)", stage_ids).
|
39
|
+
where("educode_sales_follow_ups.bidded_date >= ? AND educode_sales_follow_ups.bidded_date <= ?", begin_at, end_at).
|
40
|
+
select("SUM(#{count_type}) AS count_type, DATE_FORMAT(bidded_date, '%Y-%m') AS month").
|
41
|
+
group("DATE_FORMAT(bidded_date, '%Y-%m')").
|
42
|
+
order("DATE_FORMAT(bidded_date, '%Y-%m')")
|
43
|
+
data_1_hash = {}
|
44
|
+
data_1_total_hash = {}
|
45
|
+
data_1.each do |d|
|
46
|
+
data_1_hash[d.month] = d.count_type.round(2)
|
47
|
+
end
|
48
|
+
|
49
|
+
last_month = 0
|
50
|
+
last_sum = 0
|
51
|
+
dates.each do |month|
|
52
|
+
# 只累计当前年份
|
53
|
+
if last_month != month.split("-")[0]
|
54
|
+
last_sum = 0
|
55
|
+
end
|
56
|
+
data_1_total_hash[month] = ((data_1_hash[month] || 0) + last_sum).round(2)
|
57
|
+
last_sum += data_1_hash[month] || 0
|
58
|
+
last_month = month.split("-")[0]
|
59
|
+
end
|
60
|
+
|
61
|
+
data_2 = EducodeSales::Business.joins(:last_follow_up).
|
62
|
+
where("educode_sales_follow_ups.clazz_id != ?", x).
|
63
|
+
where("educode_sales_follow_ups.stage_id IN (?)", s_stage_ids).
|
64
|
+
where("educode_sales_follow_ups.signed_date >= ? AND educode_sales_follow_ups.signed_date <= ?", begin_at, end_at).
|
65
|
+
select("SUM(#{count_type}) AS count_type, DATE_FORMAT(signed_date, '%Y-%m') AS month").
|
66
|
+
group("DATE_FORMAT(signed_date, '%Y-%m')").
|
67
|
+
order("DATE_FORMAT(signed_date, '%Y-%m')")
|
68
|
+
data_2_hash = {}
|
69
|
+
data_2_total_hash = {}
|
70
|
+
data_2.each do |d|
|
71
|
+
data_2_hash[d.month] = d.count_type.round(2)
|
72
|
+
end
|
73
|
+
|
74
|
+
last_month = 0
|
75
|
+
last_sum = 0
|
76
|
+
dates.each do |month|
|
77
|
+
# 只累计当前年份
|
78
|
+
if last_month != month.split("-")[0]
|
79
|
+
last_sum = 0
|
80
|
+
end
|
81
|
+
data_2_total_hash[month] = ((data_2_hash[month] || 0) + last_sum).round(2)
|
82
|
+
last_sum += data_2_hash[month] || 0
|
83
|
+
last_month = month.split("-")[0]
|
84
|
+
end
|
85
|
+
|
86
|
+
data_3 = EducodeSales::Business.joins(last_follow_up: :money_plans).
|
87
|
+
where("educode_sales_follow_ups.clazz_id != ?", x).
|
88
|
+
where.not("educode_sales_money_plans.clazz!= ?", 1).
|
89
|
+
where("educode_sales_money_plans.date_at >= ? AND educode_sales_money_plans.date_at <= ?", begin_at, end_at).
|
90
|
+
select("SUM(amount) AS count_type, DATE_FORMAT(date_at, '%Y-%m') AS month").
|
91
|
+
group("DATE_FORMAT(date_at, '%Y-%m')").
|
92
|
+
order("DATE_FORMAT(date_at, '%Y-%m')")
|
93
|
+
data_3_hash = {}
|
94
|
+
data_3.each do |d|
|
95
|
+
data_3_hash[d.month] = d.count_type.round(2)
|
96
|
+
end
|
97
|
+
|
98
|
+
data_3_total_hash = {}
|
99
|
+
last_month = 0
|
100
|
+
last_sum = 0
|
101
|
+
dates.each do |month|
|
102
|
+
# 只累计当前年份
|
103
|
+
if last_month != month.split("-")[0]
|
104
|
+
last_sum = 0
|
105
|
+
end
|
106
|
+
data_3_total_hash[month] = ((data_3_hash[month] || 0) + last_sum).round(2)
|
107
|
+
last_sum += data_3_hash[month] || 0
|
108
|
+
last_month = month.split("-")[0]
|
109
|
+
end
|
110
|
+
|
111
|
+
{
|
112
|
+
labels: dates,
|
113
|
+
datasets: names.map.with_index do |name, i|
|
114
|
+
{
|
115
|
+
label: name,
|
116
|
+
data: dates.map { |d|
|
117
|
+
case i
|
118
|
+
when 0
|
119
|
+
data_1_hash[d] || 0
|
120
|
+
when 1
|
121
|
+
data_2_hash[d] || 0
|
122
|
+
else
|
123
|
+
data_3_hash[d] || 0
|
124
|
+
end
|
125
|
+
},
|
126
|
+
data1: dates.map { |d|
|
127
|
+
case i
|
128
|
+
when 0
|
129
|
+
data_1_total_hash[d] || 0
|
130
|
+
when 1
|
131
|
+
data_2_total_hash[d] || 0
|
132
|
+
else
|
133
|
+
data_3_total_hash[d] || 0
|
134
|
+
end
|
135
|
+
},
|
136
|
+
backgroundColor: colors[i],
|
137
|
+
borderColor: colors[i],
|
138
|
+
borderWidth: 1
|
139
|
+
}
|
140
|
+
end
|
141
|
+
}
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
end
|
@@ -137,5 +137,40 @@ module EducodeSales
|
|
137
137
|
@schools = (EducodeSales::Business.joins(:follow_ups, [department: :school]).where("educode_sales_follow_ups.staff_id = #{staff.id}").select("departments.id, departments.name, schools.name AS school, educode_sales_follow_ups.updated_at") + EducodeSales::Teacher.joins(:follow_up, [department: :school]).where("educode_sales_teacher_follows.staff_id = #{staff.id}").select("departments.id, departments.name, schools.name AS school, educode_sales_teacher_follows.updated_at")).uniq { |s| s.id }
|
138
138
|
end
|
139
139
|
|
140
|
+
def list
|
141
|
+
@staffs = EducodeSales::Staff.where.not(id: params[:id]).map { |d| [d.user.real_name, d.id ]}
|
142
|
+
gon.trans_staffs = @staffs.to_h.invert
|
143
|
+
render layout: false
|
144
|
+
end
|
145
|
+
|
146
|
+
def transfer
|
147
|
+
if @current_admin.is_admin?
|
148
|
+
staff = Staff.find(params[:id])
|
149
|
+
to = Staff.find(params[:to_id])
|
150
|
+
staff.businesses.update_all(staff_id: to.id)
|
151
|
+
# 商机
|
152
|
+
staff.follow_ups.update_all(staff_id: to.id)
|
153
|
+
# 销售动态
|
154
|
+
staff.sale_plans.update_all(staff_id: to.id)
|
155
|
+
# 销售计划
|
156
|
+
staff.places.update_all(staff_id: to.id)
|
157
|
+
# 渠道
|
158
|
+
staff.activities.update_all(staff_id: to.id)
|
159
|
+
# 活动
|
160
|
+
staff.teachers.update_all(staff_id: to.id)
|
161
|
+
# 教师
|
162
|
+
staff.teacher_follows.update_all(staff_id: to.id)
|
163
|
+
# 教师动态
|
164
|
+
staff.operation_plans.update_all(staff_id: to.id)
|
165
|
+
# 活动计划
|
166
|
+
|
167
|
+
EducodeSales::Activity.where(sales_id: staff.id).update_all(sales_id: to.id)
|
168
|
+
CustomerExtension.where(staff_id: staff.id).update_all(staff_id: to.id)
|
169
|
+
# 回款计划
|
170
|
+
MoneyPlan.where(staff_id: staff.id).update_all(staff_id: to.id)
|
171
|
+
# 客户
|
172
|
+
end
|
173
|
+
render_success
|
174
|
+
end
|
140
175
|
end
|
141
176
|
end
|
@@ -103,15 +103,162 @@ module EducodeSales
|
|
103
103
|
|
104
104
|
ids_a_b = Common.where(extras: %w[a_class b_class ]).pluck(:id)
|
105
105
|
ids_c_d = Common.where(extras: %w[c_class d_class]).pluck(:id)
|
106
|
-
@businesses_a_b_count = @businesses.joins("JOIN educode_sales_follow_ups ON educode_sales_businesses.last_follow_up_id = educode_sales_follow_ups.id").where("educode_sales_follow_ups.clazz_id in (?)",ids_a_b)
|
107
|
-
|
108
|
-
|
106
|
+
@businesses_a_b_count = @businesses.joins("JOIN educode_sales_follow_ups ON educode_sales_businesses.last_follow_up_id = educode_sales_follow_ups.id").where("educode_sales_follow_ups.clazz_id in (?)", ids_a_b)
|
107
|
+
.where("educode_sales_businesses.staff_id = ?", staff_id)
|
108
|
+
.where("educode_sales_businesses.created_at >= ? and educode_sales_businesses.created_at <= ?", "#{@assessment_year}-#{start_time} 00:00:00".to_date,
|
109
109
|
"#{@assessment_year}-#{end_time} 23:59:00".to_date)
|
110
|
-
@businesses_c_d_count = @businesses.joins("JOIN educode_sales_follow_ups ON educode_sales_businesses.last_follow_up_id = educode_sales_follow_ups.id").where("educode_sales_follow_ups.clazz_id in (?)",ids_c_d)
|
111
|
-
.where("educode_sales_businesses.staff_id = ?",staff_id)
|
110
|
+
@businesses_c_d_count = @businesses.joins("JOIN educode_sales_follow_ups ON educode_sales_businesses.last_follow_up_id = educode_sales_follow_ups.id").where("educode_sales_follow_ups.clazz_id in (?)", ids_c_d)
|
111
|
+
.where("educode_sales_businesses.staff_id = ?", staff_id)
|
112
112
|
.where("educode_sales_businesses.created_at >= ? and educode_sales_businesses.created_at <= ?", "#{@assessment_year}-#{start_time} 00:00:00".to_date,
|
113
113
|
"#{@assessment_year}-#{end_time} 23:59:00".to_date)
|
114
|
-
@businesses_a_b_count.count.to_i*10
|
114
|
+
@businesses_a_b_count.count.to_i * 10 + @businesses_c_d_count.count.to_i * 5
|
115
|
+
end
|
116
|
+
|
117
|
+
def get_businesses_chart(year, month)
|
118
|
+
contract_ids = EducodeSales::Common.where(clazz: '商机阶段', name: ['已中标', '已签单', '已验收', '回款中', '服务中', '已结束']).pluck(:id)
|
119
|
+
@businesses = EducodeSales::Business.joins("
|
120
|
+
JOIN educode_sales_follow_ups ON educode_sales_businesses.last_follow_up_id = educode_sales_follow_ups.id
|
121
|
+
").where("educode_sales_follow_ups.stage_id in (?)", contract_ids)
|
122
|
+
|
123
|
+
# 逾期id
|
124
|
+
late_ids = EducodeSales::Business.joins("JOIN educode_sales_follow_ups ON educode_sales_businesses.last_follow_up_id = educode_sales_follow_ups.id JOIN educode_sales_commons on educode_sales_commons.id = educode_sales_follow_ups.stage_id")
|
125
|
+
.where("educode_sales_follow_ups.bidded_date is not null")
|
126
|
+
.where("NOW() > DATE_ADD(educode_sales_follow_ups.bidded_date, INTERVAL 1 MONTH)")
|
127
|
+
.where("educode_sales_businesses.p_stage is null")
|
128
|
+
.where("educode_sales_commons.name = '已中标'")
|
129
|
+
.or(EducodeSales::Business.joins("JOIN educode_sales_follow_ups ON educode_sales_businesses.last_follow_up_id = educode_sales_follow_ups.id JOIN educode_sales_commons on educode_sales_commons.id = educode_sales_follow_ups.stage_id")
|
130
|
+
.where("NOW() > educode_sales_businesses.p_pre_money_time")
|
131
|
+
.where("educode_sales_businesses.p_pre_money_time is not null")
|
132
|
+
.where("educode_sales_businesses.p_actual_money_time is null")
|
133
|
+
).or(EducodeSales::Business.joins("JOIN educode_sales_follow_ups ON educode_sales_businesses.last_follow_up_id = educode_sales_follow_ups.id JOIN educode_sales_commons on educode_sales_commons.id = educode_sales_follow_ups.stage_id")
|
134
|
+
.where("NOW() > educode_sales_businesses.p_pre_accept_time")
|
135
|
+
.where("educode_sales_businesses.p_pre_accept_time is not null")
|
136
|
+
.where("educode_sales_businesses.p_accept_time is null")).ids
|
137
|
+
|
138
|
+
# 待交付项目
|
139
|
+
data_4 = @businesses.where("educode_sales_follow_ups.reception_at > ? AND educode_sales_follow_ups.reception_at < ?", year + "-" + month + "-01", year + "-" + month + "-31")
|
140
|
+
.count("distinct educode_sales_businesses.id")
|
141
|
+
# 实际交付
|
142
|
+
data_5 = @businesses.where("educode_sales_businesses.p_deploy_time > ? AND educode_sales_businesses.p_deploy_time < ?", year + "-" + month + "-01", year + "-" + month + "-31")
|
143
|
+
.count("distinct educode_sales_businesses.id")
|
144
|
+
# 待准备项目
|
145
|
+
data_6 = @businesses.where("educode_sales_follow_ups.reception_at > ? AND educode_sales_follow_ups.reception_at < ?", year + "-" + month + "-01", year + "-" + month + "-31")
|
146
|
+
.count("distinct educode_sales_businesses.id")
|
147
|
+
# 完成准备
|
148
|
+
data_7 = @businesses.where("educode_sales_businesses.p_status = 1")
|
149
|
+
.where("educode_sales_follow_ups.reception_at > ? AND educode_sales_follow_ups.reception_at < ?", year + "-" + month + "-01", year + "-" + month + "-31")
|
150
|
+
.count("distinct educode_sales_businesses.id")
|
151
|
+
# 待验收平台包
|
152
|
+
data_8 = @businesses.where("educode_sales_follow_ups.reception_at > ? AND educode_sales_follow_ups.reception_at < ?", year + "-" + month + "-01", year + "-" + month + "-31")
|
153
|
+
.count("distinct educode_sales_businesses.id")
|
154
|
+
# 实际验收平台包
|
155
|
+
data_9 = @businesses.where("educode_sales_businesses.p_platform_time is not null")
|
156
|
+
.where("educode_sales_follow_ups.reception_at > ? AND educode_sales_follow_ups.reception_at < ?", year + "-" + month + "-01", year + "-" + month + "-31")
|
157
|
+
.count("distinct educode_sales_businesses.id")
|
158
|
+
# 待验收课程包
|
159
|
+
data_10 = @businesses.where("educode_sales_follow_ups.reception_at > ? AND educode_sales_follow_ups.reception_at < ?", year + "-" + month + "-01", year + "-" + month + "-31")
|
160
|
+
.count("distinct educode_sales_businesses.id")
|
161
|
+
# 实际验收课程包
|
162
|
+
data_11 = @businesses.where("educode_sales_businesses.p_course_time is not null")
|
163
|
+
.where("educode_sales_follow_ups.reception_at > ? AND educode_sales_follow_ups.reception_at < ?", year + "-" + month + "-01", year + "-" + month + "-31")
|
164
|
+
.count("distinct educode_sales_businesses.id")
|
165
|
+
data_2 = data_4 + data_6 + data_8 + data_10 # 本月总任务
|
166
|
+
data_3 = data_5 + data_7 + data_9 + data_11 # 本月完成任务
|
167
|
+
# 本月任务完成度
|
168
|
+
data_1 = data_2.zero? ? 0 : (data_3.to_f / data_2.to_f).round(2) * 100
|
169
|
+
|
170
|
+
# 历史遗漏项目
|
171
|
+
data_12 = @businesses.where("educode_sales_follow_ups.reception_at < ?", year + "-01-01")
|
172
|
+
.where("educode_sales_businesses.p_course_time IS NULL
|
173
|
+
OR educode_sales_businesses.p_platform_time IS NULL
|
174
|
+
OR educode_sales_businesses.p_deploy_time IS NULL
|
175
|
+
OR educode_sales_businesses.p_actual_money_time IS NULL
|
176
|
+
OR educode_sales_businesses.p_accept_time IS NULL
|
177
|
+
").count("distinct educode_sales_businesses.id")
|
178
|
+
# 年度待交付项目
|
179
|
+
data_13 = @businesses.where("educode_sales_follow_ups.reception_at > ? AND educode_sales_follow_ups.reception_at < ?", year + "-01-01", year + "-12-31")
|
180
|
+
.count("distinct educode_sales_businesses.id")
|
181
|
+
# 年度已交付项目
|
182
|
+
data_14 = @businesses.where("educode_sales_follow_ups.reception_at > ? AND educode_sales_follow_ups.reception_at < ?", year + "-01-01", year + "-12-31")
|
183
|
+
.where("educode_sales_businesses.p_course_time IS NOT NULL
|
184
|
+
AND educode_sales_businesses.p_platform_time IS NOT NULL
|
185
|
+
AND educode_sales_businesses.p_deploy_time IS NOT NULL
|
186
|
+
AND educode_sales_businesses.p_actual_money_time IS NOT NULL
|
187
|
+
AND educode_sales_businesses.p_accept_time IS NOT NULL
|
188
|
+
").count("distinct educode_sales_businesses.id")
|
189
|
+
# 年度延期项目
|
190
|
+
data_15 = @businesses.where("educode_sales_follow_ups.reception_at > ? AND educode_sales_follow_ups.reception_at < ?", year + "-01-01", year + "-12-31")
|
191
|
+
.where(id: late_ids)
|
192
|
+
.count("distinct educode_sales_businesses.id")
|
193
|
+
|
194
|
+
year_data_all_1 = @businesses.where("educode_sales_follow_ups.reception_at > ? AND educode_sales_follow_ups.reception_at < ?", year + "-01-01", year + "-12-31")
|
195
|
+
.group(:p_staff_id).sum("case when educode_sales_businesses.p_course_time is not null then 1 else 0 end + case when educode_sales_businesses.p_platform_time is not null then 1 else 0 end + case when educode_sales_businesses.p_deploy_time is not null then 1 else 0 end + case when educode_sales_businesses.p_actual_money_time is not null then 1 else 0 end + case when educode_sales_businesses.p_accept_time is not null then 1 else 0 end")
|
196
|
+
year_data_all_2 = @businesses.where("educode_sales_follow_ups.reception_at > ? AND educode_sales_follow_ups.reception_at < ?", year + "-01-01", year + "-12-31")
|
197
|
+
.group(:p_sale_staff_id).sum("case when educode_sales_businesses.p_course_time is not null then 1 else 0 end + case when educode_sales_businesses.p_platform_time is not null then 1 else 0 end + case when educode_sales_businesses.p_deploy_time is not null then 1 else 0 end + case when educode_sales_businesses.p_actual_money_time is not null then 1 else 0 end + case when educode_sales_businesses.p_accept_time is not null then 1 else 0 end")
|
198
|
+
month_data_all_1 = @businesses.where("educode_sales_follow_ups.reception_at > ? AND educode_sales_follow_ups.reception_at < ?", year + "-" + month + "-01", year + "-" + month + "-31")
|
199
|
+
.group(:p_staff_id).sum("case when educode_sales_businesses.p_course_time is not null then 1 else 0 end + case when educode_sales_businesses.p_platform_time is not null then 1 else 0 end + case when educode_sales_businesses.p_deploy_time is not null then 1 else 0 end + case when educode_sales_businesses.p_actual_money_time is not null then 1 else 0 end + case when educode_sales_businesses.p_accept_time is not null then 1 else 0 end")
|
200
|
+
month_data_all_2 = @businesses.where("educode_sales_follow_ups.reception_at > ? AND educode_sales_follow_ups.reception_at < ?", year + "-" + month + "-01", year + "-" + month + "-31")
|
201
|
+
.group(:p_sale_staff_id).sum("case when educode_sales_businesses.p_course_time is not null then 1 else 0 end + case when educode_sales_businesses.p_platform_time is not null then 1 else 0 end + case when educode_sales_businesses.p_deploy_time is not null then 1 else 0 end + case when educode_sales_businesses.p_actual_money_time is not null then 1 else 0 end + case when educode_sales_businesses.p_accept_time is not null then 1 else 0 end")
|
202
|
+
|
203
|
+
year_merged_hash = month_data_all_1.merge(month_data_all_2) { |key, v1, v2| v1 + v2 }.sort_by { |k, v| v }.reverse.to_h
|
204
|
+
month_merged_hash = year_data_all_1.merge(year_data_all_2) { |key, v1, v2| v1 + v2 }.sort_by { |k, v| v }.reverse.to_h
|
205
|
+
|
206
|
+
not_finish_year_data_all_1 = @businesses.where("educode_sales_follow_ups.reception_at > ? AND educode_sales_follow_ups.reception_at < ?", year + "-01-01", year + "-12-31")
|
207
|
+
.group(:p_staff_id).sum("case when educode_sales_businesses.p_course_time is null then 1 else 0 end + case when educode_sales_businesses.p_platform_time is null then 1 else 0 end + case when educode_sales_businesses.p_deploy_time is null then 1 else 0 end + case when educode_sales_businesses.p_actual_money_time is null then 1 else 0 end + case when educode_sales_businesses.p_accept_time is null then 1 else 0 end")
|
208
|
+
not_finish_year_data_all_2 = @businesses.where("educode_sales_follow_ups.reception_at > ? AND educode_sales_follow_ups.reception_at < ?", year + "-01-01", year + "-12-31")
|
209
|
+
.group(:p_sale_staff_id).sum("case when educode_sales_businesses.p_course_time is null then 1 else 0 end + case when educode_sales_businesses.p_platform_time is null then 1 else 0 end + case when educode_sales_businesses.p_deploy_time is null then 1 else 0 end + case when educode_sales_businesses.p_actual_money_time is null then 1 else 0 end + case when educode_sales_businesses.p_accept_time is null then 1 else 0 end")
|
210
|
+
not_finish_month_data_all_1 = @businesses.where("educode_sales_follow_ups.reception_at > ? AND educode_sales_follow_ups.reception_at < ?", year + "-" + month + "-01", year + "-" + month + "-31")
|
211
|
+
.group(:p_staff_id).sum("case when educode_sales_businesses.p_course_time is null then 1 else 0 end + case when educode_sales_businesses.p_platform_time is null then 1 else 0 end + case when educode_sales_businesses.p_deploy_time is null then 1 else 0 end + case when educode_sales_businesses.p_actual_money_time is null then 1 else 0 end + case when educode_sales_businesses.p_accept_time is null then 1 else 0 end")
|
212
|
+
not_finish_month_data_all_2 = @businesses.where("educode_sales_follow_ups.reception_at > ? AND educode_sales_follow_ups.reception_at < ?", year + "-" + month + "-01", year + "-" + month + "-31")
|
213
|
+
.group(:p_sale_staff_id).sum("case when educode_sales_businesses.p_course_time is null then 1 else 0 end + case when educode_sales_businesses.p_platform_time is null then 1 else 0 end + case when educode_sales_businesses.p_deploy_time is null then 1 else 0 end + case when educode_sales_businesses.p_actual_money_time is null then 1 else 0 end + case when educode_sales_businesses.p_accept_time is null then 1 else 0 end")
|
214
|
+
not_finish_year_merged_hash = not_finish_year_data_all_1.merge(not_finish_year_data_all_2) { |key, v1, v2| v1 + v2 }.sort_by { |k, v| v }.reverse.to_h
|
215
|
+
not_finish_month_merged_hash = not_finish_month_data_all_1.merge(not_finish_month_data_all_2) { |key, v1, v2| v1 + v2 }.sort_by { |k, v| v }.reverse.to_h
|
216
|
+
|
217
|
+
all_year_merged_hash = year_merged_hash.merge(not_finish_year_merged_hash) { |key, v1, v2| v1 + v2 }.sort_by { |k, v| v }.reverse.to_h
|
218
|
+
all_month_merged_hash = month_merged_hash.merge(not_finish_month_merged_hash) { |key, v1, v2| v1 + v2 }.sort_by { |k, v| v }.reverse.to_h
|
219
|
+
staffs = EducodeSales::Staff.all.includes(:user)
|
220
|
+
colors = SaleTrend::COLORS
|
221
|
+
chart1 = {
|
222
|
+
labels: staffs.map { |d| d.user.real_name },
|
223
|
+
datasets: %w[已完成 未完成].map.with_index do |d, i|
|
224
|
+
{
|
225
|
+
label: d,
|
226
|
+
data: staffs.map { |s|
|
227
|
+
case d
|
228
|
+
when "已完成"
|
229
|
+
month_merged_hash[s.id].to_i
|
230
|
+
when "未完成"
|
231
|
+
not_finish_month_merged_hash[s.id].to_i
|
232
|
+
end
|
233
|
+
},
|
234
|
+
backgroundColor: colors[i],
|
235
|
+
borderColor: colors[i],
|
236
|
+
borderWidth: 1
|
237
|
+
}
|
238
|
+
end
|
239
|
+
}
|
240
|
+
chart2 = {
|
241
|
+
labels: staffs.map { |d| d.user.real_name },
|
242
|
+
datasets: %w[已完成 未完成].map.with_index do |d, i|
|
243
|
+
{
|
244
|
+
label: d,
|
245
|
+
data: staffs.map { |s|
|
246
|
+
case d
|
247
|
+
when "已完成"
|
248
|
+
year_merged_hash[s.id].to_i
|
249
|
+
when "未完成"
|
250
|
+
not_finish_year_merged_hash[s.id].to_i
|
251
|
+
end
|
252
|
+
},
|
253
|
+
backgroundColor: colors[i],
|
254
|
+
borderColor: colors[i],
|
255
|
+
borderWidth: 1
|
256
|
+
}
|
257
|
+
end
|
258
|
+
}
|
259
|
+
staff_data = EducodeSales::Staff.where(id: year_merged_hash.keys).limit(3).map { |d| [d.user.real_name, all_year_merged_hash[d.id], year_merged_hash[d.id]] }
|
260
|
+
|
261
|
+
[data_1, data_2, data_3, data_4, data_5, data_6, data_7, data_8, data_9, data_10, data_11, data_12, data_13, data_14, data_15, staff_data, chart1, chart2]
|
115
262
|
end
|
116
263
|
|
117
264
|
end
|
@@ -141,10 +141,20 @@
|
|
141
141
|
},
|
142
142
|
{
|
143
143
|
field: 'key_people',
|
144
|
-
width:
|
144
|
+
width: 100,
|
145
145
|
title: '关键人',
|
146
146
|
templet:'<div><span title="{{d.key_people}}">{{d.key_people}}</span></div>'
|
147
147
|
},
|
148
|
+
{
|
149
|
+
field: 'rival',
|
150
|
+
width: 100,
|
151
|
+
title: '竞争对手',
|
152
|
+
},
|
153
|
+
{
|
154
|
+
field: 'staff_manages',
|
155
|
+
width: 120,
|
156
|
+
title: '销售经理',
|
157
|
+
},
|
148
158
|
{
|
149
159
|
field: 'tel',
|
150
160
|
width: 90,
|
@@ -63,6 +63,14 @@
|
|
63
63
|
id="reception_at_edit" placeholder="请选择日期">
|
64
64
|
</div>
|
65
65
|
</div>
|
66
|
+
<div class="layui-inline">
|
67
|
+
<label class="layui-form-label">部署时间</label>
|
68
|
+
<div class="layui-input-inline">
|
69
|
+
<input type="text" class="layui-input" value="<%= @follow_up.business.p_deploy_time %>" name="deploy_time"
|
70
|
+
id="p_deploy_time" placeholder="请选择日期">
|
71
|
+
</div>
|
72
|
+
</div>
|
73
|
+
|
66
74
|
<br>
|
67
75
|
<div class="layui-inline service_show layui-hide">
|
68
76
|
<label class="layui-form-label required">服务期</label>
|
@@ -133,6 +141,14 @@
|
|
133
141
|
</div>
|
134
142
|
</div>
|
135
143
|
</div>
|
144
|
+
<div class="layui-form-item">
|
145
|
+
<div class="layui-inline">
|
146
|
+
<label class="layui-form-label">竞争对手</label>
|
147
|
+
<div class="layui-input-inline">
|
148
|
+
<input type="text" class="layui-input" name="rival" autocomplete="off" value="<%= @follow_up&.rival%>">
|
149
|
+
</div>
|
150
|
+
</div>
|
151
|
+
</div>
|
136
152
|
<div class="layui-form-item">
|
137
153
|
<label class="layui-form-label">指定跟进人</label>
|
138
154
|
<div class="layui-input-inline" style="">
|
@@ -209,6 +225,9 @@
|
|
209
225
|
laydate.render({
|
210
226
|
elem: '#invitation_at_edit'
|
211
227
|
})
|
228
|
+
laydate.render({
|
229
|
+
elem: '#p_deploy_time'
|
230
|
+
})
|
212
231
|
laydate.render({
|
213
232
|
elem: '#service_time',
|
214
233
|
range: true
|