@@ -2,6 +2,7 @@  | 
            ||
| 2 | 2 | 
                 | 
            
| 3 | 3 | 
                from __future__ import division  | 
            
| 4 | 4 | 
                 | 
            
| 5 | 
                +from django.db import transaction  | 
            |
| 5 | 6 | 
                from django_logit import logit  | 
            
| 6 | 7 | 
                from django_response import response  | 
            
| 7 | 8 | 
                from paginator import pagination  | 
            
                @@ -40,6 +41,7 @@ def clerk_add(request):  | 
            ||
| 40 | 41 | 
                 | 
            
| 41 | 42 | 
                 | 
            
| 42 | 43 | 
                @logit  | 
            
| 44 | 
                +@transaction.atomic  | 
            |
| 43 | 45 | 
                def clerk_delete(request):  | 
            
| 44 | 46 | 
                     distributor_id = request.POST.get('distributor_id', '')
               | 
            
| 45 | 47 | 
                     clerk_id = request.POST.get('clerk_id', '')
               | 
            
                @@ -52,7 +54,7 @@ def clerk_delete(request):  | 
            ||
| 52 | 54 | 
                return response(AdministratorStatusCode.ADMINISTRATOR_NOT_FOUND)  | 
            
| 53 | 55 | 
                 | 
            
| 54 | 56 | 
                try:  | 
            
| 55 | 
                - clerk = SaleclerkInfo.objects.get(brand_id=administrator.brand_id, clerk_id=clerk_id, status=True)  | 
            |
| 57 | 
                + clerk = SaleclerkInfo.objects.select_for_update().get(brand_id=administrator.brand_id, clerk_id=clerk_id, status=True)  | 
            |
| 56 | 58 | 
                except SaleclerkInfo.DoesNotExist:  | 
            
| 57 | 59 | 
                return response(SaleclerkStatusCode.CLERK_NOT_FOUND)  | 
            
| 58 | 60 | 
                 | 
            
                @@ -64,6 +66,7 @@ def clerk_delete(request):  | 
            ||
| 64 | 66 | 
                 | 
            
| 65 | 67 | 
                 | 
            
| 66 | 68 | 
                @logit  | 
            
| 69 | 
                +@transaction.atomic  | 
            |
| 67 | 70 | 
                def clerk_update(request):  | 
            
| 68 | 71 | 
                     distributor_id = request.POST.get('distributor_id', '')
               | 
            
| 69 | 72 | 
                     clerk_id = request.POST.get('clerk_id', '')
               | 
            
                @@ -79,7 +82,7 @@ def clerk_update(request):  | 
            ||
| 79 | 82 | 
                return response(AdministratorStatusCode.ADMINISTRATOR_NOT_FOUND)  | 
            
| 80 | 83 | 
                 | 
            
| 81 | 84 | 
                try:  | 
            
| 82 | 
                - clerk = SaleclerkInfo.objects.get(brand_id=administrator.brand_id, clerk_id=clerk_id, status=True)  | 
            |
| 85 | 
                + clerk = SaleclerkInfo.objects.select_for_update().get(brand_id=administrator.brand_id, clerk_id=clerk_id, status=True)  | 
            |
| 83 | 86 | 
                except SaleclerkInfo.DoesNotExist:  | 
            
| 84 | 87 | 
                return response(SaleclerkStatusCode.CLERK_NOT_FOUND)  | 
            
