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.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/educode_sales/indexlogo.png +0 -0
  3. data/app/controllers/educode_sales/businesses_controller.rb +27 -0
  4. data/app/controllers/educode_sales/follow_ups_controller.rb +20 -5
  5. data/app/controllers/educode_sales/project_charts_controller.rb +145 -0
  6. data/app/controllers/educode_sales/staffs_controller.rb +35 -0
  7. data/app/helpers/educode_sales/application_helper.rb +153 -6
  8. data/app/views/educode_sales/businesses/_follows.html.erb +11 -1
  9. data/app/views/educode_sales/businesses/edit_follow_record.html.erb +19 -0
  10. data/app/views/educode_sales/businesses/index.html.erb +40 -8
  11. data/app/views/educode_sales/businesses/index.json.jbuilder +3 -0
  12. data/app/views/educode_sales/businesses/key_person.html.erb +56 -0
  13. data/app/views/educode_sales/businesses/key_person.json.jbuilder +17 -0
  14. data/app/views/educode_sales/businesses/new_follow_record.html.erb +23 -9
  15. data/app/views/educode_sales/follow_ups/index.json.jbuilder +2 -0
  16. data/app/views/educode_sales/project_charts/_sales_analysis.html.erb +436 -0
  17. data/app/views/educode_sales/project_charts/sales_analysis.js.erb +1 -0
  18. data/app/views/educode_sales/project_charts/trends.html.erb +81 -0
  19. data/app/views/educode_sales/project_charts/trends.json.jbuilder +4 -0
  20. data/app/views/educode_sales/staffs/edit.html.erb +1 -1
  21. data/app/views/educode_sales/staffs/index.html.erb +20 -1
  22. data/app/views/educode_sales/staffs/list.html.erb +39 -0
  23. data/app/views/layouts/educode_sales/application.html.erb +3 -3
  24. data/config/routes.rb +14 -0
  25. data/db/migrate/20230428015007_add_deploy_time_follow_ups.rb +6 -0
  26. data/lib/educode_sales/version.rb +1 -1
  27. metadata +16 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f06396ccf8dbcf15c84aecaa042d4c444335c9ef3a09c82d5ccced165beb429a
4
- data.tar.gz: 1bbace4be30f8d50b507d9174b40cfec77073ff74e79188443359bdf1f146281
3
+ metadata.gz: bd2b28526eb6deff3149781638110e6f86c717287996bf7740437727adfd2ee3
4
+ data.tar.gz: cd3c64540eed97347f0f5b640136cc2fab13d74635246d54d5ca1e95dc1b4a43
5
5
  SHA512:
6
- metadata.gz: 6034bfe4baf04919a142b18d57cdf9a8489fc9af2ec55597d36556a5ab69b6a9d1749d2c1271556a489f7d4907144e3c0b9db3769b7573cb967291fe3fb04b0b
7
- data.tar.gz: 40edd2d1d9f49c081dad0251a573fadf67de0592755c54279d22518a80d2c3dea2777cb7d1daca05c7544f09a915078d79b3a63a9e94e4c2e025371f2a392e16
6
+ metadata.gz: f07f190aa90d48f53aa734204c86c77f7caa7fd3a374b71bd4b6a8080428542354d67b9eefd4037490da5b3784b3219fcc3286d1cba6dd1279489e6a3edabb3f
7
+ data.tar.gz: 27b899f64fe009157232ccaf573e83f4562a5496fbb69bdb5650105df89ca8599b26715c22e70af9aeff1bf355f75fcaab5ff8ef6768371ddf48ec35d85efab5
@@ -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
- .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,
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 + @businesses_c_d_count.count.to_i*5
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: 90,
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