educode_sales 0.9.68 → 0.9.69

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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/educode_sales/indexlogo.png +0 -0
  3. data/app/assets/javascripts/educode_sales/extent/treeTable.js +235 -0
  4. data/app/controllers/educode_sales/customers_controller.rb +107 -0
  5. data/app/controllers/educode_sales/follow_ups_controller.rb +6 -0
  6. data/app/controllers/educode_sales/projects_controller.rb +420 -0
  7. data/app/controllers/educode_sales/roles_controller.rb +4 -1
  8. data/app/controllers/educode_sales/teachers_controller.rb +38 -13
  9. data/app/helpers/educode_sales/application_helper.rb +1 -0
  10. data/app/models/educode_sales/business.rb +21 -5
  11. data/app/models/educode_sales/business_history.rb +8 -0
  12. data/app/models/educode_sales/permission.rb +2 -1
  13. data/app/models/educode_sales/project.rb +53 -0
  14. data/app/models/educode_sales/role_area.rb +2 -1
  15. data/app/views/educode_sales/activities/show_teachers.html.erb +1 -1
  16. data/app/views/educode_sales/businesses/index.html.erb +5 -0
  17. data/app/views/educode_sales/businesses/index.json.jbuilder +3 -0
  18. data/app/views/educode_sales/businesses/time_line.html.erb +9 -5
  19. data/app/views/educode_sales/customers/edit_major.html.erb +872 -0
  20. data/app/views/educode_sales/customers/list.html.erb +602 -0
  21. data/app/views/educode_sales/customers/list.json.jbuilder +33 -0
  22. data/app/views/educode_sales/follow_ups/index.json.jbuilder +2 -2
  23. data/app/views/educode_sales/projects/detail.html.erb +269 -0
  24. data/app/views/educode_sales/projects/edit.html.erb +246 -0
  25. data/app/views/educode_sales/projects/history.html.erb +41 -0
  26. data/app/views/educode_sales/projects/index.html.erb +688 -0
  27. data/app/views/educode_sales/projects/index.json.jbuilder +69 -0
  28. data/app/views/educode_sales/teachers/_index.html.erb +17 -1
  29. data/app/views/educode_sales/teachers/index.json.jbuilder +2 -0
  30. data/app/views/layouts/educode_sales/application.html.erb +25 -0
  31. data/config/routes.rb +12 -0
  32. data/db/migrate/20230411134203_add_realname_to_teacher.rb +5 -0
  33. data/db/migrate/20230412083510_add_p_staff_id_to_businesses.rb +20 -0
  34. data/db/migrate/20230412092000_create_business_histories.rb +10 -0
  35. data/db/migrate/20230413015619_add_permissions_to_projects.rb +11 -0
  36. data/db/migrate/20230413031029_add_pre_time_to_businesses.rb +5 -0
  37. data/lib/educode_sales/version.rb +1 -1
  38. metadata +24 -6
