educode_sales 0.9.99 → 1.0.1

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 (25) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/educode_sales/businesses_controller.rb +31 -25
  3. data/app/controllers/educode_sales/contracts_controller.rb +1 -1
  4. data/app/controllers/educode_sales/home_controller.rb +11 -5
  5. data/app/controllers/educode_sales/recycles_controller.rb +17 -1
  6. data/app/controllers/educode_sales/sale_trends_controller.rb +1 -1
  7. data/app/controllers/educode_sales/sales_details_controller.rb +8 -7
  8. data/app/helpers/educode_sales/sale_trends_helper.rb +4 -4
  9. data/app/models/educode_sales/business.rb +4 -4
  10. data/app/models/educode_sales/sales_detail.rb +1 -0
  11. data/app/models/educode_sales/user_stat_service.rb +81 -0
  12. data/app/views/educode_sales/businesses/edit.html.erb +71 -128
  13. data/app/views/educode_sales/businesses/search.json.jbuilder +2 -1
  14. data/app/views/educode_sales/contracts/new_sales_detail.html.erb +6 -0
  15. data/app/views/educode_sales/home/search_customer.json.jbuilder +7 -2
  16. data/app/views/educode_sales/recycles/_follow_up.html.erb +143 -0
  17. data/app/views/educode_sales/recycles/follow_up.json.jbuilder +21 -0
  18. data/app/views/educode_sales/recycles/index.html.erb +4 -0
  19. data/app/views/educode_sales/sale_trends/_user_stat.html.erb +0 -11
  20. data/app/views/educode_sales/sales_details/_index.html.erb +10 -1
  21. data/app/views/educode_sales/sales_details/index.json.jbuilder +2 -0
  22. data/config/routes.rb +2 -0
  23. data/db/migrate/20230523115007_add_proprietorship_educode_sales_sales_details.rb +18 -0
  24. data/lib/educode_sales/version.rb +1 -1
  25. metadata +5 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8d3b1f62cddc62c5e2d319320a0b53622d8c610a565923613fee6cf6cedcacb9
4
- data.tar.gz: 882b25401c7319bed2b1de0eca8e331a58ed46976ea6d1fff5425758ddd6ced5
3
+ metadata.gz: a74ba09bc53597cf1bc110d4c32b29a405d7f4d25bb16287429327ac66799f49
4
+ data.tar.gz: 6a0969f7bb8afa5ea2e34670164d9fd81f45a7ca085d8987492d10643b91ca5e
5
5
  SHA512:
6
- metadata.gz: 866d6f020e66dd334e039e2ac2cb67a059f03712c3ad92cd632a249d96f7076661238d7b418ca9eab87907954f81a01dea8508df86bf12169fe91f7540d151ae
7
- data.tar.gz: e0559ef009cbf4b4e0b718d00783d2d513a0ef8722831065e7b42d654c48f143c1411f6617252aae4a8b20d681e6687061a771a58ddbc1fee01967159b897cea
6
+ metadata.gz: d522ae7272dc2de4f6c9d766b0f813a1e0812d7f455e0ec6ffc228887feb4647962e679c231c0f4c06b18ec87c44e09be95b9d5a77ddcd8e5abb2440272277e5
7
+ data.tar.gz: 459678b2f2f085ad8eb877701637dbb8e52a72deb8fba6682ad1a99625cf0f26c276ff1fd8620342abb0d0a65c1b148220a9da56061076ce9cea61b071cf0477
@@ -429,31 +429,24 @@ module EducodeSales
429
429
  gon.department = {value: @business.department_id, name: "#{@business.department&.school&.name}-#{@business.department&.name}"}
430
430
  gon.value = @business.department_id
431
431
 
432
-
433
-
434
- if @business.activity
435
- gon.activity = [{value: @business.activity_id, name: @business.activity.name}]
436
- gon.activity_id = @business.activity_id
437
- else
438
- gon.activity = []
439
- gon.activity_id = ''
440
- end
441
-
442
- if @business.place
443
- gon.place = [{value: @business.place_id, name: @business.place.name}]
444
- gon.place_id = @business.place_id
445
- else
446
- gon.place = []
447
- gon.place_id = ''
448
- end
449
-
450
- if @business.customer
451
- gon.customer = [{value: @business.customer_id, name: "#{@business.customer.school.name} #{@business.customer.name}"}]
452
- gon.customer_id = @business.customer_id
432
+ if ['会议活动', '渠道代理', '客户'].include?(@business.source_way) && @business.sourcable.present?
433
+ if @business.source_way == '客户'
434
+ gon.sourcable = [{name: "#{@business.sourcable.school.name} #{@business.sourcable.name}", value: @business.sourcable_id}]
435
+ else
436
+ gon.sourcable = [{name: @business.sourcable.name, value: @business.sourcable_id}]
437
+ end
438
+
439
+ gon.sourcable_id = @business.sourcable_id
440
+ elsif @business.sourcable_type.present?
441
+ gon.sourcable = [{value: @business.sourcable_type, name: @business.sourcable_type}]
442
+ gon.sourcable_id = @business.sourcable_type
453
443
  else
454
- gon.customer = []
455
- gon.customer_id = ''
444
+ gon.sourcable = []
445
+ gon.sourcable_id = ''
456
446
  end
447
+ gon.sourcable_type = @business.sourcable_type
448
+ gon.source_way = @business.source_way
449
+
457
450
 
458
451
  render layout: false
459
452
  end
@@ -480,10 +473,23 @@ module EducodeSales
480
473
  end
481
474
  end
482
475
  end
476
+ if params[:sourcable_type].present?
477
+ if params[:source_way] == '会议活动'
478
+ params[:sourcable_type] = 'EducodeSales::Activity'
479
+ elsif params[:source_way] == '渠道代理'
480
+ params[:sourcable_type] = 'EducodeSales::Place'
481
+ elsif params[:source_way] == '客户'
482
+ params[:sourcable_type] = 'EducodeSales::Department'
483
+ else
484
+ params[:sourcable_id] = ""
485
+ end
486
+ end
487
+ if params[:sourcable_type].blank?
488
+ params[:sourcable_id] = ""
489
+ end
483
490
 
484
491
  if business.update(name: params[:name], department_id: department.id, source: params[:source], school_id: department.school_id,
485
- activity_id: params[:activity_id], place_id: params[:place_id], customer_id: params[:customer_id],
486
- company_source: params[:company_source], phone: params[:phone], email: params[:email], partner: params[:partner], invite_info: params[:invite_info], friend: params[:friend]
492
+ sourcable_type: params[:sourcable_type], sourcable_id: params[:sourcable_id], source_way: params[:source_way]
487
493
  )
488
494
  if params[:merge_business_ids].present?
489
495
  merge_business = Business.where(id: params[:merge_business_ids].split(","))
@@ -514,7 +514,7 @@ module EducodeSales
514
514
  end
515
515
 
516
516
  def sales_detail_params
517
- params.permit(:amount, :price, :total_price, :custom_clazz, :delivery_date, :product_catalog_id, :business_id)
517
+ params.permit(:amount, :price, :total_price, :custom_clazz, :delivery_date, :product_catalog_id, :business_id, :proprietorship)
518
518
  end
519
519
 
520
520
  end
@@ -98,11 +98,17 @@ module EducodeSales
98
98
  end
99
99
 
100
100
  def search_customer
101
- part_a_ids = EducodeSales::CustomerFollow.all.pluck(:school_id)
102
- part_b_ids = EducodeSales::Business.pluck(:school_id)
103
- school_ids = (part_a_ids + part_b_ids + EducodeSales::CustomerAdd.all.pluck(:school_id)).uniq
104
- @data = Department.joins(:school).where("schools.name like ?", "%#{params[:q]}%").where("schools.id in (?)", school_ids).limit(20)
105
- p @data
101
+ if params[:type] == 'customer'
102
+ part_a_ids = EducodeSales::CustomerFollow.all.pluck(:school_id)
103
+ part_b_ids = EducodeSales::Business.pluck(:school_id)
104
+ school_ids = (part_a_ids + part_b_ids + EducodeSales::CustomerAdd.all.pluck(:school_id)).uniq
105
+ @data = Department.joins(:school).where("schools.name like ?", "%#{params[:q]}%").where("schools.id in (?)", school_ids).limit(20)
106
+ elsif params[:type] == 'active'
107
+ @data = Activity.where("name like ?", "%#{params[:q]}%").limit(20)
108
+ elsif params[:type] == 'place'
109
+ @data = EducodeSales::Place
110
+ @data = @data.where("name like :q", q: "%#{params[:q].strip}%").limit(20)
111
+ end
106
112
  end
107
113
 
108
114
  end
@@ -9,7 +9,13 @@ module EducodeSales
9
9
  render_success
10
10
  end
11
11
 
12
-
12
+ def restore_follow_up
13
+ @recycle = Recycle.find(params[:id])
14
+ report_id = @recycle.source_id
15
+ EducodeSales::FollowUp.unscoped.find(report_id).update(deleted_at: nil)
16
+ @recycle.destroy
17
+ render_success
18
+ end
13
19
 
14
20
  def restore_reports
15
21
  @recycle = Recycle.find(params[:id])
@@ -52,6 +58,16 @@ module EducodeSales
52
58
  @businesses = @businesses.page(params[:page]).per(params[:limit])
53
59
  end
54
60
 
61
+ def follow_up
62
+ @data = Recycle.where(source_type:"EducodeSales::FollowUp")
63
+ if params[:sort].present? && params[:sort][:field]
64
+ @data = @data.order("created_at #{params[:sort][:order]}")
65
+ else
66
+ @data = @data.order("educode_sales_recycles.created_at desc")
67
+ end
68
+ @data = @data.page(params[:page]).per(params[:limit])
69
+ end
70
+
55
71
  def weekly
56
72
  @weekly = Recycle.where(source_type:"EducodeSales::SaleReport").order(created_at: :desc).page(params[:page]).per(params[:limit])
57
73
  if params[:sort].present? && params[:sort][:field]
@@ -456,7 +456,7 @@ module EducodeSales
456
456
  user_stat = EducodeSales::UserStatService.new
457
457
  gon.table_1 = user_stat.table_1
458
458
  gon.table_2 = user_stat.table_2(1)
459
- gon.table_3 = user_stat.table_2(0)
459
+ gon.table_3 = user_stat.table_3
460
460
  end
461
461
  end
462
462
  end
@@ -138,14 +138,15 @@ module EducodeSales
138
138
  rows.times do |r| #行数
139
139
  next unless ods.row(r+2)[0]
140
140
  business = EducodeSales::Business.find_by(number: ods.row(r+2)[0].to_s.strip)
141
- product_catalog = EducodeSales::ProductCatalog.find_by(item_clazz: ods.row(r+2)[7].to_s.strip,
142
- brand: ods.row(r+2)[8].to_s.strip,
143
- specification: ods.row(r+2)[9].to_s.strip,
144
- unit: ods.row(r+2)[10].to_s.strip,
145
- source_method: ods.row(r+2)[14].to_s.strip,
146
- supplier: ods.row(r+2)[16].to_s.strip)
141
+ product_catalog = EducodeSales::ProductCatalog.find_by(name: ods.row(r+2)[5].to_s.strip,
142
+ item_clazz: ods.row(r+2)[6].to_s.strip,
143
+ brand: ods.row(r+2)[7].to_s.strip,
144
+ specification: ods.row(r+2)[8].to_s.strip,
145
+ unit: ods.row(r+2)[9].to_s.strip,
146
+ source_method: ods.row(r+2)[13].to_s.strip,
147
+ supplier: ods.row(r+2)[15].to_s.strip)
147
148
  if business.present? && product_catalog.present?
148
- SalesDetail.create(staff_id: @current_admin.id, business_id: business.id, product_catalog_id: product_catalog.id, price: ods.row(r+2)[12].to_s.strip, amount: ods.row(r+2)[11].to_s.strip, total_price: ods.row(r+2)[13].to_s.strip, custom_clazz: ods.row(r+2)[15].to_s.strip, delivery_date: ods.row(r+2)[17].to_s.strip)
149
+ SalesDetail.create(staff_id: @current_admin.id, business_id: business.id, product_catalog_id: product_catalog.id, price: ods.row(r+2)[11].to_s.strip, amount: ods.row(r+2)[10].to_s.strip, total_price: ods.row(r+2)[12].to_s.strip, custom_clazz: ods.row(r+2)[14].to_s.strip, delivery_date: ods.row(r+2)[16].to_s.strip, proprietorship: ods.row(r+2)[17].to_s.strip)
149
150
  end
150
151
  end
151
152
 
@@ -46,7 +46,7 @@ module EducodeSales
46
46
  {
47
47
  type: type,
48
48
  label: select,
49
- data: data,
49
+ data: data.map { |d| d.round(2)},
50
50
  backgroundColor:
51
51
  backgroundColor,
52
52
  borderColor:
@@ -114,7 +114,7 @@ module EducodeSales
114
114
  {
115
115
  type: type,
116
116
  label: select,
117
- data: data,
117
+ data: data.map { |d| d.round(2)},
118
118
  backgroundColor:
119
119
  backgroundColor,
120
120
  borderColor:
@@ -179,7 +179,7 @@ module EducodeSales
179
179
  {
180
180
  type: type,
181
181
  label: select,
182
- data: data,
182
+ data: data.map { |d| d.round(2)},
183
183
  backgroundColor:
184
184
  backgroundColor,
185
185
  borderColor:
@@ -228,7 +228,7 @@ module EducodeSales
228
228
  {
229
229
  type: type,
230
230
  label: select,
231
- data: data,
231
+ data: data.map { |d| d.round(2)},
232
232
  backgroundColor:
233
233
  backgroundColor,
234
234
  borderColor:
@@ -12,10 +12,6 @@ module EducodeSales
12
12
  belongs_to :p_sale_staff, class_name: 'Staff', optional: true
13
13
  belongs_to :p_deleter, class_name: 'Staff', optional: true
14
14
 
15
- belongs_to :place, class_name: 'Place', optional: true
16
- belongs_to :customer, class_name: 'Department', optional: true
17
- belongs_to :activity, class_name: 'Activity', optional: true
18
-
19
15
  has_many :sale_plans
20
16
  has_many :follow_ups
21
17
  has_many :business_clazz_changes
@@ -23,8 +19,12 @@ module EducodeSales
23
19
  has_many :business_watches, dependent: :destroy
24
20
  has_many :business_histories, dependent: :destroy
25
21
 
22
+ belongs_to :sourcable, :polymorphic => true, optional: true
23
+
26
24
  has_many :assign_staffs, as: :sourcable, dependent: :destroy # 售后人员
27
25
 
26
+ enum source_way: ['会议活动', '公司资源', '400电话', '商务邮箱', '渠道代理', '合作伙伴', '招标信息', '客户', '朋友']
27
+
28
28
  # 关联关注
29
29
  has_many :users, :class_name => 'EducodeSales::BusinessRelationShip', foreign_key: 'business_id', :dependent => :destroy
30
30
 
@@ -4,5 +4,6 @@ module EducodeSales
4
4
  belongs_to :product_catalog
5
5
  belongs_to :staff
6
6
  enum custom_clazz: ['非定制', '低定制', '高定制', '全定制']
7
+ enum proprietorship: ['头歌', '客户', '共有']
7
8
  end
8
9
  end
@@ -109,6 +109,87 @@ module EducodeSales
109
109
  end
110
110
  end
111
111
 
112
+ def table_3
113
+ users = {'1' => [0, 0, 0], '2-5' => [0, 0, 0], '6-10' => [0, 0, 0], '11-20' => [0, 0, 0], '21-50' => [0, 0, 0], '51-100' => [0, 0, 0] }
114
+ signed_users = {'1' => [0, 0, 0], '2-5' => [0, 0, 0], '6-10' => [0, 0, 0], '11-20' => [0, 0, 0], '21-50' => [0, 0, 0], '51-100' => [0, 0, 0] }
115
+ schools(0).each do |d|
116
+ if d[1] == 1
117
+ users['1'][0] += 1
118
+ elsif d[1] <= 5
119
+ users['2-5'][0] += 1
120
+ elsif d[1] <= 10
121
+ users['6-10'][0] += 1
122
+ elsif d[1] <= 20
123
+ users['11-20'][0] += 1
124
+ elsif d[1] <= 50
125
+ users['21-50'][0] += 1
126
+ elsif d[1] <= 100
127
+ users['51-100'][0] += 1
128
+ end
129
+ end
130
+
131
+ departments(0).each do |d|
132
+ if d[1] == 1
133
+ users['1'][1] += 1
134
+ elsif d[1] <= 5
135
+ users['2-5'][1] += 1
136
+ elsif d[1] <= 10
137
+ users['6-10'][1] += 1
138
+ elsif d[1] <= 20
139
+ users['11-20'][1] += 1
140
+ elsif d[1] <= 50
141
+ users['21-50'][1] += 1
142
+ elsif d[1] <= 100
143
+ users['51-100'][1] += 1
144
+ end
145
+ end
146
+
147
+ signed_schools(0).each do |d|
148
+ if d[1] == 1
149
+ signed_users['1'][0] += 1
150
+ elsif d[1] <= 5
151
+ signed_users['2-5'][0] += 1
152
+ elsif d[1] <= 10
153
+ signed_users['6-10'][0] += 1
154
+ elsif d[1] <= 20
155
+ signed_users['11-20'][0] += 1
156
+ elsif d[1] <= 50
157
+ signed_users['21-50'][0] += 1
158
+ elsif d[1] <= 100
159
+ signed_users['51-100'][0] += 1
160
+ end
161
+ end
162
+
163
+ signed_departments(0).each do |d|
164
+ if d[1] == 1
165
+ signed_users['1'][1] += 1
166
+ elsif d[1] <= 5
167
+ signed_users['2-5'][1] += 1
168
+ elsif d[1] <= 10
169
+ p "----#{d}"
170
+ signed_users['6-10'][1] += 1
171
+ elsif d[1] <= 20
172
+ signed_users['11-20'][1] += 1
173
+ elsif d[1] <= 50
174
+ signed_users['21-50'][1] += 1
175
+ elsif d[1] <= 100
176
+ signed_users['51-100'][1] += 1
177
+ end
178
+ end
179
+
180
+
181
+ ['1', '2-5', '6-10', '11-20', '21-50', '51-100'].map do |d|
182
+ {
183
+ 'num' => d,
184
+ 'schools' => users[d][0],
185
+ 'departments' => users[d][1],
186
+ 'majors' => 0,
187
+ 'signed_schools' => signed_users[d][0],
188
+ 'signed_departments' => signed_users[d][1],
189
+ 'signed_majors' => 0,
190
+ }
191
+ end
192
+ end
112
193
 
113
194
  def public_user
114
195
  UserExtension.where(school_id: @school_ids).
@@ -17,67 +17,14 @@
17
17
  <br>
18
18
  <div class="layui-inline" style="padding-top: 20px">
19
19
  <label class="layui-form-label required">商机来源</label>
20
- <input id="source" type="text" name="source" autocomplete="off" lay-verify="required" class="layui-input" value="<%=@business.source %>" style="width: 300px;" placeholder="请输入商机来源">
21
- </div>
22
- <div class="layui-inline" style="padding-top: 20px">
23
- <p style="padding-left: 40px">请填写提供本商机的人名(如‘张明’);如果为非头歌用户,请增加单位信息(如‘张明,华为公司’)</p>
24
- </div>
25
- <div class="layui-form-item" style="padding-top: 20px">
26
- <label class="layui-form-label">会议活动</label>
27
- <div class="layui-input-inline" style="line-height: 38px;">
28
- <div id="activity" style="width: 300px"></div>
29
- </div>
30
- </div>
31
- <div class="layui-form-item">
32
- <label class="layui-form-label">渠道代理:</label>
33
- <div class="layui-input-inline" style="line-height: 38px;">
34
- <div id="place" style="width: 300px"></div>
35
- </div>
36
- </div>
37
- <div class="layui-form-item">
38
- <label class="layui-form-label">客户</label>
39
- <div class="layui-input-inline" style="line-height: 38px;">
40
- <div id="customer" style="width: 300px"></div>
41
- </div>
42
- </div>
43
- <div class="layui-inline">
44
- <label class="layui-form-label">公司资源</label>
45
- <div class="layui-input-block">
46
- <input type="text" name="company_source" autocomplete="off" class="layui-input" value="<%= @business.company_source %>">
47
- </div>
48
- </div>
49
- <div class="layui-inline">
50
- <label class="layui-form-label">400电话</label>
51
- <div class="layui-input-block">
52
- <input type="text" name="phone" autocomplete="off" class="layui-input" value="<%= @business.phone %>">
53
- </div>
54
- </div>
55
- <div class="layui-inline">
56
- <label class="layui-form-label">商务邮箱</label>
57
- <div class="layui-input-block">
58
- <input type="text" name="email" autocomplete="off" class="layui-input" value="<%= @business.email %>">
59
- </div>
60
- </div>
61
-
62
- <div class="layui-inline">
63
- <label class="layui-form-label">合作伙伴</label>
64
- <div class="layui-input-block">
65
- <input type="text" name="partner" autocomplete="off" class="layui-input" value="<%= @business.partner %>">
20
+ <div class="layui-inline">
21
+ <%= select_tag "source_way", options_for_select(EducodeSales::Business.source_ways.keys, @business.source_way), { include_blank: true, "lay-filter": 'source_id', "lay-verify": "required" } %>
66
22
  </div>
67
- </div>
68
- <div class="layui-inline">
69
- <label class="layui-form-label">招标信息</label>
70
- <div class="layui-input-block">
71
- <input type="text" name="invite_info" autocomplete="off" class="layui-input" value="<%= @business.invite_info %>">
23
+ <div class="layui-inline" style="line-height: 38px;" id="source_wraper">
24
+ <div id="customer_id" style="width: 360px"></div>
72
25
  </div>
73
26
  </div>
74
27
 
75
- <div class="layui-inline">
76
- <label class="layui-form-label">朋友</label>
77
- <div class="layui-input-block">
78
- <input type="text" name="friend" autocomplete="off" class="layui-input" value="<%= @business.friend %>">
79
- </div>
80
- </div>
81
28
  <% if can?(:merge_business, EducodeSales::Business) %>
82
29
  <div class="layui-inline-block" style="padding-top: 20px">
83
30
  <label class="layui-form-label ">合并商机</label>
@@ -149,6 +96,46 @@
149
96
  if (gon.is_secret) {
150
97
  $("#watch_ids_wraper").removeClass("layui-hide")
151
98
  }
99
+ var source_way = gon.source_way;
100
+ form.on('select(source_id)', function(data){
101
+ source_way = data.value;
102
+ setSourceWay(data.value);
103
+ $("#" + customer_select._input)[0].value = "";
104
+ });
105
+
106
+
107
+ function setSourceWay(value) {
108
+ if (value == '400电话' || value == '商务邮箱') {
109
+ $("#source_wraper").hide()
110
+ } else {
111
+ $("#source_wraper").show()
112
+ var text = "";
113
+ switch (value) {
114
+ case '会议活动':
115
+ text = "请选择活动运营";
116
+ break;
117
+ case '公司资源':
118
+ text = "请填写公司领导、部门其他同事姓名";
119
+ break;
120
+ case '渠道代理':
121
+ text = "请选择渠道";
122
+ break;
123
+ case '合作伙伴':
124
+ text = "请填写合作伙伴公司名称";
125
+ break;
126
+ case '招标信息':
127
+ text = "请填写招标信息";
128
+ break;
129
+ case '客户':
130
+ text = "请选择客户";
131
+ break;
132
+ case '朋友':
133
+ text = "请填写姓名";
134
+ break;
135
+ }
136
+ $("#" + customer_select._input)[0].placeholder = text;
137
+ }
138
+ }
152
139
 
153
140
  form.render();
154
141
  var department_id = gon.value;
@@ -172,6 +159,7 @@
172
159
  request.get('missions/search?type=department&q=' + value, {}, function (res) {
173
160
  return cb(res)
174
161
  })
162
+
175
163
  }
176
164
  });
177
165
 
@@ -189,90 +177,47 @@
189
177
  data: []
190
178
  })
191
179
 
192
- var activity_id = gon.activity_id;
193
- var activity_select = selectInput.render({
194
- elem: '#activity',
195
- name: 'activity_id', // 渲染的input的name值
196
- layFilter: 'test', //同layui form参数lay-filter
197
- // layVerify: 'required', //同layui form参数lay-verify
198
- layVerType: 'tips', // 同layui form参数lay-verType
199
- layReqText: '请填写文本', //同layui form参数lay-ReqText
200
- initValue: gon.activity_id, // 渲染初始化默认值
201
- hasSelectIcon: false,
202
- placeholder: '请输入会议活动', // 渲染的inputplaceholder值
203
- data: gon.activity,
204
- remoteSearch: true, // 是否启用远程搜索 默认是false,和远程搜索回调保存同步
205
- remoteMethod: function (value, cb) { // 远程搜索的回调函数
206
- if (!value) {
207
- activity_id = "";
208
- return cb([]);
209
- }
210
- request.get('missions/search_activity?q=' + value, {}, function (res) {
211
- if (res.data.length == 0) {
212
- activity_select.emptyValue();
213
- return cb([])
214
- }
215
- return cb(res)
216
- })
217
- }
218
- });
219
180
 
220
- var place_id = gon.place_id;
221
- var place_select = selectInput.render({
222
- elem: '#place',
223
- name: 'place_id', // 渲染的input的name值
224
- layFilter: 'test', //同layui form参数lay-filter
225
- // layVerify: 'required', //同layui form参数lay-verify
226
- layVerType: 'tips', // 同layui form参数lay-verType
227
- layReqText: '请填写文本', //同layui form参数lay-ReqText
228
- initValue: gon.place_id, // 渲染初始化默认值
229
- hasSelectIcon: false,
230
- placeholder: '请输入渠道代理', // 渲染的inputplaceholder值
231
- data: gon.place,
232
- remoteSearch: true, // 是否启用远程搜索 默认是false,和远程搜索回调保存同步
233
- remoteMethod: function (value, cb) { // 远程搜索的回调函数
234
- if (!value) {
235
- place_id = "";
236
- return cb([]);
237
- }
238
- request.get('missions/sales_place?q=' + value, {}, function (res) {
239
- if (res.data.length == 0) {
240
- place_select.emptyValue();
241
- return cb([])
242
- }
243
- return cb(res)
244
- })
245
- }
246
- });
247
-
248
- var customer_id = gon.customer_id;
181
+ var sourcable_id = gon.sourcable_id;
249
182
  var customer_select = selectInput.render({
250
- elem: '#customer',
251
- name: 'customer_id', // 渲染的input的name值
183
+ elem: '#customer_id',
184
+ name: 'sourcable_type', // 渲染的input的name值
252
185
  layFilter: 'test', //同layui form参数lay-filter
253
186
  // layVerify: 'required', //同layui form参数lay-verify
254
187
  layVerType: 'tips', // 同layui form参数lay-verType
255
188
  layReqText: '请填写文本', //同layui form参数lay-ReqText
256
- initValue: gon.customer_id, // 渲染初始化默认值
189
+ initValue: gon.sourcable_id, // 渲染初始化默认值
257
190
  hasSelectIcon: false,
258
- placeholder: '请输入客户', // 渲染的inputplaceholder值
259
- data: gon.customer,
191
+ placeholder: '请输入商机来源', // 渲染的inputplaceholder值
192
+ data: gon.sourcable,
260
193
  remoteSearch: true, // 是否启用远程搜索 默认是false,和远程搜索回调保存同步
261
194
  remoteMethod: function (value, cb) { // 远程搜索的回调函数
262
195
  if (!value) {
263
- customer_id = "";
196
+ sourcable_id = "";
264
197
  return cb([]);
265
198
  }
266
- request.get('missions/search_customer?q=' + value, {}, function (res) {
267
- if (res.data.length == 0) {
268
- customer_select.emptyValue();
269
- return cb([])
199
+ if (['会议活动', '渠道代理', '客户'].includes(source_way)) {
200
+ var type = "";
201
+ if (source_way == '客户') {
202
+ type = 'customer';
203
+ } else if (source_way == '渠道代理') {
204
+ type = 'place';
205
+ } else if (source_way == '会议活动') {
206
+ type = 'active';
270
207
  }
271
- return cb(res)
272
- })
208
+ request.get('missions/search_customer?q=' + value + "&type=" + type, {}, function (res) {
209
+ if (res.data.length == 0) {
210
+ customer_select.emptyValue();
211
+ return cb([])
212
+ }
213
+ return cb(res)
214
+ })
215
+ }
273
216
  }
274
217
  });
275
218
 
219
+ setSourceWay(source_way);
220
+
276
221
  // 当前弹出层,防止ID被覆盖
277
222
  var parentIndex = layer.index;
278
223
 
@@ -285,9 +230,7 @@
285
230
  var field = data.field;
286
231
  field.department_id = department.getValue() || department_id;
287
232
  field.merge_business_ids = data.field.merge_business_ids;
288
- field.activity_id = activity_select.getValue() || activity_id;
289
- field.place_id = place_select.getValue() || place_id;
290
- field.customer_id = customer_select.getValue() || customer_id;
233
+ field.sourcable_id = customer_select.getValue() || sourcable_id;
291
234
  request.authPut("missions/businesses/" + parent.id, field, function (res) {
292
235
  if (res.success == false) {
293
236
  layer.alert(res.msg)
@@ -1,6 +1,7 @@
1
1
  json.data do
2
2
  json.array! @business do |d|
3
3
  json.value d.id
4
- json.name d.name
4
+ staff_manage = d.last_follow_up&.assign_follow_ups.present? ? (d.last_follow_up.assign_follow_ups.map{ |d| d.staff.user.real_name}.join("、")) : d.staff&.user&.real_name
5
+ json.name d.name + " " + staff_manage + " " + d.created_at.to_s
5
6
  end
6
7
  end
@@ -44,6 +44,12 @@
44
44
  <input type="text" name="delivery_date" value="" class="layui-input" lay-verify="required" id="delivery_date">
45
45
  </div>
46
46
  </div>
47
+ <div class="layui-inline">
48
+ <label class="layui-form-label required">知识产权归属:</label>
49
+ <div class="layui-input-inline">
50
+ <%= select_tag "proprietorship", options_for_select(EducodeSales::SalesDetail.proprietorships.keys), { 'lay-filter': 'proprietorship', 'lay-verify': "required", include_blank: true, "lay-search": "" } %>
51
+ </div>
52
+ </div>
47
53
  </div>
48
54
  <div class="layui-form-item">
49
55
  <div class="layui-input-block">
@@ -1,7 +1,12 @@
1
1
  json.data do
2
2
  json.array! @data do |d|
3
- json.value d.id
4
- json.name "#{d.school.name} #{d.name}"
3
+ if params[:type] == 'customer'
4
+ json.value d.id
5
+ json.name "#{d.school.name} #{d.name}"
6
+ else
7
+ json.value d.id
8
+ json.name d.name
9
+ end
5
10
  end
6
11
  end
7
12
  json.code 0
@@ -0,0 +1,143 @@
1
+ <script type="text/html" id="toolbarfollowup">
2
+ <div class="layui-btn-container">
3
+ <span class="table-label">商机跟进列表</span>
4
+ </div>
5
+ </script>
6
+
7
+ <table class="layui-hide" id="follow_up" lay-filter="follow_up"></table>
8
+
9
+ <script type="text/html" id="currentTable_followup">
10
+ <%# if can? :update, EducodeSales::business %>
11
+ <a class="layui-btn layui-btn-normal layui-btn-xs data-count-edit" lay-event="restore">还原</a>
12
+ <%# end %>
13
+ <%# if can? :destroy, EducodeSales::business %>
14
+ <a class="layui-btn layui-btn-xs layui-btn-danger data-count-delete" lay-event="delete">删除</a>
15
+ <%# end %>
16
+ </script>
17
+
18
+ <script type="text/html" id="showchance">
19
+ <a href="/missions/businesses" class="layui-table-link">{{ d.chance }}</a>
20
+ </script>
21
+
22
+ <script>
23
+ layui.use(['form', 'table', 'miniPage', 'element', 'request'], function () {
24
+ var $ = layui.jquery,
25
+ form = layui.form,
26
+ table = layui.table,
27
+ request = layui.request,
28
+ miniPage = layui.miniPage;
29
+
30
+ table.render({
31
+ elem: '#follow_up',
32
+ url: '/missions/recycles/follow_up',
33
+ toolbar: '#toolbarfollowup',
34
+ totalRow:true,
35
+ defaultToolbar: [],
36
+ cols: [
37
+ [
38
+ {
39
+ field: 'id',
40
+ title:'序号',type: 'numbers',
41
+ },
42
+ {
43
+ field: 'name',
44
+ width: 180,
45
+ title: '商机名称'
46
+ },
47
+ {
48
+ field: 'follow_up_content',
49
+ width: 180,
50
+ title: '内容'
51
+ },
52
+ {
53
+ field: 'clazz',
54
+ title: '商机类型'
55
+ },
56
+ {
57
+ field: 'stage',
58
+ title: '阶段'
59
+ },
60
+ {
61
+ field: 'staff_manages',
62
+ width: 150,
63
+ title: '销售经理'
64
+ },
65
+ {
66
+ field: 'school',
67
+ title: '单位'
68
+ },
69
+ {
70
+ field: 'department',
71
+ title: '部门'
72
+ },
73
+ {
74
+ field: 'last_follow_person',
75
+ width: 150,
76
+ title: '最新跟进人'
77
+ },
78
+ {
79
+ field: 'latest_time',
80
+ title: '最新跟进时间',
81
+ width: 150,
82
+ },
83
+ {
84
+ field: 'deleter',
85
+ width: 90,
86
+ title: '删除人',
87
+ },
88
+ {
89
+ field: 'delete_time',
90
+ title: '删除时间',
91
+ width: 150,
92
+ sort: true,
93
+
94
+ },
95
+ {
96
+ title: '操作',
97
+ width: 120,
98
+ toolbar: '#currentTable_followup',
99
+ align: "center"
100
+ }
101
+ ]
102
+ ],
103
+ limit: 20,
104
+ limits: [10,15,20,30,40,50,60,70,80,90],
105
+ page: true
106
+ });
107
+
108
+ var sort = {}, search = {};
109
+ table.on('sort(follow_up)', function (obj) {
110
+ sort.field = obj.field;
111
+ sort.order = obj.type;
112
+ table.reload('follow_up', {
113
+ initSort: obj,
114
+ where: {
115
+ sort: sort,
116
+ q: search
117
+ }
118
+ });
119
+ })
120
+
121
+
122
+ table.on('tool(follow_up)', function (obj) {
123
+ var data = obj.data;
124
+ var id = data.id
125
+ if (obj.event === 'restore') {
126
+ layer.confirm('确定恢复' + data.name, function (index) {
127
+ request.get('missions/recycles/' + data.id + '/restore_follow_up', {}, function (res) {
128
+ layer.close(index);
129
+ table.reload("follow_up")
130
+ })
131
+ });
132
+ } else if (obj.event === 'delete') {
133
+ layer.confirm('确定删除' + data.name, function (index) {
134
+ request.delete('missions/recycles/' + data.id, {}, function (res) {
135
+ layer.close(index);
136
+ table.reload("follow_up")
137
+ })
138
+ });
139
+ }
140
+ });
141
+
142
+ });
143
+ </script>
@@ -0,0 +1,21 @@
1
+ json.data do
2
+ json.array! @data do |d|
3
+ follow_up = EducodeSales::FollowUp.unscoped.find(d.source_id)
4
+ business = EducodeSales::Business.unscoped.find(follow_up.business_id)
5
+ json.id d.id
6
+ json.name business&.name
7
+ json.clazz business.clazz&.name
8
+ json.staff_manages follow_up.assign_follow_ups.present? ? (follow_up.assign_follow_ups.map{ |s| s.staff.user&.real_name}.join("、")) : business.staff&.user&.real_name
9
+ json.follow_up_content follow_up.description
10
+ json.school business.department&.school&.name
11
+ json.department business.department&.name
12
+ json.last_follow_person follow_up.staff.user&.real_name
13
+ json.latest_time follow_up.created_at.to_s
14
+ json.deleter EducodeSales::Staff.find(d.deleter_id).user&.real_name
15
+ json.delete_time d.created_at.to_s
16
+ json.stage follow_up.stage&.name
17
+ end
18
+ end
19
+
20
+ json.code 0
21
+ json.count @data.total_count
@@ -1,6 +1,7 @@
1
1
  <div class="layui-tab" lay-filter="sale_tab">
2
2
  <ul class="layui-tab-title">
3
3
  <li class="layui-this" data="business">商机</li>
4
+ <li data="follow_up">商机跟进</li>
4
5
  <li data="week">周计划</li>
5
6
  <li data="weekly">周报</li>
6
7
  <li data="month">月计划</li>
@@ -11,6 +12,9 @@
11
12
  <div class="layui-tab-item layui-show">
12
13
  <%= render 'business' %>
13
14
  </div>
15
+ <div class="layui-tab-item">
16
+ <%= render 'follow_up' %>
17
+ </div>
14
18
  <div class="layui-tab-item">
15
19
  <%= render 'weekPlan' %>
16
20
  </div>
@@ -25,7 +25,6 @@
25
25
  align: 'center',
26
26
  width: 150,
27
27
  rowspan: 2,
28
- totalRowText:'合计',
29
28
  }
30
29
  , {
31
30
  title: '公有云',
@@ -47,59 +46,49 @@
47
46
  title: '用户数',
48
47
  align: 'center',
49
48
  width: 110,
50
- totalRow: '{{ parseInt(d.TOTAL_NUMS) }}',
51
49
  }, {
52
50
  field: 'school_1',
53
51
  title: '学校数',
54
52
  align: 'center',
55
53
  width: 110,
56
- totalRow: '{{ parseInt(d.TOTAL_NUMS) }}',
57
54
  }, {
58
55
  field: 'department_1',
59
56
  title: '学院数',
60
57
  align: 'center',
61
58
  width: 110,
62
- totalRow: '{{ parseInt(d.TOTAL_NUMS) }}',
63
59
  },{
64
60
  field: 'user_2',
65
61
  title: '用户数',
66
62
  align: 'center',
67
63
  width: 110,
68
- totalRow: '{{ parseInt(d.TOTAL_NUMS) }}',
69
64
  }, {
70
65
  field: 'school_2',
71
66
  title: '学校数',
72
67
  align: 'center',
73
68
  width: 110,
74
- totalRow: '{{ parseInt(d.TOTAL_NUMS) }}',
75
69
  }, {
76
70
  field: 'department_2',
77
71
  align: 'center',
78
72
  title: '学院数',
79
73
  width: 110,
80
- totalRow: '{{ parseInt(d.TOTAL_NUMS) }}',
81
74
  },{
82
75
  field: 'user_2',
83
76
  title: '用户数',
84
77
  align: 'center',
85
78
  width: 110,
86
- totalRow: '{{ parseInt(d.TOTAL_NUMS) }}',
87
79
  }, {
88
80
  field: 'school_2',
89
81
  title: '学校数',
90
82
  align: 'center',
91
83
  width: 110,
92
- totalRow: '{{ parseInt(d.TOTAL_NUMS) }}',
93
84
  }, {
94
85
  field: 'department_2',
95
86
  align: 'center',
96
87
  title: '学院数',
97
88
  width: 110,
98
- totalRow: '{{ parseInt(d.TOTAL_NUMS) }}',
99
89
  }]
100
90
  ],
101
91
  data: gon.table_1,
102
- totalRow: true,
103
92
  page: false
104
93
  });
