#urls.py

 """PerfectCRM URL Configuration

 The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path # ————————02PerfectCRM创建ADMIN页面————————
from django.conf.urls import url # URL
from django.conf.urls import include # 分发URL
# ————————02PerfectCRM创建ADMIN页面———————— # ————————46PerfectCRM实现登陆后页面才能访问————————
from PerfectCRM import main_views
# ————————46PerfectCRM实现登陆后页面才能访问———————— urlpatterns = [
path('admin/', admin.site.urls), # ————————02PerfectCRM创建ADMIN页面————————
url(r'^king_admin/', include("king_admin.king_urls")), # 自定义admin
# ————————02PerfectCRM创建ADMIN页面———————— # ————————03PerfectCRM创建基本数据————————
url(r'^DBadd/', include("DBadd.DBadd_urls")), # 添加随机数据
# ————————03PerfectCRM创建基本数据————————
# ————————38PerfectCRM实现全局账号登录注销————————
url(r'^gbacc/', include("gbacc.gbacc_urls")), # 全局账号登录注销
# ————————38PerfectCRM实现全局账号登录注销———————— # ————————42PerfectCRM实现AJAX全局账号注册————————
url(r'^gbacc/', include("gbacc.gbacc_ajax_urls")), # 全局账号登录注销
# ————————42PerfectCRM实现AJAX全局账号注册———————— # ————————46PerfectCRM实现登陆后页面才能访问————————
url(r'^$', main_views.PortalView.as_view()),
# ————————46PerfectCRM实现登陆后页面才能访问———————— # ————————47PerfectCRM实现CRM客户报名流程————————
url(r'^bpm/', include("bpm.sales.sales_urls")), # 业务流程
# ————————47PerfectCRM实现CRM客户报名流程———————— # ————————53PerfectCRM实现CRM客户报名流程缴费————————
url(r'^bpm/', include("bpm.financial.financial_urls")), # 财务缴费
# ————————53PerfectCRM实现CRM客户报名流程缴费———————— ]

#urls.py

 # financial_urls.py

 from django.conf.urls import url
from bpm.financial import financial_views urlpatterns = [
url(r'^not_payment/$', financial_views.not_payment, name="not_payment"), # 报名流程四 未 缴费 查询
url(r'^already_payment/$', financial_views.already_payment, name="already_payment"), # 报名流程四 已 缴费 查询
url(r'^payment/(\d+)/$', financial_views.payment, name="payment"), # 报名流程四 缴费 #财务
]
# ————————47PerfectCRM实现CRM客户报名流程————————

# financial_urls.py

 # financial_views.py
# ————————53PerfectCRM实现CRM客户报名流程缴费————————
from crm import models #数据库
from django.shortcuts import redirect,render #页面返回
from bpm.bpm_auxiliary import bpm_forms #自定制 forms
from django.contrib.auth.decorators import login_required # 登陆后页面才能访问
# #待缴费
def not_payment(request):
sign=models.Enrollment.objects.all()#所有的报名表
return render(request, 'bpm_financial/not_payment.html', locals())#
# 已缴费
def already_payment(request):
sign=models.Enrollment.objects.all()#所有的报名表
return render(request, 'bpm_financial/already_payment.html', locals())#
#缴费视图
@login_required # 登陆后页面才能访问
def payment(request,enroll_id):
sign=models.Payment.objects.all()#所有的报名表#前端对比用户#缴费记录
enroll_obj=models.Enrollment.objects.get(id=enroll_id)#取对象
errors={} #错误信息
if request.method=="POST":
payment_amount=request.POST.get('amount')#缴费金额
consultant = models.UserProfile.objects.get(id=request.user.id) #财务人员 #当前登陆人
if payment_amount:
payment_amount=int(payment_amount) #转数字类型
if payment_amount<500:
errors['err']='缴费金额不得低于500元!'
else: #生成forms
payment_obj=models.Payment.objects.create(
customer=enroll_obj.customer,##客户表 学员
course=enroll_obj.enrolled_class.course,#所报课程
consultant=consultant,# 财务人员
amount=payment_amount,#缴费金额
)
enroll_obj.Pay_cost=True#已缴费
enroll_obj.save() #保存
enroll_obj.customer.status=0#修改报名状态 为已报名#根据数据库
enroll_obj.customer.save() #保存
return redirect('/bpm/not_payment')#客户表
else:
errors['err']='金额不能为空!'
else:
payment_form= bpm_forms.PaymentForm()#生成表单
return render(request, 'bpm_financial/payment.html', locals())
# ————————53PerfectCRM实现CRM客户报名流程缴费————————

# financial_views.py

 #models.py

 # ————————01PerfectCRM基本配置ADMIN————————

 from django.db import models
# Create your models here. """
#运行 Terminal
# 生成 数据表
# python manage.py makemigrations
# 数据表 迁移
# python manage.py migrate
""" """01校区表"""
class Branch(models.Model):
name = models.CharField(max_length=128,unique=True) #校区名#CharField作用是保存文本,定长的变量类型
addr = models.CharField(max_length=128) #地址
def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
return self.name #返回 #校区名
class Meta: #通过一个内嵌类 "class Meta" 给你的 model 定义元数据
verbose_name_plural = "01校区表" #verbose_name_plural给你的模型类起一个更可读的名字 """02班级表"""
class ClassList(models.Model):
#ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
branch = models.ForeignKey("Branch",on_delete=models.CASCADE)#校区 关联到 校区表
course = models.ForeignKey("Course",on_delete=models.CASCADE) #课程 关联到 课程表 # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
contract = models.ForeignKey('ContractTemplate', blank=True, null=True, default=1,on_delete=models.CASCADE) # 合同表
# ————————48PerfectCRM实现CRM客户报名流程学生合同———————— class_type_choices = ( #上课形式
(0,'面授(脱产)'),
(1,'面授(周末)'),
(2,'网络班'),)
#PositiveSmallIntegerField正小整数 0 ~ 32767 #choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
class_type = models.SmallIntegerField(choices=class_type_choices)#上课形式 #PositiveSmallIntegerField正小整数 0 ~ 32767
semester = models.PositiveSmallIntegerField(verbose_name="学期") #课程的第几期 #ManyToManyField多对多和外键工作方式相同,只不过我们处理的是QuerySet而不是模型实例。
teachers = models.ManyToManyField("UserProfile") # 老师 关联到 账号表 start_date = models.DateField(verbose_name="开班日期") #DateField 日期格式 YYYY-MM-DD #verbose_name是Admin中显示的字段名称 # DateField 日期格式 YYYY-MM-DD #verbose_name是Admin中显示的字段名称 #Django可空#数据库可以为空
end_date = models.DateField(verbose_name="结业日期",blank=True,null=True) def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
return "%s %s %s" %(self.branch,self.course,self.semester) #返回 #%s格式化输出字符串 #校区#课程# 学期
class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
unique_together=('branch','course','semester') #联合索引
verbose_name_plural = "02班级表" #verbose_name_plural给你的模型类起一个更可读的名字 """03课程表,可以报名那些课程"""
class Course(models.Model):
name = models.CharField(max_length=64,unique=True)#课程名 #CharField作用是保存文本,定长的变量类型
price = models.PositiveSmallIntegerField(verbose_name="学费")#学费#PositiveSmallIntegerField正小整数 0 ~ 32767
period = models.PositiveSmallIntegerField(verbose_name="周期(月)") #PositiveSmallIntegerField正小整数 0 ~ 32767
outline = models.TextField() #课程大纲 #文本类型
def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
return self.name #返回 #课程名
class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
verbose_name_plural = "03课程表"#verbose_name_plural给你的模型类起一个更可读的名字 '''04客户信息表'''
class Customer(models.Model):
name = models.CharField(max_length=32,blank=True,null=True)#客户名#CharField定长文本 #名字最长32 # Django可空 #数据库可以为空
qq = models.CharField(max_length=64,unique=True) #QQ号#CharField定长文本 #名字最长64 #唯一,不能重复
qq_name = models.CharField(max_length=64,blank=True,null=True)#QQ名 #CharField定长文本 #名字最长64 # Django可空 #数据库可以为空
phone = models.CharField(max_length=64,blank=True,null=True)#手机号 #CharField定长文本 #名字最长64 # Django可空 #数据库可以为空 # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
id_num=models.CharField(max_length=64,blank=True,null=True,verbose_name='身份证号')#身份证号
email=models.EmailField(max_length=64,blank=True,null=True,verbose_name='邮箱')#email
sex_choices=((0,'保密'),(1,'男'),(2,'女'))
sex=models.SmallIntegerField(choices=sex_choices,default=0,verbose_name='性别')
# ————————48PerfectCRM实现CRM客户报名流程学生合同———————— # ————————53PerfectCRM实现CRM客户报名流程缴费————————
status_choices = ((0, '已报名'), (1, '未报名'), (2, '已退学'))
status = models.SmallIntegerField(choices=status_choices, default=1) # 学员状态
# ————————53PerfectCRM实现CRM客户报名流程缴费———————— source_choices = ( #客户渠道来源 (内存生成)
(0,'转介绍'),
(1,'QQ群'),
(2,'官网'),
(3,'百度推广'),
(4,'51CTO'),
(5,'知乎'),
(6,'市场推广'),)
#PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
source = models.SmallIntegerField(choices=source_choices)#客户渠道来源 #CharField定长文本#verbose_name是Admin中显示的字段名称#名字最长64 # Django可空 #数据库可以为空
referral_from = models.CharField(verbose_name="转介绍人qq",max_length=64,blank=True,null=True) #来自谁介绍的 #ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
consult_courses = models.ForeignKey("Course",verbose_name="咨询课程", on_delete=models.CASCADE) #关联到 课程表 content= models.TextField(verbose_name="咨询详情") #TextField无限制长度的文本#verbose_name是Admin中显示的字段名称 #ManyToManyField多对多和外键工作方式相同,只不过我们处理的是QuerySet而不是模型实例。
tags = models.ManyToManyField("Tag",blank=True)#多对多关联到 标签表 #ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
consultant = models.ForeignKey("UserProfile", on_delete=models.CASCADE) #关联到 账号表 memo = models.TextField(blank=True,null=True)#备注#TextField无限制长度的文本#Django可空#数据库可以为空 #DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
date = models.DateTimeField(auto_now_add=True)#创建时间(数据库自增) def __str__(self): #__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
return self.qq #返回 #QQ号 class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
verbose_name_plural = "04客户表" #verbose_name_plural给你的模型类起一个更可读的名字 # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
#合同模版
class ContractTemplate(models.Model):
name=models.CharField('合同名称',max_length=64,unique=True)
template=models.TextField() def __str__(self):
return self.name
class Meta:
verbose_name_plural='合同表'
# ————————48PerfectCRM实现CRM客户报名流程学生合同———————— """05客户跟进表"""
class CustomerFollowUp(models.Model): #ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
customer = models.ForeignKey("Customer", on_delete=models.CASCADE)#客户名 #关联到 客户信息表 content = models.TextField(verbose_name="跟进内容")#跟进的内容#TextField无限制长度的文本#verbose_name是Admin中显示的字段名称 #ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
consultant =models.ForeignKey("UserProfile", on_delete=models.CASCADE) #关联到 账号表 intention_choices =( #报名状态
(0,'2周内报名'),
(1,'1个月内报名'),
(2,'近期无报名计划'),
(3,'已在其它机构报名'),
(4,'已报名'),
(5,'已拉黑'),)
#PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
intention=models.SmallIntegerField(choices=intention_choices) #报名状态 #DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
date = models.DateTimeField(auto_now_add=True)#创建时间(数据库自增) def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
return "<%s:%s>" %(self.customer.qq,self.intention) #返回#格式化字符串#跨表里的QQ号#报名状态
class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
verbose_name_plural = "05客户跟进表"#verbose_name_plural给你的模型类起一个更可读的名字 """06学员报名信息表"""
class Enrollment(models.Model):
# ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
customer = models.ForeignKey("Customer",on_delete=models.CASCADE)#学员名字 #关联到 客户信息表
enrolled_class = models.ForeignKey("ClassList",verbose_name="所报班级",on_delete=models.CASCADE)#关联到 班级表
consultant = models.ForeignKey("UserProfile",verbose_name="课程顾问",on_delete=models.CASCADE) #关联到 账号表 # ————————52PerfectCRM实现CRM客户报名流程学生合同审核————————
contract_review = models.CharField(max_length=256, blank=True, null=True, verbose_name="合同审核") # 合同审核
# ————————52PerfectCRM实现CRM客户报名流程学生合同审核———————— #BooleanField布尔值类型#default=False默认(True)不允许出现空字符#verbose_name是Admin中显示的字段名称
contract_agreed = models.BooleanField(default=False,verbose_name="学员已经同意合同")#学员看合同
contract_approved = models.BooleanField(default=False,verbose_name="合同已经审核") #谁审核 # ————————53PerfectCRM实现CRM客户报名流程缴费————————
Pay_cost= models.BooleanField(default=False,verbose_name="缴费") #缴费状态#是不是交定金
# ————————53PerfectCRM实现CRM客户报名流程缴费———————— # DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
date = models.DateTimeField(auto_now_add=True)#创建时间(数据库自增) def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
return "%s %s" %(self.customer,self.enrolled_class)#返回#格式化字符串#学员名字#所报班级
class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
unique_together = ("customer","enrolled_class")#联合索引
verbose_name_plural = "06学员报名信息表"#verbose_name_plural给你的模型类起一个更可读的名字 """07缴费记录表"""
class Payment(models.Model):
#ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
customer = models.ForeignKey("Customer",on_delete=models.CASCADE)#学员名字 关联到 客户信息表
course = models.ForeignKey("Course",verbose_name="所报课程",on_delete=models.CASCADE)#关联到 课程表 #PositiveSmallIntegerField正小整数 0 ~ 32767 #verbose_name是Admin中显示的字段名称#默认值=500
amount = models.PositiveIntegerField(verbose_name="数额",default=500)#缴费数额 #ForeignKey就是表与表之间的某种约定的关系#CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
consultant = models.ForeignKey("UserProfile",on_delete=models.CASCADE)#缴费给谁 关联到 账号表 #财务人员 #DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
date=models.DateTimeField(auto_now_add=True)#创建时间(数据库自增) def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
return "%s %s" %(self.customer,self.amount)#返回#格式化字符串#学员名字#缴费数额
class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
verbose_name_plural = "07缴费记录表"#verbose_name_plural给你的模型类起一个更可读的名字 """08每节课上课纪录表"""
class CourseRecord(models.Model):
# ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
from_class = models.ForeignKey("ClassList",verbose_name="班级",on_delete=models.CASCADE) #那个班级 #PositiveSmallIntegerField正小整数 0 ~ 32767 #verbose_name是Admin中显示的字段名称
day_num = models.PositiveSmallIntegerField(verbose_name="第几节(天)") #第几节课 # ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
teacher = models.ForeignKey("UserProfile",on_delete=models.CASCADE)#老师是谁 关联到 账号表 #BooleanField布尔值类型#default=True默认(True)不允许出现空字符
has_homework = models.BooleanField(default=True) #有没有作业 # CharField定长文本#名字最长128#Django可空#数据库可以为空
homework_title = models.CharField(max_length=128,blank=True,null=True) #作业标题 #TextField无限制长度的文本#Django可空#数据库可以为空
homework_content = models.TextField(blank=True,null=True) #作业内容 #TextField无限制长度的文本#verbose_name是Admin中显示的字段名称
outline =models.TextField(verbose_name="本节课程大纲") #课程主要讲什么 # DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
date = models.DateField(auto_now_add=True)#创建时间(数据库自增) def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
return " %s:%s" %(self.from_class,self.day_num)#返回#格式化字符串#班级#第几节(天)
class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
unique_together = ("from_class","day_num") #联合索引
verbose_name_plural = "08每节课上课纪录表" #verbose_name_plural给你的模型类起一个更可读的名字 """09学习纪录"""
class StudyRecord(models.Model):
# ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
student = models.ForeignKey("Enrollment",on_delete=models.CASCADE)#学生名字 关联到 学员报名信息表
course_record = models.ForeignKey("CourseRecord",on_delete=models.CASCADE)#开课记录 # 关联到 每节课上课纪录表 attendance_choices = (# 本节课上课状态记录
(0,"已签到"),
(1,"迟到"),
(2,"缺勤"),
(3,"早退"),)
#PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
attendance = models.SmallIntegerField(choices=attendance_choices) # 本节课上课状态记录 score_choices = (#学习成绩
(100,"A+"),
(90,"A"),
(85,"B+"),
(80,"B"),
(75,"B-"),
(70,"C+"),
(65,"C"),
(40,"C-"),
(-20,"D"),
(-50,"COPY"),
(0,"N/A"),)
#PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
score = models.SmallIntegerField(choices=score_choices) #学习成绩 memo = models.TextField(blank=True,null=True)#TextField无限制长度的文本#Django可空#数据库可以为空 # DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
date = models.DateField(auto_now_add=True)#创建时间(数据库自增) def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
return "%s %s %s" % (self.student, self.course_record, self.score)#返回#格式化字符串#学生名字#开课记录#学习成绩
class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
unique_together = ('student','course_record')#联合索引#学生名字#开课记录
verbose_name_plural = "09学习纪录"#verbose_name_plural给你的模型类起一个更可读的名字 # ————————34PerfectCRM实现CRM自定义用户————————
# """10账号表"""
# class UserProfile(models.Model):
# from django.contrib.auth.models import User # 使用django内置的用户表
#
# #OneToOneField一对一 #User是django Admin里的账号表#CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
# user = models.OneToOneField(User,on_delete=models.CASCADE)# 用户名 #创建外键,关联django用户表
#
# name = models.CharField(max_length=32) #账号名(扩展用户字段)#CharField定长文本
#
# #ManyToManyField多对多和外键工作方式相同,只不过我们处理的是QuerySet而不是模型实例。#Django可空
# roles = models.ManyToManyField("Role",blank=True) #角色(权限) # 双向一对多==多对多
#
# def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
# return self.name #返回 #账号名
# class Meta: #通过一个内嵌类 "class Meta" 给你的 model 定义元数据
# verbose_name_plural = "10账号表"#verbose_name_plural给你的模型类起一个更可读的名字
# ————————34PerfectCRM实现CRM自定义用户———————— # ————————34PerfectCRM实现CRM自定义用户————————
#10账号表,创建用户和超级用户
from django.contrib.auth.models import BaseUserManager
class UserProfileManager(BaseUserManager):
def create_user(self, email, name, password=None):
"""
  创建并保存一个用户用给定的邮件,日期
  出生和密码。
