educode_sales 0.4.9 → 0.5.3
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/assets/images/educode_sales//345/233/236/346/224/266/347/253/231.png +0 -0
- data/app/controllers/educode_sales/businesses_controller.rb +27 -13
- data/app/controllers/educode_sales/follow_ups_controller.rb +3 -2
- data/app/controllers/educode_sales/operation_plans_controller.rb +23 -2
- data/app/controllers/educode_sales/operation_reports_controller.rb +33 -3
- data/app/controllers/educode_sales/plans_controller.rb +28 -7
- data/app/controllers/educode_sales/recycles_controller.rb +95 -0
- data/app/controllers/educode_sales/roles_controller.rb +5 -0
- data/app/controllers/educode_sales/sale_reports_controller.rb +34 -4
- data/app/controllers/educode_sales/sale_trends_controller.rb +171 -0
- data/app/controllers/educode_sales/sales_controller.rb +4 -0
- data/app/controllers/educode_sales/staffs_controller.rb +4 -4
- data/app/controllers/educode_sales/upload_files_controller.rb +40 -27
- data/app/models/concerns/deletable.rb +8 -0
- data/app/models/educode_sales/application_record.rb +2 -0
- data/app/models/educode_sales/business.rb +15 -2
- data/app/models/educode_sales/common.rb +2 -1
- data/app/models/educode_sales/follow_up.rb +4 -2
- data/app/models/educode_sales/recycle.rb +5 -0
- data/app/models/educode_sales/sale_plan.rb +3 -0
- data/app/models/educode_sales/sale_report.rb +2 -0
- data/app/views/educode_sales/businesses/edit_plan.html.erb +2 -2
- data/app/views/educode_sales/businesses/file.html.erb +30 -15
- data/app/views/educode_sales/businesses/index.html.erb +20 -7
- data/app/views/educode_sales/businesses/new_follow_record.html.erb +5 -1
- data/app/views/educode_sales/businesses/show_follow.html.erb +8 -2
- data/app/views/educode_sales/businesses/show_follow.json.jbuilder +1 -0
- data/app/views/educode_sales/businesses/show_follow_record.html.erb +1 -1
- data/app/views/educode_sales/businesses/time_line.html.erb +5 -1
- data/app/views/educode_sales/businesses/upload_file.html.erb +4 -4
- data/app/views/educode_sales/operation_plans/index.html.erb +6 -1
- data/app/views/educode_sales/operation_plans/new_week.html.erb +1 -1
- data/app/views/educode_sales/operation_reports/audit.html.erb +14 -6
- data/app/views/educode_sales/operation_reports/show.html.erb +13 -10
- data/app/views/educode_sales/places/index.html.erb +6 -1
- data/app/views/educode_sales/places/index.json.jbuilder +11 -1
- data/app/views/educode_sales/plans/index.html.erb +6 -1
- data/app/views/educode_sales/plans/new_monthly.html.erb +6 -6
- data/app/views/educode_sales/plans/new_week.html.erb +1 -1
- data/app/views/educode_sales/plans/new_weekly.html.erb +7 -7
- data/app/views/educode_sales/recycles/_business.html.erb +122 -0
- data/app/views/educode_sales/recycles/_monthPlan.html.erb +123 -0
- data/app/views/educode_sales/recycles/_monthly.html.erb +121 -0
- data/app/views/educode_sales/recycles/_weekPlan.html.erb +128 -0
- data/app/views/educode_sales/recycles/_weekly.html.erb +122 -0
- data/app/views/educode_sales/recycles/business.json.jbuilder +16 -0
- data/app/views/educode_sales/recycles/index.html.erb +58 -0
- data/app/views/educode_sales/recycles/monthPlan.json.jbuilder +16 -0
- data/app/views/educode_sales/recycles/monthly.json.jbuilder +15 -0
- data/app/views/educode_sales/recycles/weekPlan.json.jbuilder +16 -0
- data/app/views/educode_sales/recycles/weekly.json.jbuilder +15 -0
- data/app/views/educode_sales/roles/index.html.erb +19 -1
- data/app/views/educode_sales/roles/rename.html.erb +50 -0
- data/app/views/educode_sales/sale_reports/audit.html.erb +17 -6
- data/app/views/educode_sales/sale_reports/show.html.erb +11 -8
- data/app/views/educode_sales/sale_trends/trends.html.erb +252 -8
- data/app/views/educode_sales/sale_trends/trends.json.jbuilder +14 -0
- data/app/views/educode_sales/sales/index.html.erb +75 -9
- data/app/views/educode_sales/sales/index.json.jbuilder +35 -1
- data/app/views/educode_sales/sales/operations.json.jbuilder +11 -1
- data/app/views/educode_sales/staffs/index.html.erb +6 -1
- data/app/views/educode_sales/staffs/index.json.jbuilder +11 -1
- data/app/views/educode_sales/teachers/add_keys.html.erb +3 -3
- data/app/views/educode_sales/teachers/index.html.erb +7 -2
- data/app/views/educode_sales/teachers/new.html.erb +1 -0
- data/app/views/educode_sales/upload_files/index.json.jbuilder +2 -2
- data/app/views/layouts/educode_sales/application.html.erb +3 -0
- data/config/routes.rb +18 -0
- data/db/migrate/20210902064109_create_educode_sales_role_permissions.rb +6 -0
- data/db/migrate/20211109015617_create_educode_sales_recycles.rb +25 -0
- data/lib/educode_sales/version.rb +1 -1
- metadata +20 -2
@@ -23,6 +23,124 @@ module EducodeSales
|
|
23
23
|
@a_amount = Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id IN (?)", a).sum(:total_amount).round(2)
|
24
24
|
b = Common.where(clazz: '商机类型', name: Common.find_by(extras: EducodeSales::Common::BTYPE)&.name).pluck(:id)
|
25
25
|
@b_amount = Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id IN (?)", b).sum(:total_amount).round(2)
|
26
|
+
|
27
|
+
common = Common.find_by(clazz: 'staff_type', name: '销售')
|
28
|
+
names = Staff.includes(:user).where(job_type: common.id).map { |d| [d.user.real_name, d.id] }
|
29
|
+
x_business_ids = []
|
30
|
+
default_dates = (7.day.ago.to_date..Date.today).to_a #默认时间范围
|
31
|
+
Business.all.each do |d|
|
32
|
+
if d.last_follow_up&.clazz&.id == x
|
33
|
+
x_business_ids << d.id
|
34
|
+
end
|
35
|
+
end
|
36
|
+
colors = ['#44D7B6','#4CACFF','#F7B500','#FF0000', '#FF7F00', '#FFFF00', '#00FF00', '#00FFFF', '#0000FF', '#8B00FF', 'rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)', 'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)']
|
37
|
+
@follow_count_range = params[:follow_count_range] || "day"
|
38
|
+
@goal_count_range = params[:goal_count_range] || "day"
|
39
|
+
# 商机跟进数图表
|
40
|
+
@follow_count_data = day_follow_count_chart(default_dates,names,x_business_ids,colors)
|
41
|
+
if params[:follow_count_range].present?
|
42
|
+
case params[:follow_count_range]
|
43
|
+
when "week"
|
44
|
+
when "month" #按月
|
45
|
+
if params[:date_month].present?
|
46
|
+
# (Date.new(2020,12,1)..Date.new(2021,12,1)).map { |d| d.strftime("%Y-%m")}.uniq
|
47
|
+
date = params[:date_month].split(" - ")
|
48
|
+
dates = ((date[0]+"-01").to_date..(date[1]+"-01").to_date).map { |d| d.strftime("%Y-%m")}.uniq
|
49
|
+
@follow_count_data = month_follow_count_chart(dates,names,x_business_ids,colors)
|
50
|
+
end
|
51
|
+
when "year" #按年
|
52
|
+
if params[:date_year].present?
|
53
|
+
date = params[:date_year].split(" - ")
|
54
|
+
dates = (date[0]..date[1]).to_a
|
55
|
+
@follow_count_data = year_follow_count_chart(dates,names,x_business_ids,colors)
|
56
|
+
end
|
57
|
+
else #按天
|
58
|
+
if params[:date].present?
|
59
|
+
date = params[:date].split(" - ")
|
60
|
+
dates = (date[0].to_date..date[1].to_date).to_a
|
61
|
+
@follow_count_data = day_follow_count_chart(dates,names,x_business_ids,colors)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
# 已中标图表
|
68
|
+
goal_default_dates = ("#{Time.now.year}-01".."#{Time.now.year}-#{Time.now.month}").to_a
|
69
|
+
sale_names = ['已中标','已签单','已回款']
|
70
|
+
@goal_count_data =
|
71
|
+
{
|
72
|
+
labels: goal_default_dates,
|
73
|
+
datasets: sale_names.map do |name|{
|
74
|
+
label: name,
|
75
|
+
data: goal_default_dates.map{ |d|
|
76
|
+
case sale_names.index(name)
|
77
|
+
when 0
|
78
|
+
Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id != ?", x).where("educode_sales_follow_ups.bidded_date >= ? AND educode_sales_follow_ups.bidded_date <= ? AND educode_sales_follow_ups.stage_id IN (?)", "#{d}-01", "#{d}-31", stage_ids).sum(:total_amount).round(2)
|
79
|
+
when 1
|
80
|
+
Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id != ?", x).where("educode_sales_follow_ups.signed_date >= ? AND educode_sales_follow_ups.signed_date <= ? AND educode_sales_follow_ups.stage_id IN (?)", "#{d}-01", "#{d}-31", s_stage_ids).sum(:total_amount).round(2)
|
81
|
+
else
|
82
|
+
Business.joins(last_follow_up: :money_plans).where("educode_sales_follow_ups.clazz_id != ?", x).where.not("educode_sales_money_plans.clazz!= ?", 1).where("educode_sales_money_plans.date_at >= ? AND educode_sales_money_plans.date_at <= ? ", "#{d}-01", "#{d}-31").sum(:amount).round(2)
|
83
|
+
end
|
84
|
+
},
|
85
|
+
backgroundColor: colors[sale_names.index(name)],
|
86
|
+
borderColor: colors[sale_names.index(name)],
|
87
|
+
borderWidth: 1
|
88
|
+
}
|
89
|
+
end
|
90
|
+
}
|
91
|
+
if params[:goal_count_range].present?
|
92
|
+
case params[:goal_count_range]
|
93
|
+
when "week"
|
94
|
+
when "month" #按月
|
95
|
+
if params[:goal_date_month].present?
|
96
|
+
date = params[:goal_date_month].split(" - ")
|
97
|
+
dates = ((date[0]+"-01").to_date..(date[1]+"-01").to_date).map { |d| d.strftime("%Y-%m")}.uniq
|
98
|
+
@goal_count_data = {
|
99
|
+
labels: dates,
|
100
|
+
datasets: sale_names.map do |name|{
|
101
|
+
label: name,
|
102
|
+
data: dates.map{ |d|
|
103
|
+
case sale_names.index(name)
|
104
|
+
when 0
|
105
|
+
Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id != ?", x).where("educode_sales_follow_ups.bidded_date >= ? AND educode_sales_follow_ups.bidded_date <= ? AND educode_sales_follow_ups.stage_id IN (?)", "#{d}-01", "#{d}-31", stage_ids).sum(:total_amount).round(2)
|
106
|
+
when 1
|
107
|
+
Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id != ?", x).where("educode_sales_follow_ups.signed_date >= ? AND educode_sales_follow_ups.signed_date <= ? AND educode_sales_follow_ups.stage_id IN (?)", "#{d}-01", "#{d}-31", s_stage_ids).sum(:total_amount).round(2)
|
108
|
+
else
|
109
|
+
Business.joins(last_follow_up: :money_plans).where("educode_sales_follow_ups.clazz_id != ?", x).where.not("educode_sales_money_plans.clazz!= ?", 1).where("educode_sales_money_plans.date_at >= ? AND educode_sales_money_plans.date_at <= ? ", "#{d}-01", "#{d}-31").sum(:amount).round(2)
|
110
|
+
end },
|
111
|
+
backgroundColor: colors[sale_names.index(name)],
|
112
|
+
borderColor: colors[sale_names.index(name)],
|
113
|
+
borderWidth: 1
|
114
|
+
}
|
115
|
+
end
|
116
|
+
}
|
117
|
+
end
|
118
|
+
else #按年
|
119
|
+
if params[:goal_date_year].present?
|
120
|
+
date = params[:goal_date_year].split(" - ")
|
121
|
+
dates = (date[0]..date[1]).to_a
|
122
|
+
@goal_count_data = {
|
123
|
+
labels: dates,
|
124
|
+
datasets:sale_names.map do |name| {
|
125
|
+
label: name,
|
126
|
+
data: dates.map{ |d|
|
127
|
+
case sale_names.index(name)
|
128
|
+
when 0
|
129
|
+
Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id != ?", x).where("educode_sales_follow_ups.bidded_date >= ? AND educode_sales_follow_ups.bidded_date <= ? AND educode_sales_follow_ups.stage_id IN (?)", "#{d}-01-01", "#{d}-12-31", stage_ids).sum(:total_amount).round(2)
|
130
|
+
when 1
|
131
|
+
Business.joins(:last_follow_up).where("educode_sales_follow_ups.clazz_id != ?", x).where("educode_sales_follow_ups.signed_date >= ? AND educode_sales_follow_ups.signed_date <= ? AND educode_sales_follow_ups.stage_id IN (?)", "#{d}-01-01", "#{d}-12-31", s_stage_ids).sum(:total_amount).round(2)
|
132
|
+
else
|
133
|
+
Business.joins(last_follow_up: :money_plans).where("educode_sales_follow_ups.clazz_id != ?", x).where.not("educode_sales_money_plans.clazz!= ?", 1).where("educode_sales_money_plans.date_at >= ? AND educode_sales_money_plans.date_at <= ? ", "#{d}-01-01", "#{d}-12-31").sum(:amount).round(2)
|
134
|
+
end },
|
135
|
+
backgroundColor: colors[sale_names.index(name)],
|
136
|
+
borderColor: colors[sale_names.index(name)],
|
137
|
+
borderWidth: 1
|
138
|
+
}
|
139
|
+
end
|
140
|
+
}
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
26
144
|
end
|
27
145
|
|
28
146
|
def sale_trends
|
@@ -44,5 +162,58 @@ module EducodeSales
|
|
44
162
|
params.permit(:chance_money, :ballot_money, :sign_money, :returned_money)
|
45
163
|
end
|
46
164
|
|
165
|
+
def day_follow_count_chart(dates,names,x_business_ids,colors)
|
166
|
+
{
|
167
|
+
labels: dates,
|
168
|
+
datasets:names.map do |name|
|
169
|
+
{
|
170
|
+
hidden: names.index(name) < 3 ? false : true,
|
171
|
+
label: name[0],
|
172
|
+
data: dates.map{ |d| @follow_up = FollowUp.where(staff_id: name[1], created_at: d.beginning_of_day..d.end_of_day).where.not(business: x_business_ids).count },
|
173
|
+
backgroundColor: "#fff",
|
174
|
+
pointBorderColor: "#fff",
|
175
|
+
borderColor: colors[names.index(name)%15],
|
176
|
+
pointBackgroundColor: colors[names.index(name)%15],
|
177
|
+
borderWidth: 1
|
178
|
+
}
|
179
|
+
end
|
180
|
+
}
|
181
|
+
end
|
182
|
+
def month_follow_count_chart(dates,names,x_business_ids,colors)
|
183
|
+
{
|
184
|
+
labels: dates,
|
185
|
+
datasets:names.map do |name|
|
186
|
+
{
|
187
|
+
hidden: names.index(name) < 3 ? false : true,
|
188
|
+
label: name[0],
|
189
|
+
data: dates.map { |d| @follow_up = FollowUp.where( staff_id: name[1]).where("created_at >= ? AND created_at <= ?", "#{d}-01", "#{d}-31").where.not(business: x_business_ids).count },
|
190
|
+
backgroundColor: "#fff",
|
191
|
+
pointBorderColor: "#fff",
|
192
|
+
borderColor: colors[names.index(name)%15],
|
193
|
+
pointBackgroundColor: colors[names.index(name)%15],
|
194
|
+
borderWidth: 1
|
195
|
+
}
|
196
|
+
end
|
197
|
+
}
|
198
|
+
end
|
199
|
+
def year_follow_count_chart(dates,names,x_business_ids,colors)
|
200
|
+
{
|
201
|
+
labels: dates,
|
202
|
+
datasets:names.map do |name|
|
203
|
+
{
|
204
|
+
hidden: names.index(name) < 3 ? false : true,
|
205
|
+
label: name[0],
|
206
|
+
data: dates.map { |d| @follow_up = FollowUp.where( staff_id: name[1]).where("created_at >= ? AND created_at <= ?", "#{d}-01-01", "#{d}-12-31").where.not(business: x_business_ids).count },
|
207
|
+
backgroundColor: "#fff",
|
208
|
+
pointBorderColor: "#fff",
|
209
|
+
borderColor: colors[names.index(name)%15],
|
210
|
+
pointBackgroundColor: colors[names.index(name)%15],
|
211
|
+
borderWidth: 1
|
212
|
+
}
|
213
|
+
end
|
214
|
+
}
|
215
|
+
end
|
216
|
+
|
217
|
+
|
47
218
|
end
|
48
219
|
end
|
@@ -14,6 +14,10 @@ module EducodeSales
|
|
14
14
|
common = Common.find_by(clazz: 'staff_type', name: '销售')
|
15
15
|
@a_clazz = Common.find_by(clazz: 'business_type', name: Common.find_by(extras: EducodeSales::Common::ATYPE)&.name)
|
16
16
|
@b_clazz = Common.find_by(clazz: 'business_type', name: Common.find_by(extras: EducodeSales::Common::BTYPE)&.name)
|
17
|
+
@c_clazz = Common.find_by(clazz: 'business_type', name: Common.find_by(extras: EducodeSales::Common::CTYPE)&.name)
|
18
|
+
@d_clazz = Common.find_by(clazz: 'business_type', name: Common.find_by(extras: EducodeSales::Common::DTYPE)&.name)
|
19
|
+
@e_clazz = Common.find_by(clazz: 'business_type', name: Common.find_by(extras: EducodeSales::Common::ETYPE)&.name)
|
20
|
+
@o_clazz = Common.find_by(clazz: 'business_type', name: Common.find_by(extras: EducodeSales::Common::OTYPE)&.name)
|
17
21
|
@x = Common.find_by(extras: EducodeSales::Common::XTYPE)
|
18
22
|
@step_ids = Common.where(name: %w(已中标 已签单 已验收 回款中 服务中 已结束), clazz: 'business_step').pluck(:id)
|
19
23
|
|
@@ -8,7 +8,7 @@ module EducodeSales
|
|
8
8
|
format.html do
|
9
9
|
end
|
10
10
|
format.json do
|
11
|
-
@staffs = Staff.where(is_admin: false).page(params[:page]).per(params[:limit])
|
11
|
+
@staffs = Staff.where(is_admin: false, deleted_at: nil).page(params[:page]).per(params[:limit])
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
@@ -37,10 +37,10 @@ module EducodeSales
|
|
37
37
|
|
38
38
|
def destroy
|
39
39
|
staff = Staff.find(params[:id])
|
40
|
-
staff.
|
40
|
+
staff.update(deleted_at: Time.now, expired_at: Time.now.days_ago(1))
|
41
41
|
render_success
|
42
|
-
rescue ActiveRecord::DeleteRestrictionError => e
|
43
|
-
|
42
|
+
# rescue ActiveRecord::DeleteRestrictionError => e
|
43
|
+
# render_failure '该用户已有数据产生,暂不能删除'
|
44
44
|
end
|
45
45
|
|
46
46
|
def disable
|
@@ -8,49 +8,62 @@ module EducodeSales
|
|
8
8
|
format.html do
|
9
9
|
end
|
10
10
|
format.json do
|
11
|
-
@files = Attachment.where(description: "business", container_id:params[:business_id])
|
11
|
+
@files = Attachment.where(description: "business", container_id:params[:business_id])
|
12
|
+
if params[:sort].present? && params[:sort][:field]
|
13
|
+
@files = @files.order("#{params[:sort][:field]} #{params[:sort][:order]}")
|
14
|
+
else
|
15
|
+
@files = @files.order("created_on desc")
|
16
|
+
end
|
17
|
+
@files = @files.page(params[:page]).per(params[:limit])
|
12
18
|
end
|
13
19
|
end
|
14
20
|
end
|
15
21
|
|
16
22
|
def create
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
23
|
+
folder = File.join(Rails.root, "public", "images", 'educode_sales')
|
24
|
+
upload_file = params["file"]
|
25
|
+
raise "未上传文件" unless upload_file
|
26
|
+
save_path = File.join(folder)
|
27
|
+
ext = file_ext(upload_file.original_filename)
|
28
|
+
local_path, digest = file_save_to_local(save_path, upload_file.tempfile, ext)
|
29
|
+
content_type = upload_file.content_type.presence || 'application/octet-stream'
|
30
|
+
disk_filename = local_path[save_path.size + 1, local_path.size]
|
31
|
+
@attachment = Attachment.where(disk_filename: disk_filename,
|
32
|
+
author_id: @current_admin.user_id).first
|
33
|
+
if @attachment.blank?
|
34
|
+
@attachment = Attachment.new
|
35
|
+
@attachment.filename = upload_file.original_filename
|
36
|
+
@attachment.description = "business"
|
37
|
+
@attachment.disk_filename = local_path[save_path.size + 1, local_path.size]
|
38
|
+
@attachment.filesize = upload_file.tempfile.size
|
39
|
+
@attachment.content_type = content_type
|
40
|
+
@attachment.digest = digest
|
41
|
+
@attachment.author_id = @current_admin.user_id
|
42
|
+
@attachment.container_id = params[:business_id]
|
43
|
+
@attachment.save!
|
44
|
+
else
|
45
|
+
logger.info "文件已存在,id = #{@attachment.id}, filename = #{@attachment.filename}"
|
46
|
+
end
|
47
|
+
render_success
|
41
48
|
end
|
42
49
|
|
43
50
|
def destroy
|
51
|
+
folder = File.join(Rails.root, "public", "images", 'educode_sales')
|
44
52
|
file = Attachment.find(params[:id])
|
45
53
|
file.destroy
|
46
|
-
File.delete("
|
54
|
+
File.delete(folder + "/" +file.disk_filename) if FileTest::exist?(folder + "/" +file.disk_filename)
|
47
55
|
render_success
|
48
56
|
end
|
49
57
|
|
50
58
|
def download
|
59
|
+
folder = File.join(Rails.root, "public", "images", 'educode_sales')
|
51
60
|
file = Attachment.find_by_id(params[:id])
|
52
61
|
raise "未找到文件" unless file
|
53
|
-
send_file("
|
62
|
+
send_file(folder + "/" +file.disk_filename, filename: file.title, stream: true, type: file.content_type.presence || 'application/octet-stream')
|
63
|
+
end
|
64
|
+
|
65
|
+
def edu_setting name
|
66
|
+
EduSetting.get(name)
|
54
67
|
end
|
55
68
|
|
56
69
|
|
@@ -1,10 +1,23 @@
|
|
1
1
|
module EducodeSales
|
2
2
|
class Business < ApplicationRecord
|
3
|
+
|
3
4
|
belongs_to :staff
|
4
5
|
belongs_to :department
|
5
6
|
belongs_to :last_follow_up, class_name: 'FollowUp', optional: true
|
6
7
|
|
7
|
-
has_many :sale_plans
|
8
|
-
has_many :follow_ups
|
8
|
+
has_many :sale_plans
|
9
|
+
has_many :follow_ups
|
10
|
+
|
11
|
+
default_scope -> {where(deleted_at: nil)}
|
12
|
+
|
13
|
+
def soft_destroy(user_id)
|
14
|
+
self.update(deleted_at: Time.now)
|
15
|
+
self.sale_plans.each do |d|
|
16
|
+
d.soft_destroy(user_id)
|
17
|
+
end
|
18
|
+
self.follow_ups.update_all(deleted_at: Time.now)
|
19
|
+
EducodeSales::Recycle.create(source: self, deleter_id: user_id)
|
20
|
+
end
|
21
|
+
|
9
22
|
end
|
10
23
|
end
|
@@ -8,6 +8,7 @@ module EducodeSales
|
|
8
8
|
BTYPE = 'b_class'
|
9
9
|
CTYPE = 'c_class'
|
10
10
|
DTYPE = 'd_class'
|
11
|
+
ETYPE = 'e_class'
|
11
12
|
|
12
13
|
validates :name, uniqueness: {scope: :clazz, message: '已存在'}
|
13
14
|
|
@@ -25,7 +26,7 @@ module EducodeSales
|
|
25
26
|
}
|
26
27
|
|
27
28
|
def self.job_type_name
|
28
|
-
self.where(clazz: 'staff_type'
|
29
|
+
self.where(clazz: 'staff_type').pluck(:id, :name).to_h
|
29
30
|
end
|
30
31
|
|
31
32
|
def self.teacher_source_name
|
@@ -1,14 +1,16 @@
|
|
1
1
|
module EducodeSales
|
2
2
|
class FollowUp < ApplicationRecord
|
3
|
+
include ::Deletable
|
3
4
|
belongs_to :business, counter_cache: true
|
4
5
|
belongs_to :place, optional: true
|
5
|
-
has_many :money_plans
|
6
|
+
has_many :money_plans
|
6
7
|
has_many :key_person
|
7
8
|
has_many :teachers, through: :key_person
|
8
|
-
has_many :assign_follow_ups
|
9
|
+
has_many :assign_follow_ups
|
9
10
|
belongs_to :staff
|
10
11
|
belongs_to :stage, class_name: 'Common'
|
11
12
|
belongs_to :clazz, class_name: 'Common'
|
13
|
+
default_scope -> {where(deleted_at: nil)}
|
12
14
|
|
13
15
|
|
14
16
|
end
|
@@ -1,9 +1,12 @@
|
|
1
1
|
module EducodeSales
|
2
2
|
class SalePlan < ApplicationRecord
|
3
|
+
include ::Deletable
|
3
4
|
belongs_to :business
|
4
5
|
belongs_to :staff
|
5
6
|
validates :business_id, presence: true
|
6
7
|
|
7
8
|
validates :month, presence: true
|
9
|
+
|
10
|
+
default_scope -> {where(deleted_at: nil)}
|
8
11
|
end
|
9
12
|
end
|
@@ -56,13 +56,13 @@
|
|
56
56
|
</div>
|
57
57
|
</script>
|
58
58
|
<script type="text/html" id="return_money_tabar">
|
59
|
-
{{# if(parent.is_latest){ }}
|
59
|
+
{{# if(parent.is_latest && parent.flag){ }}
|
60
60
|
<a class="layui-btn layui-btn-normal layui-btn-xs data-count-edit" lay-event="edit">保存</a>
|
61
61
|
<a class="layui-btn layui-btn-danger layui-btn-xs data-count-edit" lay-event="delete">删除</a>
|
62
62
|
{{# } }}
|
63
63
|
</script>
|
64
64
|
<script>
|
65
|
-
if(!parent.is_latest){
|
65
|
+
if(!parent.is_latest || !parent.flag){
|
66
66
|
document.getElementById("show_plan_box").style.display="none";//隐藏
|
67
67
|
}
|
68
68
|
layui.use(['form', 'table', 'upload', 'laytpl', 'request', 'laydate'], function () {
|
@@ -1,13 +1,14 @@
|
|
1
|
+
<%= Gon::Base.render_data %>
|
1
2
|
<script type="text/html" id="toolbarDemo">
|
2
3
|
<div class="layui-btn-container">
|
3
4
|
<span class="table-label">附件信息</span>
|
4
|
-
<%# if can? :create, EducodeSales::
|
5
|
+
<%# if can? :create, EducodeSales::file %>
|
5
6
|
<button class="layui-btn layui-btn-normal layui-btn-sm data-add-btn pull-right" lay-event="upload_file">上传文件</button>
|
6
7
|
<%# end %>
|
7
8
|
</div>
|
8
9
|
</script>
|
9
10
|
|
10
|
-
<table class="layui-hide" id="
|
11
|
+
<table class="layui-hide" id="file" lay-filter="file"></table>
|
11
12
|
|
12
13
|
<script type="text/html" id="currentTableBar_file">
|
13
14
|
<a class="layui-btn layui-btn-normal layui-btn-xs data-count-edit" lay-event="preview">预览</a>
|
@@ -31,7 +32,7 @@
|
|
31
32
|
|
32
33
|
var business_id = parent.id
|
33
34
|
table.render({
|
34
|
-
elem: '#
|
35
|
+
elem: '#file',
|
35
36
|
url: '/missions/upload_files?business_id='+business_id,
|
36
37
|
toolbar: '#toolbarDemo',
|
37
38
|
defaultToolbar: [],
|
@@ -44,7 +45,6 @@
|
|
44
45
|
},
|
45
46
|
{
|
46
47
|
field: 'name',
|
47
|
-
width: 500,
|
48
48
|
title: '文件名'
|
49
49
|
},
|
50
50
|
{
|
@@ -53,18 +53,20 @@
|
|
53
53
|
title: '文件大小',
|
54
54
|
},
|
55
55
|
{
|
56
|
-
field: '
|
57
|
-
width:
|
58
|
-
title: '上传时间'
|
56
|
+
field: 'created_on',
|
57
|
+
width: 200,
|
58
|
+
title: '上传时间',
|
59
|
+
sort: true
|
59
60
|
},
|
60
61
|
{
|
61
62
|
field: 'upload_person',
|
62
|
-
width:
|
63
|
+
width: 80,
|
63
64
|
totalRow:true,
|
64
65
|
title: '上传人',
|
65
66
|
},
|
66
67
|
{
|
67
68
|
title: '操作',
|
69
|
+
width: 200,
|
68
70
|
toolbar: '#currentTableBar_file',
|
69
71
|
align: "center"
|
70
72
|
}
|
@@ -76,7 +78,20 @@
|
|
76
78
|
});
|
77
79
|
|
78
80
|
|
79
|
-
|
81
|
+
var sort = {};
|
82
|
+
table.on('sort(file)', function (obj) {
|
83
|
+
sort.field = obj.field;
|
84
|
+
sort.order = obj.type;
|
85
|
+
table.reload('file', {
|
86
|
+
initSort: obj,
|
87
|
+
where: {
|
88
|
+
sort: sort
|
89
|
+
}
|
90
|
+
});
|
91
|
+
})
|
92
|
+
|
93
|
+
|
94
|
+
table.on('toolbar(file)', function (obj) {
|
80
95
|
if (obj.event === 'upload_file') { //
|
81
96
|
id =parent.id
|
82
97
|
var content = miniPage.getHrefContent('/missions/businesses/upload_file');
|
@@ -98,20 +113,20 @@
|
|
98
113
|
});
|
99
114
|
|
100
115
|
|
101
|
-
|
102
|
-
table.on('tool(currentTableFilter)', function (obj) {
|
116
|
+
table.on('tool(file)', function (obj) {
|
103
117
|
var data = obj.data;
|
104
118
|
var id = data.id
|
105
119
|
name = data.disk_filename
|
120
|
+
folder = gon.folder
|
121
|
+
console.log(folder);
|
106
122
|
if (obj.event === 'preview') {
|
107
123
|
if (data.content_type.split("/")[0] === "image"){
|
108
|
-
// var img = "<img src='/images/" + name + "' />";
|
109
124
|
layer.photos({
|
110
|
-
photos: { "data": [{"src": '/images/'+name}] }
|
125
|
+
photos: { "data": [{"src": '/images/educode_sales/' + name}] }
|
111
126
|
,anim: 5 //0-6的选择,指定弹出图片动画类型,默认随机
|
112
127
|
});
|
113
128
|
}else if (data.content_type.split("/")[1] === "pdf"){
|
114
|
-
var pdf = '/images/' + name;
|
129
|
+
var pdf = '/images/business_file/' + name;
|
115
130
|
console.log(pdf);
|
116
131
|
var openWH = miniPage.getOpenWidthHeight();
|
117
132
|
layer.open({
|
@@ -130,7 +145,7 @@
|
|
130
145
|
layer.confirm('确定删除' + data.name, function (index) {
|
131
146
|
request.delete('missions/upload_files/' + data.id + '?disk_filename=' + data.disk_filename, {}, function (res) {
|
132
147
|
layer.close(index);
|
133
|
-
table.reload("
|
148
|
+
table.reload("file")
|
134
149
|
})
|
135
150
|
});
|
136
151
|
}
|
@@ -53,7 +53,7 @@
|
|
53
53
|
<div class="layui-inline">
|
54
54
|
<button type="reset" class="layui-btn layui-btn-primary" lay-submit lay-filter="reset_business_search">重置
|
55
55
|
</button>
|
56
|
-
<button type="submit" class="layui-btn layui-btn-primary" lay-submit lay-filter="search_bussiness">搜索
|
56
|
+
<button type="submit" id="search_bt" class="layui-btn layui-btn-primary" lay-submit lay-filter="search_bussiness">搜索
|
57
57
|
</button>
|
58
58
|
</div>
|
59
59
|
</div>
|
@@ -173,13 +173,13 @@
|
|
173
173
|
field: 'bidded_date',
|
174
174
|
width: 105,
|
175
175
|
title: '中标时间',
|
176
|
-
|
176
|
+
sort: true
|
177
177
|
},
|
178
178
|
{
|
179
179
|
field: 'signed_date',
|
180
180
|
width: 105,
|
181
181
|
title: '签单时间',
|
182
|
-
|
182
|
+
sort: true
|
183
183
|
},
|
184
184
|
{
|
185
185
|
field: 'reception_at',
|
@@ -335,14 +335,14 @@
|
|
335
335
|
title: '商机列表/'+name+'的附件信息',
|
336
336
|
type: 1,
|
337
337
|
shade: 0.2,
|
338
|
-
maxmin: true,
|
338
|
+
// maxmin: true,
|
339
339
|
shadeClose: true,
|
340
340
|
area: [openWH[0] + 'px', openWH[1] + 'px'],
|
341
341
|
offset: [openWH[2] + 'px', openWH[3] + 'px'],
|
342
342
|
content: content
|
343
343
|
});
|
344
344
|
$(window).on("resize", function () {
|
345
|
-
layer.full(sindex);
|
345
|
+
// layer.full(sindex);
|
346
346
|
});
|
347
347
|
}
|
348
348
|
|
@@ -373,6 +373,13 @@
|
|
373
373
|
});
|
374
374
|
}
|
375
375
|
|
376
|
+
function hn(){
|
377
|
+
$("#search_bt").trigger("click");
|
378
|
+
}
|
379
|
+
$(document).ready(function(){
|
380
|
+
window.onload=hn;
|
381
|
+
});
|
382
|
+
|
376
383
|
|
377
384
|
var sort = {}, search = {};
|
378
385
|
table.on('sort(businesses_table)', function (obj) {
|
@@ -390,7 +397,8 @@
|
|
390
397
|
// 监听搜索操作
|
391
398
|
form.on('submit(search_bussiness)', function (data) {
|
392
399
|
search = data.field
|
393
|
-
|
400
|
+
console.log(search);
|
401
|
+
table.reload('businesses_table', {
|
394
402
|
page: {
|
395
403
|
curr: 1
|
396
404
|
},
|
@@ -606,4 +614,9 @@
|
|
606
614
|
});
|
607
615
|
|
608
616
|
});
|
609
|
-
</script>
|
617
|
+
</script>
|
618
|
+
<style>
|
619
|
+
.layui-table-tool-temp{
|
620
|
+
padding-right: 30px; !important;
|
621
|
+
}
|
622
|
+
</style>
|
@@ -97,9 +97,13 @@
|
|
97
97
|
</div>
|
98
98
|
<div class="layui-form-item">
|
99
99
|
<label class="layui-form-label">指定跟进人</label>
|
100
|
-
<div class="layui-input-inline">
|
100
|
+
<div class="layui-input-inline" style="z-index: 100">
|
101
101
|
<div id="assign_follow" style="width: 512px;"></div>
|
102
102
|
</div>
|
103
|
+
<div class="layui-inline" style="padding: 9px 15px">
|
104
|
+
<label class="layui-form-label" style="padding-left: 220px"></label>
|
105
|
+
指定跟进人和商机创建者,同时拥有对该商机的管理权限
|
106
|
+
</div>
|
103
107
|
</div>
|
104
108
|
<div class="layui-form-item layui-form-text">
|
105
109
|
<label class="layui-form-label required">最新进展</label>
|