@@ -0,0 +1,420 @@
1
+ require_dependency "educode_sales/application_controller"
2
+
3
+ module EducodeSales
4
+ class ProjectsController < ApplicationController
5
+
6
+ before_action :find_project, only: [:edit, :destroy, :detail, :history, :update, :recycle]
7
+
8
+ def index
9
+ authorize! :contract_business, Business
10
+ respond_to do |format|
11
+ format.html do
12
+ common = Common.find_by(clazz: 'staff_type', name: '销售')
13
+ @staffs = Staff.joins(:user).where(job_type: common.id).where.not(role_id: 11).map { |d| [d.user.real_name, d.id] }
14
+ gon.staffs = Staff.joins(:user).where(job_type: common.id).where.not(role_id: 11).map { |d| { name: d.user.real_name, value: d.id } }
15
+ @more = true
16
+ gon.menus = []
17
+ gon.export_menus = []
18
+ gon.place = params[:place_id].present? ? [{ value: params[:place_id], name: EducodeSales::Place.find(params[:place_id]).name }] : []
19
+
20
+ bussiness_type = []
21
+ if params[:type]
22
+ # 项目类型
23
+ bussiness_type = EducodeSales::Business.include_types(params[:type]) || []
24
+ end
25
+
26
+ business_step = []
27
+ if params[:step]
28
+ # 项目阶段
29
+ business_step = EducodeSales::Business.include_steps(params[:step]) || []
30
+ end
31
+
32
+ if params[:business_year].present? && params[:business_year] != '全部'
33
+ gon.business_year = params[:business_year]
34
+ end
35
+
36
+ if params[:bidded_date_year].present? && params[:bidded_date_year] != '全部'
37
+ if params[:step] == '应收款'
38
+ gon.bidded_date = "2015-01-01" + " - " + Time.new(params[:bidded_date_year]).end_of_year.strftime("%Y-%m-%d")
39
+ else
40
+ gon.bidded_date = Time.new(params[:bidded_date_year]).strftime("%Y-%m-%d") + " - " + Time.new(params[:bidded_date_year]).end_of_year.strftime("%Y-%m-%d")
41
+ end
42
+ end
43
+
44
+ if params[:signed_date_year].present? && params[:signed_date_year] != '全部'
45
+ gon.signed_date = Time.new(params[:signed_date_year]).strftime("%Y-%m-%d") + " - " + Time.new(params[:signed_date_year]).end_of_year.strftime("%Y-%m-%d")
46
+ end
47
+
48
+ if params[:date_at].present? && params[:date_at] != '全部'
49
+ # 回款时间
50
+ gon.date_at = Time.new(params[:date_at]).strftime("%Y-%m-%d") + " - " + Time.new(params[:date_at]).end_of_year.strftime("%Y-%m-%d")
51
+ end
52
+
53
+ gon.business_type = Common.where(clazz: 'business_type').map do |d|
54
+ { value: d.id, name: d.name, selected: bussiness_type.include?(d.extras) }
55
+ end
56
+
57
+ gon.business_step = Common.where(clazz: 'business_step', name: ['已中标', '已签单', '已验收', '回款中', '服务中', '已结束']).order("position").map do |d|
58
+ { value: d.id, name: d.name, selected: business_step.include?(d.name) }
59
+ end
60
+
61
+ filter = Filter.find_or_create_by(staff_id: @current_admin.id, clazz: "businesses_list")
62
+ if filter.extras.present?
63
+ if filter.extras['area'].nil?
64
+ filter.extras['area'] = 1
65
+ filter.extras['property'] = 1
66
+ filter.extras['sale_way'] = 1
67
+ end
68
+ filter.save
69
+ gon.filter = filter.extras
70
+ else
71
+ gon.filter = { 'area': 1, 'property': 1, 'sale_way': 1 }
72
+ end
73
+ end
74
+ format.json do
75
+ if @current_admin.is_admin?
76
+ @businesses = Business
77
+ else
78
+ level = @current_admin.role.role_areas.find_by(clazz: '商机管理').level
79
+ case level
80
+ when '自己'
81
+ business_ids = Business.joins(last_follow_up: :assign_follow_ups).where("educode_sales_assign_follow_ups.staff_id = ?", @current_admin.id).pluck(:id)
82
+ @businesses = Business.where("educode_sales_businesses.staff_id = ? OR educode_sales_businesses.id in (?)", @current_admin.id, business_ids)
83
+ when '区域'
84
+ # 查看区域商机,需要排除掉其它人员手上的监管学校
85
+ other_staff_school_id = EducodeSales::StaffSchool.where.not(staff_id: @current_admin.id).where("school_id IN (SELECT school_id FROM educode_sales_staff_schools WHERE staff_id = #{@current_admin.id}) IS NOT TRUE").distinct.pluck :school_id
86
+
87
+ school_ids = School.where(province: @current_admin.areas.pluck(:name)).pluck(:id) + StaffSchool.where(staff_id: @current_admin.id).pluck(:school_id) - other_staff_school_id
88
+ if can?(:special, EducodeSales::Business)
89
+ # 专项商机
90
+ school_tag_ids = @current_admin.staff_school_tags.pluck(:school_tag_id)
91
+ tag_school_ids = SchoolTagMiddle.where(school_tag_id: school_tag_ids).pluck(:school_id)
92
+ school_ids += tag_school_ids
93
+ end
94
+ business_ids = Business.joins(last_follow_up: :assign_follow_ups).where("educode_sales_assign_follow_ups.staff_id = ?", @current_admin.id).pluck(:id)
95
+ @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)
96
+ else
97
+ @businesses = Business
98
+ end
99
+ end
100
+ @businesses =
101
+ if params[:is_deleted].to_s.present?
102
+ @businesses.where.not(p_deleted_at: nil)
103
+ else
104
+ @businesses.where(p_deleted_at: nil)
105
+ end
106
+
107
+ @is_deleted = params[:is_deleted].to_s.present?
108
+ gon.is_deleted = @is_deleted ? 1 : 0
109
+ if params[:q].present? && params[:q][:name].present?
110
+ @year = params[:q][:name].split("-")[1].present? ? params[:q][:name].split("-")[1] : ''
111
+ end
112
+ # @budget_stage_ids = Common.where(clazz: '商机阶段', name: ['初步接洽', '准备方案','已交方案', '已立项']).pluck(:id)
113
+ if params[:q] && params[:q][:signed_date].present?
114
+ date = params[:q][:signed_date].split(" - ")
115
+ @businesses = @businesses.joins("
116
+ JOIN educode_sales_follow_ups ON educode_sales_businesses.last_follow_up_id = educode_sales_follow_ups.id
117
+ ").where("educode_sales_follow_ups.signed_date >= ? AND educode_sales_follow_ups.signed_date <= ?", date[0], date[1])
118
+ end
119
+
120
+ if params[:q] && params[:q][:date_at].present?
121
+ date = params[:q][:date_at].split(" - ")
122
+ x_id = Common.find_by(extras: EducodeSales::Common::XTYPE)&.id
123
+ @businesses = @businesses.joins(follow_ups: :money_plans).where("educode_sales_follow_ups.clazz_id != ?", x_id).where.not("educode_sales_money_plans.clazz!= 1").where("educode_sales_money_plans.date_at >= ? AND educode_sales_money_plans.date_at <= ? ", date[0] + " 00:00:00", date[1] + " 23:59:59").distinct
124
+ end
125
+
126
+ if params[:q] && params[:q][:bidded_date].present?
127
+ date = params[:q][:bidded_date].split(" - ")
128
+ @businesses = @businesses.joins("
129
+ JOIN educode_sales_follow_ups ON educode_sales_businesses.last_follow_up_id = educode_sales_follow_ups.id
130
+ ").where("educode_sales_follow_ups.bidded_date >= ? AND educode_sales_follow_ups.bidded_date <= ?", date[0], date[1])
131
+ end
132
+
133
+ if params[:q].present? && params[:q][:all].present?
134
+ @businesses = @businesses
135
+ end
136
+
137
+ if params[:q].present? && params[:q][:name].present?
138
+ @businesses = @businesses.where("educode_sales_businesses.name like ?", "%#{params[:q][:name]}%")
139
+ end
140
+ if params[:q].present? && params[:q][:p_stage].present?
141
+ @businesses = @businesses.where(p_stage: "#{params[:q][:p_stage].to_s.strip}")
142
+ end
143
+ if params[:q].present? && params[:q][:p_staff_id].present?
144
+ @businesses = @businesses.where(p_staff_id: params[:q][:p_staff_id])
145
+ end
146
+ if params[:q].present? && params[:q][:p_special].present?
147
+ @businesses = @businesses.where(p_special: "#{params[:q][:p_special]}")
148
+ end
149
+ if params[:q].present? && params[:q][:p_difficulty].present?
150
+ @businesses = @businesses.where(p_difficulty: "#{params[:q][:p_difficulty]}")
151
+ end
152
+
153
+ # bidded_date = d.last_follow_up&.bidded_date
154
+ # stage = d.last_follow_up&.stage&.name
155
+ # (d.p_pre_money_time.present? && Time.now > d.p_pre_money_time && d.p_actual_money_time.blank?) ||
156
+ # (d.p_pre_accept_time.present? && Time.now > d.p_pre_accept_time && d.p_accept_time.blank?) ? "逾期" : "正常"
157
+ # SELECT * FROM users WHERE NOW() > DATE_ADD(bidded_date, INTERVAL 1 MONTH)
158
+
159
+ if params[:q].present? && params[:q][:p_state].present?
160
+ p_state = params[:q][:p_state].to_i
161
+ # 逾期id
162
+ late_ids = 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")
163
+ .where("educode_sales_follow_ups.bidded_date is not null")
164
+ .where("NOW() > DATE_ADD(educode_sales_follow_ups.bidded_date, INTERVAL 1 MONTH)")
165
+ .where("educode_sales_businesses.p_stage is null")
166
+ .where("educode_sales_commons.name = '已中标'")
167
+ .or(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")
168
+ .where("NOW() > educode_sales_businesses.p_pre_money_time")
169
+ .where("educode_sales_businesses.p_pre_money_time is not null")
170
+ .where("educode_sales_businesses.p_actual_money_time is null")
171
+ ).or(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")
172
+ .where("NOW() > educode_sales_businesses.p_pre_accept_time")
173
+ .where("educode_sales_businesses.p_pre_accept_time is not null")
174
+ .where("educode_sales_businesses.p_accept_time is null")).ids
175
+ if p_state == 0 # 正常
176
+ @businesses = @businesses.where.not(id: late_ids)
177
+ else
178
+ # 逾期
179
+ @businesses = @businesses.where(id: late_ids)
180
+ end
181
+ end
182
+ if params[:q].present? && params[:q][:department].present?
183
+ departments_ids = Department.joins(:school).where("schools.name like ?", "%#{params[:q][:department]}%").pluck(:id)
184
+ @businesses = @businesses.joins(:department).where("departments.id in (?)", departments_ids)
185
+ end
186
+ if params[:q].present? && params[:q][:staff_id].present?
187
+ part_a_ids = @businesses.where("educode_sales_businesses.last_follow_up_id is null AND educode_sales_businesses.staff_id = ?", params[:q][:staff_id]).ids
188
+ part_b_ids = @businesses.where("educode_sales_businesses.last_follow_up_id is not null").joins("
189
+ JOIN educode_sales_follow_ups ON educode_sales_businesses.last_follow_up_id = educode_sales_follow_ups.id
190
+ ").where("educode_sales_follow_ups.staff_id = ?", params[:q][:staff_id]).ids
191
+ business_ids = part_a_ids + part_b_ids
192
+ if params[:q][:clazz] == 'delete_list'
193
+ @businesses = EducodeSales::Business.unscoped.where(id: business_ids)
194
+ else
195
+ @businesses = EducodeSales::Business.where(id: business_ids)
196
+ end
197
+ end
198
+ if params[:q].present? && params[:q][:business_type].present?
199
+ @businesses = @businesses.where("educode_sales_businesses.clazz_id in (?)", params[:q][:business_type].split(",").map(&:to_i))
200
+ end
201
+ contract_ids = Common.where(clazz: '商机阶段', name: ['已中标', '已签单', '已验收', '回款中', '服务中', '已结束']).pluck(:id)
202
+ @businesses = @businesses.joins("
203
+ JOIN educode_sales_follow_ups ON educode_sales_businesses.last_follow_up_id = educode_sales_follow_ups.id
204
+ ").where("educode_sales_follow_ups.stage_id in (?)", contract_ids)
205
+ if params[:q].present? && params[:q][:business_step].present?
206
+ @businesses = @businesses.joins("
207
+ JOIN educode_sales_follow_ups ON educode_sales_businesses.last_follow_up_id = educode_sales_follow_ups.id
208
+ ").where("educode_sales_follow_ups.stage_id in (?)", params[:q][:business_step].split(",").map(&:to_i))
209
+ end
210
+ if params[:q].present? && params[:q][:place_id].present?
211
+ @businesses = @businesses.joins("
212
+ JOIN educode_sales_follow_ups ON educode_sales_businesses.last_follow_up_id = educode_sales_follow_ups.id
213
+ ").where("educode_sales_follow_ups.place_id = ?", params[:q][:place_id])
214
+ end
215
+ if params[:q].present? && params[:q][:business_year].present?
216
+ @businesses = @businesses.joins("
217
+ JOIN educode_sales_follow_ups ON educode_sales_businesses.last_follow_up_id = educode_sales_follow_ups.id
218
+ ").where("educode_sales_follow_ups.year = ?", params[:q][:business_year])
219
+ end
220
+
221
+ if params[:q].present? && params[:q][:year].present?
222
+ @businesses = @businesses.joins("
223
+ JOIN educode_sales_follow_ups ON educode_sales_businesses.last_follow_up_id = educode_sales_follow_ups.id
224
+ ").where("educode_sales_follow_ups.year <= ?", params[:q][:year])
225
+ end
226
+
227
+ if params[:q].present? && params[:q][:o_business_deployment].present?
228
+ @businesses = @businesses.joins("
229
+ JOIN educode_sales_follow_ups ON educode_sales_businesses.last_follow_up_id = educode_sales_follow_ups.id
230
+ ").where("educode_sales_follow_ups.o_business_deployment = ?", params[:q][:o_business_deployment])
231
+ end
232
+
233
+ if params[:q].present? && params[:q][:area].present?
234
+ p = EducodeSales::Common.find(params[:q][:area]).name
235
+ if @current_admin.is_admin?
236
+ @businesses = @businesses.joins("
237
+ JOIN departments ON educode_sales_businesses.department_id = departments.id
238
+ JOIN schools ON departments.school_id = schools.id
239
+ ").where("province = ?", p)
240
+ else
241
+ level = @current_admin.role.role_areas.find_by(clazz: '商机管理').level
242
+ if level == "区域"
243
+ @businesses = @businesses.joins("
244
+ JOIN schools ON departments.school_id = schools.id
245
+ ").where("province = ?", p)
246
+ else
247
+ @businesses = @businesses.joins("
248
+ JOIN departments ON educode_sales_businesses.department_id = departments.id
249
+ JOIN schools ON departments.school_id = schools.id
250
+ ").where("province = ?", p)
251
+ end
252
+ end
253
+ end
254
+
255
+ if params[:q].present? && params[:q][:date].present?
256
+ date = params[:q][:date].split(" - ")
257
+ @businesses = @businesses.where("educode_sales_businesses.created_at > ? AND educode_sales_businesses.created_at < ?", date[0], date[1] + '23:59:59')
258
+ end
259
+ if params[:q].present? && params[:q][:search_p_actual_money_time].present?
260
+ date = params[:q][:search_p_actual_money_time].split(" - ")
261
+ @businesses = @businesses.where("educode_sales_businesses.p_actual_money_time > ? AND educode_sales_businesses.p_actual_money_time < ?", date[0], date[1] + '23:59:59')
262
+ end
263
+
264
+ if params[:q].present? && params[:q][:invitation_at].present?
265
+ date = params[:q][:invitation_at].split(" - ")
266
+ @businesses = @businesses.joins("
267
+ JOIN educode_sales_follow_ups ON educode_sales_businesses.last_follow_up_id = educode_sales_follow_ups.id
268
+ ").where("educode_sales_follow_ups.invitation_at > ? AND educode_sales_follow_ups.invitation_at < ?", date[0] + '00:00:00', date[1] + '23:59:59')
269
+ end
270
+
271
+ # 根据编号获取商机
272
+ if params[:q].present? && params[:q][:number].present?
273
+ @businesses = @businesses.where("number like :data", data: "%#{params[:q][:number].strip}%")
274
+ end
275
+
276
+ if params[:q].present? && params[:q][:clazz].present?
277
+ # 我的关注
278
+ if params[:q][:clazz] == 'followes'
279
+ my_ids = BusinessRelationShip.where(user_id: @current_admin.user_id).pluck(:business_id)
280
+ @businesses = @businesses.where(id: my_ids)
281
+ elsif params[:q][:clazz] == 'me'
282
+ ids = AssignFollowUp.joins("JOIN educode_sales_follow_ups ON educode_sales_follow_ups.id = educode_sales_assign_follow_ups.follow_up_id").where(staff_id: @current_admin.id).pluck(:business_id)
283
+ @businesses = @businesses.where("educode_sales_businesses.id in (?) or educode_sales_businesses.staff_id = ?", ids, @current_admin.id)
284
+ end
285
+ end
286
+
287
+ # 商机变化
288
+ if params[:q][:clazz_changes].present?
289
+ clazz_changes = EducodeSales::BusinessClazzChange.clazz_changes_value[params[:q][:clazz_changes].to_s]
290
+ @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)
291
+ end
292
+
293
+ if params[:sort].present? && params[:sort][:field]
294
+ if params[:sort][:field] == "service_end_time"
295
+ @businesses = @businesses.order("service_time_long #{params[:sort][:order]}")
296
+ else
297
+ @businesses = @businesses.order("#{params[:sort][:field]} #{params[:sort][:order]}")
298
+ end
299
+ else
300
+ @businesses = @businesses.order("educode_sales_businesses.created_at desc")
301
+ end
302
+
303
+ @business_count = @businesses.distinct.count
304
+ # mysql -select
305
+ @businesses = @businesses.select("
306
+ distinct
307
+ educode_sales_businesses.*,
308
+ last_follow.invitation_at,
309
+ last_follow.budget_amount,
310
+ last_follow.o_business_deployment,
311
+ last_follow.service_time_long,
312
+ last_follow.service_end_time,
313
+ last_follow.service_start_time,
314
+ last_follow.reception_at,
315
+ last_follow.bidded_date,
316
+ last_follow.signed_date,
317
+ last_follow.year,
318
+ last_follow.created_at as latest_time,
319
+ last_follow.actual_amount,
320
+ last_follow.divide_rate,
321
+ last_follow.divide_amount,
322
+ (last_follow.total_amount - last_follow.actual_amount) as divide_money,
323
+ (last_follow.actual_amount - educode_sales_businesses.return_money) as wait_return_money,
324
+ last_follow.total_amount,
325
+ total_follow_ups.follow_ups_counts
326
+ ").joins("
327
+ LEFT JOIN educode_sales_follow_ups AS last_follow ON educode_sales_businesses.last_follow_up_id = last_follow.id AND last_follow.deleted_at IS NULL
328
+ LEFT JOIN (
329
+ SELECT COUNT(*) AS follow_ups_counts, educode_sales_follow_ups.business_id
330
+ FROM educode_sales_follow_ups
331
+ WHERE educode_sales_follow_ups.deleted_at IS NULL
332
+ GROUP BY educode_sales_follow_ups.business_id
333
+ ) AS total_follow_ups ON educode_sales_businesses.id = total_follow_ups.business_id
334
+ ").includes(:users, last_follow_up: [:clazz, :assign_follow_ups]).page(params[:page]).per(params[:limit])
335
+
336
+ end
337
+
338
+ end
339
+ end
340
+
341
+ def detail
342
+ staffs = Staff.where.not(role_id: 11).includes(:user)
343
+ gon.staffs = staffs.map { |d| { name: d.user.real_name, value: d.id } }
344
+ gon.staff_value = @project.p_staff_id ? [{ name: @project.p_staff&.user&.real_name, value: @project.p_staff_id }] : []
345
+ gon.sale_staff_value = @project.p_sale_staff_id ? [{ name: @project.p_sale_staff&.user&.real_name, value: @project.p_sale_staff_id }] : []
346
+ render layout: false
347
+ end
348
+
349
+ def history
350
+ render layout: false
351
+ end
352
+
353
+ def update
354
+ @project.assign_attributes(project_params)
355
+ check_changes
356
+ @project.save
357
+ render_success
358
+ end
359
+
360
+ def destroy
361
+ @project.p_soft_destroy(current_user.id)
362
+ render_success
363
+ end
364
+
365
+ def edit
366
+ staffs = Staff.where.not(role_id: 11).includes(:user)
367
+ gon.staffs = staffs.map { |d| { name: d.user.real_name, value: d.id } }
368
+ gon.staff_value = @project.p_staff_id ? [{ name: @project.p_staff&.user&.real_name, value: @project.p_staff_id }] : []
369
+ gon.sale_staff_value = @project.p_sale_staff_id ? [{ name: @project.p_sale_staff&.user&.real_name, value: @project.p_sale_staff_id }] : []
370
+ render layout: false
371
+ end
372
+
373
+ def recycle
374
+ @project.p_recycle
375
+ render_success
376
+ end
377
+
378
+ private
379
+
380
+ def project_params
381
+ permit =
382
+ %i[p_stage p_difficulty p_special
383
+ p_status p_staff_id p_sale_staff_id
384
+ p_course_time p_platform_time p_deploy_time
385
+ p_accept_time p_pre_money_time p_actual_money_time
386
+ p_money p_content p_pre_accept_time]
387
+
388
+ params.permit(permit)
389
+
390
+ end
391
+
392
+ def find_project
393
+ @project = Business.find(params[:id])
394
+ end
395
+
396
+ def check_changes
397
+ unless @project.new_record?
398
+ history = []
399
+ except_attr = %i[id staff_id department_id name created_at updated_at follow_ups_count last_follow_up_id return_money source deleted_at school_id number clazz_id delete_reason auth_desc state_id p_deleted_at p_deleter_id]
400
+ arr = @project.attributes.except(except_attr).keys
401
+ arr.each do |attr|
402
+ if @project.send("#{attr}_changed?")
403
+ old_value, new_value = @project.send("#{attr}_was"), @project.send(attr)
404
+ res = Project.save_history(attr, old_value, new_value)
405
+ history << res if res
406
+ end
407
+ end
408
+ @project.business_histories.create(content: history, staff: current_user) if history.present?
409
+ end
410
+ end
411
+
412
+ def edu_setting name
413
+ EduSetting.get(name)
414
+ end
415
+
416
+ def follow_business(user_id, business_id)
417
+ BusinessRelationShip.where(user_id: user_id, business_id: business_id).first
418
+ end
419
+ end
420
+ 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' }])
19
+ role.role_areas.build([{ clazz: 'Business' }, { 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
@@ -90,6 +90,9 @@ module EducodeSales
90
90
  r = role.role_areas.find_or_initialize_by(clazz: 'Idea')
91
91
  r.level = params[:idea]
92
92
  r.save
93
+ r = role.role_areas.find_or_initialize_by(clazz: 'Project')
94
+ r.level = params[:project]
95
+ r.save
93
96
  render_success
94
97
  end
95
98
 
@@ -24,12 +24,12 @@ module EducodeSales
24
24
  common = Common.find_by(clazz: 'staff_type', name: '运营')
25
25
  role = EducodeSales::Role.find_by(name: '生态经理')
26
26
  if role
27
- @staff_manage = Staff.joins(:user).where(role_id: role.id).map { |d| [d.user.real_name, d.id]}
27
+ @staff_manage = Staff.includes(:user).where(role_id: role.id).map { |d| [d.user.real_name, d.id]}
28
28
  else
29
29
  @staff_manage = Staff.none
30
30
  end
31
-
32
- @staffs = Staff.joins(:user).where(job_type: common.id).map { |d| [d.user.real_name, d.id]}
31
+ @follow_upers = Staff.includes(:user).map { |d| [d.user.real_name, d.id]}
32
+ @staffs = Staff.includes(:user).where(job_type: common.id).map { |d| [d.user.real_name, d.id]}
33
33
  @more = can?(:create, EducodeSales::OperationPlan) || can?(:update, EducodeSales::Teacher) || can?(:destroy, EducodeSales::Teacher)
34
34
  gon.menus = []
35
35
  if can?(:create, EducodeSales::OperationPlan)
@@ -70,6 +70,8 @@ module EducodeSales
70
70
  end
71
71
  end
72
72
 
73
+ @teachers = @teachers.includes(department: [:department_majors, :school])
74
+
73
75
  if @current_admin.job_type == Common.find_by(clazz: 'staff_type', name: '销售').id
74
76
  public_teacher_ids = EducodeSales::Teacher.where(staff_id: 0).pluck(:id) - EducodeSales::TeacherAssignFollow.where(staff_id: @current_admin.id).pluck(:teacher_id)
75
77
  @teachers = @teachers.where.not(id: public_teacher_ids)
@@ -131,16 +133,39 @@ module EducodeSales
131
133
  @teachers = @teachers.where("educode_sales_teachers.created_at > ? AND educode_sales_teachers.created_at < ?", date[0], date[1])
132
134
  end
133
135
 
134
- @teachers = @teachers.select("
135
- educode_sales_teachers.*,
136
- users.created_on,
137
- last_follow.created_at as latest_time,
138
- users.grade,
139
- users.experience,
140
- users.last_login_on").joins("
141
- LEFT JOIN users ON educode_sales_teachers.user_id = users.id
142
- LEFT JOIN educode_sales_teacher_follows AS last_follow ON last_follow.teacher_id = educode_sales_teachers.id AND last_follow.deleted_at IS NULL
143
- ")
136
+ if params[:q].present? && params[:q][:staff_manage].present?
137
+ staff = Staff.find(params[:q][:staff_manage])
138
+ school_ids = School.where(province: staff.areas.pluck(:name)).pluck(:id)
139
+ teacher_ids = EducodeSales::Teacher.joins("JOIN departments ON educode_sales_teachers.department_id = departments.id").where("departments.school_id in (?)", school_ids).pluck(:id)
140
+ @teachers = @teachers.where(id: teacher_ids)
141
+ end
142
+
143
+
144
+
145
+ if params[:q].present? && params[:q][:staff_id].present?
146
+ @teachers = @teachers.select("
147
+ educode_sales_teachers.*,
148
+ users.created_on,
149
+ last_follow.created_at as latest_time,
150
+ users.grade,
151
+ users.experience,
152
+ users.last_login_on").joins("
153
+ JOIN educode_sales_teacher_follows AS last_follow ON last_follow.id = educode_sales_teachers.follow_up_id AND last_follow.deleted_at IS NULL
154
+ LEFT JOIN users ON educode_sales_teachers.user_id = users.id
155
+ ")
156
+ @teachers = @teachers.where("last_follow.staff_id = ?", params[:q][:staff_id].to_i)
157
+ else
158
+ @teachers = @teachers.select("
159
+ educode_sales_teachers.*,
160
+ users.created_on,
161
+ last_follow.created_at as latest_time,
162
+ users.grade,
163
+ users.experience,
164
+ users.last_login_on").joins("
165
+ LEFT JOIN users ON educode_sales_teachers.user_id = users.id
166
+ LEFT JOIN educode_sales_teacher_follows AS last_follow ON last_follow.id = educode_sales_teachers.follow_up_id AND last_follow.deleted_at IS NULL
167
+ ")
168
+ end
144
169
  if params[:sort].present? && params[:sort][:field]
145
170
  @teachers = @teachers.order("#{params[:sort][:field]} #{params[:sort][:order]}")
146
171
  else
@@ -19,6 +19,7 @@ module EducodeSales
19
19
  File.join("images/avatars", ["#{source&.class}", "#{source&.id}"]) + "?t=#{ctime}"
20
20
  end
21
21
  elsif source.class.to_s == 'User'
22
+
22
23
  str = source.user_extension.try(:gender).to_i == 0 ? "b" : "g"
23
24
  File.join(relative_path, "#{source.class}", str)
24
25
  elsif source.class.to_s == 'Subject'
@@ -1,25 +1,34 @@
1
1
  module EducodeSales
2
2
  class Business < ApplicationRecord
3
3
 
4
- validates_uniqueness_of :number ,allow_nil: true
4
+ validates_uniqueness_of :number, allow_nil: true
5
5
 
6
6
  belongs_to :clazz, class_name: 'Common'
7
7
  belongs_to :staff
8
8
  belongs_to :department
9
9
  belongs_to :last_follow_up, class_name: 'FollowUp', optional: true # 允许last_follow_up_id字段中的数为nil
10
10
 
11
+ belongs_to :p_staff, class_name: 'Staff', optional: true
12
+ belongs_to :p_sale_staff, class_name: 'Staff', optional: true
13
+ belongs_to :p_deleter, class_name: 'Staff', optional: true
14
+
11
15
  has_many :sale_plans
12
16
  has_many :follow_ups
13
17
  has_many :business_clazz_changes
14
18
  has_many :business_levels, dependent: :destroy
15
19
  has_many :business_watches, dependent: :destroy
20
+ has_many :business_histories, dependent: :destroy
16
21
 
17
- #关联关注
18
- has_many :users,:class_name => 'EducodeSales::BusinessRelationShip',foreign_key: 'business_id',:dependent => :destroy
22
+ # 关联关注
23
+ has_many :users, :class_name => 'EducodeSales::BusinessRelationShip', foreign_key: 'business_id', :dependent => :destroy
19
24
 
20
- #每次查询时 默认的查询条件
21
- default_scope -> {where(deleted_at: nil)}
25
+ # 每次查询时 默认的查询条件
26
+ default_scope -> { where(deleted_at: nil) }
22
27
 
28
+ enum p_stage: %w[合同阶段 验收阶段 回款阶段]
29
+ enum p_difficulty: %w[困难 适中 容易]
30
+ enum p_special: %w[是 否]
31
+ enum p_status: %w[未完成 已完成]
23
32
 
24
33
  def soft_destroy(user_id)
25
34
  self.update(deleted_at: Time.now, state_id: 2)
@@ -30,6 +39,13 @@ module EducodeSales
30
39
  EducodeSales::Recycle.create(source: self, deleter_id: user_id)
31
40
  end
32
41
 
42
+ def p_soft_destroy(staff_id)
43
+ self.update(p_deleted_at: Time.now, p_deleter_id: staff_id)
44
+ end
45
+
46
+ def p_recycle
47
+ self.update(p_deleted_at: nil, p_deleter_id: nil)
48
+ end
33
49
 
34
50
  def self.include_types(type)
35
51
  {
@@ -0,0 +1,8 @@
1
+ module EducodeSales
2
+ class BusinessHistory < ApplicationRecord
3
+ belongs_to :business
4
+ belongs_to :staff
5
+
6
+ serialize :content, Array
7
+ end
8
+ end
@@ -14,7 +14,8 @@ module EducodeSales
14
14
  '客户管理': 'customer',
15
15
  '回款管理': 'money_plan',
16
16
  '绩效考核': 'assessments_setting',
17
- '方案管理': 'idea'
17
+ '方案管理': 'idea',
18
+ '项目管理': 'project'
18
19
  }
19
20
  end
20
21
  end
@@ -0,0 +1,53 @@
1
+ module EducodeSales
2
+ class Project < ApplicationRecord
3
+ self.table_name = "educode_sales_businesses"
4
+
5
+ enum p_stage: %w[合同阶段 验收阶段 回款阶段]
6
+ enum p_difficulty: %w[困难 适中 容易]
7
+ enum p_special: %w[是 否]
8
+ enum p_status: %w[未完成 已完成]
9
+
10
+ def self.save_history(attr, old_value, new_value)
11
+ # old_value = St.find_by(id: old_value)&.name
12
+ # new_value = Department.find_by(id: new_value)&.name
13
+ case attr
14
+ when "p_stage"
15
+ "项目阶段由“#{old_value}”变更为“#{new_value}”"
16
+ when "p_difficulty"
17
+ "项目难度由“#{old_value}”变更为“#{new_value}”"
18
+ when "p_special"
19
+ "定制由“#{old_value}”变更为“#{new_value}”"
20
+ when "p_status"
21
+ "交付由“#{old_value}”变更为“#{new_value}”"
22
+ when "p_staff_id"
23
+ old_value = Staff.find_by(id: old_value)&.user&.real_name
24
+ new_value = Staff.find_by(id: new_value)&.user&.real_name
25
+ "指派人由“#{old_value}”变更为“#{new_value}”"
26
+ when "p_sale_staff_id"
27
+ old_value = Staff.find_by(id: old_value)&.user&.real_name
28
+ new_value = Staff.find_by(id: new_value)&.user&.real_name
29
+ "销售经理由“#{old_value}”变更为“#{new_value}”"
30
+ when "p_course_time"
31
+ "课程交付时间由“#{old_value}”变更为“#{new_value}”"
32
+ when "p_platform_time"
33
+ "平台交付时间由“#{old_value}”变更为“#{new_value}”"
34
+ when "p_deploy_time"
35
+ "现场部署时间由“#{old_value}”变更为“#{new_value}”"
36
+ when "p_accept_time"
37
+ "实际验收时间由“#{old_value}”变更为“#{new_value}”"
38
+ when "p_pre_money_time"
39
+ "拟定回款时间由“#{old_value}”变更为“#{new_value}”"
40
+ when "p_actual_money_time"
41
+ "实际回款时间由“#{old_value}”变更为“#{new_value}”"
42
+ when "p_money"
43
+ "回款由“#{old_value}”变更为“#{new_value}”"
44
+ when "p_content"
45
+ "问题备注由“#{old_value}”变更为“#{new_value}”"
46
+ when "p_pre_accept_time"
47
+ "预计验收时间由“#{old_value}”变更为“#{new_value}”"
48
+ else
49
+ nil
50
+ end
51
+ end
52
+ end
53
+ end
@@ -11,7 +11,8 @@ module EducodeSales
11
11
  '客户管理': 'Customer',
12
12
  '回款管理': 'MoneyPlan',
13
13
  '绩效考核': 'AssessmentsSetting',
14
- '方案管理': 'Idea'
14
+ '方案管理': 'Idea',
15
+ '项目管理': 'Project'
15
16
  }
16
17
  end
17
18
  end