educode_sales 1.10.59 → 1.10.71

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/educode_sales/application.js +1 -0
  3. data/app/assets/javascripts/educode_sales/functions.js +24 -0
  4. data/app/controllers/educode_sales/application_controller.rb +11 -3
  5. data/app/controllers/educode_sales/business_courses_controller.rb +19 -8
  6. data/app/controllers/educode_sales/follow_ups_controller.rb +4 -0
  7. data/app/controllers/educode_sales/plans_controller.rb +448 -124
  8. data/app/controllers/educode_sales/shixuns_controller.rb +20 -10
  9. data/app/controllers/educode_sales/subjects_controller.rb +10 -6
  10. data/app/controllers/educode_sales/teacher_follows_controller.rb +4 -0
  11. data/app/controllers/educode_sales/teachers_controller.rb +3 -0
  12. data/app/models/educode_sales/business.rb +5 -5
  13. data/app/models/educode_sales/sales_target.rb +10 -0
  14. data/app/models/educode_sales/sales_target_log.rb +11 -0
  15. data/app/views/educode_sales/business_courses/index.html.erb +1 -1
  16. data/app/views/educode_sales/business_courses/new.html.erb +2 -2
  17. data/app/views/educode_sales/businesses/_follows.html.erb +107 -100
  18. data/app/views/educode_sales/businesses/index.html.erb +6 -3
  19. data/app/views/educode_sales/businesses/index.json.jbuilder +2 -2
  20. data/app/views/educode_sales/businesses/show_follow.json.jbuilder +1 -1
  21. data/app/views/educode_sales/contracts/_follows.html.erb +75 -69
  22. data/app/views/educode_sales/contracts/_list.html.erb +283 -249
  23. data/app/views/educode_sales/contracts/index.json.jbuilder +1 -1
  24. data/app/views/educode_sales/follow_ups/index.json.jbuilder +1 -1
  25. data/app/views/educode_sales/plans/_year_execute.html.erb +294 -159
  26. data/app/views/educode_sales/plans/_year_target.html.erb +330 -215
  27. data/app/views/educode_sales/plans/index.html.erb +3 -4
  28. data/app/views/educode_sales/plans/staff_year_business.html.erb +96 -0
  29. data/app/views/educode_sales/plans/staff_year_business.json.jbuilder +22 -0
  30. data/app/views/educode_sales/plans/staff_year_target.json.jbuilder +35 -0
  31. data/app/views/educode_sales/plans/staff_year_target_log.html.erb +62 -0
  32. data/app/views/educode_sales/plans/staff_year_target_log.json.jbuilder +34 -0
  33. data/app/views/educode_sales/plans/years_all_target.json.jbuilder +5 -4
  34. data/app/views/educode_sales/sales_details/_index.html.erb +6 -3
  35. data/app/views/educode_sales/shixun_dectects/markdown.html.erb +40 -1
  36. data/app/views/educode_sales/shixuns/index.html.erb +106 -97
  37. data/app/views/educode_sales/shixuns/new.html.erb +2 -2
  38. data/app/views/educode_sales/staffs/index.json.jbuilder +1 -1
  39. data/app/views/educode_sales/subjects/index.html.erb +1 -1
  40. data/app/views/educode_sales/subjects/new.html.erb +2 -2
  41. data/app/views/educode_sales/teachers/_follows.html.erb +24 -17
  42. data/app/views/educode_sales/teachers/_index.html.erb +6 -0
  43. data/app/views/layouts/educode_sales/application.html.erb +6 -3
  44. data/config/environments/development.rb +16 -0
  45. data/config/routes.rb +7 -0
  46. data/db/migrate/20230729085359_create_educode_sales_sales_target_histories.rb +1 -1
  47. data/lib/educode_sales/version.rb +1 -1
  48. metadata +11 -2
@@ -141,7 +141,10 @@
141
141
  </div>
142
142
  </script>
143
143
  <script>
