educode_sales 0.9.83 → 0.9.86
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 +28 -3
- data/app/controllers/educode_sales/sale_trends_controller.rb +1 -1
- data/app/controllers/educode_sales/sales_details_controller.rb +141 -0
- data/app/helpers/educode_sales/sale_trends_helper.rb +225 -135
- data/app/models/educode_sales/follow_up.rb +2 -0
- data/app/models/educode_sales/sale_trend.rb +3 -3
- data/app/models/educode_sales/sales_detail.rb +8 -0
- data/app/services/return_forecast_service.rb +230 -0
- data/app/views/educode_sales/contracts/_list.html.erb +22 -1
- data/app/views/educode_sales/contracts/new_follow_up.html.erb +9 -3
- data/app/views/educode_sales/contracts/new_sales_detail.html.erb +116 -0
- data/app/views/educode_sales/contracts/select_product.html.erb +126 -0
- data/app/views/educode_sales/sale_trends/_goal_forecast.html.erb +5 -2
- data/app/views/educode_sales/sales_details/edit.html.erb +115 -0
- data/app/views/educode_sales/sales_details/index.html.erb +401 -0
- data/app/views/educode_sales/sales_details/index.json.jbuilder +34 -0
- data/app/views/layouts/educode_sales/application.html.erb +4 -0
- data/config/routes.rb +6 -0
- data/db/migrate/20230510144317_create_educode_sales_sales_details.rb +20 -0
- data/lib/educode_sales/version.rb +1 -1
- metadata +14 -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: 85457062bb8c20c8e1703353efcb1f958eb39d5e15ca0936efac9f58ca720184
|
4
|
+
data.tar.gz: f115e02bf7cdfc392673bf27c533fd6d6cbb87a462936708eb3d1e8e093607f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d0b2b9d028276ee69d72a5e480772c4676c341c8390c6bdfad9880bb9b303f8ab004c9ca2b52f44a9b0bf20e6d259a5973bb0fa83f022b4fa23cb96f27ac581
|
7
|
+
data.tar.gz: 2ee2104f1259feac76bc7d562616e266cce1488d5785e5383158dab5450799b7d3436822f29d57d3ae9f3c7044fb94815f3dec0450890ea6a1ef0db2451359af
|
@@ -233,12 +233,14 @@ module EducodeSales
|
|
233
233
|
@business = Business.find(params[:id])
|
234
234
|
@last_follow_up = @business.last_follow_up
|
235
235
|
@deployment_type = EducodeSales::FollowUp::BUSINESS_DEPLOYMENT
|
236
|
+
@signed_clazz = EducodeSales::FollowUp.signed_clazzs.keys
|
237
|
+
|
236
238
|
signed_department = @last_follow_up.signed_department
|
237
239
|
if signed_department
|
238
|
-
gon.department = {value: signed_department.id, name: "#{signed_department&.school&.name}-#{signed_department&.name}"}
|
240
|
+
gon.department = [{value: signed_department.id, name: "#{signed_department&.school&.name}-#{signed_department&.name}"}]
|
239
241
|
gon.value = signed_department.id
|
240
242
|
else
|
241
|
-
gon.department =
|
243
|
+
gon.department = []
|
242
244
|
gon.value = ''
|
243
245
|
end
|
244
246
|
|
@@ -452,13 +454,36 @@ module EducodeSales
|
|
452
454
|
render layout: false
|
453
455
|
end
|
454
456
|
|
457
|
+
def new_sales_detail
|
458
|
+
render layout: false
|
459
|
+
end
|
460
|
+
|
461
|
+
def select_product
|
462
|
+
render layout: false
|
463
|
+
end
|
464
|
+
|
465
|
+
def sales_detail
|
466
|
+
sales_detail = SalesDetail.new(sales_detail_params)
|
467
|
+
sales_detail.staff = @current_admin
|
468
|
+
if sales_detail.save
|
469
|
+
render_success
|
470
|
+
else
|
471
|
+
render_failure sales_detail
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
455
475
|
private
|
456
476
|
def follow_up_params
|
457
|
-
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)
|
477
|
+
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, :signed_clazz)
|
458
478
|
end
|
459
479
|
|
460
480
|
def product_up_params
|
461
481
|
params.permit(:name, :item_clazz, :brand, :specification, :unit, :param, :source_method, :supplier)
|
462
482
|
end
|
483
|
+
|
484
|
+
def sales_detail_params
|
485
|
+
params.permit(:amount, :price, :total_price, :custom_clazz, :delivery_date, :product_catalog_id, :business_id)
|
486
|
+
end
|
487
|
+
|
463
488
|
end
|
464
489
|
end
|
@@ -391,7 +391,7 @@ module EducodeSales
|
|
391
391
|
staff_id = params[:staff_id] || nil
|
392
392
|
@forecast_count_range = params[:forecast_count_range] || "month"
|
393
393
|
forecast_default_dates = ("#{Time.now.year}-01-01".to_date.."#{Time.now.year}-#{Time.now.month}-01".to_date).map { |d| d.strftime("%Y-%m") }.uniq
|
394
|
-
sale_names = %w[计划投标额 实际中标额]
|
394
|
+
sale_names = %w[计划投标额 计划投标额累计 实际中标额 实际中标额累计]
|
395
395
|
case @forecast_count_range
|
396
396
|
when "week"
|
397
397
|
# 年初第一天周数是0会导致周数重复计算
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require_dependency "educode_sales/application_controller"
|
2
|
+
|
3
|
+
module EducodeSales
|
4
|
+
class SalesDetailsController < ApplicationController
|
5
|
+
|
6
|
+
def index
|
7
|
+
respond_to do |format|
|
8
|
+
format.html do
|
9
|
+
common = Common.find_by(clazz: 'staff_type', name: '销售')
|
10
|
+
staffs = Staff.joins(:user).where(job_type: common.id).where.not(role_id: 11)
|
11
|
+
@staffs = staffs.map { |d| [d.user.real_name, d.id]}
|
12
|
+
gon.place = params[:place_id].present? ? [{ value: params[:place_id], name: EducodeSales::Place.find(params[:place_id]).name }] : []
|
13
|
+
gon.staffs = staffs.map { |d| {name: d.user.real_name, value: d.id } }
|
14
|
+
|
15
|
+
bussiness_type = []
|
16
|
+
if params[:type]
|
17
|
+
# 项目类型
|
18
|
+
bussiness_type = EducodeSales::Business.include_types(params[:type]) || []
|
19
|
+
end
|
20
|
+
|
21
|
+
business_step = []
|
22
|
+
if params[:step]
|
23
|
+
# 项目阶段
|
24
|
+
business_step = EducodeSales::Business.include_steps(params[:step]) || []
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
gon.business_type = Common.where(clazz: 'business_type').map do |d|
|
29
|
+
{value: d.id, name: d.name, selected: bussiness_type.include?(d.extras)}
|
30
|
+
end
|
31
|
+
|
32
|
+
gon.business_step = Common.where(clazz: 'business_step', name: ['已中标', '已签单', '已验收', '回款中', '服务中', '已结束']).order("position").map do |d|
|
33
|
+
{value: d.id, name: d.name, selected: business_step.include?(d.name)}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
format.json do
|
37
|
+
@sales_details = SalesDetail
|
38
|
+
@sales_details = @sales_details.joins(:business).includes(:business, :product_catalog)
|
39
|
+
|
40
|
+
if params[:q] && params[:q][:signed_date].present?
|
41
|
+
date = params[:q][:signed_date].split(" - ")
|
42
|
+
@sales_details = @sales_details.joins("
|
43
|
+
JOIN educode_sales_follow_ups ON educode_sales_businesses.last_follow_up_id = educode_sales_follow_ups.id
|
44
|
+
").where("educode_sales_follow_ups.signed_date >= ? AND educode_sales_follow_ups.signed_date <= ?", date[0], date[1])
|
45
|
+
end
|
46
|
+
|
47
|
+
if params[:q] && params[:q][:bidded_date].present?
|
48
|
+
date = params[:q][:bidded_date].split(" - ")
|
49
|
+
@sales_details = @sales_details.joins("
|
50
|
+
JOIN educode_sales_follow_ups ON educode_sales_businesses.last_follow_up_id = educode_sales_follow_ups.id
|
51
|
+
").where("educode_sales_follow_ups.bidded_date >= ? AND educode_sales_follow_ups.bidded_date <= ?", date[0], date[1])
|
52
|
+
end
|
53
|
+
|
54
|
+
if params[:q].present? && params[:q][:name].present?
|
55
|
+
@sales_details = @sales_details.where("educode_sales_businesses.name like ?", "%#{params[:q][:name]}%")
|
56
|
+
end
|
57
|
+
|
58
|
+
if params[:sort].present? && params[:sort][:field]
|
59
|
+
@sales_details = @sales_details.order("#{params[:sort][:field]} #{params[:sort][:order]}")
|
60
|
+
else
|
61
|
+
@sales_details = @sales_details.order("educode_sales_sales_details.created_at desc")
|
62
|
+
end
|
63
|
+
|
64
|
+
if params[:q].present? && params[:q][:business_step].present?
|
65
|
+
@sales_details = @sales_details.joins("
|
66
|
+
JOIN educode_sales_follow_ups ON educode_sales_businesses.last_follow_up_id = educode_sales_follow_ups.id
|
67
|
+
").where("educode_sales_follow_ups.stage_id in (?)", params[:q][:business_step].split(",").map(&:to_i))
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
if params[:q].present? && params[:q][:sales_staff_id].present?
|
72
|
+
# 销售经理
|
73
|
+
@sales_details = @sales_details.joins("LEFT JOIN educode_sales_assign_follow_ups ON educode_sales_assign_follow_ups.follow_up_id = educode_sales_businesses.last_follow_up_id").
|
74
|
+
where("(educode_sales_assign_follow_ups.id IS NOT NULL AND educode_sales_assign_follow_ups.staff_id = ?) OR (educode_sales_assign_follow_ups.id IS NULL AND educode_sales_businesses.staff_id = ?)", params[:q][:sales_staff_id], params[:q][:sales_staff_id])
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
if params[:q].present? && params[:q][:department].present?
|
79
|
+
departments_ids = Department.joins(:school).where("schools.name like ?", "%#{params[:q][:department]}%").pluck(:id)
|
80
|
+
@sales_details = @sales_details.joins(business: :department).where("departments.id in (?)", departments_ids)
|
81
|
+
end
|
82
|
+
|
83
|
+
if params[:q].present? && params[:q][:area].present?
|
84
|
+
area = EducodeSales::Common.find(params[:q][:area]).name
|
85
|
+
if @current_admin.is_admin?
|
86
|
+
@sales_details = @sales_details.joins("
|
87
|
+
JOIN departments ON educode_sales_businesses.department_id = departments.id
|
88
|
+
JOIN schools ON departments.school_id = schools.id
|
89
|
+
").where("province = ?", area)
|
90
|
+
else
|
91
|
+
level = @current_admin.role.role_areas.find_by(clazz: '商机管理').level
|
92
|
+
if level == "区域"
|
93
|
+
@sales_details = @sales_details.joins("
|
94
|
+
JOIN schools ON departments.school_id = schools.id
|
95
|
+
").where("province = ?", area)
|
96
|
+
else
|
97
|
+
@sales_details = @sales_details.joins("
|
98
|
+
JOIN departments ON educode_sales_businesses.department_id = departments.id
|
99
|
+
JOIN schools ON departments.school_id = schools.id
|
100
|
+
").where("province = ?", area)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
@sales_details = @sales_details.page(params[:page]).per(params[:limit])
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def destroy
|
111
|
+
sales_detail = SalesDetail.find(params[:id])
|
112
|
+
if sales_detail.destroy
|
113
|
+
render_success
|
114
|
+
else
|
115
|
+
render_failure sales_detail
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def edit
|
120
|
+
@sale_detail = SalesDetail.find(params[:id])
|
121
|
+
@name = [@sale_detail.business.name, @sale_detail.product_catalog.item_clazz, @sale_detail.product_catalog.brand, @sale_detail.product_catalog.specification, @sale_detail.product_catalog.unit, @sale_detail.product_catalog.source_method, @sale_detail.product_catalog.param, @sale_detail.product_catalog.supplier].join(" ")
|
122
|
+
render layout: false
|
123
|
+
end
|
124
|
+
|
125
|
+
def update
|
126
|
+
sale_detail = SalesDetail.find(params[:id])
|
127
|
+
if sale_detail.update(sales_detail_params)
|
128
|
+
render_success
|
129
|
+
else
|
130
|
+
render_failure sale_detail
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
private
|
135
|
+
|
136
|
+
def sales_detail_params
|
137
|
+
params.permit(:amount, :price, :total_price, :custom_clazz, :delivery_date, :product_catalog_id)
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
end
|
@@ -1,45 +1,58 @@
|
|
1
1
|
module EducodeSales
|
2
2
|
module SaleTrendsHelper
|
3
|
-
|
3
|
+
NAMES = %w[计划投标额 计划投标额累计 实际中标额 实际中标额累计]
|
4
4
|
def goal_forecast_quarter(labels, selects, staff_id = nil)
|
5
5
|
plan_get = plan_get(staff_id, labels, "quarter")
|
6
6
|
actual_get = actual_get(staff_id, labels, "quarter")
|
7
|
-
datasets = selects.map do |select|
|
8
|
-
if select ==
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
7
|
+
datasets = selects.map.with_index do |select, i|
|
8
|
+
data = if select == NAMES[0]
|
9
|
+
labels.map do |d|
|
10
|
+
quarter = d.split("-").last.to_i
|
11
|
+
year = d.split("-").first.to_i
|
12
|
+
plan_get[[year, quarter]]&.pluck(:budget_amount)&.reject(&:blank?)&.sum.to_f
|
13
|
+
end
|
14
|
+
elsif select == NAMES[1]
|
15
|
+
arr = labels.map do |d|
|
16
|
+
quarter = d.split("-").last.to_i
|
17
|
+
year = d.split("-").first.to_i
|
18
|
+
plan_get[[year, quarter]]&.pluck(:budget_amount)&.reject(&:blank?)&.sum.to_f
|
19
|
+
end
|
20
|
+
arr.map.with_index(1) { |num, i| arr.first(i).inject(:+) }
|
21
|
+
elsif select == NAMES[2]
|
22
|
+
labels.map do |d|
|
23
|
+
quarter = d.split("-").last.to_i
|
24
|
+
year = d.split("-").first.to_i
|
25
|
+
actual_get[[year, quarter]]&.pluck(:actual_amount)&.reject(&:blank?)&.sum.to_f
|
26
|
+
end
|
27
|
+
elsif select == NAMES[3]
|
28
|
+
arr = labels.map do |d|
|
29
|
+
quarter = d.split("-").last.to_i
|
30
|
+
year = d.split("-").first.to_i
|
31
|
+
actual_get[[year, quarter]]&.pluck(:actual_amount)&.reject(&:blank?)&.sum.to_f
|
32
|
+
end
|
33
|
+
arr.map.with_index(1) { |num, i| arr.first(i).inject(:+) }
|
34
|
+
end
|
35
|
+
type = if select == NAMES[3] || select == NAMES[1]
|
36
|
+
'line'
|
37
|
+
else
|
38
|
+
"bar"
|
39
|
+
end
|
40
|
+
backgroundColor = if select == NAMES[3] || select == NAMES[1]
|
41
|
+
'rgba(54, 162, 235, 0.2)'
|
42
|
+
else
|
43
|
+
SaleTrend::COLORS[i]
|
44
|
+
end
|
45
|
+
{
|
46
|
+
type: type,
|
47
|
+
label: select,
|
48
|
+
data: data,
|
49
|
+
backgroundColor:
|
50
|
+
backgroundColor,
|
51
|
+
borderColor:
|
52
|
+
SaleTrend::COLORS[i],
|
53
|
+
borderWidth: 1
|
54
|
+
}
|
41
55
|
end
|
42
|
-
|
43
56
|
{
|
44
57
|
labels: labels,
|
45
58
|
datasets: datasets
|
@@ -50,42 +63,58 @@ module EducodeSales
|
|
50
63
|
|
51
64
|
plan_get = plan_get(staff_id, labels, "week")
|
52
65
|
actual_get = actual_get(staff_id, labels, "week")
|
53
|
-
datasets = selects.map do |select|
|
54
|
-
if select ==
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
66
|
+
datasets = selects.map.with_index do |select, i|
|
67
|
+
data = if select == NAMES[0]
|
68
|
+
labels.map do |d|
|
69
|
+
week = d.split("-").last
|
70
|
+
year = d.split("-").first
|
71
|
+
yearweek = "#{year}#{week}".to_i
|
72
|
+
plan_get[yearweek].to_f
|
73
|
+
end
|
74
|
+
elsif select == NAMES[1]
|
75
|
+
arr = labels.map do |d|
|
76
|
+
week = d.split("-").last
|
77
|
+
year = d.split("-").first
|
78
|
+
yearweek = "#{year}#{week}".to_i
|
79
|
+
plan_get[yearweek].to_f
|
80
|
+
end
|
81
|
+
arr.map.with_index(1) { |num, i| arr.first(i).inject(:+) }
|
82
|
+
elsif select == NAMES[2]
|
83
|
+
labels.map do |d|
|
84
|
+
week = d.split("-").last
|
85
|
+
year = d.split("-").first
|
86
|
+
yearweek = "#{year}#{week}".to_i
|
87
|
+
actual_get[yearweek].to_f
|
88
|
+
end
|
89
|
+
elsif select == NAMES[3]
|
90
|
+
arr = labels.map do |d|
|
91
|
+
week = d.split("-").last
|
92
|
+
year = d.split("-").first
|
93
|
+
yearweek = "#{year}#{week}".to_i
|
94
|
+
actual_get[yearweek].to_f
|
95
|
+
end
|
96
|
+
arr.map.with_index(1) { |num, i| arr.first(i).inject(:+) }
|
97
|
+
end
|
98
|
+
type = if select == NAMES[0] || select == NAMES[2]
|
99
|
+
'bar'
|
100
|
+
else
|
101
|
+
"line"
|
102
|
+
end
|
103
|
+
backgroundColor = if select == NAMES[0] || select == NAMES[2]
|
104
|
+
SaleTrend::COLORS[i]
|
105
|
+
else
|
106
|
+
'rgba(54, 162, 235, 0.2)'
|
107
|
+
end
|
108
|
+
{
|
109
|
+
type: type,
|
110
|
+
label: select,
|
111
|
+
data: data,
|
112
|
+
backgroundColor:
|
113
|
+
backgroundColor,
|
114
|
+
borderColor:
|
115
|
+
SaleTrend::COLORS[i],
|
116
|
+
borderWidth: 1
|
117
|
+
}
|
89
118
|
end
|
90
119
|
|
91
120
|
{
|
@@ -97,40 +126,55 @@ module EducodeSales
|
|
97
126
|
def goal_forecast_month(labels, selects, staff_id = nil)
|
98
127
|
plan_get = plan_get(staff_id, labels, "month")
|
99
128
|
actual_get = actual_get(staff_id, labels, "month")
|
100
|
-
datasets = selects.map do |select|
|
101
|
-
if select ==
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
129
|
+
datasets = selects.map.with_index do |select, i|
|
130
|
+
data = if select == NAMES[0]
|
131
|
+
labels.map do |d|
|
132
|
+
month = d.split("-").last.to_i
|
133
|
+
year = d.split("-").first.to_i
|
134
|
+
plan_get[[year, month]]&.pluck(:budget_amount)&.reject(&:blank?)&.sum.to_f
|
135
|
+
end
|
136
|
+
elsif select == NAMES[1]
|
137
|
+
arr = labels.map do |d|
|
138
|
+
month = d.split("-").last.to_i
|
139
|
+
year = d.split("-").first.to_i
|
140
|
+
plan_get[[year, month]]&.pluck(:budget_amount)&.reject(&:blank?)&.sum.to_f
|
141
|
+
end
|
142
|
+
arr.map.with_index(1) { |num, i| arr.first(i).inject(:+) }
|
143
|
+
elsif select == NAMES[2]
|
144
|
+
labels.map do |d|
|
145
|
+
month = d.split("-").last.to_i
|
146
|
+
year = d.split("-").first.to_i
|
147
|
+
actual_get[[year, month]]&.pluck(:actual_amount)&.reject(&:blank?)&.sum.to_f
|
148
|
+
end
|
149
|
+
elsif select == NAMES[3]
|
150
|
+
arr = labels.map do |d|
|
151
|
+
month = d.split("-").last.to_i
|
152
|
+
year = d.split("-").first.to_i
|
153
|
+
actual_get[[year, month]]&.pluck(:actual_amount)&.reject(&:blank?)&.sum.to_f
|
154
|
+
end
|
155
|
+
arr.map.with_index(1) { |num, i| arr.first(i).inject(:+) }
|
156
|
+
end
|
157
|
+
|
158
|
+
type = if select == NAMES[3] || select == NAMES[1]
|
159
|
+
'line'
|
160
|
+
else
|
161
|
+
"bar"
|
162
|
+
end
|
163
|
+
backgroundColor = if select == NAMES[3] || select == NAMES[1]
|
164
|
+
'rgba(54, 162, 235, 0.2)'
|
165
|
+
else
|
166
|
+
SaleTrend::COLORS[i]
|
167
|
+
end
|
168
|
+
{
|
169
|
+
type: type,
|
170
|
+
label: select,
|
171
|
+
data: data,
|
172
|
+
backgroundColor:
|
173
|
+
backgroundColor,
|
174
|
+
borderColor:
|
175
|
+
SaleTrend::COLORS[i],
|
176
|
+
borderWidth: 1
|
177
|
+
}
|
134
178
|
end
|
135
179
|
|
136
180
|
{
|
@@ -142,34 +186,40 @@ module EducodeSales
|
|
142
186
|
def goal_forecast_year(labels, selects, staff_id = nil)
|
143
187
|
plan_get = plan_get(staff_id, labels, "year")
|
144
188
|
actual_get = actual_get(staff_id, labels, "year")
|
145
|
-
datasets = selects.map do |select|
|
146
|
-
if select ==
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
}
|
158
|
-
else
|
159
|
-
{
|
160
|
-
label: select,
|
161
|
-
data: labels.map { |d| actual_get[d.to_i] || 0 },
|
162
|
-
backgroundColor: [
|
163
|
-
'rgba(54, 162, 235, 0.2)',
|
164
|
-
],
|
165
|
-
borderColor: [
|
166
|
-
'rgba(54, 162, 235, 1)',
|
167
|
-
],
|
168
|
-
borderWidth: 1
|
169
|
-
}
|
170
|
-
end
|
171
|
-
end
|
189
|
+
datasets = selects.map.with_index do |select, i|
|
190
|
+
data = if select == NAMES[0]
|
191
|
+
labels.map { |d| plan_get[d.to_i] || 0 }
|
192
|
+
elsif select == NAMES[1]
|
193
|
+
arr = labels.map { |d| plan_get[d.to_i] || 0 }
|
194
|
+
arr.map.with_index(1) { |num, i| arr.first(i).inject(:+) }
|
195
|
+
elsif select == NAMES[2]
|
196
|
+
labels.map { |d| actual_get[d.to_i] || 0 }
|
197
|
+
elsif select == NAMES[3]
|
198
|
+
arr = labels.map { |d| actual_get[d.to_i] || 0 }
|
199
|
+
arr.map.with_index(1) { |num, i| arr.first(i).inject(:+) }
|
200
|
+
end
|
172
201
|
|
202
|
+
type = if select == NAMES[3] || select == NAMES[1]
|
203
|
+
'line'
|
204
|
+
else
|
205
|
+
"bar"
|
206
|
+
end
|
207
|
+
backgroundColor = if select == NAMES[3] || select == NAMES[1]
|
208
|
+
'rgba(54, 162, 235, 0.2)'
|
209
|
+
else
|
210
|
+
SaleTrend::COLORS[i]
|
211
|
+
end
|
212
|
+
{
|
213
|
+
type: type,
|
214
|
+
label: select,
|
215
|
+
data: data,
|
216
|
+
backgroundColor:
|
217
|
+
backgroundColor,
|
218
|
+
borderColor:
|
219
|
+
SaleTrend::COLORS[i],
|
220
|
+
borderWidth: 1
|
221
|
+
}
|
222
|
+
end
|
173
223
|
{
|
174
224
|
labels: labels,
|
175
225
|
datasets: datasets
|
@@ -180,9 +230,29 @@ module EducodeSales
|
|
180
230
|
|
181
231
|
def plan_get(staff_id, time_range, type)
|
182
232
|
# budget_amount 预算额
|
233
|
+
start_time = case type
|
234
|
+
when "month"
|
235
|
+
time_range.first + "-01"
|
236
|
+
when "year"
|
237
|
+
time_range.first + "-01-01"
|
238
|
+
when "week"
|
239
|
+
time_range.first.split("-").first + "-01-01"
|
240
|
+
when "quarter"
|
241
|
+
time_range.first.split("-").first + "-01-01"
|
242
|
+
end
|
243
|
+
end_time = case type
|
244
|
+
when "month"
|
245
|
+
time_range.last + "-31"
|
246
|
+
when "year"
|
247
|
+
time_range.last + "-12-31"
|
248
|
+
when "week"
|
249
|
+
time_range.last.split("-").first + "-12-31"
|
250
|
+
when "quarter"
|
251
|
+
time_range.last.split("-").first + "-12-31"
|
252
|
+
end
|
183
253
|
staff_id = staff_id.present? ? Array(staff_id) : nil
|
184
254
|
data = Business.joins(:last_follow_up)
|
185
|
-
.where("educode_sales_follow_ups.invitation_at >= ? and educode_sales_follow_ups.invitation_at <= ? #{staff_id.present? ? "AND educode_sales_follow_ups.staff_id in (#{staff_id.join(",")})" : ""}",
|
255
|
+
.where("educode_sales_follow_ups.invitation_at >= ? and educode_sales_follow_ups.invitation_at <= ? #{staff_id.present? ? "AND educode_sales_follow_ups.staff_id in (#{staff_id.join(",")})" : ""}", start_time, end_time)
|
186
256
|
case type
|
187
257
|
when "week"
|
188
258
|
data.select("educode_sales_follow_ups.*, yearweek(educode_sales_follow_ups.invitation_at) as week").group("yearweek(educode_sales_follow_ups.invitation_at)").sum(:budget_amount)
|
@@ -198,10 +268,30 @@ module EducodeSales
|
|
198
268
|
end
|
199
269
|
|
200
270
|
def actual_get(staff_id, time_range, type)
|
271
|
+
start_time = case type
|
272
|
+
when "month"
|
273
|
+
time_range.first + "-01"
|
274
|
+
when "year"
|
275
|
+
time_range.first + "-01-01"
|
276
|
+
when "week"
|
277
|
+
time_range.first.split("-").first + "-01-01"
|
278
|
+
when "quarter"
|
279
|
+
time_range.first.split("-").first + "-01-01"
|
280
|
+
end
|
281
|
+
end_time = case type
|
282
|
+
when "month"
|
283
|
+
time_range.last + "-31"
|
284
|
+
when "year"
|
285
|
+
time_range.last + "-12-31"
|
286
|
+
when "week"
|
287
|
+
time_range.last.split("-").first + "-12-31"
|
288
|
+
when "quarter"
|
289
|
+
time_range.last.split("-").first + "-12-31"
|
290
|
+
end
|
201
291
|
# actual_amount 合同额
|
202
292
|
staff_id = staff_id.present? ? Array(staff_id) : nil
|
203
293
|
data = Business.joins(:last_follow_up)
|
204
|
-
.where("educode_sales_follow_ups.bidded_date >= ? and educode_sales_follow_ups.bidded_date <= ? #{staff_id.present? ? "AND educode_sales_follow_ups.staff_id in (#{staff_id.join(",")})" : ""}",
|
294
|
+
.where("educode_sales_follow_ups.bidded_date >= ? and educode_sales_follow_ups.bidded_date <= ? #{staff_id.present? ? "AND educode_sales_follow_ups.staff_id in (#{staff_id.join(",")})" : ""}", start_time, end_time)
|
205
295
|
case type
|
206
296
|
when "week"
|
207
297
|
data.select("educode_sales_follow_ups.*, yearweek(educode_sales_follow_ups.bidded_date) as week").group("yearweek(educode_sales_follow_ups.bidded_date)").sum(:actual_amount)
|
@@ -2,12 +2,12 @@ module EducodeSales
|
|
2
2
|
class SaleTrend < ApplicationRecord
|
3
3
|
|
4
4
|
COLORS = [
|
5
|
-
'#44D7B6', '#4CACFF', '#F7B500', '#FF0000', '#FF7F00', '#FFFF00', '#00FF00', '#00FFFF', '#0000FF',
|
6
|
-
'#8B00FF', 'rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)', 'rgba(75, 192, 192, 1)',
|
5
|
+
'#44D7B6', '#7CFC00', '#4CACFF', "#110FD7", '#F7B500', '#48D1CC', '#FF0000', '#FF7F00', '#FFFF00', '#00FF00', '#00FFFF', '#0000FF',
|
6
|
+
'#8B00FF', 'rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)', 'rgba(75, 192, 192, 1)',
|
7
7
|
'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)', 'rgba(255, 0, 250, 1)', '#A2D9CE', '#D6EAF8', '#E8DAEF', '#FADBD8',
|
8
8
|
'#F5B7B1', '#E6B0AA', '#FCF3CF', '#FDEBD0', '#F6DDCC', '#D98880', '#EC7063', '#A569BD', '#85C1E9', '#45B39D', '#F7DC6F',
|
9
9
|
'#DC7633', '#839192', '#6C3483', '#B03A2E', '#7B7D7D', '#4D5656', '#28B463', '#0E6655', '#F39C12', '#0E6251', '#1B4F72',
|
10
|
-
'#FAE5D3', '#82E0AA', '#FF00FF', '#663399', '#4B0082', '#7CFC00'
|
10
|
+
'#FAE5D3', '#82E0AA', '#FF00FF', '#663399', '#4B0082', '#7CFC00'
|
11
11
|
]
|
12
12
|
end
|
13
13
|
end
|