educode_sales 0.9.97 → 0.9.99

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: 312c157ed210ab8e0ada99a141e3ba4565e87d164cfa03efb3448b90227a113e
4
- data.tar.gz: afd966def27af48056c7ece566a3fc6b87f47430ccbe848785d0d44303edbea8
3
+ metadata.gz: 8d3b1f62cddc62c5e2d319320a0b53622d8c610a565923613fee6cf6cedcacb9
4
+ data.tar.gz: 882b25401c7319bed2b1de0eca8e331a58ed46976ea6d1fff5425758ddd6ced5
5
5
  SHA512:
6
- metadata.gz: 9d88c0be318d3a494a792722ec2cc820f05d4ed9354a81da2e969f57194eebec448b779518f3911c5d4c102902f2cf995edfc2c0fb0781b69d360b460d4e22ff
7
- data.tar.gz: 02f8787c4223c8e6950f7d7b8cc1f30ab914ed110bd2fb4186f56601b81e6d44ca0b5be4a7b05253a4de6d590d06a97a2c5d7a5f2a75c7abb3fb503188058d80
6
+ metadata.gz: 866d6f020e66dd334e039e2ac2cb67a059f03712c3ad92cd632a249d96f7076661238d7b418ca9eab87907954f81a01dea8508df86bf12169fe91f7540d151ae
7
+ data.tar.gz: e0559ef009cbf4b4e0b718d00783d2d513a0ef8722831065e7b42d654c48f143c1411f6617252aae4a8b20d681e6687061a771a58ddbc1fee01967159b897cea
@@ -428,6 +428,33 @@ module EducodeSales
428
428
  gon.watche_ids = Staff.all.map { |d| {name: d.user&.real_name, value: d.id, selected: staff_ids.include?(d.id)}}
429
429
  gon.department = {value: @business.department_id, name: "#{@business.department&.school&.name}-#{@business.department&.name}"}
430
430
  gon.value = @business.department_id
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
453
+ else
454
+ gon.customer = []
455
+ gon.customer_id = ''
456
+ end
457
+
431
458
  render layout: false
432
459
  end
433
460
 
@@ -454,7 +481,10 @@ module EducodeSales
454
481
  end
455
482
  end
456
483
 
457
- if business.update(name: params[:name], department_id: department.id, source: params[:source], school_id: department.school_id)
484
+ 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]
487
+ )
458
488
  if params[:merge_business_ids].present?
459
489
  merge_business = Business.where(id: params[:merge_business_ids].split(","))
460
490
  merge_business.each do |b|
@@ -496,11 +496,9 @@ module EducodeSales
496
496
  xlsx = Roo::Spreadsheet.open(params[:file])
497
497
  ods = xlsx.sheet(0)
498
498
  rows = ods.last_row - 1
499
- i = 0
500
499
  rows.times do |r| #行数
501
- i += 1
502
- next unless ods.row(r+1)[0]
503
- EducodeSales::ProductCatalog.create(name: ods.row(r+1)[0].to_s.strip, item_clazz: ods.row(r+1)[1].to_s.strip, brand: ods.row(r+1)[2].to_s.strip, specification: ods.row(r+1)[3].to_s.strip, unit: ods.row(r+1)[4].to_s.strip, param: ods.row(r+1)[5].to_s.strip, source_method: ods.row(r+1)[6].to_s.strip, supplier: ods.row(r+1)[7].to_s.strip)
500
+ next unless ods.row(r+2)[0]
501
+ EducodeSales::ProductCatalog.create(name: ods.row(r+2)[0].to_s.strip, item_clazz: ods.row(r+2)[1].to_s.strip, brand: ods.row(r+2)[2].to_s.strip, specification: ods.row(r+2)[3].to_s.strip, unit: ods.row(r+2)[4].to_s.strip, param: ods.row(r+2)[5].to_s.strip, source_method: ods.row(r+2)[6].to_s.strip, supplier: ods.row(r+2)[7].to_s.strip)
504
502
  end
505
503
 
506
504
  render json: { succcess: true}
@@ -92,5 +92,18 @@ module EducodeSales
92
92
  @places = @places.page(params[:page]).per(10)
93
93
  end
94
94
 
95
+
96
+ def search_activity
97
+ @data = Activity.where("name like ?", "%#{params[:q]}%").limit(20)
98
+ end
99
+
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
106
+ end
107
+
95
108
  end
96
109
  end
@@ -131,6 +131,28 @@ module EducodeSales
131
131
  end
132
132
  end
133
133
 
134
+ def upload
135
+ xlsx = Roo::Spreadsheet.open(params[:file])
136
+ ods = xlsx.sheet(0)
137
+ rows = ods.last_row - 1
138
+ rows.times do |r| #行数
139
+ next unless ods.row(r+2)[0]
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)
147
+ 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
+ end
150
+ end
151
+
152
+ render json: { succcess: true}
153
+ end
154
+
155
+
134
156
  private
135
157
 
136
158
  def sales_detail_params
@@ -12,6 +12,10 @@ 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
+
15
19
  has_many :sale_plans
16
20
  has_many :follow_ups
