educode_sales 0.9.84 → 0.9.89
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 +44 -2
- data/app/controllers/educode_sales/sale_trends_controller.rb +11 -8
- data/app/controllers/educode_sales/sales_details_controller.rb +135 -0
- data/app/helpers/educode_sales/sale_trends_helper.rb +49 -22
- data/app/models/educode_sales/sales_detail.rb +1 -0
- data/app/views/educode_sales/businesses/new_follow_record.html.erb +1 -8
- data/app/views/educode_sales/contracts/_list.html.erb +22 -1
- data/app/views/educode_sales/contracts/index.html.erb +10 -0
- data/app/views/educode_sales/contracts/new_follow_up.html.erb +242 -192
- 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 +24 -18
- data/app/views/educode_sales/sales_details/_index.html.erb +401 -0
- 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.js.erb +1 -0
- data/app/views/educode_sales/sales_details/index.json.jbuilder +34 -0
- data/app/views/layouts/educode_sales/application.html.erb +0 -2
- data/config/routes.rb +3 -0
- data/db/migrate/20230510144317_create_educode_sales_sales_details.rb +4 -0
- data/lib/educode_sales/version.rb +1 -1
- metadata +11 -6
- data/app/assets/images/educode_sales/indexlogo.png +0 -0
@@ -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">
|
@@ -23,6 +26,12 @@
|
|
23
26
|
<input type="text" class="layui-input forecast_day layui-hide" id="forecast_date_day" name="forecast_date_day" placeholder=" - " value="<%= params[:forecast_date_day] %>" autocomplete="off">
|
24
27
|
</div>
|
25
28
|
</div>
|
29
|
+
<div class="layui-inline m-t-10">
|
30
|
+
<label class="layui-form-label">客户类型</label>
|
31
|
+
<div class="layui-input-inline">
|
32
|
+
<%= select_tag "property", options_for_select(SchoolTag.where(for_missions: true).pluck(:name, :id), params[:property]), { include_blank: true } %>
|
33
|
+
</div>
|
34
|
+
</div>
|
26
35
|
<div class="layui-inline">
|
27
36
|
<button type="button" id="search_bt" class="forecast_count_bt layui-btn layui-btn-primary" lay-submit lay-filter="search_sales">确定
|
28
37
|
</button>
|
@@ -31,7 +40,7 @@
|
|
31
40
|
</form>
|
32
41
|
</div>
|
33
42
|
<canvas id="forecast_myChart2" width="960" height="350"></canvas>
|
34
|
-
|
43
|
+
<canvas id="forecast_myChart2_1" width="960" height="350" style="margin-top: 30px;"></canvas>
|
35
44
|
</div>
|
36
45
|
</div>
|
37
46
|
<script>
|
@@ -75,21 +84,6 @@
|
|
75
84
|
}
|
76
85
|
};
|
77
86
|
|
78
|
-
var res_data = <%=raw @forecast_count_data.to_json %>;
|
79
|
-
var datasets = [];
|
80
|
-
var color = ['#44D7B6', '#4CACFF', '#F7B500', '#FF0000', '#FF7F00'];
|
81
|
-
res_data.datasets.forEach(function (d, i) {
|
82
|
-
datasets.push({
|
83
|
-
label: d.label,
|
84
|
-
type: 'line',
|
85
|
-
data: d.data1,
|
86
|
-
borderColor: color[i],
|
87
|
-
pointRadius: 1,
|
88
|
-
fill: false,
|
89
|
-
lineTension: 0
|
90
|
-
})
|
91
|
-
})
|
92
|
-
|
93
87
|
laydate.render({
|
94
88
|
type: 'year',
|
95
89
|
elem: '#forecast_date_year',
|
@@ -140,7 +134,19 @@
|
|
140
134
|
var ctx = document.getElementById('forecast_myChart2');
|
141
135
|
var forecast_myChart2 = new Chart(ctx, {
|
142
136
|
type: 'bar',
|
143
|
-
data: <%=raw @
|
137
|
+
data: <%=raw @forecast_count_data_0.to_json %>,
|
138
|
+
options: {
|
139
|
+
elements: {
|
140
|
+
line: {
|
141
|
+
tension: 0
|
142
|
+
}
|
143
|
+
}
|
144
|
+
}
|
145
|
+
});
|
146
|
+
var ctx = document.getElementById('forecast_myChart2_1');
|
147
|
+
var forecast_myChart2_1 = new Chart(ctx, {
|
148
|
+
type: 'bar',
|
149
|
+
data: <%=raw @forecast_count_data_1.to_json %>,
|
144
150
|
options: {
|
145
151
|
elements: {
|
146
152
|
line: {
|