123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489 |
- # coding=utf-8
- from rest_framework.views import APIView
- from django.db.models import Q
- import traceback
- import datetime
- from django.db import transaction
- from rest_framework.serializers import ValidationError
- from django.utils import timezone
- from rest_framework.decorators import action
- from utils.permission import isLogin, permission_required, check_permission
- from utils.custom_modelviewset import CustomModelViewSet
- from utils import response_ok, response_error
- from utils.exceptions import CustomError
- from apps.log.models import BizLog
- from apps.option.models import Option
- from apps.option.serializers import OptionComboboxSerializer
- from .models import ReportCustomer, NewCustomer, Review, NewCustomerRemind
- from .serializers import ReportCustomerSerializer, NewCustomerSerializer, ReviewSerializer
- from .filters import ReportCustomerFilter, NewCustomerFilter, ReviewFilter
- from django.contrib.auth import get_user_model
- from apps.order.models import ProgressDetails
- from apps.order.serializers import Order, OrderSerializer
- from apps.upload.models import Upload
- from apps.account.models import OfficeStoreUser
- User = get_user_model()
- class ReportCustomerViewSet(CustomModelViewSet):
- permission_classes = [isLogin]
- queryset = ReportCustomer.objects.filter()
- serializer_class = ReportCustomerSerializer
- @permission_required('customer.view_report_customer')
- def filter_queryset(self, queryset):
- queryset = queryset.filter(
- Q(store_id__in=self.request.user.get_manager_range()) |
- Q(create_user=self.request.user))
- f = ReportCustomerFilter(self.request.GET, queryset=queryset)
- return f.qs
- @permission_required('customer.add_report_customer')
- def perform_create(self, serializer):
- super(ReportCustomerViewSet, self).perform_create(serializer)
- instance = serializer.instance
- validated_data = serializer.validated_data
- BizLog.objects.addnew(self.request.user, BizLog.INSERT,
- u'添加客户报备[%s],id=%d' % (instance.name, instance.id), validated_data)
- @permission_required('customer.add_report_customer')
- def perform_update(self, serializer):
- super(ReportCustomerViewSet, self).perform_update(serializer)
- instance = serializer.instance
- validated_data = serializer.validated_data
- BizLog.objects.addnew(self.request.user, BizLog.UPDATE,
- u'修改客户报备[%s],id=%d' % (instance.name, instance.id), validated_data)
- @permission_required('customer.delete_report_customer')
- def perform_destroy(self, instance):
- BizLog.objects.addnew(self.request.user, BizLog.DELETE,
- u'删除客户报备[%s],id=%d' % (instance.name, instance.id))
- super(ReportCustomerViewSet, self).perform_destroy(instance)
- @action(methods=['post'], detail=True)
- def dispatch_customer(self, request, pk):
- check_permission(request, 'customer.check_report_customer')
- # 报备客户审核 分配
- user_id = request.POST.get('user')
- try:
- with transaction.atomic():
- instance = ReportCustomer.objects.filter(id=pk).first()
- if not instance:
- raise CustomError('当前客户报备信息有误,请刷新重试!')
- instance.check_user = self.request.user
- instance.report_status = ReportCustomer.CHECKED
- instance.check_time = timezone.now()
- instance.save()
- BizLog.objects.addnew(request.user, BizLog.INSERT,
- u'分配客户报备[%s],id=%d' % (instance.name, instance.id), user_id)
- # 创建潜客跟踪表
- stage_progress = Option.objects.filter(type=Option.STAGE_PROGRESS, enable=True).order_by('sort').first()
- if not stage_progress.track_day:
- raise CustomError('当前阶段,没有设置跟踪天数!')
- next_time = (timezone.now() + datetime.timedelta(days=stage_progress.track_day)).strftime('%Y-%m-%d')
- customer = NewCustomer.objects.create(report_customer=instance,
- track_user_id=user_id, stage_progress=stage_progress,
- create_user=instance.create_user, store=instance.store,
- name=instance.name, tel=instance.tel, village=instance.village,
- address=instance.address, source=instance.source,
- notes=instance.notes,next_time=next_time,
- )
- projects = instance.project.all()
- for project in projects:
- customer.project.add(project.id)
- NewCustomerRemind.objects.create(customer=customer,store=customer.store, next_time=next_time, remind_user_id=user_id,)
- # 根据分配人所在店面,创建内部跟踪提醒
- remind_users = request.user.get_remind_users()
- # 跟踪人和提醒人是同一个人的,不需要在加提醒
- remind_users.remove(int(user_id))
- # 把next_time用当前日期加上5天
- next_time = (timezone.now() + datetime.timedelta(days=5)).strftime('%Y-%m-%d')
- for remind_user in remind_users:
- NewCustomerRemind.objects.create(customer=customer, next_time=next_time, remind_user_id=remind_user,
- is_employee=False, store=instance.store)
- except CustomError as e:
- return response_error(e.get_error_msg())
- except Exception as e:
- return response_error(str(e))
- return response_ok()
- @action(methods=['post'], detail=True)
- def sign_hit(self, request, pk):
- check_permission(request, 'customer.check_report_customer')
- # 报备客户标记撞单
- try:
- with transaction.atomic():
- instance = ReportCustomer.objects.filter(id=pk).first()
- if not instance:
- raise CustomError('当前客户报备信息有误,请刷新重试!')
- instance.check_user = self.request.user
- instance.report_status = ReportCustomer.REPEAT_REPORT
- instance.check_time = timezone.now()
- instance.save()
- BizLog.objects.addnew(request.user, BizLog.INSERT,
- u'标记客户[%s]为撞单,id=%d' % (instance.name, instance.id))
- except CustomError as e:
- return response_error(e.get_error_msg())
- except Exception as e:
- return response_error(str(e))
- return response_ok()
- class ReportCustomerDictView(APIView):
- permission_classes = [isLogin]
- def get(self, request):
- source = Option.objects.filter(type=Option.CUSTOMER_SOURCE, enable=True)
- project = Option.objects.filter(type=Option.CATEGORY, enable=True)
- serializer_source = OptionComboboxSerializer(source, many=True)
- serializer_project = OptionComboboxSerializer(project, many=True)
- return response_ok({
- 'source': serializer_source.data,
- 'project': serializer_project.data,
- })
- class UserDictView(APIView):
- permission_classes = [isLogin]
- def get(self, request):
- store = request.user.store
- office_user_id = OfficeStoreUser.objects.filter(store=store).values('office_user_id')
- if not store:
- return response_error('当前账号未绑定门店,禁止分配客户!')
- users = User.objects.filter(Q(store=store) | Q(id__in=office_user_id)).values('id', 'name')
- users = [{'value': user['id'], 'lable': user['name']} for user in users]
- return response_ok(users)
- class NewCustomerViewSet(CustomModelViewSet):
- permission_classes = [isLogin, ]
- queryset = NewCustomer.objects.filter()
- serializer_class = NewCustomerSerializer
- @permission_required('customer.view_new_customer')
- def filter_queryset(self, queryset):
- queryset = queryset.filter(
- Q(store_id__in=self.request.user.get_manager_range()) |
- Q(create_user=self.request.user) |
- Q(track_user=self.request.user)
- )
- f = NewCustomerFilter(self.request.GET, queryset=queryset)
- return f.qs
- def paginate_queryset(self, queryset):
- if self.paginator is None or self.request.GET.get('export'):
- return None
- return self.paginator.paginate_queryset(queryset, self.request, view=self)
- @action(methods=['post'], detail=True)
- def add_review(self, request, pk):
- # 添加跟踪报告
- check_permission(request, 'customer.add_review')
- description = request.POST.get('description')
- instruction = request.POST.get('instruction')
- is_entry = request.POST.get('is_entry') == '1'
- is_giveup = request.POST.get('is_giveup') == '1'
- next_time = request.POST.get('next_time')
- try:
- with transaction.atomic():
- instance = NewCustomer.objects.filter(id=pk).first()
- if not instance:
- raise CustomError('当前客户信息有误,请刷新重试!')
- data = {
- 'customer': instance.id,
- 'store': instance.store.id,
- 'create_user': request.user.id,
- 'description': description,
- 'instruction': instruction or None,
- 'is_entry': is_entry,
- 'is_giveup': is_giveup,
- }
- serializer = ReviewSerializer(data=data)
- if serializer.is_valid(raise_exception=True):
- serializer.save()
- sort = 1
- track_day = 1
- try:
- sort = int(instance.stage_progress.sort)
- track_day = int(instance.stage_progress.track_day)
- except:
- pass
- # 预定客户,sort排序大于1,提交跟踪报告此字段为空
- if sort > 1 or not next_time:
- next_time = (timezone.now() + datetime.timedelta(days=track_day)).strftime('%Y-%m-%d')
- data = {
- 'next_time':next_time,
- 'end_time':timezone.now(),
- 'status':NewCustomer.NORMAL,
- }
- NewCustomerRemind.objects.filter(customer=instance,remind_user=request.user).update(next_time=next_time)
- # 如果客户已放弃,再次跟踪后自动改成正常客户,同时工单状态改成正常
- if instance.status == NewCustomer.ABANDONED:
- Order.objects.filter(customer=instance).update(status=Order.NORMAL)
- ser = self.serializer_class(instance, data=data, partial=True)
- if ser.is_valid(raise_exception=True):
- ser.save()
- except ValidationError as e:
- traceback.print_exc()
- return response_error('数据格式有误')
- except CustomError as e:
- return response_error(e.get_error_msg())
- except Exception as e:
- return response_error(str(e))
- return response_ok()
- @action(methods=['post'], detail=True)
- def add_order(self, request, pk):
- # 更新订单进度
- check_permission(request, 'order.update_order_process')
- stage_progress = request.POST.get('stage_progress')
- notes = request.POST.get('notes')
- try:
- with transaction.atomic():
- instance = NewCustomer.objects.filter(id=pk).first()
- if not instance:
- raise CustomError('当前客户信息有误,请刷新重试!')
- order = Order.objects.filter(customer=instance).first()
- if order:
- if order.stage_progress.end_stage:
- raise CustomError('当前客户订单进度已到最后阶段,请勿重复更新!')
- if order.status == Order.WAIT_DISPATCH:
- raise CustomError('当前客户订单等待分配中,请勿重复更新!')
- data = {
- 'status': Order.WAIT_DISPATCH,
- 'stage_progress': stage_progress,
- }
- ser = OrderSerializer(order, data=data, partial=True)
- if ser.is_valid(raise_exception=True):
- ser.save()
- else:
- data = {
- 'status': Order.WAIT_DISPATCH,
- 'stage_progress_id': stage_progress,
- 'customer': instance,
- 'service_user': instance.track_user,
- 'store': instance.store,
- 'notes': instance.notes,
- }
- order = Order.objects.create(**data)
- order.no = order.get_no()
- order.save()
- projects = instance.project.all()
- for project in projects:
- order.project.add(project.id)
- # 创建订单流程,保存图片
- user = request.user
- operation = u'更新进度为:{}'.format(order.stage_progress.name)
- progress_details = ProgressDetails.objects.create(order=order, user=user, operation=operation,
- notes=notes)
- for i in range(6):
- file = request.data.get('file{}'.format(i))
- if file:
- upload = Upload.objects._addnew(instance.store, progress_details, user, file)
- if not upload:
- return response_error('上传失败,请重新上传!')
- except ValidationError as e:
- traceback.print_exc()
- return response_error('数据格式有误')
- except CustomError as e:
- return response_error(e.get_error_msg())
- except Exception as e:
- return response_error(str(e))
- return response_ok()
- @action(methods=['post'], detail=True)
- def inner_review(self, request , pk):
- #内部跟踪
- description = request.POST.get('description')
- next_time = request.POST.get('next_time')
- is_copy = request.POST.get('is_copy') == '1'
- try:
- with transaction.atomic():
- instance = NewCustomer.objects.filter(id=pk).first()
- if not instance:
- raise CustomError('客户信息有误,请刷新重试!')
- data = {
- 'customer': instance.id,
- 'store': instance.store.id,
- 'create_user': request.user.id,
- 'description': description,
- 'is_copy': is_copy,
- }
- serializer = ReviewSerializer(data=data)
- if serializer.is_valid(raise_exception=True):
- serializer.save()
- NewCustomerRemind.objects.filter(customer=instance, remind_user=request.user).update(next_time=next_time)
- except ValidationError as e:
- traceback.print_exc()
- return response_error('数据格式有误')
- except CustomError as e:
- return response_error(e.get_error_msg())
- except Exception as e:
- return response_error(str(e))
- return response_ok()
- @action(methods=['post'], detail=True)
- def again_dispatch(self, request, pk):
- #重新分配
- check_permission(request, 'customer.again_dispatch')
- track_user_id = request.POST.get('track_user')
- try:
- with transaction.atomic():
- instance = NewCustomer.objects.filter(id=pk).first()
- if not instance:
- raise CustomError('客户信息有误,请刷新重试!')
- old_track_user = instance.track_user
- if not instance.stage_progress.track_day:
- raise CustomError('当前阶段,没有设置跟踪天数!')
- next_time = (timezone.now() + datetime.timedelta(days=instance.stage_progress.track_day)).strftime('%Y-%m-%d')
- instance.track_user_id = track_user_id
- instance.next_time = next_time
- instance.save()
- # 把原跟踪人提醒更新为新的跟踪人
- NewCustomerRemind.objects.filter(customer=instance, remind_user=old_track_user).update(
- next_time=next_time,track_user_id=track_user_id)
- BizLog.objects.addnew(request.user, BizLog.INSERT,
- u'重新分配客户经理[%s]为%s,id=%d' % (instance.name,track_user_id, instance.id), track_user_id)
- except CustomError as e:
- return response_error(e.get_error_msg())
- except Exception as e:
- return response_error(str(e))
- return response_ok()
- class StageCountView(APIView):
- permission_classes = [isLogin]
- @permission_required('customer.view_new_customer')
- def get(self, request):
- type = request.query_params.get('type') or 'user'
- id = request.query_params.get('id') or request.user.id
- data = []
- stage_progress = Option.objects.filter(type=Option.STAGE_PROGRESS, enable=True).order_by('sort').values('id','name')
- time_now = timezone.now().strftime('%Y-%m-%d')
- for stage in stage_progress:
- # 查询正常状态客户
- reminds = NewCustomerRemind.objects.filter(customer__stage_progress=stage['id'], customer__status=NewCustomer.NORMAL)
- if type == 'store':
- reminds = reminds.filter(store_id=id, is_employee=True)
- elif type == 'user':
- try:
- # 默认登录人没有门店,
- user_id = id.split('_')[1]
- store_id = id.split('_')[0]
- reminds = reminds.filter(remind_user_id=user_id, store_id=store_id)
- except:
- reminds = reminds.filter(remind_user_id=id)
- elif type == 'agent':
- reminds = reminds.filter(store__agent_id=id, store_id__in=request.user.get_manager_range(), is_employee=True)
- elif type == 'general_agent':
- reminds = reminds.filter(store__agent__general_agent_id=id, store_id__in=request.user.get_manager_range(), is_employee=True)
- stage_count = {
- 'stage_id': stage['id'], # 阶段id
- 'stage': stage['name'], # 阶段名称
- 'total_count': reminds.count(), # 总人数
- 'today_count': reminds.filter(next_time=time_now).count(), # 今日人数
- 'overdue_count': reminds.filter(next_time__lt=time_now).count() # 逾期人数
- }
- data.append(stage_count)
- return response_ok(data)
- class GetReviewViewSet(CustomModelViewSet):
- permission_classes = [isLogin]
- queryset = Review.objects.filter()
- serializer_class = ReviewSerializer
- @permission_required('customer.view_new_customer')
- def filter_queryset(self, queryset):
- # 过滤记录中是否抄送业务员
- if len(self.request.user.get_manager_range()) == 0:
- queryset = queryset.filter(is_copy=True)
- f = ReviewFilter(self.request.GET, queryset=queryset)
- return f.qs
- class ReviewViewSet(CustomModelViewSet):
- permission_classes = [isLogin]
- queryset = Review.objects.filter()
- serializer_class = ReviewSerializer
- @permission_required('customer.check_review')
- def filter_queryset(self, queryset):
- queryset = queryset.filter(store_id__in=self.request.user.get_manager_range())
- f = ReviewFilter(self.request.GET, queryset=queryset)
- return f.qs
- @action(methods=['post'], detail=True)
- def track_review(self, request, pk):
- check_permission(request, 'customer.check_review')
- # 跟踪审核
- check_status = request.POST.get('check_status')
- check_comment = request.POST.get('check_comment')
- next_time = request.POST.get('next_time')
- try:
- with transaction.atomic():
- instance = Review.objects.filter(id=pk).first()
- if int(check_status) == Review.KEEPUP:
- instance.check_user = request.user
- instance.check_status = check_status
- instance.check_comment = check_comment
- instance.check_time = timezone.now()
- instance.save()
- if int(check_status) == Review.ABANDON:
- instance.check_user = request.user
- instance.check_status = check_status
- instance.check_comment = check_comment
- instance.check_time = timezone.now()
- instance.save()
- instance.customer.status = NewCustomer.ABANDONED
- # 如果客户已下单,把工单状态改成放弃
- Order.objects.filter(customer=instance.customer).update(status=Order.ABANDONED)
- instance.customer.next_time = next_time
- instance.customer.save()
- NewCustomerRemind.objects.filter(customer=instance.customer, remind_user=instance.customer.track_user).update(next_time=next_time)
- except CustomError as e:
- return response_error(e.get_error_msg())
- except Exception as e:
- return response_error(str(e))
- return response_ok()
- class ListCountView(APIView):
- permission_classes = [isLogin]
- def get(self, request):
- report_customer_count = ReportCustomer.objects.filter(Q(store_id__in=request.user.get_manager_range()) |
- Q(create_user=request.user),
- report_status=ReportCustomer.NOT_CHECKED).count()
- review_count = Review.objects.filter(store_id__in=request.user.get_manager_range(),
- check_status=Review.DEFAULT).count()
- order_count = Order.objects.filter(Q(store_id__in=request.user.get_manager_range()) |
- Q(service_user=request.user) |
- Q(customer__create_user=request.user), status=Order.WAIT_DISPATCH).count()
- data ={
- 'report_customer_count': report_customer_count, # 报备审核数量
- 'review_count': review_count, # 跟踪审核数量
- 'order_count': order_count, # 进度审核数量
- }
- return response_ok(data)
|