wushaodong пре 4 година
родитељ
комит
7673f07bf6
3 измењених фајлова са 159 додато и 107 уклоњено
  1. 13 2
      apps/account/models.py
  2. 15 0
      apps/customer/models.py
  3. 131 105
      apps/customer/views.py

+ 13 - 2
apps/account/models.py

@@ -104,11 +104,22 @@ class User(AbstractBaseUser, PermissionsMixin):
 
         return list(set(stores))
 
+    def get_remind_users(self):
+        # 报备客户转潜客,查询有“内部跟踪”权限且有管理网点的人
+        if not self.store:
+            return []
+        users = []
+        stores = ManageStoreUser.objects.filter(store=self.store)
+        for store in stores:
+            if store.manage_user.has_perm('customer.inner_review'):
+                users.append(store.manage_user.id)
+        return list(set(users))
+
     def change_password(self, new_password, confirm_password, old_password):
         if new_password != confirm_password:
-            raise CustomError(u'两次输入的密码不一致, 请检查')
+            raise CustomError(u'两次输入的密码不一致,请检查')
         if not self.check_password(old_password):
-            raise CustomError(u'原密码输入错误, 请检查')
+            raise CustomError(u'原密码输入错误,请检查')
         self.set_password(new_password)
 
     def update_item(self, validated_data):

+ 15 - 0
apps/customer/models.py

@@ -90,8 +90,23 @@ class NewCustomer(models.Model):
             ('view_new_customer', u'查看'),
             ('add_review', u'跟踪报告'),
             ('check_review', u'跟踪审核'),
+            ('inner_review', u'内部跟踪'),
         ]
 
+class NewCustomerRemind(models.Model):
+    customer = models.ForeignKey(NewCustomer, related_name='remind_customer', verbose_name=u"客户",
+                                 on_delete=models.PROTECT)
+    next_time = models.DateField(verbose_name=u'下次跟踪时间', null=True)
+    remind_user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u'提醒人', related_name='remind_user',
+                                   editable=False, on_delete=models.PROTECT)
+    is_employee = models.BooleanField(verbose_name=u'是否业务员', default=True)
+
+    class Meta:
+        db_table = 'new_customer_remind'
+        verbose_name = u'潜客跟踪提醒'
+        ordering = ['-id']
+        default_permissions = ()
+
 class Review(models.Model):
     DEFAULT = 0
     KEEPUP = 1

+ 131 - 105
apps/customer/views.py

@@ -14,9 +14,9 @@ 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
-from .serializers import ReportCustomerSerializer,NewCustomerSerializer, ReviewSerializer
-from .filters import ReportCustomerFilter,NewCustomerFilter,ReviewFilter
+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
@@ -24,6 +24,7 @@ from apps.upload.models import Upload
 
 User = get_user_model()
 
+
 class ReportCustomerViewSet(CustomModelViewSet):
     permission_classes = [isLogin]
     queryset = ReportCustomer.objects.filter()
@@ -65,32 +66,41 @@ class ReportCustomerViewSet(CustomModelViewSet):
         # 报备客户审核 分配
         user_id = request.POST.get('user')
         try:
-            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))
-            # 创建潜客跟踪表
-            potential_level = Option.objects.filter(type=Option.POTENTIAL_LEVEL, enable=True).order_by('sort').first()
-            stage_progress = Option.objects.filter(type=Option.STAGE_PROGRESS, enable=True).order_by('sort').first()
-            if not potential_level.track_day:
-                raise CustomError('当前潜客级别,没有可用跟踪天数!')
-            next_time = (timezone.now() + datetime.timedelta(days=potential_level.track_day)).strftime('%Y-%m-%d')
-
-            customer = NewCustomer.objects.create(report_customer=instance, potential_level=potential_level,
-                                       track_user_id=user_id, next_time=next_time, 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,
-                                       )
-            projects = instance.project.all()
-            for project in projects:
-                customer.project.add(project.id)
+            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))
+                # 创建潜客跟踪表
+                potential_level = Option.objects.filter(type=Option.POTENTIAL_LEVEL, enable=True).order_by(
+                    'sort').first()
+                stage_progress = Option.objects.filter(type=Option.STAGE_PROGRESS, enable=True).order_by('sort').first()
+                if not potential_level.track_day:
+                    raise CustomError('当前潜客级别,没有可用跟踪天数!')
+                next_time = (timezone.now() + datetime.timedelta(days=potential_level.track_day)).strftime('%Y-%m-%d')
+
+                customer = NewCustomer.objects.create(report_customer=instance, potential_level=potential_level,
+                                                      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,
+                                                      )
+                projects = instance.project.all()
+                for project in projects:
+                    customer.project.add(project.id)
+                NewCustomerRemind.objects.create(customer=customer, next_time=next_time, remind_user_id=user_id,)
+                # 根据分配人所在店面,创建内部跟踪提醒
+                remind_users = request.user.get_remind_users()
+                for remind_user in remind_users:
+                    NewCustomerRemind.objects.create(customer=customer, next_time=next_time, remind_user_id=remind_user,
+                                                     is_employee=False)
         except CustomError as e:
             return response_error(e.get_error_msg())
         except Exception as e:
