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
@@ -0,0 +1,230 @@
|
|
1
|
+
module EducodeSales
|
2
|
+
class ReturnForecastService
|
3
|
+
attr_reader :user, :params, :request
|
4
|
+
# ReturnForecastService.new(current_user, request, params).call
|
5
|
+
def initialize(user, request, params)
|
6
|
+
@user = user
|
7
|
+
@request = request
|
8
|
+
@params = params
|
9
|
+
end
|
10
|
+
|
11
|
+
def call
|
12
|
+
end
|
13
|
+
|
14
|
+
def return_forecast_quarter(labels, selects, staff_id = nil)
|
15
|
+
plan_get = plan_get(staff_id, labels, "quarter")
|
16
|
+
actual_get = actual_get(staff_id, labels, "quarter")
|
17
|
+
datasets = selects.map do |select|
|
18
|
+
if select == "计划投标额"
|
19
|
+
{
|
20
|
+
label: select,
|
21
|
+
data: labels.map do |d|
|
22
|
+
quarter = d.split("-").last.to_i
|
23
|
+
year = d.split("-").first.to_i
|
24
|
+
plan_get[[year, quarter]]&.pluck(:budget_amount)&.reject(&:blank?)&.sum.to_f
|
25
|
+
end,
|
26
|
+
backgroundColor: [
|
27
|
+
'rgba(255, 99, 132, 0.2)',
|
28
|
+
],
|
29
|
+
borderColor: [
|
30
|
+
'rgba(255,99,132,1)',
|
31
|
+
],
|
32
|
+
borderWidth: 1
|
33
|
+
}
|
34
|
+
else
|
35
|
+
{
|
36
|
+
label: select,
|
37
|
+
data: labels.map do |d|
|
38
|
+
quarter = d.split("-").last.to_i
|
39
|
+
year = d.split("-").first.to_i
|
40
|
+
actual_get[[year, quarter]]&.pluck(:actual_amount)&.reject(&:blank?)&.sum.to_f
|
41
|
+
end,
|
42
|
+
backgroundColor: [
|
43
|
+
'rgba(54, 162, 235, 0.2)',
|
44
|
+
],
|
45
|
+
borderColor: [
|
46
|
+
'rgba(54, 162, 235, 1)',
|
47
|
+
],
|
48
|
+
borderWidth: 1
|
49
|
+
}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
{
|
54
|
+
labels: labels,
|
55
|
+
datasets: datasets
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
def return_forecast_week(labels, selects, staff_id = nil)
|
60
|
+
|
61
|
+
plan_get = plan_get(staff_id, labels, "week")
|
62
|
+
actual_get = actual_get(staff_id, labels, "week")
|
63
|
+
datasets = selects.map do |select|
|
64
|
+
if select == "计划投标额"
|
65
|
+
{
|
66
|
+
label: select,
|
67
|
+
data: labels.map do |d|
|
68
|
+
week = d.split("-").last
|
69
|
+
year = d.split("-").first
|
70
|
+
yearweek = "#{year}#{week}".to_i
|
71
|
+
plan_get[yearweek].to_f
|
72
|
+
end,
|
73
|
+
backgroundColor: [
|
74
|
+
'rgba(255, 99, 132, 0.2)',
|
75
|
+
],
|
76
|
+
borderColor: [
|
77
|
+
'rgba(255,99,132,1)',
|
78
|
+
],
|
79
|
+
borderWidth: 1
|
80
|
+
}
|
81
|
+
else
|
82
|
+
{
|
83
|
+
label: select,
|
84
|
+
data: labels.map do |d|
|
85
|
+
week = d.split("-").last
|
86
|
+
year = d.split("-").first
|
87
|
+
yearweek = "#{year}#{week}".to_i
|
88
|
+
actual_get[yearweek].to_f
|
89
|
+
end,
|
90
|
+
backgroundColor: [
|
91
|
+
'rgba(54, 162, 235, 0.2)',
|
92
|
+
],
|
93
|
+
borderColor: [
|
94
|
+
'rgba(54, 162, 235, 1)',
|
95
|
+
],
|
96
|
+
borderWidth: 1
|
97
|
+
}
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
{
|
102
|
+
labels: labels,
|
103
|
+
datasets: datasets
|
104
|
+
}
|
105
|
+
end
|
106
|
+
|
107
|
+
def return_forecast_month(labels, selects, staff_id = nil)
|
108
|
+
plan_get = plan_get(staff_id, labels, "month")
|
109
|
+
actual_get = actual_get(staff_id, labels, "month")
|
110
|
+
datasets = selects.map do |select|
|
111
|
+
if select == "计划投标额"
|
112
|
+
{
|
113
|
+
label: select,
|
114
|
+
data: labels.map do |d|
|
115
|
+
month = d.split("-").last.to_i
|
116
|
+
year = d.split("-").first.to_i
|
117
|
+
plan_get[[year, month]]&.pluck(:budget_amount)&.reject(&:blank?)&.sum.to_f
|
118
|
+
end,
|
119
|
+
backgroundColor: [
|
120
|
+
'rgba(255, 99, 132, 0.2)',
|
121
|
+
],
|
122
|
+
borderColor: [
|
123
|
+
'rgba(255,99,132,1)',
|
124
|
+
],
|
125
|
+
borderWidth: 1
|
126
|
+
}
|
127
|
+
else
|
128
|
+
{
|
129
|
+
label: select,
|
130
|
+
data: labels.map do |d|
|
131
|
+
month = d.split("-").last.to_i
|
132
|
+
year = d.split("-").first.to_i
|
133
|
+
actual_get[[year, month]]&.pluck(:actual_amount)&.reject(&:blank?)&.sum.to_f
|
134
|
+
end,
|
135
|
+
backgroundColor: [
|
136
|
+
'rgba(54, 162, 235, 0.2)',
|
137
|
+
],
|
138
|
+
borderColor: [
|
139
|
+
'rgba(54, 162, 235, 1)',
|
140
|
+
],
|
141
|
+
borderWidth: 1
|
142
|
+
}
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
{
|
147
|
+
labels: labels,
|
148
|
+
datasets: datasets
|
149
|
+
}
|
150
|
+
end
|
151
|
+
|
152
|
+
def return_forecast_year(labels, selects, staff_id = nil)
|
153
|
+
plan_get = plan_get(staff_id, labels, "year")
|
154
|
+
actual_get = actual_get(staff_id, labels, "year")
|
155
|
+
datasets = selects.map do |select|
|
156
|
+
if select == "计划投标额"
|
157
|
+
{
|
158
|
+
label: select,
|
159
|
+
data: labels.map { |d| plan_get[d.to_i] || 0 },
|
160
|
+
backgroundColor: [
|
161
|
+
'rgba(255, 99, 132, 0.2)',
|
162
|
+
],
|
163
|
+
borderColor: [
|
164
|
+
'rgba(255,99,132,1)',
|
165
|
+
],
|
166
|
+
borderWidth: 1
|
167
|
+
}
|
168
|
+
else
|
169
|
+
{
|
170
|
+
label: select,
|
171
|
+
data: labels.map { |d| actual_get[d.to_i] || 0 },
|
172
|
+
backgroundColor: [
|
173
|
+
'rgba(54, 162, 235, 0.2)',
|
174
|
+
],
|
175
|
+
borderColor: [
|
176
|
+
'rgba(54, 162, 235, 1)',
|
177
|
+
],
|
178
|
+
borderWidth: 1
|
179
|
+
}
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
{
|
184
|
+
labels: labels,
|
185
|
+
datasets: datasets
|
186
|
+
}
|
187
|
+
end
|
188
|
+
|
189
|
+
private
|
190
|
+
|
191
|
+
def plan_get(staff_id, time_range, type)
|
192
|
+
# budget_amount 预算额
|
193
|
+
staff_id = staff_id.present? ? Array(staff_id) : nil
|
194
|
+
data = Business.joins(:last_follow_up)
|
195
|
+
.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(",")})" : ""}", time_range.first, time_range.last)
|
196
|
+
case type
|
197
|
+
when "week"
|
198
|
+
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)
|
199
|
+
when "quarter"
|
200
|
+
data = data.select("educode_sales_follow_ups.*, quarter(educode_sales_follow_ups.invitation_at) as quarter, year(educode_sales_follow_ups.invitation_at) as year")
|
201
|
+
data.group_by { |d| [d.year, d.quarter] }
|
202
|
+
when "month"
|
203
|
+
data = data.select("educode_sales_follow_ups.*, year(educode_sales_follow_ups.invitation_at) as year, month(educode_sales_follow_ups.invitation_at) as month")
|
204
|
+
data.group_by { |d| [d.year, d.month] }
|
205
|
+
when "year"
|
206
|
+
data.select("educode_sales_follow_ups.*, year(educode_sales_follow_ups.invitation_at) as year").group("year(educode_sales_follow_ups.invitation_at)").sum(:budget_amount)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def actual_get(staff_id, time_range, type)
|
211
|
+
# actual_amount 合同额
|
212
|
+
staff_id = staff_id.present? ? Array(staff_id) : nil
|
213
|
+
data = Business.joins(:last_follow_up)
|
214
|
+
.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(",")})" : ""}", time_range.first, time_range.last)
|
215
|
+
case type
|
216
|
+
when "week"
|
217
|
+
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)
|
218
|
+
when "quarter"
|
219
|
+
data = data.select("educode_sales_follow_ups.*, quarter(educode_sales_follow_ups.bidded_date) as quarter, year(educode_sales_follow_ups.bidded_date) as year")
|
220
|
+
data.group_by { |d| [d.year, d.quarter] }
|
221
|
+
when "month"
|
222
|
+
data = data.select("educode_sales_follow_ups.*, year(educode_sales_follow_ups.bidded_date) as year, month(educode_sales_follow_ups.bidded_date) as month")
|
223
|
+
data.group_by { |d| [d.year, d.month] }
|
224
|
+
when "year"
|
225
|
+
data.select("educode_sales_follow_ups.*, year(educode_sales_follow_ups.bidded_date) as year").group("year(educode_sales_follow_ups.bidded_date)").sum(:actual_amount)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
230
|
+
end
|
@@ -110,6 +110,7 @@
|
|
110
110
|
<% if can? :assign_contract, EducodeSales::Business %>
|
111
111
|
<a class="layui-btn layui-btn-default layui-btn-xs data-count-edit" lay-event="assign">指派售后</a>
|
112
112
|
<% end %>
|
113
|
+
<a class="layui-btn layui-btn-default layui-btn-xs data-count-edit" lay-event="add_sales">添加销售明细</a>
|
113
114
|
|
114
115
|
</script>
|
115
116
|
|
@@ -431,7 +432,7 @@
|
|
431
432
|
},
|
432
433
|
{
|
433
434
|
title: '操作',
|
434
|
-
minWidth:
|
435
|
+
minWidth: 300,
|
435
436
|
toolbar: '#currentTableBar',
|
436
437
|
align: "center",
|
437
438
|
fixed: 'right'
|
@@ -546,6 +547,26 @@
|
|
546
547
|
layer.full(sindex);
|
547
548
|
});
|
548
549
|
return false;
|
550
|
+
} else if (obj.event === 'add_sales') {
|
551
|
+
business_id = data.id
|
552
|
+
var content = miniPage.getHrefContent('/missions/contracts/new_sales_detail?id=' + data.id);
|
553
|
+
var openWH = miniPage.getOpenWidthHeight();
|
554
|
+
new_sale_index = layer.open({
|
555
|
+
title: '添加销售明细',
|
556
|
+
type: 1,
|
557
|
+
shade: 0.2,
|
558
|
+
maxmin: true,
|
559
|
+
shadeClose: true,
|
560
|
+
area: [openWH[0] + 'px', openWH[1] + 'px'],
|
561
|
+
offset: [openWH[2] + 'px', openWH[3] + 'px'],
|
562
|
+
content: content,
|
563
|
+
success: function (layero, index) {
|
564
|
+
form.render('select');
|
565
|
+
}
|
566
|
+
});
|
567
|
+
$(window).on("resize", function () {
|
568
|
+
layer.full(new_follow_index);
|
569
|
+
});
|
549
570
|
}
|
550
571
|
});
|
551
572
|
|
@@ -102,7 +102,7 @@
|
|
102
102
|
<hr>
|
103
103
|
<div class="layui-inline">
|
104
104
|
<label class="layui-form-label">计划签单时间:</label>
|
105
|
-
<div class="layui-input-inline" style="line-height: 38px;">
|
105
|
+
<div class="layui-input-inline" style="line-height: 38px;width: 100px;">
|
106
106
|
<input type="text" class="layui-input date" name="plan_signed_date" autocomplete="off" value="<%= @last_follow_up&.plan_signed_date %>">
|
107
107
|
</div>
|
108
108
|
</div>
|
@@ -115,10 +115,16 @@
|
|
115
115
|
</div>
|
116
116
|
<div class="layui-inline">
|
117
117
|
<label class="layui-form-label" style="width:100px;">实际签单时间:</label>
|
118
|
-
<div class="layui-input-inline" style="line-height: 38px;">
|
118
|
+
<div class="layui-input-inline" style="line-height: 38px;width: 100px;">
|
119
119
|
<input type="text" class="layui-input date" name="signed_date" autocomplete="off" value="<%= @last_follow_up&.signed_date %>">
|
120
120
|
</div>
|
121
121
|
</div>
|
122
|
+
<div class="layui-inline">
|
123
|
+
<label class="layui-form-label">签单类型:</label>
|
124
|
+
<div class="layui-input-inline" style="line-height: 38px;width:110px;">
|
125
|
+
<%= select_tag "signed_clazz", options_for_select(@signed_clazz, @last_follow_up&.signed_clazz), class: 'required' %>
|
126
|
+
</div>
|
127
|
+
</div>
|
122
128
|
<div class="layui-inline">
|
123
129
|
<label class="layui-form-label" style="width:100px;">签约单位:</label>
|
124
130
|
<div class="layui-input-inline" style="line-height: 38px;">
|
@@ -611,7 +617,7 @@
|
|
611
617
|
initValue: gon.value, // 渲染初始化默认值
|
612
618
|
hasSelectIcon: false,
|
613
619
|
placeholder: '请输入头歌平台上单位部门', // 渲染的inputplaceholder值
|
614
|
-
data:
|
620
|
+
data: gon.department,
|
615
621
|
remoteSearch: true, // 是否启用远程搜索 默认是false,和远程搜索回调保存同步
|
616
622
|
remoteMethod: function (value, cb) { // 远程搜索的回调函数
|
617
623
|
if (!value) {
|
@@ -0,0 +1,116 @@
|
|
1
|
+
<%= Gon::Base.render_data %>
|
2
|
+
<div style="padding:30px">
|
3
|
+
<div class="layui-form layuimini-form" lay-filter="searchform">
|
4
|
+
<div class="layui-form-item">
|
5
|
+
<div class="layui-inline">
|
6
|
+
<label class="layui-form-label">产品名称:</label>
|
7
|
+
<div class="layui-input-inline" style="line-height: 38px;width: 400px;" id="product_name">
|
8
|
+
</div>
|
9
|
+
<div class="layui-form-mid layui-text-em"><button class="layui-btn layui-btn-sm" id="open_product">选择产品</button></div>
|
10
|
+
<input type="hidden" name="product_catalog_id" id="product_catalog_id">
|
11
|
+
</div>
|
12
|
+
</div>
|
13
|
+
<div class="layui-form-item">
|
14
|
+
<div class="layui-inline">
|
15
|
+
<label class="layui-form-label required">单价:</label>
|
16
|
+
<div class="layui-input-inline">
|
17
|
+
<input type="number" name="price" value="" class="layui-input" lay-verify="required">
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
<div class="layui-inline">
|
21
|
+
<label class="layui-form-label required">数量:</label>
|
22
|
+
<div class="layui-input-inline">
|
23
|
+
<input type="number" name="amount" value="" class="layui-input" lay-verify="required">
|
24
|
+
</div>
|
25
|
+
</div>
|
26
|
+
<div class="layui-inline">
|
27
|
+
<label class="layui-form-label required">金额:</label>
|
28
|
+
<div class="layui-input-inline">
|
29
|
+
<input type="number" name="total_price" value="" class="layui-input" lay-verify="required">
|
30
|
+
</div>
|
31
|
+
</div>
|
32
|
+
|
33
|
+
</div>
|
34
|
+
<div class="layui-form-item">
|
35
|
+
<div class="layui-inline">
|
36
|
+
<label class="layui-form-label required">定制类型:</label>
|
37
|
+
<div class="layui-input-inline">
|
38
|
+
<%= select_tag "custom_clazz", options_for_select(EducodeSales::SalesDetail.custom_clazzs.keys), { 'lay-filter': 'source_method', 'lay-verify': "required", include_blank: true, "lay-search": "" } %>
|
39
|
+
</div>
|
40
|
+
</div>
|
41
|
+
<div class="layui-inline">
|
42
|
+
<label class="layui-form-label required">交货时间:</label>
|
43
|
+
<div class="layui-input-inline">
|
44
|
+
<input type="text" name="delivery_date" value="" class="layui-input" lay-verify="required" id="delivery_date">
|
45
|
+
</div>
|
46
|
+
</div>
|
47
|
+
</div>
|
48
|
+
<div class="layui-form-item">
|
49
|
+
<div class="layui-input-block">
|
50
|
+
<button class="layui-btn layui-btn-normal" lay-submit lay-filter="saveBtn">保存</button>
|
51
|
+
</div>
|
52
|
+
</div>
|
53
|
+
</div>
|
54
|
+
</div>
|
55
|
+
|
56
|
+
<script type="text/html" id="sale_toolbar">
|
57
|
+
<div class="layui-btn-container">
|
58
|
+
<button class="layui-btn layui-btn-sm" lay-event="select_product">选择产品</button>
|
59
|
+
</div>
|
60
|
+
</script>
|
61
|
+
<script>
|
62
|
+
function selectProduct(data) {
|
63
|
+
$("#product_catalog_id").val(data.id)
|
64
|
+
product_name.innerText = [data.name, data.item_clazz, data.brand, data.specification, data.unit, data.source_method, data.param, data.supplier].join(" ")
|
65
|
+
}
|
66
|
+
layui.use(['form', 'table', 'upload', 'laytpl', 'request', 'laydate'], function() {
|
67
|
+
var form = layui.form,
|
68
|
+
layer = layui.layer,
|
69
|
+
table = layui.table,
|
70
|
+
laydate = layui.laydate,
|
71
|
+
laytpl = layui.laytpl,
|
72
|
+
request = layui.request,
|
73
|
+
$ = layui.$;
|
74
|
+
form.render();
|
75
|
+
|
76
|
+
laydate.render({
|
77
|
+
elem: '#delivery_date',
|
78
|
+
});
|
79
|
+
|
80
|
+
|
81
|
+
$("#open_product").on("click", function() {
|
82
|
+
var content = miniPage.getHrefContent('/missions/contracts/select_product');
|
83
|
+
var openWH = miniPage.getOpenWidthHeight();
|
84
|
+
product_index = layer.open({
|
85
|
+
title: '选择产品',
|
86
|
+
type: 1,
|
87
|
+
shade: 0.2,
|
88
|
+
maxmin: true,
|
89
|
+
shadeClose: true,
|
90
|
+
area: [openWH[0] + 'px', openWH[1] + 'px'],
|
91
|
+
offset: [openWH[2] + 'px', openWH[3] + 'px'],
|
92
|
+
content: content,
|
93
|
+
success: function (layero, index) {
|
94
|
+
form.render('select');
|
95
|
+
}
|
96
|
+
});
|
97
|
+
$(window).on("resize", function () {
|
98
|
+
layer.full(new_follow_index);
|
99
|
+
});
|
100
|
+
})
|
101
|
+
|
102
|
+
form.on('submit(saveBtn)', function(data) {
|
103
|
+
console.log( data.field)
|
104
|
+
data.field.business_id = parent.business_id;
|
105
|
+
if (data.field.product_catalog_id == "") {
|
106
|
+
layer.alert("请选择产品")
|
107
|
+
return false;
|
108
|
+
}
|
109
|
+
request.post("missions/contracts/sales_detail", data.field, function(res) {
|
110
|
+
layer.close(parent.new_sale_index)
|
111
|
+
// parent.table.reload('add_sale_detail_table')
|
112
|
+
})
|
113
|
+
return false;
|
114
|
+
});
|
115
|
+
});
|
116
|
+
</script>
|
@@ -0,0 +1,126 @@
|
|
1
|
+
<div style="padding:30px">
|
2
|
+
<div class="layui-form layuimini-form" style="padding:30px" lay-filter="search_product_form">
|
3
|
+
<div class="layui-form-item">
|
4
|
+
<div class="layui-inline">
|
5
|
+
<label class="layui-form-label">产品名称</label>
|
6
|
+
<div class="layui-input-inline">
|
7
|
+
<input type="text" name="name" class="layui-input" value="">
|
8
|
+
</div>
|
9
|
+
</div>
|
10
|
+
<div class="layui-inline">
|
11
|
+
<label class="layui-form-label">销售品目</label>
|
12
|
+
<div class="layui-input-inline">
|
13
|
+
<%= select_tag "item_clazz", options_for_select(EducodeSales::ProductCatalog.item_clazzs.keys), { 'lay-filter': 'item_clazz', include_blank: true , "lay-search": "" } %>
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
<div class="layui-inline">
|
17
|
+
<button type="submit" id="search_bt" class="layui-btn layui-btn-primary" lay-submit lay-filter="search_product_catalog_form">搜索</button>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
<div id="sale_detail_table_wraper">
|
22
|
+
<table class="layui-hide" id="sale_detail_table" lay-filter="sale_detail_table"></table>
|
23
|
+
</div>
|
24
|
+
</div>
|
25
|
+
|
26
|
+
<script type="text/html" id="sale_toolbar">
|
27
|
+
<div class="layui-btn-container">
|
28
|
+
<button class="layui-btn layui-btn-sm" lay-event="select_product">选择产品</button>
|
29
|
+
</div>
|
30
|
+
</script>
|
31
|
+
<script>
|
32
|
+
layui.use(['form', 'table', 'upload', 'laytpl', 'request', 'selectInput'], function() {
|
33
|
+
var form = layui.form,
|
34
|
+
layer = layui.layer,
|
35
|
+
table = layui.table,
|
36
|
+
laytpl = layui.laytpl,
|
37
|
+
request = layui.request,
|
38
|
+
$ = layui.$;
|
39
|
+
form.render();
|
40
|
+
|
41
|
+
var cols_table = [
|
42
|
+
[{
|
43
|
+
type: 'radio',
|
44
|
+
fixed: true
|
45
|
+
}, {
|
46
|
+
field: 'id',
|
47
|
+
width: 60,
|
48
|
+
title: '序号',
|
49
|
+
}, {
|
50
|
+
field: 'name',
|
51
|
+
width: 120,
|
52
|
+
title: '产品名称',
|
53
|
+
}, {
|
54
|
+
field: 'item_clazz',
|
55
|
+
width: 150,
|
56
|
+
title: '销售品目',
|
57
|
+
}, {
|
58
|
+
field: 'brand',
|
59
|
+
width: 150,
|
60
|
+
title: '品牌',
|
61
|
+
}, {
|
62
|
+
field: 'specification',
|
63
|
+
width: 150,
|
64
|
+
title: '规格型号',
|
65
|
+
}, {
|
66
|
+
field: 'unit',
|
67
|
+
width: 150,
|
68
|
+
title: '单位',
|
69
|
+
}, {
|
70
|
+
field: 'param',
|
71
|
+
width: 150,
|
72
|
+
title: '参数',
|
73
|
+
}, {
|
74
|
+
field: 'source_method',
|
75
|
+
width: 150,
|
76
|
+
title: '来源方式',
|
77
|
+
}, {
|
78
|
+
field: 'supplier',
|
79
|
+
width: 150,
|
80
|
+
title: '供货商',
|
81
|
+
}, ]
|
82
|
+
]
|
83
|
+
|
84
|
+
var sale_detail_table = table.render({
|
85
|
+
elem: '#sale_detail_table',
|
86
|
+
url: '/missions/contracts/product_list',
|
87
|
+
autoSort: false,
|
88
|
+
title: '销售产品',
|
89
|
+
toolbar: '#sale_toolbar',
|
90
|
+
cols: cols_table,
|
91
|
+
limit: 20,
|
92
|
+
limits: [10, 15, 20, 30, 40, 50, 60, 70, 80, 90],
|
93
|
+
page: true,
|
94
|
+
skin: 'line',
|
95
|
+
});
|
96
|
+
|
97
|
+
form.on('submit(search_product_catalog_form)', function(data) {
|
98
|
+
var data = form.val("search_product_form");
|
99
|
+
console.log(data)
|
100
|
+
table.reload('sale_detail_table', {
|
101
|
+
url: '/missions/contracts/product_list',
|
102
|
+
page: {
|
103
|
+
curr: 1
|
104
|
+
},
|
105
|
+
where: {
|
106
|
+
q: data,
|
107
|
+
}
|
108
|
+
}, 'data');
|
109
|
+
return false;
|
110
|
+
});
|
111
|
+
|
112
|
+
table.on('toolbar(sale_detail_table)', function(obj) {
|
113
|
+
var id = obj.config.id;
|
114
|
+
if (obj.event == 'select_product') {
|
115
|
+
var checkStatus = table.checkStatus(id);
|
116
|
+
var row = checkStatus.data;
|
117
|
+
if (row[0]) {
|
118
|
+
var data = row[0];
|
119
|
+
parent.selectProduct(data)
|
120
|
+
layer.close(product_index);
|
121
|
+
}
|
122
|
+
}
|
123
|
+
})
|
124
|
+
|
125
|
+
});
|
126
|
+
</script>
|
@@ -6,7 +6,10 @@
|
|
6
6
|
<div class="layui-inline m-t-10">
|
7
7
|
<label class="layui-form-label">销售人员</label>
|
8
8
|
<div class="layui-input-inline">
|
9
|
-
|
9
|
+
<% common = EducodeSales::Common.find_by(clazz: 'staff_type', name: '销售')
|
10
|
+
staffs = EducodeSales::Staff.where(job_type: common.id)
|
11
|
+
%>
|
12
|
+
<%= select_tag "staff_id", options_for_select(staffs.includes(:user).map { |d| [d.user.real_name, d.id] }, params[:staff_id]), { 'lay-filter': 'staff_id', include_blank: true } %>
|
10
13
|
</div>
|
11
14
|
</div>
|
12
15
|
<div class="layui-inline m-t-10">
|
@@ -139,7 +142,7 @@
|
|
139
142
|
|
140
143
|
var ctx = document.getElementById('forecast_myChart2');
|
141
144
|
var forecast_myChart2 = new Chart(ctx, {
|
142
|
-
type: '
|
145
|
+
type: 'bar',
|
143
146
|
data: <%=raw @forecast_count_data.to_json %>,
|
144
147
|
options: {
|
145
148
|
elements: {
|