educode_sales 0.9.75 → 0.9.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3360ea7a50189fd2b8954d7111e05c3e2592d403072661f4eca95a7f1a0ef3e1
4
- data.tar.gz: af8e512e5f7e91c7eb8a211406817f19701311b205ed191982abae08cfc536dd
3
+ metadata.gz: ec6bd4aff88d498d4b416ae1a654e7e0d391a1438b3dc3358ab9d0c44e843355
4
+ data.tar.gz: 3b83113b2949c8b7ea4faf3b029a367ecf994b6a42492b67111c5b6bb6539eb6
5
5
  SHA512:
6
- metadata.gz: df64d18c074d376248f60469c2b0dcac72eafeff9b145420bfc8aa3f9b88e610471e686263a1b26cee7d2096a4094cf533c2af3a0182134c39157aeacb57a60a
7
- data.tar.gz: c3dac636495d444ac104ff6b4fdd7f65844645120127e0b1b2ccd4fe1a7a70e287dddb4e8238ef1f7b9a4c080b4aef83d8ff620d292e0c62085d793d619ad23f
6
+ metadata.gz: 99d66d74810cd737a62330d5b69782fbcf3c26a9e087fb7859c53f37c6eb5187f03f2692afd67f23060be03c3baa397e0928da12202d3d59b55314844fac6dc0
7
+ data.tar.gz: f997afa839cf458d0bbcdbedf8aa4a564c512499092c4cc9597449d9c8a9b39e3d1825f3a45ac1f777a453b9467da4fbf698b743a86804c06d010de81170cd86
@@ -47,13 +47,15 @@ module EducodeSales
47
47
  level = @current_admin.role.role_areas.find_by(clazz: '合同管理').level
48
48
  case level
49
49
  when '自己'
50
- @businesses = @businesses.where("educode_sales_businesses.staff_id = ?", @current_admin.id)
50
+ assign_business_ids = EducodeSales::Business.joins(:assign_staffs).where("educode_sales_assign_staffs.staff_id = ?", @current_admin.id).pluck(:id)
51
+
52
+ @businesses = @businesses.where("educode_sales_businesses.staff_id = ? OR educode_sales_businesses.id in (?)", @current_admin.id, assign_business_ids)
51
53
  when '区域'
52
54
  school_ids = School.where(province: @current_admin.areas.pluck(:name)).pluck(:id) + StaffSchool.where(staff_id: @current_admin.id).pluck(:school_id)
53
- business_ids = Business.joins(last_follow_up: :assign_follow_ups).where("educode_sales_assign_follow_ups.staff_id = ?", @current_admin.id).pluck(:id)
54
- @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)
55
- business_ids = @businesses.pluck(:id)
56
- @businesses = @businesses.where(business_id: business_ids)
55
+ business_ids = @businesses.joins(last_follow_up: :assign_follow_ups).where("educode_sales_assign_follow_ups.staff_id = ?", @current_admin.id).pluck(:id)
56
+ assign_business_ids = EducodeSales::Business.joins(:assign_staffs).where("educode_sales_assign_staffs.staff_id = ?", @current_admin.id).pluck(:id)
57
+
58
+ @businesses = @businesses.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 + assign_business_ids)
57
59
  end
58
60
  end
59
61
 
@@ -162,7 +164,7 @@ module EducodeSales
162
164
 
163
165
  if params[:q].present? && params[:q][:after_sales_staff_id].present?
164
166
  # 售后工程师
165
- @businesses = @businesses.joins("LEFT JOIN educode_sales_assign_staffs ON educode_sales_assign_staffs.sourcable_type = 'EducodeSales::FollowUp' AND educode_sales_assign_staffs.sourcable_id = educode_sales_businesses.last_follow_up_id").
167
+ @businesses = @businesses.joins("LEFT JOIN educode_sales_assign_staffs ON educode_sales_assign_staffs.sourcable_type = 'EducodeSales::Business' AND educode_sales_assign_staffs.sourcable_id = educode_sales_businesses.id").
166
168
  where("educode_sales_assign_staffs.staff_id = ?", params[:q][:after_sales_staff_id])
167
169
 
168
170
  end
@@ -239,7 +241,7 @@ module EducodeSales
239
241
  contract_ids = Common.where(clazz: '商机阶段', name: ['已中标', '已签单', '已验收', '回款中', '服务中', '已结束']).pluck(:id)