@@ -102,16 +112,17 @@ class ReportCustomerViewSet(CustomModelViewSet):
         check_permission(request, 'customer.check_report_customer')
         # 报备客户标记撞单
         try:
-            instance = ReportCustomer.objects.filter(id=pk).first()
-            if not instance:
-                raise CustomError('当前客户报备信息有误,请刷新重试!')
-            instance.check_user = self.request.user
+            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))
+                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())
@@ -182,45 +193,46 @@ class NewCustomerViewSet(CustomModelViewSet):
         next_time = request.POST.get('next_time')
 
         try:
-            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 = {
-                'potential_level':potential_level or None, #预定客户,sort排序大于1,,无客户等级
-                'next_time':next_time,
-                'end_time':timezone.now(),
-                'stage_progress':instance.stage_progress.id,
-                'status':NewCustomer.NORMAL,
-            }
-            # TODO 如果客户已放弃,再次跟踪后自动改成正常客户,同时工单状态改成正常
-            if instance.status == NewCustomer.ABANDONED:
-                data['status'] = NewCustomer.NORMAL
-            ser = self.serializer_class(instance, data=data, partial=True)
-            if ser.is_valid(raise_exception=True):
-                ser.save()
+            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 = {
+                    'potential_level': potential_level or None,  # 预定客户,sort排序大于1,,无客户等级
+                    'next_time': next_time,
+                    'end_time': timezone.now(),
+                    'stage_progress': instance.stage_progress.id,
+                    'status': NewCustomer.NORMAL,
+                }
+                # TODO 如果客户已放弃,再次跟踪后自动改成正常客户,同时工单状态改成正常
+                if instance.status == NewCustomer.ABANDONED:
+                    data['status'] = NewCustomer.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()
@@ -274,7 +286,8 @@ class NewCustomerViewSet(CustomModelViewSet):
                 # 创建订单流程,保存图片
                 user = self.request.user
                 operation = u'更新进度为:{}'.format(order.stage_progress.name)
-                progress_details = ProgressDetails.objects.create(order=order, user=user, operation=operation, notes=notes)
+                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:
@@ -291,25 +304,36 @@ class NewCustomerViewSet(CustomModelViewSet):
             return response_error(str(e))
         return response_ok()
 
+
 class StageCountView(APIView):
     permission_classes = [isLogin]
 
     @permission_required('customer.view_new_customer')
-    def get(self,request):
+    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')
+        stage_progress = Option.objects.filter(type=Option.STAGE_PROGRESS, enable=True).order_by('sort').values('id','name')
         user = request.user
         time_now = timezone.now().strftime('%Y-%m-%d')
         for stage in stage_progress:
-            new_customers = NewCustomer.objects.filter(Q(track_user=user) |
-                                                       Q(track_user__store_id__in=request.user.get_manager_range()),
-                                                       stage_progress=stage)
+            reminds = NewCustomerRemind.objects.filter(customer__stage_progress=stage['id'])
+            if type == 'store':
+                reminds = reminds.filter(customer__store_id=id, is_employee=True)
+            elif type == 'user':
+                reminds = reminds.filter(remind_user_id=id)
+
+            # new_customers = NewCustomer.objects.filter(
+            #     Q(track_user=user) |
+            #     Q(track_user__store_id__in=request.user.get_manager_range()),
+            #     stage_progress=stage['id'])
+
             stage_count = {
-                'stage_id': stage.id,    # 阶段名称
-                'stage': stage.name,    # 阶段名称
-                'total_count': new_customers.count(),   # 总人数
-                'today_count': new_customers.filter(next_time=time_now).count(),  # 今日人数
-                'overdue_count': new_customers.filter(next_time__lt=time_now).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)
@@ -326,6 +350,7 @@ class GetReviewViewSet(CustomModelViewSet):
         f = ReviewFilter(self.request.GET, queryset=queryset)
         return f.qs
 
+
 class ReviewViewSet(CustomModelViewSet):
     permission_classes = [isLogin]
     queryset = Review.objects.filter()
@@ -345,23 +370,24 @@ class ReviewViewSet(CustomModelViewSet):
         check_comment = request.POST.get('check_comment')
         next_time = request.POST.get('next_time')
         try:
-            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
-                # TODO 如果客户已下单,把工单状态改成放弃
-            instance.customer.next_time = next_time
-            instance.customer.save()
+            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
+                    # TODO 如果客户已下单,把工单状态改成放弃
+                instance.customer.next_time = next_time
+                instance.customer.save()
         except CustomError as e:
             return response_error(e.get_error_msg())
         except Exception as e: