一、销售与客户 - 表结构

---公共客户(公共资源)
1、没有报名
2、3天没有跟进
3、15天没有成单 客户分布表
龙泰 男 yuan 2018-5-1 3天未跟进
龙泰 男 三江 2018-5-5 15天未成单
龙泰 男 暴雨 2018-5-21 正在跟进 ---我的客户(抢单)
crontab:
2018-5-15 12:00 龙泰 男 三江 2018-5-15 正在跟进 2018-5-16 0:0
2018-5-17 0:0
2018-5-18 0:0
2018-5-19 0:0 龙泰 男 三江 2018-5-19 3天未跟进 key: CustomerDistrbute为什么创建 ,为什么不能直接用Customer 因为:销售可以查看,自己的客户是否已过期,是否正在跟进,月底可以算业绩!
不能说没谈成,就没有业绩!! 一过期,就改了。定时脚本来完成!!
linux 固定时间,执行脚本 os 去做,
每天00:00去监测! 隔半天或隔一天,脚本每天凌晨监测一遍过期就放到公共客户。 新增客户分布表:
class CustomerDistrbute(models.Model):
customer = models.ForeignKey("Customer", related_name="customers")
consultant = models.ForeignKey(verbose_name="课程顾问", to="UserInfo", limit_choices_to={"depart_id":1001})
date = models.DateField()
status_choices = (
(1, '正在跟进'),
(2, '已报名'),
(3, '三天未跟进'),
(4, '15天未成单'),
)
status = models.IntegerField(choices=status_choices, default=1)
meno = models.CharField(max_length=255) def __str__(self):
return self.customer.name + ":" + self.consultant.name

新的表结构


二、公共客户

知识点

1. 新增url

temp.append(url(r'^public/', self.public_customer))

2. datetime.timedelta ( 时间 + - )

    datetime.datetime
datetime.date
datetime.time
datetime.timedelta(days=7) now = datetime.datetime.now()
delta_day3 = datetime.timedelta(days=3)
delta_day15 = datetime.timedelta(days=15)

3. 未报名且3天未跟进或者15天未成单

  # 3天未跟进   now - last_consult_date > 3  --> last_consult_date < now - 3
  # 15天未成单 now - recv_date > 15 --> recv_date < now - 15 Q查询 last_consult_date__lt recv_date__lt customer_list = Customer.objects.filter(
Q(last_consult_date__lt=now-delta_day3)|Q(recv_date__lt=now-delta_day15),status=2)

4. exclude(排除)

  # 不应该让之前的课程顾问 再看到这个已经放到公共名单的人了
user_id = 3
customer_list = Customer.objects.filter(
Q(last_consult_date__lt=now - delta_day3) | Q(recv_date__lt=now - delta_day15),
      status=2).exclude(consultant=user_id)

5. customer_list.query( sql 语句 )

        # print(customer_list.query)
"""
SELECT "crm_customer"."id", "crm_customer"."qq",
"crm_customer"."name", "crm_customer"."gender",
"crm_customer"."education", "crm_customer"."graduation_school",
"crm_customer"."major", "crm_customer"."experience",
"crm_customer"."work_status", "crm_customer"."company",
"crm_customer"."salary", "crm_customer"."source",
"crm_customer"."referral_from_id", "crm_customer"."status",
"crm_customer"."consultant_id", "crm_customer"."date",
"crm_customer"."recv_date", "crm_customer"."last_consult_date"
FROM "crm_customer"
WHERE (("crm_customer"."last_consult_date" < 2018-06-24
OR "crm_customer"."recv_date" < 2018-06-12)
AND "crm_customer"."status" = 2) """
    def public_customer(self, request):
# 未报名且3天未跟进或者15天未成单
from django.db.models import Q
import datetime
"""
datetime.datetime
datetime.date
datetime.time
datetime.timedelta(days=7)
"""
now = datetime.datetime.now()
delta_day3 = datetime.timedelta(days=3)
delta_day15 = datetime.timedelta(days=15)
# 3天未跟进 now - last_consult_date > 3 --> last_consult_date < now - 3
# 15天未成单 now - recv_date > 15 --> recv_date < now - 15 # customer_list = Customer.objects.filter(
# Q(last_consult_date__lt=now-delta_day3)|Q(recv_date__lt=now-delta_day15),status=2) # 不应该让之前的课程顾问 再看到这个人已经放到公共名单的人了
user_id = 3
customer_list = Customer.objects.filter(
Q(last_consult_date__lt=now - delta_day3) | Q(recv_date__lt=now - delta_day15), status=2).exclude(consultant=user_id) # print(customer_list.query)
"""
SELECT "crm_customer"."id", "crm_customer"."qq",
"crm_customer"."name", "crm_customer"."gender",
"crm_customer"."education", "crm_customer"."graduation_school",
"crm_customer"."major", "crm_customer"."experience",
"crm_customer"."work_status", "crm_customer"."company",
"crm_customer"."salary", "crm_customer"."source",
"crm_customer"."referral_from_id", "crm_customer"."status",
"crm_customer"."consultant_id", "crm_customer"."date",
"crm_customer"."recv_date", "crm_customer"."last_consult_date"
FROM "crm_customer"
WHERE (("crm_customer"."last_consult_date" < 2018-06-24
OR "crm_customer"."recv_date" < 2018-06-12)
AND "crm_customer"."status" = 2) """
print("----->>:", customer_list) return render(request, 'public.html', locals()) ------------------------
  temp.append(url(r'^public/', self.public_customer))

public.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css"> </head>
<body>
<h3>公共客户</h3> <div class="container">
<div class="row">
<div class="col-md-6">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>QQ</th>
<th>课程顾问</th>
<th>跟进详情</th>
<th>确认跟进</th>
</tr>
</thead>
<tbody>
{% for customer in customer_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ customer.name }}</td>
<td>{{ customer.qq }}</td>
<td>{{ customer.consultant }}</td>
<td><a href="/stark/crm/consultrecord/?customer={{ customer.pk }}">跟进记录</a></td>
<td><a href="/stark/crm/customer/further/{{ customer.pk }}">确认跟进</a></td>
</tr>
{% endfor %} </tbody>
</table>
</div>
</div>
</div> </body>
</html>

public.html

三、确认跟进

知识点

1. 新增url

temp.append(url(r'^further/(\d+)', self.further))

2. 更改课程顾问和对应的时间

  一定要先过滤;防止多个用户同时抢单,给了 最后一个抢单的人;先过滤之后再抢单,注意提示已经被跟进了。

   ret = Customer.objects.filter(pk=customer_id).filter(
Q(last_consult_date__lt=now-delta_day3)|Q(recv_date__lt=now-delta_day15),status=2).update(
consultant=user_id,last_consult_date = now,recv_date=now
)

3. 创建一条客户分布表

  为我的客户页面做准备

        CustomerDistrbute.objects.create(
customer_id=customer_id,consultant_id=user_id,
date=now,status=1,
)
   temp.append(url(r'^further/(\d+)', self.further))

-------------------------------------------------------

    def further(self, request,customer_id):
"""确认跟进"""
user_id = 3 now = datetime.datetime.now()
delta_day3 = datetime.timedelta(days=3)
delta_day15 = datetime.timedelta(days=15) # 为该客户更改课程顾问 和对应得时间,
ret = Customer.objects.filter(pk=customer_id).filter(
Q(last_consult_date__lt=now-delta_day3)|Q(recv_date__lt=now-delta_day15),status=2).update(
consultant=user_id,last_consult_date = now,recv_date=now
)
if not ret:
return HttpResponse('已经被跟进了') CustomerDistrbute.objects.create(
customer_id=customer_id,consultant_id=user_id,
date=now,status=1,
)
return HttpResponse('跟进成功')

四、我的客户

知识点

1. 新增url

temp.append(url(r'^mycustomer/', self.mycustomer))

2. 客户分布表查询

  不能再 Customer表查询,这里查到的只是正在跟踪的客户信息

  但是,之前跟踪过的客户,状态也要显示

     customer_distrubute_list = CustomerDistrbute.objects.filter(consultant_id=user_id)
   temp.append(url(r'^mycustomer/', self.mycustomer))

---------------------------------------------

    def mycustomer(self, request):
user_id = 3 customer_distrubute_list = CustomerDistrbute.objects.filter(consultant_id=user_id) return render(request,'mycustomer.html', locals())
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h4>我的客户</h4>
<ul>
{% for customer_distrubute in customer_distrubute_list %}
<li>
{{ customer_distrubute.customer }}
-----{{ customer_distrubute.date|date:'Y-m-d' }}
-----{{ customer_distrubute.get_status_display }}
</li>
{% endfor %} </ul> </body>
</html>

mycustomer.html

五、code

crm/stark.py

# -*- coding:utf-8 -*-

from .models import *
from stark.service.stark import site, ModelStark
from django.utils.safestring import mark_safe
from django.conf.urls import url
from django.shortcuts import HttpResponse,reverse,redirect,render
import datetime
from django.db.models import Q class DepartmentConfig(ModelStark):
list_display = ['title', 'code'] site.register(Department, DepartmentConfig) class UserInfoConfig(ModelStark):
list_display = ["name", 'email', 'depart'] site.register(UserInfo, UserInfoConfig) class ClassListConfig(ModelStark):
def display_classname(self,obj=None,header=False):
if header:
return "班级名称"
return "%s(%s)"%(obj.course.name, obj.semester) list_display = [display_classname, 'tutor', 'teachers'] site.register(ClassList, ClassListConfig) class CustomerConfig(ModelStark):
def display_course(self, obj=None, header=False):
if header:
return "咨询课程" temp = []
for course in obj.course.all():
temp.append("<a href='/stark/crm/customer/cancel_course/%s/%s' style='border:1px solid #369; padding:3px 6px;'><span>%s</span></a>&nbsp;"%(obj.pk,course.pk,course.name)) return mark_safe("".join(temp)) def cancel_course(self, request, customer_id, course_id):
customer_obj = Customer.objects.filter(pk=customer_id).first()
customer_obj.course.remove(course_id)
return redirect(self.get_list_url()) # 重定向到当前表得查看页面 def public_customer(self, request):
# 未报名且3天未跟进或者15天未成单
from django.db.models import Q
import datetime
"""
datetime.datetime
datetime.date
datetime.time
datetime.timedelta(days=7)
"""
now = datetime.datetime.now()
delta_day3 = datetime.timedelta(days=3)
delta_day15 = datetime.timedelta(days=15)
# 3天未跟进 now - last_consult_date > 3 --> last_consult_date < now - 3
# 15天未成单 now - recv_date > 15 --> recv_date < now - 15 # customer_list = Customer.objects.filter(
# Q(last_consult_date__lt=now-delta_day3)|Q(recv_date__lt=now-delta_day15),status=2) # 不应该让之前的课程顾问 再看到这个已经放到公共名单的人了
user_id = 3
customer_list = Customer.objects.filter(
Q(last_consult_date__lt=now - delta_day3) | Q(recv_date__lt=now - delta_day15), status=2).exclude(consultant=user_id) # print(customer_list.query)
"""
SELECT "crm_customer"."id", "crm_customer"."qq",
"crm_customer"."name", "crm_customer"."gender",
"crm_customer"."education", "crm_customer"."graduation_school",
"crm_customer"."major", "crm_customer"."experience",
"crm_customer"."work_status", "crm_customer"."company",
"crm_customer"."salary", "crm_customer"."source",
"crm_customer"."referral_from_id", "crm_customer"."status",
"crm_customer"."consultant_id", "crm_customer"."date",
"crm_customer"."recv_date", "crm_customer"."last_consult_date"
FROM "crm_customer"
WHERE (("crm_customer"."last_consult_date" < 2018-06-24
OR "crm_customer"."recv_date" < 2018-06-12)
AND "crm_customer"."status" = 2) """
print("----->>:", customer_list) return render(request, 'public.html', locals()) def further(self, request,customer_id):
"""确认跟进"""
user_id = 3 now = datetime.datetime.now()
delta_day3 = datetime.timedelta(days=3)
delta_day15 = datetime.timedelta(days=15) # 为该客户更改课程顾问 和对应得时间,
ret = Customer.objects.filter(pk=customer_id).filter(
Q(last_consult_date__lt=now-delta_day3)|Q(recv_date__lt=now-delta_day15),status=2).update(
consultant=user_id,last_consult_date = now,recv_date=now
)
if not ret:
return HttpResponse('已经被跟进了') CustomerDistrbute.objects.create(
customer_id=customer_id,consultant_id=user_id,
date=now,status=1,
)
return HttpResponse('跟进成功') def mycustomer(self, request):
user_id = 3 customer_distrubute_list = CustomerDistrbute.objects.filter(consultant_id=user_id) return render(request,'mycustomer.html', locals()) def extra_url(self):
temp = []
temp.append(url(r'^cancel_course/(\d+)/(\d+)', self.cancel_course))
temp.append(url(r'^public/', self.public_customer))
temp.append(url(r'^further/(\d+)', self.further))
temp.append(url(r'^mycustomer/', self.mycustomer))
return temp list_display = ["name", "gender",display_course ,"consultant"] site.register(Customer, CustomerConfig) class ConsultRecordConfig(ModelStark):
list_display = ["customer", 'consultant','date','note'] site.register(ConsultRecord, ConsultRecordConfig) from django.http import JsonResponse
class StudentConfig(ModelStark):
def score_view(self,request,sid):
if request.is_ajax():
# print(request.GET)
cid = request.GET.get('cid')
sid = request.GET.get('sid') # 跨表查
study_record_list = StudyRecord.objects.filter(student=sid,course_record__class_obj=cid) data_list = []
for study_record in study_record_list:
day_num = study_record.course_record.day_num
data_list.append(["day%s"%day_num,study_record.score])
# # [['day94', 85], ['day95', 85], ['day96', -1]]
return JsonResponse(data_list,safe=False) else:
student = Student.objects.filter(pk=sid).first()
class_list = student.class_list.all()
return render(request,'score_view.html', locals()) def extra_url(self):
temp = []
temp.append(url(r"^score_view/(\d+)",self.score_view))
return temp def score_show(self, obj=None, header=False):
if header:
return "查看成绩"
return mark_safe("<a href='score_view/%s'>查看成绩</a>"%obj.pk) list_display = ['customer','class_list',score_show]
list_display_links = ['customer'] site.register(Student,StudentConfig) class CourseRecordConfig(ModelStark): def score(self,request, course_record_id):
if request.method == "POST":
print('post::::', request.POST)
"""
<QueryDict: {'csrfmiddlewaretoken': ['muIrf7pwbxIueSJcKADRlZEGVbzzRZOaiGVkBV8DGYC2V9gmxZtyZgujddFtTojk'],
'score_33': ['100'], 'homework_note_33': ['很好'],
'score_34': ['85'], 'homework_note_34': ['棒'],
'score_35': ['60'], 'homework_note_35': ['None']}>
"""
data = {} # data={"33":{"score":100,"homework_note":'xxx'},}
for key,value in request.POST.items():
if key == "csrfmiddlewaretoken":continue
field, pk = key.rsplit('_', 1) if pk in data:
data[pk][field] = value
else:
data[pk] = {field:value} print("data-->",data)
"""
{'33': {'score': '90', 'homework_note': '很好'},
'34': {'score': '80', 'homework_note': '帮帮哒'},
'35': {'score': '50', 'homework_note': '没问题'}} """
for pk,update_data in data.items():
StudyRecord.objects.filter(pk=pk).update(**update_data) return redirect(request.path) else:
study_record_list = StudyRecord.objects.filter(course_record__id=course_record_id)
score_choices = StudyRecord.score_choices
return render(request,'score.html',locals()) def extra_url(self):
temp = []
temp.append(url(r'^record_score/(\d+)', self.score))
return temp def record(self, obj=None, header=False):
if header:
return "学习记录"
return mark_safe("<a href='/stark/crm/studyrecord/?course_record=%s'>记录</a>"%(obj.pk)) def record_score(self, obj=None, header=False):
if header:
return "录入成绩"
return mark_safe("<a href='record_score/%s'>录入成绩</a>"%obj.pk) list_display = ["class_obj", 'day_num', "teacher", record, record_score ] def patch_studyrecord(self,request,queryset):
# print('queryset:--》',queryset)
temp = []
for course_record in queryset:
# 与course_record 关联得班级对应得学生
students_list = Student.objects.filter(class_list__id = course_record.class_obj.pk)
for student in students_list:
student_obj = StudyRecord(course_record=course_record,student=student)
temp.append(student_obj) StudyRecord.objects.bulk_create(temp) actions = [patch_studyrecord]
patch_studyrecord.short_description = "批量生成学习记录" site.register(CourseRecord,CourseRecordConfig) class StudyRecordConfig(ModelStark):
list_display = ['student','course_record','record','score'] def patch_late(self, request, queryset):
queryset.update(record="late") patch_late.short_description = "迟到"
actions = [patch_late] site.register(StudyRecord,StudyRecordConfig) site.register(Course)
site.register(School) class CustomerDistrbuteConfig(ModelStark):
list_display = ["customer",'consultant','date','status'] site.register(CustomerDistrbute,CustomerDistrbuteConfig)