105
94
 
@@ -151,14 +151,20 @@
151
151
  field: 'majors',
152
152
  width: 150,
153
153
  title: '专业',
154
+ hide: true
154
155
  }, {
155
156
  field: 'signed_department',
156
157
  title: '签约单位',
157
158
  width: 280,
159
+ hide: true
158
160
  }, {
159
161
  field: 'actual_amount',
160
162
  width: 120,
161
163
  title: '合同金额',
164
+ }, {
165
+ field: 'project_name',
166
+ width: 100,
167
+ title: '产品名称',
162
168
  }, {
163
169
  field: 'item_clazz',
164
170
  width: 100,
@@ -204,7 +210,10 @@
204
210
  field: 'delivery_date',
205
211
  width: 120,
206
212
  title: '交货时间',
207
- sort: true,
213
+ }, {
214
+ field: 'proprietorship',
215
+ width: 120,
216
+ title: '知识产权归属',
208
217
  }, {
209
218
  title: '操作',
210
219
  minWidth: 350,
@@ -26,6 +26,8 @@ json.data do
26
26
  json.custom_clazz d.custom_clazz
27
27
  json.supplier d.product_catalog.supplier
28
28
  json.delivery_date d.delivery_date
29
+ json.proprietorship d.proprietorship
30
+ json.project_name d.product_catalog.name
29
31
  end
30
32
  end
31
33
 
data/config/routes.rb CHANGED
@@ -185,11 +185,13 @@ EducodeSales::Engine.routes.draw do
185
185
  get :weekPlan
186
186
  get :business
187
187
  get :yearPlan
188
+ get :follow_up
188
189
  end
189
190
  member do
190
191
  get :restore_plans
191
192
  get :restore_reports
192
193
  get :restore_businesses
194
+ get :restore_follow_up
193
195
  end
194
196
  end
195
197
 
@@ -0,0 +1,18 @@
1
+ class AddProprietorshipEducodeSalesSalesDetails < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :educode_sales_sales_details, :proprietorship, :integer
4
+ add_column :educode_sales_businesses, :source_way, :integer
5
+ add_column :educode_sales_businesses, :sourcable_type, :string
6
+ add_column :educode_sales_businesses, :sourcable_id, :integer
7
+
8
+ remove_column :educode_sales_businesses, :activity_id, :integer
9
+ remove_column :educode_sales_businesses, :place_id, :integer
10
+ remove_column :educode_sales_businesses, :customer_id, :integer
11
+ remove_column :educode_sales_businesses, :company_source, :string
12
+ remove_column :educode_sales_businesses, :phone, :string
13
+ remove_column :educode_sales_businesses, :email, :string
14
+ remove_column :educode_sales_businesses, :partner, :string
15
+ remove_column :educode_sales_businesses, :invite_info, :string
16
+ remove_column :educode_sales_businesses, :friend, :string
17
+ end
18
+ end
@@ -1,3 +1,3 @@
1
1
  module EducodeSales
2
- VERSION = '0.9.99'
2
+ VERSION = '1.0.1'
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.99
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - anke1460
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-05-22 00:00:00.000000000 Z
11
+ date: 2023-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -495,12 +495,14 @@ files:
495
495
  - app/views/educode_sales/projects/index.html.erb
496
496
  - app/views/educode_sales/projects/index.json.jbuilder
497
497
  - app/views/educode_sales/recycles/_business.html.erb
498
+ - app/views/educode_sales/recycles/_follow_up.html.erb
498
499
  - app/views/educode_sales/recycles/_monthPlan.html.erb
499
500
  - app/views/educode_sales/recycles/_monthly.html.erb
500
501
  - app/views/educode_sales/recycles/_weekPlan.html.erb
501
502
  - app/views/educode_sales/recycles/_weekly.html.erb
502
503
  - app/views/educode_sales/recycles/_yearPlan.html.erb
503
504
  - app/views/educode_sales/recycles/business.json.jbuilder
505
+ - app/views/educode_sales/recycles/follow_up.json.jbuilder
504
506
  - app/views/educode_sales/recycles/index.html.erb
505
507
  - app/views/educode_sales/recycles/monthPlan.json.jbuilder
506
508
  - app/views/educode_sales/recycles/monthly.json.jbuilder
@@ -682,6 +684,7 @@ files:
682
684
  - db/migrate/20230502142912_create_educode_sales_product_catalogs.rb
683
685
  - db/migrate/20230510144317_create_educode_sales_sales_details.rb
684
686
  - db/migrate/20230520023902_add_activity_educode_sales_business.rb
687
+ - db/migrate/20230523115007_add_proprietorship_educode_sales_sales_details.rb
685
688
  - lib/educode_sales.rb
686
689
  - lib/educode_sales/engine.rb
687
690
  - lib/educode_sales/version.rb