educode_sales 0.9.72 → 0.9.74

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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/educode_sales/indexlogo.png +0 -0
  3. data/app/controllers/educode_sales/contracts_controller.rb +309 -0
  4. data/app/controllers/educode_sales/follow_ups_controller.rb +1 -1
  5. data/app/controllers/educode_sales/home_controller.rb +7 -0
  6. data/app/controllers/educode_sales/ideas_controller.rb +146 -76
  7. data/app/controllers/educode_sales/project_charts_controller.rb +145 -0
  8. data/app/controllers/educode_sales/roles_controller.rb +2 -1
  9. data/app/controllers/educode_sales/upload_files_controller.rb +3 -0
  10. data/app/helpers/educode_sales/application_helper.rb +153 -6
  11. data/app/models/educode_sales/assign_staff.rb +6 -0
  12. data/app/models/educode_sales/contract_date_list.rb +6 -0
  13. data/app/models/educode_sales/follow_up.rb +6 -0
  14. data/app/models/educode_sales/idea.rb +16 -5
  15. data/app/models/educode_sales/idea_follow.rb +11 -0
  16. data/app/models/educode_sales/permission.rb +2 -1
  17. data/app/models/educode_sales/role_area.rb +2 -1
  18. data/app/views/educode_sales/businesses/_contract_list.html.erb +160 -0
  19. data/app/views/educode_sales/contracts/_follows.html.erb +323 -0
  20. data/app/views/educode_sales/contracts/_list.html.erb +596 -0
  21. data/app/views/educode_sales/contracts/follow_ups.json.jbuilder +23 -0
  22. data/app/views/educode_sales/contracts/index.html.erb +50 -0
  23. data/app/views/educode_sales/contracts/index.json.jbuilder +74 -0
  24. data/app/views/educode_sales/contracts/list.js.erb +1 -0
  25. data/app/views/educode_sales/contracts/new_follow_up.html.erb +671 -0
  26. data/app/views/educode_sales/home/staff_business.json.jbuilder +9 -0
  27. data/app/views/educode_sales/idea_recycles/detail.html.erb +4 -4
  28. data/app/views/educode_sales/idea_recycles/index.html.erb +5 -5
  29. data/app/views/educode_sales/ideas/_follows.html.erb +258 -0
  30. data/app/views/educode_sales/ideas/_index.html.erb +544 -0
  31. data/app/views/educode_sales/ideas/detail.html.erb +7 -7
  32. data/app/views/educode_sales/ideas/edit.html.erb +77 -15
  33. data/app/views/educode_sales/ideas/files.html.erb +157 -0
  34. data/app/views/educode_sales/ideas/files.json.jbuilder +13 -0
  35. data/app/views/educode_sales/ideas/follow_ups.json.jbuilder +14 -0
  36. data/app/views/educode_sales/ideas/index.html.erb +12 -353
  37. data/app/views/educode_sales/ideas/index.json.jbuilder +7 -1
  38. data/app/views/educode_sales/ideas/new.html.erb +81 -25
  39. data/app/views/educode_sales/ideas/new_follow_up.html.erb +105 -0
  40. data/app/views/educode_sales/ideas/search_new.html.erb +1 -1
  41. data/app/views/educode_sales/ideas/show_schools.html.erb +84 -0
  42. data/app/views/educode_sales/ideas/show_schools.json.jbuilder +12 -0
  43. data/app/views/educode_sales/ideas/show_teachers.html.erb +372 -0
  44. data/app/views/educode_sales/ideas/upload_file.html.erb +43 -0
  45. data/app/views/educode_sales/project_charts/_sales_analysis.html.erb +436 -0
  46. data/app/views/educode_sales/project_charts/sales_analysis.js.erb +1 -0
  47. data/app/views/educode_sales/project_charts/trends.html.erb +81 -0
  48. data/app/views/educode_sales/project_charts/trends.json.jbuilder +4 -0
  49. data/app/views/educode_sales/projects/detail.html.erb +1 -1
  50. data/app/views/educode_sales/projects/edit.html.erb +1 -1
  51. data/app/views/educode_sales/roles/edit.html.erb +16 -0
  52. data/app/views/layouts/educode_sales/application.html.erb +8 -8
  53. data/config/routes.rb +30 -0
  54. data/db/migrate/20230227061043_create_educode_sales_ideas.rb +2 -2
  55. data/db/migrate/20230430023424_add_plan_signed_date_to_follow_ups.rb +21 -0
  56. data/db/migrate/20230430040332_create_educode_sales_contract_date_lists.rb +15 -0
  57. data/db/migrate/20230430104708_create_idea_follows.rb +25 -0
  58. data/db/migrate/20230430121335_add_permissions_for_ideas.rb +16 -0
  59. data/db/migrate/20230430134710_create_educode_sales_assign_staffs.rb +11 -0
  60. data/lib/educode_sales/version.rb +1 -1
  61. metadata +40 -6
