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 +4 -4
- data/app/controllers/educode_sales/contracts_controller.rb +99 -13
- data/app/models/educode_sales/business.rb +2 -0
- data/app/models/educode_sales/contract_date_list.rb +2 -0
- data/app/models/educode_sales/follow_up.rb +3 -1
- data/app/models/educode_sales/follow_up_trend.rb +8 -0
- data/app/views/educode_sales/contracts/_follows.html.erb +7 -8
- data/app/views/educode_sales/contracts/_list.html.erb +11 -6
- data/app/views/educode_sales/contracts/_product_list.html.erb +358 -0
- data/app/views/educode_sales/contracts/assign.html.erb +46 -0
- data/app/views/educode_sales/contracts/follow_ups.json.jbuilder +3 -5
- data/app/views/educode_sales/contracts/index.html.erb +6 -0
- data/app/views/educode_sales/contracts/index.json.jbuilder +1 -1
- data/app/views/educode_sales/contracts/new_follow_up.html.erb +8 -18
- data/app/views/educode_sales/contracts/product_list.js.erb +1 -0
- data/config/routes.rb +6 -0
- data/db/migrate/20230501034307_create_educode_sales_follow_up_trends.rb +12 -0
- data/lib/educode_sales/version.rb +1 -1
- metadata +10 -6
- data/app/assets/images/educode_sales/indexlogo.png +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ec6bd4aff88d498d4b416ae1a654e7e0d391a1438b3dc3358ab9d0c44e843355
|
4
|
+
data.tar.gz: 3b83113b2949c8b7ea4faf3b029a367ecf994b6a42492b67111c5b6bb6539eb6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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 =
|
54
|
-
|
55
|
-
|
56
|
-
@businesses = @businesses.where(
|
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::
|
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
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
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
|
|
@@ -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 :
|
27
|
+
has_many :follow_up_trends
|
28
|
+
has_many :contract_date_lists
|
27
29
|
|
28
30
|
|
29
31
|
default_scope -> {where(deleted_at: nil)}
|
@@ -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:
|
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: '
|
149
|
-
width:
|
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"
|
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.
|
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
|
-
|
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(
|
565
|
+
layer.full(new_follow_index);
|
561
566
|
});
|
562
567
|
} else if (obj.event === 'assign') {
|
563
|
-
var content = miniPage.getHrefContent('/missions/
|
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: [
|
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.
|
8
|
-
json.
|
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.
|
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 "
|
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
|
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
|
604
|
+
var add_department_select = selectInput.render({
|
605
605
|
elem: '#add_department',
|
606
|
-
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
@@ -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
|
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.
|
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-
|
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: []
|
Binary file
|