17
21
  has_many :business_clazz_changes
@@ -21,7 +21,7 @@ module EducodeSales
21
21
  department_years_2 = {} #department_users(2)
22
22
 
23
23
  years = {}
24
- (2018..Time.current.year).each do |d|
24
+ (2014..Time.current.year).each do |d|
25
25
  years[d] = {
26
26
  'year' => d,
27
27
  'user_1' => (user_years_1[d.to_s] || 0) + (years[d-1] && years[d-1]['user_1']).to_i,
@@ -16,12 +16,68 @@
16
16
  </div>
17
17
  <br>
18
18
  <div class="layui-inline" style="padding-top: 20px">
19
- <label class="layui-form-label ">商机来源</label>
20
- <input id="source" type="text" name="source" autocomplete="off" class="layui-input" value="<%=@business.source %>" style="width: 300px;" placeholder="请输入商机来源">
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
21
  </div>
22
22
  <div class="layui-inline" style="padding-top: 20px">
23
23
  <p style="padding-left: 40px">请填写提供本商机的人名(如‘张明’);如果为非头歌用户,请增加单位信息(如‘张明,华为公司’)</p>
24
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 %>">
66
+ </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 %>">
72
+ </div>
73
+ </div>
74
+
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>
25
81
  <% if can?(:merge_business, EducodeSales::Business) %>
26
82
  <div class="layui-inline-block" style="padding-top: 20px">
27
83
  <label class="layui-form-label ">合并商机</label>
@@ -133,6 +189,90 @@
133
189
  data: []
134
190
  })
135
191
 
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
+
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;
249
+ var customer_select = selectInput.render({
250
+ elem: '#customer',
251
+ name: 'customer_id', // 渲染的input的name值
252
+ layFilter: 'test', //同layui form参数lay-filter
253
+ // layVerify: 'required', //同layui form参数lay-verify
254
+ layVerType: 'tips', // 同layui form参数lay-verType
255
+ layReqText: '请填写文本', //同layui form参数lay-ReqText
256
+ initValue: gon.customer_id, // 渲染初始化默认值
257
+ hasSelectIcon: false,
258
+ placeholder: '请输入客户', // 渲染的inputplaceholder值
259
+ data: gon.customer,
260
+ remoteSearch: true, // 是否启用远程搜索 默认是false,和远程搜索回调保存同步
261
+ remoteMethod: function (value, cb) { // 远程搜索的回调函数
262
+ if (!value) {
263
+ customer_id = "";
264
+ return cb([]);
265
+ }
266
+ request.get('missions/search_customer?q=' + value, {}, function (res) {
267
+ if (res.data.length == 0) {
268
+ customer_select.emptyValue();
269
+ return cb([])
270
+ }
271
+ return cb(res)
272
+ })
273
+ }
274
+ });
275
+
136
276
  // 当前弹出层,防止ID被覆盖
137
277
  var parentIndex = layer.index;
138
278
 
@@ -143,9 +283,11 @@
143
283
  return false;