@@ -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
@@ -16,7 +16,7 @@ module EducodeSales
16
16
 
17
17
  def create
18
18
  role = Role.new(name: params[:name])
19
- role.role_areas.build([{ clazz: 'Business' }, { clazz: 'SalePlan' }, { clazz: 'Teacher' }, { clazz: 'Operation' }, { clazz: 'Customer' }, { clazz: 'MoneyPlan' }, { clazz: 'AssessmentsSetting' }, { clazz: 'Idea' }, { clazz: 'Project' }])
19
+ role.role_areas.build([{ clazz: 'Business' }, { clazz: 'Contract' }, { clazz: 'SalePlan' }, { clazz: 'Teacher' }, { clazz: 'Operation' }, { clazz: 'Customer' }, { clazz: 'MoneyPlan' }, { clazz: 'AssessmentsSetting' }, { clazz: 'Idea' }, { clazz: 'Project' }])
20
20
  if role.save
21
21
  render_success
22
22
  else
@@ -75,6 +75,7 @@ module EducodeSales
75
75
  def view
76
76
  role = Role.find(params[:id])
77
77
  role.role_areas.find_by(clazz: 'Business').update(level: params[:business])
78
+ role.role_areas.find_by(clazz: 'Contract').update(level: params[:contract])
78
79
  role.role_areas.find_by(clazz: 'Operation').update(level: params[:operation])
79
80
  role.role_areas.find_by(clazz: 'SalePlan').update(level: params[:sale_plan])
80
81
  role.role_areas.find_by(clazz: 'Teacher').update(level: params[:teacher])
@@ -36,6 +36,9 @@ module EducodeSales
36
36
  if params[:activity_id].present?
37
37
  @attachment.container_id = params[:activity_id]
38
38
  @attachment.container_type = 'EducodeSales::Activity'
39
+ elsif params[:idea_id].present?
40
+ @attachment.container_id = params[:idea_id]
41
+ @attachment.container_type = 'EducodeSales::Idea'
39
42
  else
40
43
  @attachment.description = "business"
41
44
  @attachment.container_id = params[:business_id]
@@ -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
@@ -0,0 +1,6 @@
1
+ module EducodeSales
2
+ class AssignStaff < ApplicationRecord
3
+ belongs_to :staff
4
+ belongs_to :sourcable, :polymorphic => true
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module EducodeSales
2
+ class ContractDateList < ApplicationRecord
3
+ belongs_to :follow_up
4
+ belongs_to :staff
5
+ end
6
+ end
@@ -8,6 +8,10 @@ module EducodeSales
8
8
  ["混合云", 3]
9
9
  ]
10
10
 
11
+ InfoClazz = ['跟进信息', '建议信息', '评论信息', '审核信息']
12
+
13
+ enum funding_source: ['贷款资金', '财政资金', '自由资金']
14
+
11
15
  include ::Deletable
12
16
  belongs_to :business, counter_cache: true # counter_cache(自动计算 business对应follow_up表中对应的个数)
13
17
  belongs_to :place, optional: true
@@ -19,6 +23,8 @@ module EducodeSales
19
23
  belongs_to :stage, class_name: 'Common'
20
24
  belongs_to :clazz, class_name: 'Common'
21
25
 
26
+ has_many :assign_staffs, as: :sourcable # 售后人员
27
+
22
28
 
23
29
  default_scope -> {where(deleted_at: nil)}
24
30
 
@@ -1,6 +1,7 @@
1
1
  module EducodeSales
2
2
  class Idea < ApplicationRecord
3
3
  belongs_to :department, optional: true
4
+ belongs_to :business, optional: true
4
5
  belongs_to :staff, optional: true
5
6
  belongs_to :school, optional: true
6
7
  belongs_to :attachment, optional: true
@@ -8,19 +9,25 @@ module EducodeSales
8
9
  belongs_to :deleter, class_name: 'Staff', optional: true