144
- layui.use(['form', 'table', 'miniPage', 'element', 'request', 'laydate', 'dropdown','laytpl', 'xmSelect'], function () {
144
+ layui.use(['form', 'table', 'miniPage', 'element', 'request', 'laydate', 'dropdown','laytpl', 'xmSelect', 'functions'], function () {
145
+ var layer = layui.layer;
146
+ var functions = layui.functions;
147
+
145
148
  var $ = layui.jquery,
146
149
  form = layui.form,
147
150
  request = layui.request,
@@ -239,267 +242,275 @@
239
242
  })
240
243
  index_place_list.setValue(gon.place)
241
244
 
242
-
243
- var data = form.val("search_form");
244
- table = layui.table;
245
- var cols_table = [
246
- [
247
- {
248
- field: 'id',
249
- width: 60,
250
- title: '序号', type: 'numbers',
251
- totalRowText: '合计',
252
- fixed: "left"
253
- },
254
- {
255
- field: 'number',
256
- width: 120,
257
- title: '编号',
258
- fixed: 'left',
259
- },
260
- {
261
- field: 'name',
262
- width: 170,
263
- title: '商机名称',
264
- templet: '<div><a href="javascript:void(0);" class="layui-table-link" lay-event="show_business"><span title="{{d.name}}">{{d.name}}</span></a></div>',
265
- fixed: 'left',
266
- },
267
- {
268
- field: 'name',
245
+ var data = form.val("search_form");
246
+ table = layui.table;
247
+ var cols_table = [
248
+ {
249
+ field: 'id',
250
+ width: 60,
251
+ title: '序号', type: 'numbers',
252
+ totalRowText: '合计',
253
+ fixed: "left"
254
+ },
255
+ {
256
+ field: 'number',
269
257
  width: 120,
270
- title: '合同名称',
271
- },
272
- {
273
- field: 'area',
274
- width: 100,
275
- title: '地域',
276
- },
277
- {
278
- field: 'school',
279
- width: 150,
280
- title: '用户单位',
281
- templet: '#school_name',
282
- },
283
- {
284
- field: 'property',
285
- width: 150,
286
- title: '客户类型',
287
- },
288
- {
289
- field: 'department',
290
- width: 150,
291
- title: '部门',
292
- templet: '<div><span title="{{d.department}}">{{d.department}}</span></div>',
293
- },
294
- {
295
- field: 'follow_ups_count',
296
- title: '跟进',
297
- width: 60,
298
- templet: '#show_follow',
299
- totalRow: true,
300
- },
301
- {
302
- field: 'clazz',
303
- width: 80,
304
- title: '类型',
305
- templet: "<div><span title='{{d.clazz}}' class='changed-{{d.clazz_changed}}'>{{d.clazz}}</span></div>",
306
- },
307
- {
308
- field: 'stage',
309
- width: 90,
310
- title: '阶段',
311
- },
312
- {
313
- field: 'staff_manages',
258
+ title: '编号',
259
+ fixed: 'left',
260
+ },
261
+ {
262
+ field: 'bname',
263
+ width: 170,
264
+ title: '商机名称',
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
+ fixed: 'left',
267
+ },
268
+ {
269
+ field: 'name',
270
+ width: 120,
271
+ title: '合同名称',
272
+ },
273
+ {
274
+ field: 'area',
275
+ width: 100,
276
+ title: '地域',
277
+ },
278
+ {
279
+ field: 'school',
314
280
  width: 150,
315
- title: '销售经理',
316
- },
317
- {
318
- field: 'assign_staffs',
281
+ title: '用户单位',
282
+ templet: '#school_name',
283
+ },
284
+ {
285
+ field: 'property',
319
286
  width: 150,
320
- title: '售后工程师',
321
- },
322
- {
323
- field: 'source',
324
- width: 90,
325
- title: '商机来源',
326
- },
327
- {
328
- field: 'last_follow_person',
329
- width: 100,
330
- title: '最新跟进人',
331
- },
332
- {
333
- field: 'no_followup_days',
334
- width: 100,
335
- title: '无跟进天数',
336
- },
337
- {
338
- field: 'created_at',
339
- width: 200,
340
- title: '商机创建时间',
341
- sort: true,
342
- },
343
- {
344
- field: 'latest_time',
345
- width: 200,
346
- title: '最新跟进时间',
347
- sort: true,
348
- },
349
- {
350
- field: 'invitation_at',
351
- width: 105,
352
- title: '计划投标时间',
353
- sort: true,
354
- },
355
- {
356
- field: 'bidded_date',
357
- width: 105,
358
- title: '中标时间',
359
- sort: true,
360
- },
361
- {
362
- field: 'signed_date',
363
- width: 105,
364
- title: '签单时间',
365
- sort: true,
366
- },
367
- {
368
- field: 'reception_at',
369
- width: 105,
370
- title: '验收时间',
371
- sort: true,
372
- },
373
- {
374
- field: 'service_end_time',
375
- width: 200,
376
- title: '服务期',
377
- sort: true,
378
- },
379
- {
380
- field: 'o_business_deployment',
381
- width: 150,
382
- title: '部署类型',
383
- sort: true,
384
- },
385
- {
386
- field: 'p_deploy_time',
387
- width: 150,
388
- title: '部署时间',
389
- sort: true,
390
- },
391
- {
392
- field: 'budget_amount',
393
- width: 105,
394
- title: '预算金额',
395
- totalRow: true,
396
- sort: true,
397
- },
398
- {
399
- field: 'total_amount',
400
- width: 100,
401
- title: '中标额',
402
- totalRow: true,
403
- sort: true,
404
- },
405
- {
406
- field: 'actual_amount',
407
- width: 100,
408
- title: '合同额',
409
- totalRow: true,
410
- sort: true,
411
- },
412
- {
413
- field: 'return_money',
414
- width: 100,
415
- title: '回款',
416
- sort: true,
417
- totalRow: true,
418
- },
419
- {
420
- field: 'wait_return_money',
421
- width: 100,
422
- title: '待回款',
423
- sort: true,
424
- totalRow: true,
425
- },
426
- {
427
- field: 'return_money_days',
428
- width: 150,
429
- title: '首次回款周期(天)',
430
- },
431
- {
432
- field: 'divide_rate',
433
- width: 160,
434
- title: '渠道分成比例',
287
+ title: '客户类型',
288
+ },
289
+ {
290
+ field: 'department',
291
+ width: 150,
292
+ title: '部门',
293
+ templet: '<div><span title="{{d.department}}">{{d.department}}</span></div>',
294
+ },
295
+ {
296
+ field: 'follow_ups_count',
297
+ title: '跟进',
298
+ width: 60,
299
+ templet: '#show_follow',
300
+ totalRow: true,
301
+ },
302
+ {
303
+ field: 'clazz',
304
+ width: 80,
305
+ title: '类型',
306
+ templet: "<div><span title='{{d.clazz}}' class='changed-{{d.clazz_changed}}'>{{d.clazz}}</span></div>",
307
+ },
308
+ {
309
+ field: 'stage',
310
+ width: 90,
311
+ title: '阶段',
312
+ },
313
+ {
314
+ field: 'staff_manages',
315
+ width: 150,
316
+ title: '销售经理',
317
+ },
318
+ {
319
+ field: 'assign_staffs',
320
+ width: 150,
321
+ title: '售后工程师',
322
+ },
323
+ {
324
+ field: 'source',
325
+ width: 90,
326
+ title: '商机来源',
327
+ },
328
+ {
329
+ field: 'last_follow_person',
330
+ width: 100,
331
+ title: '最新跟进人',
332
+ },
333
+ {
334
+ field: 'no_followup_days',
335
+ width: 100,
336
+ title: '无跟进天数',
337
+ },
338
+ {
339
+ field: 'created_at',
340
+ width: 200,
341
+ title: '商机创建时间',
435
342
  sort: true,
436
- },
437
- {
438
- field: 'divide_money',
439
- width: 160,
440
- title: '渠道分成金额',
343
+ },
344
+ {
345
+ field: 'latest_time',
346
+ width: 200,
347
+ title: '最新跟进时间',
441
348
  sort: true,
442
- },
443
- {
444
- field: 'place',
445
- width: 160,
446
- title: '渠道',
447
- },
448
- {
449
- field: 'sale_way',
450
- width: 160,
451
- title: '销售方式',
452
- },
453
- {
454
- field: 'year',
455
- width: 105,
456
- title: '所属年度',
457
- sort: true,
458
- },
459
- {
460
- field: 'followed',
461
- templet:function(d){
462
- if (d.followed==1){
463
- return '<i class="layui-icon" style="color: goldenrod">&#xe658;</i> '
464
- }
465
- else return ''
466
- },
467
- width: 105,
468
- title: '关注',
469
- align: "center",
470
-
471
- },
472
- {
473
- title: '操作',
474
- minWidth: 300,
475
- toolbar: '#currentTableBar',
476
- align: "center",
477
- fixed: 'right'
478
- }
479
- ]
480
- ]
349
+ },
350
+ {
351
+ field: 'invitation_at',
352
+ width: 105,
353
+ title: '计划投标时间',
354
+ sort: true,
355
+ },
356
+ {
357
+ field: 'bidded_date',
358
+ width: 105,
359
+ title: '中标时间',
360
+ sort: true,
361
+ },
362
+ {
363
+ field: 'signed_date',
364
+ width: 105,
365
+ title: '签单时间',
366
+ sort: true,
367
+ },
368
+ {
369
+ field: 'reception_at',
370
+ width: 105,
371
+ title: '验收时间',
372
+ sort: true,
373
+ },
374
+ {
375
+ field: 'service_end_time',
376
+ width: 200,
377
+ title: '服务期',
378
+ sort: true,
379
+ },
380
+ {
381
+ field: 'o_business_deployment',
382
+ width: 150,
383
+ title: '部署类型',
384
+ sort: true,
385
+ },
386
+ {
387
+ field: 'p_deploy_time',
388
+ width: 150,
389
+ title: '部署时间',
390
+ sort: true,
391
+ },
392
+ {
393
+ field: 'budget_amount',
394
+ width: 105,
395
+ title: '预算金额',
396
+ totalRow: true,
397
+ sort: true,
398
+ },
399
+ {
400
+ field: 'total_amount',
401
+ width: 100,
402
+ title: '中标额',
403
+ totalRow: true,
404
+ sort: true,
405
+ },
406
+ {
407
+ field: 'actual_amount',
408
+ width: 100,
409
+ title: '合同额',
410
+ totalRow: true,
411
+ sort: true,
412
+ },
413
+ {
414
+ field: 'return_money',
415
+ width: 100,
416
+ title: '回款',
417
+ sort: true,
418
+ totalRow: true,
419
+ },
420
+ {
421
+ field: 'wait_return_money',
422
+ width: 100,
423
+ title: '待回款',
424
+ sort: true,
425
+ totalRow: true,
426
+ },
427
+ {
428
+ field: 'return_money_days',
429
+ width: 150,
430
+ title: '首次回款周期(天)',
431
+ },
432
+ {
433
+ field: 'divide_rate',
434
+ width: 160,
435
+ title: '渠道分成比例',
436
+ sort: true,
437
+ },
438
+ {
439
+ field: 'divide_money',
440
+ width: 160,
441
+ title: '渠道分成金额',
442
+ sort: true,
443
+ },
444
+ {
445
+ field: 'place',
446
+ width: 160,
447
+ title: '渠道',
448
+ },
449
+ {
450
+ field: 'sale_way',
451
+ width: 160,
452
+ title: '销售方式',
453
+ },
454
+ {
455
+ field: 'year',
456
+ width: 105,
457
+ title: '所属年度',
458
+ sort: true,
459
+ },
460
+ {
461
+ field: 'followed',
462
+ templet:function(d){
463
+ if (d.followed==1){
464
+ return '<i class="layui-icon" style="color: goldenrod">&#xe658;</i> '
465
+ }
466
+ else return ''
467
+ },
468
+ width: 105,
469
+ title: '关注',
470
+ align: "center",
481
471
 
472
+ },
473
+ {
474
+ title: '操作',
475
+ minWidth: 300,
476
+ toolbar: '#currentTableBar',
477
+ align: "center",
478
+ fixed: 'right'
479
+ }
480
+ ];
481
+ functions.initTableColumnsFilter('contact_table', cols_table);
482
482
 
483
483
  form.on('submit(show_hide_contract)', function (data) {
484
484
  $(".show_item_contract").toggle()
485
485
  return false;
486
486
  });
487
- var contract_table = table.render({
488
- elem: '#contact_table',
489
- // url: '/missions/contracts',
490
- autoSort: false,
491
- where: {q: data},
492
- defaultToolbar: ['filter'],
493
- title: '合同数据表',
494
- totalRow: true,//开启合并行
495
- cols: cols_table,
496
- toolbar: '#toolbar_contract',
497
- limit: 20,
498
- limits: [10,15,20,30,40,50,60,70,80,90],
499
- page: true,
500
- skin: 'line',
487
+ var contract_table = table.render({
488
+ elem: '#contact_table',
489
+ // url: '/missions/contracts',
490
+ autoSort: false,
491
+ where: {q: data},
492
+ defaultToolbar: ['filter'],
493
+ title: '合同数据表',
494
+ totalRow: true,//开启合并行
495
+ cols: [cols_table],
496
+ toolbar: '#toolbar_contract',
497
+ limit: 20,
498
+ limits: [10,15,20,30,40,50,60,70,80,90],
499
+ page: true,
500
+ skin: 'line',
501
+ done: function () {
502
+ var that = this;
503
+ functions.observerTableColumnFilter(that);
504
+ }
501
505
  });
502
506
 
507
+ // 获取上次的筛选状态
508
+ var savedFilter = localStorage.getItem('tableFilter.contracts');
509
+ if (savedFilter) {
510
+ var filterObj = JSON.parse(savedFilter);
511
+ table.reload('contact_table', { where: filterObj });
512
+ }
513
+
503
514
  if (gon.bidded_date) {
504
515
  table.reload('contact_table', {
505
516
  url: '/missions/contracts',
@@ -582,6 +593,29 @@
582
593
  }
583
594
  });
584
595
 
596
+ table.on('filter(contact_table)', function (obj) {
597
+ console.log(obj.event);
598
+ if (obj.event === 'export') { //导出
599
+ layer.load(0, {});
600
+ var data = form.val("search_form");
601
+ var business_step = [];
602
+ business_step_list.getValue().forEach(function(d) {
603
+ business_step.push(d.value);
604
+ });
605
+ data.business_step = business_step.toString();
606
+ request.authGet("missions/contracts?" + $.param({q:data}), {
607
+ }, function (res) {
608
+ data = res.data;
609
+ table.exportFile(contract_table.config.id, data, 'xls');
610
+ layer.closeAll('loading');
611
+ })
612
+ } else if (obj.event === 'filter') {
613
+ console.log(11111);
614
+ var filter = table.filter('contact_table'); // 获取当前的筛选状态
615
+ localStorage.setItem('tableFilter.contracts', JSON.stringify(filter)); // 保存筛选状态
616
+ }
617
+ });
618
+
585
619
  table.on('tool(contact_table)', function (obj) {
586
620
  var data = obj.data;
587
621
  id = data.id
@@ -26,7 +26,7 @@ json.data do
26
26
  json.created_at d.created_at.to_s
27
27
  json.no_followup_days (d['latest_time'] ? DateTime.parse(Time.now.strftime("%Y-%m-%d")) - DateTime.parse(d['latest_time'].strftime("%Y-%m-%d")) : DateTime.parse(Time.now.strftime("%Y-%m-%d")) - DateTime.parse(d.created_at.strftime("%Y-%m-%d"))).to_i
28
28
 
29
- json.staff_manages 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
29
+ json.staff_manages 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
30
30
  json.divide_rate d.divide_rate
31
31
  json.divide_money d.divide_amount.to_f.round(2)
32
32
  json.budget_amount d.budget_amount.to_f.round(2) #d.follow_ups.where(stage_id: @budget_stage_ids).order("created_at desc").first&.total_amount&.round(2) || 0
@@ -12,7 +12,7 @@ json.data do
12
12
  json.business d.business.name
13
13
  json.business_id d.business.id
14
14
  json.rival d.rival || ''
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
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
16
  # teacher_ids = d.key_person.pluck(:teacher_id)
17
17
  json.tel d.key_person.pluck(:tel).select { |d| d.present? }.join("、")
18
18
  json.key_people d.key_person.map { |d| d.name }.join("、")# key_people(teacher_ids)