144
284
  } else {
145
285
  var field = data.field;
146
- console.log('field', field)
147
286
  field.department_id = department.getValue() || department_id;
148
287
  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;
149
291
  request.authPut("missions/businesses/" + parent.id, field, function (res) {
150
292
  if (res.success == false) {
151
293
  layer.alert(res.msg)
@@ -0,0 +1,8 @@
1
+ json.data do
2
+ json.array! @data do |d|
3
+ json.value d.id
4
+ json.name d.name
5
+ end
6
+ end
7
+ json.code 0
8
+ json.msg 'succcess'
@@ -0,0 +1,8 @@
1
+ json.data do
2
+ json.array! @data do |d|
3
+ json.value d.id
4
+ json.name "#{d.school.name} #{d.name}"
5
+ end
6
+ end
7
+ json.code 0
8
+ json.msg 'succcess'
@@ -84,19 +84,18 @@
84
84
 
85
85
  </script>
86
86
 
87
- <script type="text/html" id="toolbar_contract">
88
- <div class="layui-btn-container">
89
- <span class="table-label">销售明细</span>
90
- </div>
87
+ <script type="text/html" id="toolbar_sales">
88
+ <button class="layui-btn layui-btn-normal layui-btn-sm data-add-btn pull-right" id="upload_sales_btn" style="margin-left: 20px;">批量导入销售明细</button>
91
89
  </script>
92
90
  <script>
93
- layui.use(['form', 'table', 'miniPage', 'element', 'request', 'laydate', 'dropdown', 'laytpl', 'xmSelect'], function() {
91
+ layui.use(['form', 'table', 'miniPage', 'element', 'request', 'laydate', 'dropdown', 'laytpl', 'xmSelect', 'upload'], function() {
94
92
  var $ = layui.jquery,
95
93
  form = layui.form,
96
94
  request = layui.request,
97
95
  miniPage = layui.miniPage,
98
96
  dropdown = layui.dropdown,
99
97
  xmSelect = layui.xmSelect,
98
+ upload = layui.upload,
100
99
  laydate = layui.laydate;
101
100
  var openWH = miniPage.getOpenWidthHeight();
102
101
  laydate.render({
@@ -181,6 +180,10 @@
181
180
  width: 100,
182
181
  title: '数量',
183
182
  }, {
183
+ field: 'price',
184
+ width: 100,
185
+ title: '单价',
186
+ },{
184
187
  field: 'total_price',
185
188
  width: 100,
186
189
  title: '金额',
@@ -223,14 +226,42 @@
223
226
  title: '销售明细数据表',
224
227
  totalRow: true, //开启合并行
225
228
  cols: cols_table,
226
- toolbar: '#toolbar_contract',
229
+ toolbar: '#toolbar_sales',
227
230
  limit: 20,
228
231
  limits: [10, 15, 20, 30, 40, 50, 60, 70, 80, 90],
229
232
  page: true,
230
233
  skin: 'line',
234
+ done: function() {
235
+ if ($('#upload_sales_btn').length > 0) {
236
+ uploadSales();
237
+ }
238
+ }
231
239
  });
232
240
 
233
-
241
+ function uploadSales() {
242
+ upload.render({
243
+ elem: '#upload_sales_btn'
244
+ ,url: '/missions/sales_details/upload'
245
+ ,accept: 'file' //普通文件
246
+ ,acceptMime: 'application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,application/vnd.ms-excel'
247
+ ,headers: {
248
+ 'X-CSRF-Token': $('meta[name=csrf-token]').attr('content')
249
+ }
250
+ ,before: function(obj){
251
+ layer.load();
252
+ }
253
+ ,done: function(res){
254
+ layer.msg('导入成功');
255
+ table.reload('sales_details_table');
256
+ layer.closeAll('loading'); //关闭loading
257
+ }
258
+ ,error: function(index, upload){
259
+ table.reload('file');
260
+ layer.closeAll('loading'); //关闭loading
261
+ layer.alert('导入失败,请检查文件格式')
262
+ }
263
+ });
264
+ }
234
265
  var sort = {},
235
266
  search = data;
236
267
 
@@ -20,6 +20,7 @@ json.data do
20
20
  json.specification d.product_catalog.specification
21
21
  json.unit d.product_catalog.unit
22
22
  json.amount d.amount
23
+ json.price d.price
23
24
  json.total_price d.total_price
24
25
  json.source_method d.product_catalog.source_method
25
26
  json.custom_clazz d.custom_clazz
data/config/routes.rb CHANGED
@@ -17,12 +17,17 @@ EducodeSales::Engine.routes.draw do
17
17
  get :staff_business, to: "home#staff_business"
18
18
  get :staff_departments, to: "home#staff_departments"
19
19
  get :filter, to: "application#filter"
20
+ get :search_activity, to: "home#search_activity"
21
+ get :search_customer, to: "home#search_customer"
20
22
 
21
23
 
22
24
  resources :sessions do
23
25
  end
24
26
 
25
27
  resources :sales_details do
28
+ collection do
29
+ post :upload
30
+ end
26
31
  end
27
32
 
28
33
  resources :contracts do
@@ -0,0 +1,13 @@
1
+ class AddActivityEducodeSalesBusiness < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :educode_sales_businesses, :activity_id, :integer
4
+ add_column :educode_sales_businesses, :place_id, :integer
5
+ add_column :educode_sales_businesses, :customer_id, :integer
6
+ add_column :educode_sales_businesses, :company_source, :string
7
+ add_column :educode_sales_businesses, :phone, :string
8
+ add_column :educode_sales_businesses, :email, :string
9
+ add_column :educode_sales_businesses, :partner, :string
10
+ add_column :educode_sales_businesses, :invite_info, :string
11
+ add_column :educode_sales_businesses, :friend, :string
12
+ end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module EducodeSales
2
- VERSION = '0.9.97'
2
+ VERSION = '0.9.99'
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.97
4
+ version: 0.9.99
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-19 00:00:00.000000000 Z
11
+ date: 2023-05-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -355,6 +355,8 @@ files:
355
355
  - app/views/educode_sales/home/sales_place.json.jbuilder
356
356
  - app/views/educode_sales/home/sales_staff.json.jbuilder
357
357
  - app/views/educode_sales/home/search.json.jbuilder
358
+ - app/views/educode_sales/home/search_activity.json.jbuilder
359
+ - app/views/educode_sales/home/search_customer.json.jbuilder
358
360
  - app/views/educode_sales/home/search_edu_teacher.json.jbuilder
359
361
  - app/views/educode_sales/home/search_edu_user.json.jbuilder
360
362
  - app/views/educode_sales/home/search_operation_teacher.json.jbuilder
@@ -679,6 +681,7 @@ files:
679
681
  - db/migrate/20230501034307_create_educode_sales_follow_up_trends.rb
680
682
  - db/migrate/20230502142912_create_educode_sales_product_catalogs.rb
681
683
  - db/migrate/20230510144317_create_educode_sales_sales_details.rb
684
+ - db/migrate/20230520023902_add_activity_educode_sales_business.rb
682
685
  - lib/educode_sales.rb
683
686
  - lib/educode_sales/engine.rb
684
687
  - lib/educode_sales/version.rb