| 85 | 88 | 
                 | 
            
                @@ -14,8 +14,8 @@ class SaleclerkIntegralIncomeExpensesInfoAdmin(ReadOnlyModelAdmin, admin.ModelAd  | 
            ||
| 14 | 14 | 
                 | 
            
| 15 | 15 | 
                 | 
            
| 16 | 16 | 
                class SaleclerkSubmitLogInfoAdmin(ReadOnlyModelAdmin, admin.ModelAdmin):  | 
            
| 17 | 
                -    list_display = ('clerk_id', 'code', 'remark', 'dupload', 'test_user', 'status', 'created_at', 'updated_at')
               | 
            |
| 18 | 
                -    list_filter = ('dupload', 'test_user', 'status')
               | 
            |
| 17 | 
                +    list_display = ('clerk_id', 'code', 'remark', 'dupload', 'test_user', 'test_sn', 'status', 'created_at', 'updated_at')
               | 
            |
| 18 | 
                +    list_filter = ('dupload', 'test_user', 'test_sn', 'status')
               | 
            |
| 19 | 19 | 
                     search_fields = ('code', 'remark')
               | 
            
| 20 | 20 | 
                 | 
            
| 21 | 21 | 
                 | 
            
                @@ -97,6 +97,7 @@ class SaleclerkSubmitLogInfo(BaseModelMixin):  | 
            ||
| 97 | 97 | 
                dupload = models.BooleanField(_(u'dupload'), default=False, help_text=_(u'是否为重复提交'), db_index=True)  | 
            
| 98 | 98 | 
                 | 
            
| 99 | 99 | 
                test_user = models.BooleanField(_(u'test_user'), default=False, help_text=_(u'是否为测试用户'), db_index=True)  | 
            
| 100 | 
                + test_sn = models.BooleanField(_(u'test_sn'), default=False, help_text=_(u'是否为测试序列号'), db_index=True)  | 
            |
| 100 | 101 | 
                 | 
            
| 101 | 102 | 
                class Meta:  | 
            
| 102 | 103 | 
                verbose_name = _(u'saleclerksubmitloginfo')  | 
            
                @@ -398,6 +398,8 @@ KODO_SCREEN_LOGIN_URL = 'http://pai.ai/w/o?s=snsapi_base&r=http%3A%2F%2Fkodo.xfo  | 
            ||
| 398 | 398 | 
                 GIS_2_ADMINISTRATIVE_DIVISION = 'http://116.196.105.215:1234/gis?auth_user=freevip&latitude={0}&longitude={1}'
               | 
            
| 399 | 399 | 
                 PHONE_2_ADMINISTRATIVE_DIVISION = 'https://www.baifubao.com/callback?cmd=1059&callback=phone&phone={0}'
               | 
            
| 400 | 400 | 
                 | 
            
| 401 | 
                +TESTING_SNS = ['000000']  | 
            |
| 402 | 
                +  | 
            |
| 401 | 403 | 
                # 开发调试相关配置  | 
            
| 402 | 404 | 
                if DEBUG:  | 
            
| 403 | 405 | 
                try:  | 
            
                @@ -37,6 +37,8 @@ def clerk_sale_submit_api(request):  | 
            ||
| 37 | 37 | 
                 | 
            
| 38 | 38 | 
                     file_path = request.POST.get('file_path', '')
               | 
            
| 39 | 39 | 
                 | 
            
| 40 | 
                + test_sn = serialNo in settings.TESTING_SNS  | 
            |
| 41 | 
                +  | 
            |
| 40 | 42 | 
                try:  | 
            
| 41 | 43 | 
                user = UserInfo.objects.get(user_id=user_id, status=True)  | 
            
| 42 | 44 | 
                except UserInfo.DoesNotExist:  | 
            
                @@ -63,7 +65,7 @@ def clerk_sale_submit_api(request):  | 
            ||
| 63 | 65 | 
                return response(ProductModelStatusCode.MODEL_NOT_FOUND)  | 
            
| 64 | 66 | 
                 | 
            
| 65 | 67 | 
                try:  | 
            
| 66 | 
                - clerk = SaleclerkInfo.objects.get(brand_id=brand.brand_id, unionid=user.unionid, status=True)  | 
            |
| 68 | 
                + clerk = SaleclerkInfo.objects.select_for_update().get(brand_id=brand.brand_id, unionid=user.unionid, status=True)  | 
            |
| 67 | 69 | 
                except SaleclerkInfo.DoesNotExist:  | 
            
| 68 | 70 | 
                return response(SaleclerkStatusCode.CLERK_NOT_FOUND)  | 
            
| 69 | 71 | 
                 | 
            
                @@ -87,8 +89,15 @@ def clerk_sale_submit_api(request):  | 
            ||
| 87 | 89 | 
                lon=lon,  | 
            
| 88 | 90 | 
                image=file_path,  | 
            
| 89 | 91 | 
                test_user=clerk.test_user,  | 
            
| 92 | 
                + test_sn=test_sn,  | 
            |
| 90 | 93 | 
                )  | 
            