240
242
  @follow_ups = FollowUp.joins("
241
243
  JOIN educode_sales_businesses ON educode_sales_follow_ups.business_id = educode_sales_businesses.id
242
- ").where("educode_sales_follow_ups.stage_id in (?)", contract_ids)
244
+ ").joins(:follow_up_trends).where("educode_sales_follow_ups.stage_id in (?)", contract_ids).select("educode_sales_follow_ups.*, educode_sales_follow_up_trends.clazz, educode_sales_follow_up_trends.content")
243
245
 
244
246
  if @current_admin.is_admin?
245
247
  @follow_ups = @follow_ups
@@ -283,6 +285,10 @@ module EducodeSales
283
285
 
284
286
  end
285
287
 
288
+ if params[:q].present? && params[:q][:info_clazz].present?
289
+ @follow_ups = @follow_ups.where("educode_sales_follow_up_trends.clazz = ?", params[:q][:info_clazz])
290
+ end
291
+
286
292
  @follow_ups = @follow_ups.includes(:staff, :clazz, :stage, key_person: :teacher, business: [department: :school])
287
293
 
288
294
  if params[:sort].present? && params[:sort][:field]
@@ -294,16 +300,96 @@ module EducodeSales
294
300
  end
295
301
 
296
302
  def add_follow_ups
297
- p params["1_promise_date"]
298
- p params["1_promise_date"].keys
299
- params["1_promise_date"].each do |d, v|
300
- p '-----22-'
301
- p d
302
- p v
303
+ data = []
304
+ 6.times do |i|
305
+ data[i] = []
306
+ params["#{i+1}_promise_date"].each do |d, v|
307
+ data[i] << [v]
308
+ end
309
+ params["#{i+1}_num"].each do |d, v|
310
+ data[i][d.to_i] << v
311
+ end
312
+ params["#{i+1}_plan_date"].each do |d, v|
313
+ data[i][d.to_i] << v
314
+ end
315
+ params["#{i+1}_actual_date"].each do |d, v|
316
+ data[i][d.to_i] << v
317
+ end
318
+ end
319
+ data.each do |d|
320
+ d.select! { |d| d.delete_if{|f| f == ''}.present? }
321
+ end
322
+
323
+ @business = Business.find(params[:business_id])
324
+ follow_up = @business.follow_ups.build(follow_up_params)
325
+ follow_up.stage = @business.last_follow_up.stage
326
+ follow_up.clazz = @business.last_follow_up.clazz
327
+ if params[:service_time].present?
328
+ date = params[:service_time].split(" - ")
329
+ follow_up.service_start_time = date[0]
330
+ follow_up.service_end_time = date[1]
331
+ follow_up.service_time_long = (date[1].to_date - date[0].to_date).to_i
332
+ end
333
+ follow_up.staff = @current_admin
334
+
335
+ last_follow_up = @business.last_follow_up
336
+
337
+ if follow_up.save!
338
+ contract_lists = EducodeSales::ContractDateList.clazzs.invert
339
+ data.each_with_index do |s, i|
340
+ if s.present?
341
+ s.each do |d|
342
+ follow_up.contract_date_lists.create!({promise_date: d[0], num: d[1], plan_date: d[2], actual_date: d[3], staff_id: @current_admin.id, clazz: contract_lists[i]})
343
+ end
344
+ end
345
+ end
346
+ follow_up.follow_up_trends.create(clazz: '跟进信息', content: params[:content], staff_id: @current_admin.id)
347
+ @business.update(last_follow_up_id: follow_up.id)
348
+ render_success
349
+ else
350
+ render_failure follow_up
351
+ end
352
+ end
353
+
354
+ def advise
355
+ followup = FollowUp.find(params[:id])
356
+ followup.follow_up_trends.create(clazz: '建议信息', content: params[:content], staff_id: @current_admin.id)
357
+ render_success
358
+ end
359
+
360
+ def assign
361
+ common = Common.find_by(clazz: 'staff_type', name: '销售')
362
+ staffs = Staff.joins(:user).where(job_type: common.id).where.not(role_id: 11)
363
+ gon.sales_staffs = staffs.map { |d| {name: d.user.real_name, value: d.id } }
364
+ render layout: false
365
+ end
366
+
367
+ def product_list
368
+ respond_to do |format|
369
+ format.html do
370
+
371
+ end
372
+ format.js do
373
+ common = Common.find_by(clazz: 'staff_type', name: '销售')
374
+ staffs = Staff.joins(:user).where(job_type: common.id).where.not(role_id: 11)
375
+ @staffs = staffs.map { |d| [d.user.real_name, d.id]}
376
+ end
377
+ format.json do
378
+ end
303
379
  end
380
+ end
304
381
 
382
+ def assign_staff
383
+ @business = Business.find(params[:id])
384
+ params[:to_id].split(",").each do |i|
385
+ @business.assign_staffs.create({staff_id: i})
386
+ end
305
387
  render_success
306
388
  end
307
389
 
390
+ private
391
+ def follow_up_params
392
+ params.permit(:o_business_deployment, :plan_signed_date, :bidded_days, :signed_date, :signed_department_id, :service_years, :service_start_time, :service_end_time, :funding_source)
393
+ end
308
394
  end
309
395
  end
@@ -19,6 +19,8 @@ module EducodeSales
19
19
  has_many :business_watches, dependent: :destroy
20
20
  has_many :business_histories, dependent: :destroy
21
21
 
22
+ has_many :assign_staffs, as: :sourcable # 售后人员
23
+
22
24
  # 关联关注
23
25
  has_many :users, :class_name => 'EducodeSales::BusinessRelationShip', foreign_key: 'business_id', :dependent => :destroy
24
26
 
@@ -2,5 +2,7 @@ module EducodeSales
2
2
  class ContractDateList < ApplicationRecord
3
3
  belongs_to :follow_up
4
4
  belongs_to :staff
5
+
6
+ enum clazz: ['交货', '验收', '预收款', '交付款', '验收款', '质保金']
5
7
  end
6
8
  end
@@ -15,6 +15,7 @@ module EducodeSales
15
15
  include ::Deletable
16
16
  belongs_to :business, counter_cache: true # counter_cache(自动计算 business对应follow_up表中对应的个数)
17
17
  belongs_to :place, optional: true
18
+ belongs_to :signed_department, class_name: 'Department', optional: true
18
19
  has_many :money_plans
19
20
  has_many :key_person
20
21
  has_many :teachers, through: :key_person
@@ -23,7 +24,8 @@ module EducodeSales
23
24
  belongs_to :stage, class_name: 'Common'
24
25
  belongs_to :clazz, class_name: 'Common'
25
26
 
26
- has_many :assign_staffs, as: :sourcable # 售后人员
27
+ has_many :follow_up_trends
28
+ has_many :contract_date_lists
27
29
 
28
30
 
29
31
  default_scope -> {where(deleted_at: nil)}
@@ -0,0 +1,8 @@
1
+ module EducodeSales
2
+ class FollowUpTrend < ApplicationRecord
3
+ belongs_to :follow_up
4
+ belongs_to :staff
5
+
6
+ enum clazz: ['跟进信息', '建议信息', '评论信息', '审核信息']
7
+ end
8
+ end
@@ -28,7 +28,7 @@
28
28
  <div class="layui-inline">
29
29
  <label class="layui-form-label">信息类型</label>
30
30
  <div class="layui-input-inline">
31
- <%= select_tag "info_clazz", options_for_select(EducodeSales::FollowUp::InfoClazz), { include_blank: true } %>
31
+ <%= select_tag "info_clazz", options_for_select(EducodeSales::FollowUp::InfoClazz.each_with_index.map { |d, i| [d, i] }), { include_blank: true } %>
32
32
  </div>
33
33
  </div>
34
34
  <div class="layui-inline">
@@ -129,9 +129,8 @@
129
129
  },