stark.py

CRM - 销售与客户的更多相关文章

  1. 3 CRM 销售与客户 我的客户,公共客户池

    1.销售与客户的表结构 1.公共客户与我的客户 ---公共客户(公共资源) 1.没有报名 2.3天没有跟进 3.15天没有成单 客户分布表 龙泰 男 yuan 2018-5-1 3天未跟进 龙泰 男 ...

  2. CRM——销售与客户

    一.销售与客户——表结构 1.客户类型 (1)公共客户(公共资源) 必备条件:没有报名: 在必备条件满足的情况下,满足以下任意条件都是公共客户: 3天没有跟进:15天没有成单. (2)我的客户 原销售 ...

  3. 如何借助CRM销售管理系统提升业绩?

    与传统企业销售模式不同,现代企业在网络背书下,销售活动与网络密切相关.销售数据需要网络保存,销售渠道需要网络挖掘.在线的销售软件让销售活动起到了事半功倍的效果.CRM销售管理系统是企业必不可少的在线软 ...

  4. 企业管理CRM不只是客户录入系统

    企业在举办营销活动或者展会之后,将会收集到大量的客户信息,将这些信息有效地整理.完善.储存也是一个不小的工程.如果您的企业经常面遇到这样的情况,不妨使用Zoho CRM系统来帮您完成.但是,Zoho ...

  5. 【JAVAEE学习笔记】hibernate01:简介、搭建、配置文件详解、API详解和CRM练习:保存客户

    今日学习:hibernate是什么 一.hibernate是什么 框架是什么: 1.框架是用来提高开发效率的 2.封装了好了一些功能.我们需要使用这些功能时,调用即可.不需要再手动实现. 3.所以框架 ...

  6. JAVAEE学习——hibernate01:简介、搭建、配置文件详解、API详解和CRM练习:保存客户

    今日学习:hibernate是什么 一.hibernate是什么 框架是什么: 1.框架是用来提高开发效率的 2.封装了好了一些功能.我们需要使用这些功能时,调用即可.不需要再手动实现. 3.所以框架 ...

  7. crm销售管理系统一

    一.环境配置 1.首先配置pip,环境变量配置 pip 9.0.1 from c:\users\administrator\envs\crm\lib\site-packages (python 3.6 ...

  8. CRM系统对管理客户的帮助

    我们可以把客户关系看做是一种长期的投资,在资源有限的基础上,把人力财力物力放到那些能够持续创造价值的客户身上,从而为企业带来源源不断的收益.通过进行客户关系管理,能够让企业与客户之间建立沟通的渠道,形 ...

  9. Hibernate框架:CRM练习--保存客户

    crm:customer ralation manager 客户关系管理系统 一.准备 1.创建web项目 2.导包 最终为: 3.引入静态页面 将文件复制放入项目的WebContent目录下面: 4 ...

随机推荐

  1. 为什么要整合apache 和tomcat?

    1. Apache是web服务器,Tomcat是应用(java)服务器,它只是一个servlet容器,是Apache的扩展. 2. Apache和Tomcat都可以做为独立的web服务器来运行,但是A ...

  2. php数组函数常见的那些

    一.数组操作的基本函数 array_values($arr); //获得数组的值 array_keys($arr); //获得数组的键名 array_flip($arr); //数组中的值与键名互换( ...

  3. 浅谈session测试

    Session 是用于保持状态的基于 Web 服务器的方法,在 Web 服务器上保持用户的状态信息供在任何时间从任何页访问.Session 允许通过将对象存储在 Web 服务器的内存中在整个用户会话过 ...

  4. VCL 中的 Windows API 函数(6): BeginDeferWindowPos

    BeginDeferWindowPos 和 DeferWindowPos.EndDeferWindowPos 是一组一起使用的函数, 可对一组窗口的位置.大小.Z 序等进行调整, 在 ExtCtrls ...

  5. 腾讯QQ空间超分辨率技术TSR

    腾讯QQ空间超分辨率技术TSR:为用户节省3/4流量,处理效果和速度超谷歌RAISR 雷锋网AI科技评论: 随着移动端屏幕分辨率越来越高,甚至像iPhone更有所谓的“视网膜屏”,人们对高清图片的诉求 ...

  6. 【转自IT虾米网:www.itxm.net】外部应用和drools-wb6.1集成解决方案

    一.手把手教你集成外部应用和drools workbench6.1 1.         首先按照官方文档安装workbench ,我用的是最完整版的jbpm6-console的平台系统,里面既包含j ...

  7. Extjs学习笔记--(六,选择器)

    文档对象dom是javascript与页面元素的桥梁 选择器的作用就是通过元素的标签名,属性名,css属性名对页面进行快速,准确的定位及选择 Extjs的选择器:Ext.DomQuery Ext.qu ...

  8. Android 使用DatePicker以及TimePicker显示当前日期和时间

    课程内容1.介绍DatePicker和TimePicker两种实现动态输入日期和事件的功能2.介绍DatePickerDialog和TimePickerDialog来年耕种实现动态输入日期和事件的对话 ...

  9. ExtJS 6.2 基础使用

    一. 安装: 下载两个压缩包:分别是 ext-6.2.0-gpl(这个是ExtJS 的SDK文件,创建新项目的时候需要用). SenchaCmd-6.5.2-windows-64bit (这个下载下来 ...

  10. 【thinkphp5】 分页样式修改

    1 找到文件:/thinkphp/library/think/paginator/driver/Bootstrap.php <?php // +------------------------- ...