"""
if not email:#没有email 报错
raise ValueError('用户必须有一个电子邮件地址') user = self.model(
email=self.normalize_email(email),#验证邮箱格式
name=name,
)
user.set_password(password)#加密
user.is_active = True
user.save(using=self._db)
return user
def create_superuser(self, email, name, password):
"""
  创建并保存一个超级用户具有给定邮件,日期
  出生和密码。
"""
user = self.create_user(email,
password=password,
name=name
)
user.is_active = True
user.is_superuser = True
user.save(using=self._db)
return user """10账号表"""
""" #删除数据库 #调用objects = UserProfileManager()#创建账号 #关联这个函数 #运行 Terminal
# 生成 数据表
# python manage.py makemigrations
# 数据表 迁移
# python manage.py migrate
Django Admin里账号密码重置方法
#运行 Terminal
python manage.py createsuperuser Email address: admin@qq.com
用户名 : admin
Password: admin123456
Password (again): admin123456
"""
from django.contrib.auth.models import AbstractBaseUser
# ————————35PerfectCRM实现CRM重写Admin密码修改————————
from django.utils.translation import ugettext_lazy as _ # 语言国际化
from django.utils.safestring import mark_safe
from django.contrib.auth.models import PermissionsMixin
# class UserProfile(AbstractBaseUser):
class UserProfile(AbstractBaseUser,PermissionsMixin):
# ————————35PerfectCRM实现CRM重写Admin密码修改————————
email=models.EmailField(
verbose_name='邮箱账号',
max_length=255,
unique=True#唯一 #登陆账号
)
name=models.CharField(max_length=32,verbose_name='用户名') # ————————35PerfectCRM实现CRM重写Admin密码修改————————
password = models.CharField(_('password'), max_length=128, help_text=mark_safe('''<a href=\"../password/\">修改密码</a>'''))
# ————————35PerfectCRM实现CRM重写Admin密码修改———————— is_active = models.BooleanField(default=True,verbose_name='合法账号')#权限#合法账号
is_superuser = models.BooleanField(default=False,verbose_name='超级账号') #超级账号
objects = UserProfileManager()#创建账号 #关联这个函数
USERNAME_FIELD ='email'#指定做为 #登陆账号
REQUIRED_FIELDS = ['name']#必填字段
def get_full_name(self):
return self.email
def get_short_name(self):
#用户确认的电子邮件地址
return self.email
def __str__(self):
return self.name
def has_perm(self,perm,obj=None):
#指明用户是否被认为活跃的。以反选代替删除帐号。
#最简单的可能的答案:是的,总是
return True #有效 账号
def has_module_perms(self, app_label):
#指明用户是否可以登录到这个管理站点。
# 最简单的可能的答案:是的,总是
return True #职员状态
@property
def is_staff(self):
'''“用户的员工吗?”'''
#最简单的可能的答案:所有管理员都是员工
return self.is_superuser#是不是超级用户状态
# AUTH_USER_MODEL = 'crm.UserProfile'#使用自定的admin 表单 #settings.py
# ————————34PerfectCRM实现CRM自定义用户———————— """11角色表"""
class Role(models.Model):
name = models.CharField(unique=True,max_length=32)#角色名#CharField定长文本#角色名不可以重复#最长度=32字节
def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
return self.name#返回 #角色名
class Meta: #通过一个内嵌类 "class Meta" 给你的 model 定义元数据
verbose_name_plural = "11角色表" #verbose_name_plural给你的模型类起一个更可读的名字 """12标签表"""
class Tag(models.Model):
name = models.CharField(max_length=64,unique=True) #标签名#CharField定长文本#最长度=64字节#不可以重复
def __str__(self): #__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
return self.name #返回 #标签名
class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
verbose_name_plural = "12标签表" #verbose_name_plural给你的模型类起一个更可读的名字 # ————————01PerfectCRM基本配置ADMIN————————

#models.py

 # forms.py
# ————————47PerfectCRM实现CRM客户报名流程————————
from crm import models #数据库
from django.forms import ModelForm #继承forms自定制
#报名 销售填写
class EnrollmentForm(ModelForm):
def __new__(cls, *args, **kwargs):
for field_name,field_obj in cls.base_fields.items():
field_obj.widget.attrs['class'] = 'form-control'## 前端的样式
return ModelForm.__new__(cls)
class Meta:
model= models.Enrollment
fields= ['enrolled_class']
# ————————47PerfectCRM实现CRM客户报名流程———————— # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
#报名学员填 写
class CustomerForm(ModelForm):
def __new__(cls, *args, **kwargs):
for field_name,field_obj in cls.base_fields.items():
field_obj.widget.attrs['class'] = 'form-control'## 前端的样式
if field_name in cls.Meta.readonly_fields:#如果不可修改
field_obj.widget.attrs['disabled'] = True## 前端的样式 灰色
return ModelForm.__new__(cls) # ————————49PerfectCRM实现CRM客户报名流程学生合同表单验证————————
def clean_qq(self):
#print(self.instance.qq,self.cleaned_data['qq'],'9696969696')
if self.instance.qq != self.cleaned_data['qq']: #输入的值和 cleaned_data的值
self.add_error('qq',"大神,请勿非法修改!")
return self.cleaned_data['qq'] def clean_consultant(self):
if self.instance.consultant != self.cleaned_data['consultant']:
self.add_error('consultant',"非法修改!不要尝试!")
return self.cleaned_data['consultant'] def clean_source(self):
if self.instance.source != self.cleaned_data['source']:
self.add_error('source',"非法修改!不能通过!")
return self.cleaned_data['source']
# ————————49PerfectCRM实现CRM客户报名流程学生合同表单验证———————— class Meta:
model=models.Customer#客户表
fields='__all__'
exclude=['tags','content','memo','status','referral_from','consult_courses']#排除,不显示
readonly_fields=['qq','consultant','source']#不可修改
# ————————48PerfectCRM实现CRM客户报名流程学生合同———————— # ————————53PerfectCRM实现CRM客户报名流程缴费————————
#缴费记录
class PaymentForm(ModelForm):
def __new__(cls, *args, **kwargs):
for field_name,field_obj in cls.base_fields.items():
field_obj.widget.attrs['class'] = 'form-control'## 前端的样式
return ModelForm.__new__(cls)
class Meta:
model=models.Payment
fields='__all__' # ————————53PerfectCRM实现CRM客户报名流程缴费————————

# forms.py

 {#not_audit.html#}
{## # ————————53PerfectCRM实现CRM客户报名流程缴费————————#}
{% extends 'bpm_master/bpm_sample.html' %}
{% block right-container-content %} {#自定义内容开始 右边页面内容#}
<div class="panel-default">
<div class="panel-body">
<h3>待缴费 | <a class="btn btn-info pull" href={% url 'already_payment' %}>已缴费</a></h3>
<table class="table table-striped table-responsive">
<thead>
<tr>
<th>客户名字</th>
<th>客户QQ</th>
<th>手机号码</th>
<th>咨询顾问</th> <th>所报班级</th>
<th>报名课程顾问</th>
<th>合同审核</th>
<th>合同状态</th>
<th>日期时间</th>
</tr>
</thead>
<tbody>
{% for foo in sign %}
{# {% if foo.contract_agreed and foo.contract_approved == false %}#}
{% if foo.contract_approved and not foo.Pay_cost %}
<tr>
<td><a href="{% url 'payment' foo.id %}">{{ foo.customer.name }}</a></td>
<td>{{ foo.customer }}</td>
<td>{{ foo.customer.phone }}</td>
<td>{{ foo.customer.consultant }}</td> <td>{{ foo.enrolled_class }}</td>
<td>{{ foo.consultant }}</td>
<td>{{ foo.contract_review }}</td>
<td>{{ foo.contract_approved }}</td>
<td>{{ foo.date }}</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock %} {## # ————————53PerfectCRM实现CRM客户报名流程缴费————————#}

{#not_audit.html#}

 {#already_payment.html#}
{## # ————————53PerfectCRM实现CRM客户报名流程缴费————————#}
{% extends 'bpm_master/bpm_sample.html' %}
{% block right-container-content %} {#自定义内容开始 右边页面内容#}
<div class="panel-default">
<div class="panel-body">
<h3>已缴费 | <a class="btn btn-success pull" href={% url 'not_payment' %}>待缴费</a></h3>
<table class="table table-striped table-responsive">
<thead>
<tr>
<th>客户名字</th>
<th>客户QQ</th>
<th>手机号码</th>
<th>咨询顾问</th> <th>所报班级</th>
<th>报名课程顾问</th>
<th>合同审核</th>
<th>合同状态</th>
<th>日期时间</th>
</tr>
</thead>
<tbody>
{% for foo in sign %}
{# {% if foo.contract_agreed and foo.contract_approved == false %}#}
{% if foo.contract_approved and foo.Pay_cost %}
<tr>
<td><a href="{% url 'payment' foo.id %}">{{ foo.customer.name }}</a></td>
<td>{{ foo.customer }}</td>
<td>{{ foo.customer.phone }}</td>
<td>{{ foo.customer.consultant }}</td> <td>{{ foo.enrolled_class }}</td>
<td>{{ foo.consultant }}</td>
<td>{{ foo.contract_review }}</td>
<td>{{ foo.contract_approved }}</td>
<td>{{ foo.date }}</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock %} {## # ————————53PerfectCRM实现CRM客户报名流程缴费————————#}

{#already_payment.html#}

 {#payment.html#}
{## # ————————53PerfectCRM实现CRM客户报名流程缴费————————#}
{% extends 'bpm_master/bpm_sample.html' %}
{% block right-container-content %} {#自定义内容开始 右边页面内容#}
<div class="panel panel-info">
<h4> 学员缴费:</h4>
</div>
<div id="content">
<form action="" class="form-horizontal col-lg-5" role="form" method="post">{% csrf_token %}
<table>
<div class="form-group">
<label for="inputeEmail4" class="col-sm-3"> 客户名字: </label>
<div class="col-sm-3"> {{ enroll_obj.customer.name }}</div>
</div>
<div class="form-group">
<label for="inputeEmail4" class="col-sm-3"> 客户QQ: </label>
<div class="col-sm-3"> {{ enroll_obj.customer }}</div>
</div>
<div class="form-group">
<label for="inputeEmail4" class="col-sm-3"> 手机号码: </label>
<div class="col-sm-3"> {{ enroll_obj.customer.phone }}</div>
</div>
<div class="form-group">
<label for="inputeEmail4" class="col-sm-3">咨询顾问 : </label>
<div class="col-sm-3"> {{ enroll_obj.customer.consultant }} </div>
</div>
<div class="form-group">
<label for="inputeEmail4" class="col-sm-3"> 所报课程 : </label>
<div class="col-sm-3"> {{ enroll_obj.enrolled_class }} </div>
</div>
<div class="form-group">
<label for="inputeEmail4" class="col-sm-3">报名课程顾问 : </label>
<div class="col-sm-3"> {{ enroll_obj.consultant }} </div>
</div>
<div class="form-group">
<label for="inputeEmail4" class="col-sm-3">合同审核 : </label>
<div class="col-sm-3"> {{ enroll_obj.contract_review }} </div>
</div>
<div class="form-group">
<label for="inputeEmail9" class="col-sm-3">缴费金额 :</label>
<div><input type="text" name="amount" placeholder="至少不低于500">
<span style="color: #c7254e">{{ errors.err }}</span>
</div>
</div>
<div class="form-group">
<label for="inputeEmail9" class="col-sm-3">财务人员 :</label>
<div class="col-sm-3"> {{ request.user.name }} </div>
</div>
</table>
<div class="form-group col-sm-6">
<a class="btn btn-danger pull " href={% url 'not_payment' %}>返回</a>
<input type="submit" class="btn btn-success pull-right " value="缴费">
</div>
</form> <hr>
<table class="table table-striped table-responsive">
<thead>
<tr>
<th>客户名字</th>
<th>客户QQ</th>
<th>手机号码</th>
<th>咨询顾问</th>
<th>所报课程</th> <th>报名课程顾问</th>
<th>合同审核</th> <th>缴费金额</th>
<th>财务人员</th>
<th>日期时间</th>
</tr>
</thead>
<tbody>
{% for foo in sign %}
{% if foo.customer == enroll_obj.customer %}
<tr>
<td>{{ foo.customer.name }}</td>
<td>{{ foo.customer }}</td>
<td>{{ foo.customer.phone }}</td>
<td>{{ foo.customer.consultant }}</td>
<td>{{ foo.course }}</td> <td>{{ enroll_obj.consultant }}</td>
<td>{{ enroll_obj.contract_review }}</td> <td>{{ foo.amount }}</td>
<td>{{ foo.consultant }}</td>
<td>{{ foo.date }}</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
{## # ————————53PerfectCRM实现CRM客户报名流程缴费————————#}

{#payment.html#}

Django项目:CRM(客户关系管理系统)--63--53PerfectCRM实现CRM客户报名流程缴费的更多相关文章

  1. 文献综述二十:基于UML技术的客户关系管理系统实现

    一.基本信息 标题:基于UML技术的客户关系管理系统实现 时间:2015 出版源:电子设计工程 文件分类:uml技术的研究 二.研究背景 设计出可应用与银行和储户之间沟通的客户关系管理系统,从而实现对 ...

  2. Django项目:CRM(客户关系管理系统)--84--74PerfectCRM实现CRM权限和权限组限制访问URL

    #models.py # ————————01PerfectCRM基本配置ADMIN———————— from django.db import models # Create your models ...

  3. Django项目:CRM(客户关系管理系统)--85--75PerfectCRM实现CRM扩展权限

    # sales_urls.py # ————————47PerfectCRM实现CRM客户报名流程———————— from django.conf.urls import url from bpm. ...

  4. Django项目:CRM(客户关系管理系统)--82--72PerfectCRM实现CRM动态菜单和角色

    #models.py # ————————01PerfectCRM基本配置ADMIN———————— from django.db import models # Create your models ...

  5. Django项目:CRM(客户关系管理系统)--70--60PerfectCRM实现CRM学生上课记录

    #urls.py """PerfectCRM URL Configuration The `urlpatterns` list routes URLs to views. ...

  6. Django项目:CRM(客户关系管理系统)--78--68PerfectCRM实现CRM业务流程(bpm)报名缴费分页

    # pagination.py # ————————68PerfectCRM实现CRM业务流程(bpm)报名缴费分页———————— from django.utils.safestring impo ...

  7. Django项目:CRM(客户关系管理系统)--73--63PerfectCRM实现CRM讲师下载作业

    # teacher_urls.py # ————————62PerfectCRM实现CRM讲师讲课记录———————— from django.conf.urls import url from bp ...

  8. Django项目:CRM(客户关系管理系统)--71--61PerfectCRM实现CRM学生上传作业

    # student_urls.py # ————————60PerfectCRM实现CRM学生上课记录———————— from django.conf.urls import url from bp ...

  9. Django项目:CRM(客户关系管理系统)--67--57PerfectCRM实现admin批量生成上课记录

    #admin.py # ————————01PerfectCRM基本配置ADMIN———————— from django.contrib import admin # Register your m ...