| 91 | 94 | 
                 | 
            
| 95 | 
                + if test_sn:  | 
            |
| 96 | 
                +        return response(200, data={
               | 
            |
| 97 | 
                + 'integral': 0,  | 
            |
| 98 | 
                + 'total_integral': clerk.integral,  | 
            |
| 99 | 
                + })  | 
            |
| 100 | 
                +  | 
            |
| 92 | 101 | 
                try:  | 
            
| 93 | 102 | 
                sci = SaleclerkIntegralIncomeExpensesInfo.objects.get(code=serialNo, status=True)  | 
            
| 94 | 103 | 
                except SaleclerkIntegralIncomeExpensesInfo.DoesNotExist:  | 
            
                @@ -117,25 +126,26 @@ def clerk_sale_submit_api(request):  | 
            ||
| 117 | 126 | 
                clerk.save()  | 
            
| 118 | 127 | 
                 | 
            
| 119 | 128 | 
                # 店员积分记录  | 
            
| 120 | 
                - SaleclerkIntegralIncomeExpensesInfo.objects.create(  | 
            |
| 121 | 
                - clerk_id=clerk.clerk_id,  | 
            |
| 122 | 
                - type=SaleclerkIntegralIncomeExpensesInfo.INCOME,  | 
            |
| 123 | 
                - brand_id=brand.brand_id,  | 
            |
| 124 | 
                - brand_name=brand.brand_name,  | 
            |
| 125 | 
                - model_id=model.model_id,  | 
            |
| 126 | 
                - model_name=model.model_name,  | 
            |
| 127 | 
                - distributor_id=distributor.distributor_id,  | 
            |
| 128 | 
                - distributor_name=distributor.distributor_name,  | 
            |
| 129 | 
                - code=serialNo,  | 
            |
| 130 | 
                - consumer_name=consumer_name,  | 
            |
| 131 | 
                - consumer_phone=consumer_phone,  | 
            |
| 132 | 
                - lat=lat,  | 
            |
| 133 | 
                - lon=lon,  | 
            |
| 134 | 
                - image=file_path,  | 
            |
| 135 | 
                - integral=integral,  | 
            |
| 136 | 
                - left_integral=clerk.total_integral,  | 
            |
| 137 | 
                - test_user=clerk.test_user,  | 
            |
| 138 | 
                - )  | 
            |
| 129 | 
                + if integral > 0:  | 
            |
| 130 | 
                + SaleclerkIntegralIncomeExpensesInfo.objects.create(  | 
            |
| 131 | 
                + clerk_id=clerk.clerk_id,  | 
            |
| 132 | 
                + type=SaleclerkIntegralIncomeExpensesInfo.INCOME,  | 
            |
| 133 | 
                + brand_id=brand.brand_id,  | 
            |
| 134 | 
                + brand_name=brand.brand_name,  | 
            |
| 135 | 
                + model_id=model.model_id,  | 
            |
| 136 | 
                + model_name=model.model_name,  | 
            |
| 137 | 
                + distributor_id=distributor.distributor_id,  | 
            |
| 138 | 
                + distributor_name=distributor.distributor_name,  | 
            |
| 139 | 
                + code=serialNo,  | 
            |
| 140 | 
                + consumer_name=consumer_name,  | 
            |
| 141 | 
                + consumer_phone=consumer_phone,  | 
            |
| 142 | 
                + lat=lat,  | 
            |
| 143 | 
                + lon=lon,  | 
            |
| 144 | 
                + image=file_path,  | 
            |
| 145 | 
                + integral=integral,  | 
            |
| 146 | 
                + left_integral=clerk.total_integral,  | 
            |
| 147 | 
                + test_user=clerk.test_user,  | 
            |
| 148 | 
                + )  | 
            |
| 139 | 149 | 
                 | 
            
| 140 | 150 | 
                # TODO: Make statistic async  | 
            
| 141 | 151 | 
                if not sci:  |