9
10
  belongs_to :sale_staff, class_name: 'Staff', optional: true
10
11
  belongs_to :idea_staff, class_name: 'Staff', optional: true
12
+ has_many :idea_follows, dependent: :destroy
13
+ has_one :last_idea_follow, class_name: 'IdeaFollow'
11
14
 
12
15
  has_many :idea_histories, dependent: :destroy
13
16
 
17
+ has_many :files, class_name: 'Attachment', as: :container, dependent: :destroy
18
+
14
19
  scope :deleted, -> { where(is_deleted: true) }
15
20
  scope :not_deleted, -> { where(is_deleted: false) }
16
21
 
17
22
  enum level: %w[高 中 低]
18
23
  enum status: %w[未完成 已完成]
19
- enum types: %w[定制 非定制]
24
+ enum types: %w[低定制 非定制 高定制 全定制]
20
25
  enum model: %w[本地版 线上版 混合版]
26
+ enum idea_type: %w[售前 售后]
21
27
 
22
28
  serialize :assist_staff_ids,Array
23
29
  serialize :attachment_ids, Array
30
+ serialize :other_staff_ids, Array
24
31
 
25
32
  # before_save :check_changes
26
33
 
@@ -32,6 +39,10 @@ module EducodeSales
32
39
  Staff.where(id: self.assist_staff_ids)
33
40
  end
34
41
 
42
+ def other_staffs
43
+ Staff.where(id: self.other_staff_ids)
44
+ end
45
+
35
46
  def attachments
36
47
  Attachment.where(id: self.attachment_ids)
37
48
  end
@@ -68,7 +79,7 @@ module EducodeSales
68
79
  when "staff_id"
69
80
  old_value = Staff.find_by(id: old_value)&.user&.real_name
70
81
  new_value = Staff.find_by(id: new_value)&.user&.real_name
71
- "方案指派人由“#{old_value}”变更为“#{new_value}”"
82
+ "方案经理由“#{old_value}”变更为“#{new_value}”"
72
83
  when "status"
73
84
  "状态由“#{old_value}”变更为“#{new_value}”"
74
85
  when "types"
@@ -84,13 +95,13 @@ module EducodeSales
84
95
  when "end_time"
85
96
  "截止时间由“#{old_value}”变更为“#{new_value}”"
86
97
  when "content"
87
- "反馈情况由“#{old_value}”变更为“#{new_value}”"
98
+ "需求说明由“#{old_value}”变更为“#{new_value}”"
88
99
  when "department_id"
89
100
  old_value = Department.find_by(id: old_value)&.name
90
101
  new_value = Department.find_by(id: new_value)&.name
91
- "院系/部门由“#{old_value}”变更为“#{new_value}”"
102
+ "部门由“#{old_value}”变更为“#{new_value}”"
92
103
  when "manager_name"
93
- "学校负责人由“#{old_value}”变更为“#{new_value}”"
104
+ "单位联系人由“#{old_value}”变更为“#{new_value}”"
94
105
  when "manager_phone"
95
106
  "负责人电话由“#{old_value}”变更为“#{new_value}”"
96
107
  else
@@ -0,0 +1,11 @@
1
+ module EducodeSales
2
+ class IdeaFollow < ApplicationRecord
3
+ belongs_to :idea, optional: true, counter_cache: true
4
+ belongs_to :staff, optional: true
5
+ belongs_to :sale_staff, class_name: "Staff", foreign_key: "sale_staff_id", optional: true
6
+ belongs_to :idea_staff, class_name: "Staff", foreign_key: "idea_staff_id", optional: true
7
+ belongs_to :school, optional: true
8
+
9
+ enum status: %w[未完成 已完成]
10
+ end
11
+ end
@@ -15,7 +15,8 @@ module EducodeSales
15
15
  '回款管理': 'money_plan',
16
16
  '绩效考核': 'assessments_setting',
17
17
  '方案管理': 'idea',
18
- '项目管理': 'project'
18
+ '项目管理': 'project',
19
+ '合同管理': 'contract'
19
20
  }
20
21
  end
21
22
  end
@@ -12,7 +12,8 @@ module EducodeSales
12
12
  '回款管理': 'MoneyPlan',
13
13
  '绩效考核': 'AssessmentsSetting',
14
14
  '方案管理': 'Idea',
15
- '项目管理': 'Project'
15
+ '项目管理': 'Project',
16
+ '合同管理': 'Contract'
16
17
  }
17
18
  end
18
19
  end