一、销售与客户 - 表结构

---公共客户(公共资源)
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. mac下普通用户无法创建crontab的问题解决

    想在mac下弄一个crontab定时任务,以为会像linux上那样顺利那,结果碰壁了,报错信息例如以下: ➜  autoshell  crontab -ecrontab: no crontab for ...

  2. 3d引擎列表

    免费引擎 Agar - 一个高级图形应用程序框架,用于2D和3D游戏. Allegro library - 基于 C/C++ 的游戏引擎,支持图形,声音,输入,游戏时钟,浮点,压缩文件以及GUI. A ...

  3. Win10開始菜单打不开

    一.前言 自从用Win10之后(附上<我的Win10之旅>).用清理软件.总是深度清理,导致rt问题. 每次百度都是没用的解决方法: 今天,再一次清理(Wise Care 365 注冊表深 ...

  4. MVC4 Controller 与 WebApi 的 Session 传值问

    在MVC以后,Session方式可能已经不太常用,但偶尔还是会用到,比如页面验证码之类的.例如登录页面使用的验证码通过Controller提供一个View来实现,可以使用Session来存储这个值.但 ...

  5. XP 终端服务组件 恢复补丁包 terminal service patch

    terminal 终端服务组件恢复包 下载地址(点击) winconnect server xp软件 下载地址(点击)

  6. jenkins第一次登陆,输入完密码之后,卡在了SetupWizard[jenkins]处

    问题描述: 前几天在安装测试环境的jenkins,启动tomcat之后,通过页面进行登录,输入完初始化的密码之后,就一直卡在 SetupWizard[jenkins]这个地方. 问题如下图: 备注:等 ...

  7. c++ 类数据成员的定义、声明

    C++为类中提供类成员的初始化列表类对象的构造顺序是这样的:1.分配内存,调用构造函数时,隐式/显示的初始化各数据成员2.进入构造函数后在构造函数中执行一般计算  1.类里面的任何成员变量在定义时是不 ...

  8. 联想服务器thinkserver rd650安装 windows server 2008 r2

    前几天,客户那边来电话说业务系统上不去了,远程连接发现密码也被改了,数据也没有备份出来,所以想使用 PE工具进入破解密码,具体的方法不多讲了,很多PE工具是自带更改密码的工具的,我们只要一步一步的按着 ...

  9. Effective C++ Item 16 Use the same form in corresponding uses of new and delete

    1. When you created an array and want to return the memory to system. You need to explicitly add [] ...

  10. 08python之列表的常用方法

    列表list是python常用的数据类型,需要掌握以下常用方法: name_list = ['alex','tenglan','65brother'] 这个变量和之前的变量只存一个数字或字符串,这个列 ...