随机推荐

  1. 阿里云SaaS加速器“宜搭”发布宜搭Plus提升6倍研发效率

    9月26日,在杭州云栖大会上,阿里云SaaS加速器的“底座”——“宜搭”正式发布“宜搭Plus”低代码开发平台.开发复杂企业业务系统所需要的领域数据模型.逻辑&服务编排.专业UI页面设计等,都 ...

  2. (JS)应为","

    在写cshtml的时候,vs提示:(JS)应为"," 功能无法实现,一般是因为 标点切成全角了,但是我是应为把‘’打成了“” 以下错误示范: $("ol").a ...

  3. 搭建CA颁发证书做https加密网站

    92.168.10.187 CA服务器 192.168.10.190 web服务器 (1)搭建CA cd /etc/pki/CA 在这个目录下创建serial和index.txt两个文件 echo 0 ...

  4. ul列表元素在float:right后li元素倒转

    发现对li元素进行float:right后,虽然成功右浮动,但是的元素是倒转的 解决方案: 对ul进行右浮动,然后对li左浮动 结果

  5. Vue 中 computed ,watch,methods 的异同

    methods,watch和computed都是以函数为基础的. computed 和 watch 都可以观察页面的相应式数据的变化.当处理页面的数据变化时,我们有时候很容易滥用watch, 而通常更 ...

  6. 一次性安装python常用模块

    链接:https://pan.baidu.com/s/1fuIxRUnkJJfzgrbQ8kIgvw 提取码:d1r6 电脑必须是win64才可以安装 Anaconda3安装完成后,不需要自己添加环境 ...

  7. VMware Workstation 10 简体中文安装教程

    分享到 一键分享 QQ空间 新浪微博 百度云收藏 人人网 腾讯微博 百度相册 开心网 腾讯朋友 百度贴吧 豆瓣网 搜狐微博 百度新首页 QQ好友 和讯微博 更多... 百度分享 分享到 一键分享 QQ ...

  8. Amazon AWS

  9. js判断客服端

    ua: function () {                    return navigator.userAgent.toLowerCase()                },      ...

  10. laydate实现设置最小时间为当前时间

    当前时间之前的日期不能选择,添加个min,主要代码如下: var now = new Date(); startTime= laydate.render({ elem: '#test1', type: ...