130
130
  {
131
131
  field: 'signed_department',
132
- width: 120,
133
- title: '签约单位',
134
- templet:'#signed_department'
132
+ width: 160,
133
+ title: '签约单位'
135
134
  },
136
135
  {
137
136
  field: 'stage',
@@ -145,8 +144,8 @@
145
144
  title: '销售经理',
146
145
  },
147
146
  {
148
- field: 'infoclazz',
149
- width: 80,
147
+ field: 'clazz',
148
+ width: 100,
150
149
  title: '信息类型',
151
150
  },
152
151
  {
@@ -288,14 +287,14 @@
288
287
  type: 1,
289
288
  area: '400px;',
290
289
  id: 'LAY_layuipro',
291
- content: '<div class="layui-form" lay-filter="edit_project" style="padding: 20px;"><textarea autocomplete="off" type="text" name="name" lay-verify="required" class="layui-textarea">' + data.advise + '</textarea></div>' ,
290
+ content: '<div class="layui-form" lay-filter="edit_project" style="padding: 20px;"><textarea autocomplete="off" type="text" name="name" lay-verify="required" class="layui-textarea"></textarea></div>' ,
292
291
  btn: ['保存', '取消'],
293
292
  btn1: function(index, l) {
294
293
  if (l.find("textarea").val().trim() == '') {
295
294
  layer.msg('内容不能为空')
296
295
  return false;
297
296
  } else {
298
- request.authPut("/missions/follow_ups/" + data.id + "/update_advise", {content: l.find("textarea").val().trim()}, function(res) {
297
+ request.authPost("/missions/contracts/" + data.id + "/advise", {content: l.find("textarea").val().trim()}, function(res) {
299
298
  if (res.success == false) {
300
299
  layer.alert(res.msg);
301
300
  } else {
@@ -265,6 +265,11 @@
265
265
  templet: '<div><a href="javascript:void(0);" class="layui-table-link" lay-event="show_business"><span title="{{d.name}}">{{d.name}}</span></a></div>',
266
266
  fixed: 'left',
267
267
  },
268
+ {
269
+ field: 'name',
270
+ width: 120,
271
+ title: '合同名称',
272
+ },
268
273
  {
269
274
  field: 'area',
270
275
  width: 100,
@@ -543,7 +548,7 @@
543
548
  business_id = data.id
544
549
  var content = miniPage.getHrefContent('/missions/contracts/new_follow_up?id=' + data.id);
545
550
  var openWH = miniPage.getOpenWidthHeight();
546
- sale_plan_index = layer.open({
551
+ new_follow_index = layer.open({
547
552
  title: '添加合同跟进记录',
548
553
  type: 1,
549
554
  shade: 0.2,
@@ -557,19 +562,19 @@
557
562
  }
558
563
  });
559
564
  $(window).on("resize", function () {
560
- layer.full(sale_plan_index);
565
+ layer.full(new_follow_index);
561
566
  });
562
567
  } else if (obj.event === 'assign') {
563
- var content = miniPage.getHrefContent('/missions/businesses/' + id + '/edit');
568
+ var content = miniPage.getHrefContent('/missions/contracts/' + id + '/assign');
564
569
  var openWH = miniPage.getOpenWidthHeight();
570
+ name = data.name;
565
571
  sindex = layer.open({
566
- title: '编辑',
572
+ title: '指派合同【' + name + "】售后工程师",
567
573
  type: 1,
568
574
  shade: 0.2,
569
575
  maxmin: true,
570
576
  shadeClose: true,
571
- area: [openWH[0] + 'px', openWH[1] + 'px'],
572
- offset: [openWH[2] + 'px', openWH[3] + 'px'],
577
+ area: ['600px', '600px'],
573
578
  content: content
574
579
  });
575
580
  $(window).on("resize", function () {
@@ -0,0 +1,358 @@
1
+ <div class="min-height-table" id="product_list">
2
+ <div style="margin: 10px 10px 10px 10px">
3
+ <form class="layui-form layui-form-pane" lay-filter="search_form">
4
+ <div class="layui-form-item">
5
+ <div class="layui-inline">
6
+ <label class="layui-form-label">合同名称</label>
7
+ <div class="layui-input-inline">
8
+ <input type="text" name="name" class="layui-input" value="">
9
+ </div>
10
+ </div>
11
+ <div class="layui-inline">
12
+ <label class="layui-form-label">用户单位</label>
13
+ <div class="layui-input-inline">
14
+ <input type="text" name="department" value="" class="layui-input">
15
+ </div>
16
+ </div>
17
+ <div class="layui-inline">
18
+ <label class="layui-form-label">签约单位</label>
19
+ <div class="layui-input-inline">
20
+ <input type="text" name="assign_department" value="" class="layui-input">
21
+ </div>
22
+ </div>
23
+ <div class="layui-inline">
24
+ <label class="layui-form-label">销售经理</label>
25
+ <div class="layui-input-inline">
26
+ <%= select_tag "sales_staff_id", options_for_select(@staffs, params[:staff_id]), { 'lay-filter': 'staff_id', include_blank: true , "lay-search": "" } %>
27
+ </div>
28
+ </div>
29
+ <div class="layui-inline show_item_contract">
30
+ <label class="layui-form-label">区域</label>
31
+ <div class="layui-input-inline">
32
+ <%= select_tag "area", options_for_select(EducodeSales::Common.where(clazz: 'area').pluck(:name, :id)), { include_blank: true } %>
33
+ </div>
34
+ </div>
35
+ <div class="layui-inline show_item_contract">
36
+ <label class="layui-form-label">项目阶段</label>
37
+ <div class="layui-input-inline">
38
+ <div id="contract_business_step" style="width: 190px;"></div>
39
+ </div>
40
+ </div>
41
+ <div class="layui-inline show_item_contract">
42
+ <label class="layui-form-label">渠道名称</label>
43
+ <div class="layui-input-inline">
44
+ <div id="contract_index_place" style="width: 190px;"></div>
45
+ </div>
46
+ </div>
47
+ <div class="layui-inline show_item_contract">
48
+ <label class="layui-form-label">中标时间</label>
49
+ <div class="layui-input-inline">
50
+ <input type="text" class="layui-input" id="bidded_date" name="bidded_date" placeholder=" - " autocomplete="off">
51
+ </div>
52
+ </div>
53
+ <div class="layui-inline show_item_contract">
54
+ <label class="layui-form-label">签单时间</label>
55
+ <div class="layui-input-inline">
56
+ <input type="text" class="layui-input" id="signed_date" name="signed_date" placeholder=" - " autocomplete="off">
57
+ </div>
58
+ </div>
59
+ <div class="layui-inline">
60
+ <button type="reset" class="layui-btn layui-btn-primary" lay-submit lay-filter="reset_business_search">重置
61
+ </button>
62
+ <button type="submit" id="search_bt" class="layui-btn layui-btn-primary" lay-submit lay-filter="search_bussiness_contract">搜索
63
+ </button>
64
+ </div>
65
+ </div>
66
+ </form>
67
+ </div>
68
+ <div id="contact_table_wraper">
69
+ <table class="layui-hide" id="contact_product_table" lay-filter="contact_product_table"></table>
70
+ </div>
71
+ </div>
72
+
73
+ <script type="text/html" id="currentTableBarProduct">
74
+ <a class="layui-btn layui-btn-normal layui-btn-xs data-count-edit" lay-event="add_product">添加销售目录</a>
75
+ </script>
76
+
77
+
78
+ <script>
79
+ layui.use(['form', 'table', 'miniPage', 'element', 'request', 'laydate', 'dropdown','laytpl', 'xmSelect'], function () {
80
+ var $ = layui.jquery,
81
+ form = layui.form,
82
+ request = layui.request,
83
+ miniPage = layui.miniPage,
84
+ dropdown = layui.dropdown,
85
+ xmSelect = layui.xmSelect,
86
+ laydate = layui.laydate;
87
+ var openWH = miniPage.getOpenWidthHeight();
88
+ laydate.render({
89
+ elem: '#date',
90
+ range: true
91
+ });
92
+
93
+ laydate.render({
94
+ elem: '#invitation_at',
95
+ range: true
96
+ });
97
+
98
+ laydate.render({
99
+ elem: '#bidded_date',
100
+ range: true,
101
+ value: gon.bidded_date
102
+ });
103
+ laydate.render({
104
+ elem: '#signed_date',
105
+ range: true,
106
+ value: gon.signed_date
107
+ });
108
+
109
+ laydate.render({
110
+ elem: '#date_at',
111
+ range: true,
112
+ value: gon.date_at
113
+ });
114
+
115
+
116
+ var business_type_list = xmSelect.render({
117
+ el: '#contract_business_type',
118
+ data: gon.business_type
119
+ })
120
+
121
+
122
+ var business_step_list = xmSelect.render({
123
+ el: '#contract_business_step',
124
+ data: gon.business_step
125
+ })
126
+
127
+ var index_place_list = xmSelect.render({
128
+ el: '#contract_index_place',
129
+ model: {
130
+ icon: 'hidden',
131
+ label: {
132
+ type: 'text',
133
+ text: {
134
+ //左边拼接的字符
135
+ left: '',
136
+ //右边拼接的字符
137
+ right: '',
138
+ //中间的分隔符
139
+ separator: ', ',
140
+ },
141
+ }
142
+ },
143
+ remoteSearch: true,
144
+ clickClose: true,
145
+ delay: 1000,
146
+ paging: true,
147
+ radio: true,
148
+ pageRemote: true,
149
+ filterable: true,
150
+ remoteMethod: function (val, cb, show, pageIndex) {
151
+ $.ajax( '/missions/sales_place', {
152
+ method: 'get',
153
+ data: {
154
+ q: val,
155
+ page: pageIndex
156
+ },
157
+ dataType: 'json',
158
+ success: function (res) {
159
+ var data = res.data;
160
+ if (res.code == 0) {
161
+ cb(res.data, res.count);
162
+ } else {
163
+ layer.msg(res.msg, {time: 2000, icon: 2, shade: 0.01});
164
+ }
165
+ }
166
+ })
167
+ }
168
+ })
169
+ index_place_list.setValue(gon.place)
170
+
171
+
172
+ var data = form.val("search_form");
173
+ table = layui.table;
174
+ var cols_table = [
175
+ [
176
+ {
177
+ field: 'id',
178
+ width: 60,
179
+ title: '序号', type: 'numbers',
180
+ totalRowText: '合计',
181
+ fixed: "left"
182
+ },
183
+ {
184
+ field: 'number',
185
+ width: 120,
186
+ title: '编号',
187
+ fixed: 'left',
188
+ },
189
+ {
190
+ field: 'name',
191
+ width: 120,
192
+ title: '合同名称',
193
+ },
194
+ {
195
+ field: 'area',
196
+ width: 100,
197
+ title: '地域',
198
+ },
199
+ {
200
+ field: 'school',
201
+ width: 150,
202
+ title: '用户单位',
203
+ templet: '#school_name',
204
+ },
205
+ {
206
+ field: 'property',
207
+ width: 150,
208
+ title: '客户类型',
209
+ },
210
+ {
211
+ field: 'department',
212
+ width: 150,
213
+ title: '部门',
214
+ templet: '<div><span title="{{d.department}}">{{d.department}}</span></div>',
215
+ },
216
+ {
217
+ field: 'item_clazz',
218
+ width: 150,
219
+ title: '销售品目',
220
+ },
221
+ {
222
+ field: 'brand',
223
+ width: 150,
224
+ title: '品牌',
225
+ },
226
+ {
227
+ field: 'specification',
228
+ width: 150,
229
+ title: '规格',
230
+ },
231
+ {
232
+ field: 'supplier',
233
+ width: 150,
234
+ title: '供货商',
235
+ }
236
+ ]
237
+ ]
238
+
239
+ var business_table = table.render({
240
+ elem: '#contact_product_table',
241
+ url: '/missions/contracts',
242
+ autoSort: false,
243
+ where: {q: data},
244
+ defaultToolbar: ['filter'],
245
+ title: '合同数据表',
246
+ totalRow: true,//开启合并行
247
+ cols: cols_table,
248
+
249
+ limit: 20,
250
+ limits: [10,15,20,30,40,50,60,70,80,90],
251
+ page: true,
252
+ skin: 'line',
253
+ });
254
+
255
+
256
+ var sort = {}, search = data;
257
+
258
+ table.on('sort(contact_product_table)', function (obj) {
259
+ var data = form.val("search_form");
260
+ sort.field = obj.field;
261
+ sort.order = obj.type;
262
+ table.reload('contact_product_table', {
263
+ url: '/missions/businesses',
264
+ initSort: obj,
265
+ where: {
266
+ sort: sort,
267
+ q: search
268
+ }
269
+ });
270
+ })
271
+
272
+ // 监听搜索操作
273
+ form.on('submit(search_bussiness_contract)', function (data) {
274
+ if (search['clazz']) {
275
+ data.field['clazz'] = search['clazz']
276
+ }
277
+ search = data.field
278
+ table.reload('contact_product_table', {
279
+ url: '/missions/contracts',
280
+ page: {
281
+ curr: 1
282
+ },
283
+ where: {q: search, sort: sort}
284
+ }, 'data');
285
+
286
+ return false;
287
+ });
288
+
289
+ form.on('submit(reset_business_search)', function (data) {
290
+ var field = data.field;
291
+ form.val('search_form', {
292
+ name: '', department: '', staff_id: '', business_type: '', business_step: '',
293
+ place_id: '', date: '', area: '', invitation_at: '', business_year: '', number: ''
294
+ })
295
+ business_type_list.setValue([])
296
+ business_step_list.setValue([])
297
+ index_place_list.setValue([])
298
+ return false;
299
+ });
300
+
301
+ table.on('tool(contact_product_table)', function (obj) {
302
+ var data = obj.data;
303
+ id = data.id
304
+ if (obj.event === 'add_event') { // 监听添加操作
305
+ business_id = data.id
306
+ var content = miniPage.getHrefContent('/missions/contracts/new_follow_up?id=' + data.id);
307
+ var openWH = miniPage.getOpenWidthHeight();
308
+ new_follow_index = layer.open({
309
+ title: '添加合同跟进记录',
310
+ type: 1,
311
+ shade: 0.2,
312
+ maxmin: true,
313
+ shadeClose: true,
314
+ area: [openWH[0] + 'px', openWH[1] + 'px'],
315
+ offset: [openWH[2] + 'px', openWH[3] + 'px'],
316
+ content: content,
317
+ success: function (layero, index) {
318
+ form.render('select');
319
+ }
320
+ });
321
+ $(window).on("resize", function () {
322
+ layer.full(new_follow_index);
323
+ });
324
+ } else if (obj.event === 'assign') {
325
+ var content = miniPage.getHrefContent('/missions/contracts/' + id + '/assign');
326
+ var openWH = miniPage.getOpenWidthHeight();
327
+ name = data.name;
328
+ sindex = layer.open({
329
+ title: '指派合同【' + name + "】售后工程师",
330
+ type: 1,
331
+ shade: 0.2,
332
+ maxmin: true,
333
+ shadeClose: true,
334
+ area: ['600px', '600px'],
335
+ content: content
336
+ });
337
+ $(window).on("resize", function () {
338
+ layer.full(sindex);
339
+ });
340
+ return false;
341
+ }
342
+ });
343
+
344
+
345
+ });
346
+ </script>
347
+ <style>
348
+ .layui-table-tool-temp{
349
+ padding-right: 30px; !important;
350
+ }
351
+ .layui-table-fixed .layui-table-body {
352
+ height: auto!important;
353
+ }
354
+ .layui-table-fixed.layui-hide {
355
+ display: block!important;
356
+ }
357
+
358
+ </style>
@@ -0,0 +1,46 @@
1
+
2
+ <%= Gon::Base.render_data %>
3
+ <div class="layui-form layuimini-form" style="padding:30px">
4
+ <div class="layui-form-item">
5
+ <label class="layui-form-label required">选择售后工程师:</label>
6
+ <div class="layui-input-block" style="width: 300px">
7
+ <div id="sales_id"></div>
8
+ </div>
9
+ </div>
10
+ <hr>
11
+ <div class="layui-form-item">
12
+ <div class="layui-input-block">
13
+ <button class="layui-btn layui-btn-normal" lay-submit lay-filter="saveBtn">确认保存</button>
14
+ </div>
15
+ </div>
16
+ </div>
17
+
18
+ <script>
19
+ layui.use(['form', 'table', 'upload', 'laytpl', 'request', 'selectInput'], function () {
20
+ var form = layui.form,
21
+ layer = layui.layer,
22
+ table = layui.table,
23
+ laytpl = layui.laytpl,
24
+ request = layui.request,
25
+ $ = layui.$;
26
+
27
+ form.render();
28
+ staff_list_select = xmSelect.render({
29
+ el: '#sales_id',
30
+ data: gon.sales_staffs,
31
+ filterable: true,
32
+ radio: false,
33
+ })
34
+ var parentIndex = layer.index;
35
+ form.on('submit(saveBtn)', function (data) {
36
+ layer.confirm('确定指派合同【' + parent.name + "】售后工程师?", function (index) {
37
+ request.post('missions/contracts/' + parent.id +"/assign_staff", {to_id: staff_list_select.getValue('valueStr')}, function (res) {
38
+ layer.close(index);
39
+ layer.close(parentIndex)
40
+ // parent.table.reload('contact_table')
41
+ })
42
+ });
43
+ return false;
44
+ });
45
+ });
46
+ </script>
@@ -4,17 +4,15 @@ json.data do
4
4
  json.clazz d.clazz.name
5
5
  json.stage d.stage.name
6
6
  json.staff d.staff.user.real_name
7
- json.description d.description
8
- json.advise d.advise
7
+ json.clazz EducodeSales::FollowUpTrend.clazzs.invert[d['clazz']]
8
+ json.description d['content']
9
9
  json.school d.business.department&.school&.name
10
10
  json.school_id d.business.department&.school&.id
11
+ json.signed_department d.signed_department&.school&.name || ''
11
12
  json.created_at d.created_at.to_s
12
13
  json.business d.business.name
13
14
  json.business_id d.business.id
14
- json.rival d.rival || ''
15
15
  json.staff_manages d.business.last_follow_up&.assign_follow_ups.present? ? (d.business.last_follow_up.assign_follow_ups.map{ |d| d.staff.user.real_name}.join("、")) : d.business.staff&.user&.real_name
16
- # teacher_ids = d.key_person.pluck(:teacher_id)
17
- json.tel d.key_person.pluck(:tel).select { |d| d.present? }.join("、")
18
16
 
19
17
  end
20
18
  end
@@ -3,6 +3,7 @@
3
3
  <ul class="layui-tab-title">
4
4
  <li class="layui-this follows_li">跟进动态</li>
5
5
  <li class="contracts_list_li">合同列表</li>
6
+ <li class="contracts_product_li">产品目录</li>
6
7
  </ul>
7
8
  <div class="layui-tab-content">
8
9
  <div class="layui-tab-item follows_div layui-show">
@@ -11,6 +12,9 @@
11
12
  <div class="layui-tab-item contracts_list_div">
12
13
  <div id="contract_list_wraper"></div>
13
14
  </div>
15
+ <div class="layui-tab-item contracts_product_div">
16
+ <div id="contract_product_wraper"></div>
17
+ </div>
14
18
  </div>
15
19
  </div>
16
20
 
@@ -31,6 +35,8 @@
31
35
  element.on('tab(contract_tab)', function(data) {
32
36
  if (data.index == 1 && $("#contract_list").length == 0) {
33
37
  loadPage('/missions/contracts/list')
38
+ } else if (data.index == 2 && $("#product_list").length == 0) {
39
+ loadPage('/missions/contracts/product_list')
34
40
  }
35
41
  });
36
42
 
@@ -56,7 +56,7 @@ json.data do
56
56
  json.source d.source
57
57
  json.assign_follow_ups d.last_follow_up.present? ? d.last_follow_up.assign_follow_ups.pluck(:staff_id) : []
58
58
 
59
- json.assign_staffs d.last_follow_up&.assign_staffs.present? ? (d.last_follow_up.assign_staffs.map{ |d| d.staff.user.real_name}.join("、")) : ''
59
+ json.assign_staffs d.assign_staffs.map{ |d| d.staff.user.real_name}.join("、")
60
60
  json.current_staff_id @current_admin.id
61
61
  json.staff_id d.staff_id
62
62
  json.latest_time d.last_follow_up.present? ? d.last_follow_up.created_at.to_s : ''
@@ -94,7 +94,7 @@
94
94
  <div class="layui-inline">
95
95
  <label class="layui-form-label">项目资金来源:</label>
96
96
  <div class="layui-input-inline" style="line-height: 38px;">
97
- <%= select_tag "o_business_deployment", options_for_select([''] + EducodeSales::FollowUp::funding_sources.keys, @last_follow_up&.funding_source), class: 'required' %>
97
+ <%= select_tag "funding_source", options_for_select([''] + EducodeSales::FollowUp::funding_sources.keys, @last_follow_up&.funding_source), class: 'required' %>
98
98
  </div>
99
99
  </div>
100
100
  <br>
@@ -120,7 +120,7 @@
120
120
  </div>
121
121
  </div>
122
122
  <div class="layui-inline">
123
- <label class="layui-form-label required" style="width:100px;">签约单位:</label>
123
+ <label class="layui-form-label" style="width:100px;">签约单位:</label>
124
124
  <div class="layui-input-inline" style="line-height: 38px;">
125
125
  <div id="add_department" style="width: 200px"></div>
126
126
  </div>
@@ -330,10 +330,10 @@
330
330
  </div>
331
331
  <div class="layui-form-mid layui-word-aux">年</div>
332
332
  </div>
333
- <div class="layui-form-item layui-form-text" style="margin-top:25px;">
333
+ <div class="layui-form-item layui-form-text required" style="margin-top:25px;">
334
334
  <label class="layui-form-label">最新根据记录:</label>
335
335
  <div class="layui-input-block">
336
- <textarea name="content" placeholder=" " class="layui-textarea"></textarea>
336
+ <textarea name="content" placeholder=" " class="layui-textarea" lay-verify="required"></textarea>
337
337
  </div>
338
338
  </div>
339
339
  <div class="layui-form-item m-t-20">
@@ -601,9 +601,9 @@
601
601
  })
602
602
 
603
603
 
604
- var add_department = selectInput.render({
604
+ var add_department_select = selectInput.render({
605
605
  elem: '#add_department',
606
- name: 'signed_department_id', // 渲染的input的name值
606
+ name: 'signed_departmen', // 渲染的input的name值
607
607
  layFilter: 'test', //同layui form参数lay-filter
608
608
  // layVerify: 'required', //同layui form参数lay-verify
609
609
  layVerType: 'tips', // 同layui form参数lay-verType
@@ -624,19 +624,9 @@
624
624
  });
625
625
 
626
626
  form.on('submit(add_follow_up)', function (data) {
627
- if (data.field.clazz_id == <%= EducodeSales::Common.where(extras: EducodeSales::Common::OTYPE).first&.id %>) {
628
- if (data.field.service_time.length == 0) {
629
- layer.msg('请选择服务期', {time: 2000, icon: 2, shade: 0.01});
630
- return false;
631
- }
632
- if (data.field.o_business_deployment === ''){
633
- layer.msg('请选择部署类型', {time: 2000, icon: 2, shade: 0.01});
634
- return false // 退出添加该条记录
635
- }
636
- }
637
627
  $(".submit-btn").addClass("layui-hide");
638
-
639
628
  data.field.business_id = "<%= @business.id %>";
629
+ data.field.signed_department_id = add_department_select.getValue(),
640
630
  Rails.ajax({
641
631
  url: "/missions/contracts/add_follow_ups",
642
632
  type: 'POST',
@@ -649,7 +639,7 @@
649
639
  if (res.success == false) {
650
640
  layer.alert(res.msg)
651
641
  } else {
652
-
642
+ layer.close(new_follow_index);
653
643
  }
654
644
  }
655
645
  })
@@ -0,0 +1 @@
1
+ $("#contract_product_wraper").html("<%= j render 'product_list' %>");
data/config/routes.rb CHANGED
@@ -28,6 +28,12 @@ EducodeSales::Engine.routes.draw do
28
28
  get :list
29
29
  get :new_follow_up
30
30
  post :add_follow_ups
31
+ get :product_list
32
+ end
33
+ member do
34
+ post :advise
35
+ get :assign
36
+ post :assign_staff
31
37
  end
32
38
  end
33
39
 
@@ -0,0 +1,12 @@
1
+ class CreateEducodeSalesFollowUpTrends < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :educode_sales_follow_up_trends do |t|
4
+ t.references :follow_up
5
+ t.integer :clazz
6
+ t.text :content
7
+ t.references :staff
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -1,3 +1,3 @@
1
1
  module EducodeSales
2
- VERSION = '0.9.75'
2
+ VERSION = '0.9.76'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: educode_sales
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.75
4
+ version: 0.9.76
5
5
  platform: ruby
6
6
  authors:
7
7
  - anke1460
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-05-01 00:00:00.000000000 Z
11
+ date: 2023-05-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -105,7 +105,6 @@ files:
105
105
  - app/assets/images/educode_sales/icon-login.png
106
106
  - app/assets/images/educode_sales/icon.png
107
107
  - app/assets/images/educode_sales/indexLogo.png
108
- - app/assets/images/educode_sales/indexlogo.png
109
108
  - app/assets/images/educode_sales/loading-0.gif
110
109
  - app/assets/images/educode_sales/loading-1.gif
111
110
  - app/assets/images/educode_sales/loading-2.gif
@@ -218,6 +217,7 @@ files:
218
217
  - app/models/educode_sales/eco_staff.rb
219
218
  - app/models/educode_sales/filter.rb
220
219
  - app/models/educode_sales/follow_up.rb
220
+ - app/models/educode_sales/follow_up_trend.rb
221
221
  - app/models/educode_sales/idea.rb
222
222
  - app/models/educode_sales/idea_follow.rb
223
223
  - app/models/educode_sales/idea_history.rb
@@ -307,11 +307,14 @@ files:
307
307
  - app/views/educode_sales/commons/show.json.jbuilder
308
308
  - app/views/educode_sales/contracts/_follows.html.erb
309
309
  - app/views/educode_sales/contracts/_list.html.erb
310
+ - app/views/educode_sales/contracts/_product_list.html.erb
311
+ - app/views/educode_sales/contracts/assign.html.erb
310
312
  - app/views/educode_sales/contracts/follow_ups.json.jbuilder
311
313
  - app/views/educode_sales/contracts/index.html.erb
312
314
  - app/views/educode_sales/contracts/index.json.jbuilder
313
315
  - app/views/educode_sales/contracts/list.js.erb
314
316
  - app/views/educode_sales/contracts/new_follow_up.html.erb
317
+ - app/views/educode_sales/contracts/product_list.js.erb
315
318
  - app/views/educode_sales/customers/edit.html.erb
316
319
  - app/views/educode_sales/customers/edit_department.html.erb
317
320
  - app/views/educode_sales/customers/edit_follow_record.html.erb
@@ -653,6 +656,7 @@ files:
653
656
  - db/migrate/20230430104708_create_idea_follows.rb
654
657
  - db/migrate/20230430121335_add_permissions_for_ideas.rb
655
658
  - db/migrate/20230430134710_create_educode_sales_assign_staffs.rb
659
+ - db/migrate/20230501034307_create_educode_sales_follow_up_trends.rb
656
660
  - lib/educode_sales.rb
657
661
  - lib/educode_sales/engine.rb
658
662
  - lib/educode_sales/version.rb
@@ -661,7 +665,7 @@ homepage: https://www.educoder.net
661
665
  licenses:
662
666
  - MIT
663
667
  metadata: {}
664
- post_install_message:
668
+ post_install_message:
665
669
  rdoc_options: []
666
670
  require_paths:
667
671
  - lib
@@ -677,7 +681,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
677
681
  version: '0'
678
682
  requirements: []
679
683
  rubygems_version: 3.0.9
680
- signing_key:
684
+ signing_key:
681
685
  specification_version: 4
682
686
  summary: Summary of EducodeSales.
683
687
  test_files: []