@@ -229,7 +229,8 @@ urlpatterns += [ |
||
229 | 229 |
url(r'^clerk/submit$', oauth_views.clerk_submit_api, name='clerk_submit_api'), # 店员信息提交 |
230 | 230 |
url(r'^clerk/sale/decrypt$', sale_views.clerk_sale_decrypt_api, name='clerk_sale_decrypt_api'), |
231 | 231 |
url(r'^clerk/sale/submit$', sale_views.clerk_sale_submit_api, name='clerk_sale_submit_api'), # 店员销售信息提交 |
232 |
- url(r'^clerk/integral/list$', sale_views.clerk_integral_list_api, name='clerk_integral_list_api'), # 店员销售积分列表 |
|
232 |
+ url(r'^clerk/integral/list$', sale_views.clerk_integral_list_api, name='clerk_integral_list_api'), # |
|
233 |
+ url(r'^clerk/consumer/impression$', sale_views.clerk_consumer_impression_api, name='clerk_consumer_impression_api'), |
|
233 | 234 |
] |
234 | 235 |
|
235 | 236 |
urlpatterns += [ |
@@ -4,7 +4,7 @@ from django.db import models |
||
4 | 4 |
from django.utils.translation import ugettext_lazy as _ |
5 | 5 |
from django_models_ext import BaseModelMixin, upload_path |
6 | 6 |
|
7 |
-from mch.models import ModelInfo |
|
7 |
+from mch.models import ConsumeImpressionInfo, ModelInfo |
|
8 | 8 |
|
9 | 9 |
|
10 | 10 |
class SaleclerkIntegralIncomeExpensesInfo(BaseModelMixin): |
@@ -64,12 +64,21 @@ class SaleclerkIntegralIncomeExpensesInfo(BaseModelMixin): |
||
64 | 64 |
return info |
65 | 65 |
|
66 | 66 |
@property |
67 |
+ def consumer_impression(self): |
|
68 |
+ try: |
|
69 |
+ impression = ConsumeImpressionInfo.objects.get(clerk_id=self.clerk_id, model_id=self.clerk_id, brand_id=self.brand_id, serialNo=self.code) |
|
70 |
+ except ConsumeImpressionInfo.DoesNotExist: |
|
71 |
+ impression = None |
|
72 |
+ return impression.data if impression else {} |
|
73 |
+ |
|
74 |
+ @property |
|
67 | 75 |
def data(self): |
68 | 76 |
return { |
69 | 77 |
'type': self.type, |
70 | 78 |
'integral': self.integral, |
71 | 79 |
'model_info': self.model_info, |
72 | 80 |
'modelName': self.model_name, |
81 |
+ 'consumer_impression': self.consumer_impression, |
|
73 | 82 |
'serialNo': self.code, |
74 | 83 |
'created_at': self.created_at, |
75 | 84 |
} |
@@ -8,7 +8,7 @@ from django_admin import AdvancedActionsModelAdmin, AdvancedExportExcelModelAdmi |
||
8 | 8 |
from django_models_ext import ProvinceShortModelMixin |
9 | 9 |
from pysnippets.strsnippets import strip |
10 | 10 |
|
11 |
-from mch.models import (ActivityInfo, AdministratorInfo, BrandInfo, ConsumeInfoSubmitLogInfo, DistributorInfo, |
|
11 |
+from mch.models import (ActivityInfo, AdministratorInfo, BrandInfo, ConsumeInfoSubmitLogInfo, ConsumeImpressionInfo, DistributorInfo, |
|
12 | 12 |
LatestAppInfo, LatestAppScreenInfo, ModelInfo, OperatorInfo, SaleclerkInfo) |
13 | 13 |
|
14 | 14 |
|
@@ -179,6 +179,11 @@ class LatestAppScreenInfoAdmin(admin.ModelAdmin): |
||
179 | 179 |
obj.save() |
180 | 180 |
|
181 | 181 |
|
182 |
+class ConsumeImpressionInfoAdmin(ReadOnlyModelAdmin, admin.ModelAdmin): |
|
183 |
+ list_display = ('clerk_id', 'brand_id', 'model_id', 'serialNo', 'sex', 'rage', 'identity', 'purpose', 'status', 'created_at', 'updated_at') |
|
184 |
+ list_filter = ('sex', 'rage', 'status') |
|
185 |
+ |
|
186 |
+ |
|
182 | 187 |
class ConsumeInfoSubmitLogInfoAdmin(ReadOnlyModelAdmin, admin.ModelAdmin): |
183 | 188 |
list_display = ('user_id', 'phone', 'lat', 'lon', 'serialNo', 'verifyResult', 'dupload', 'test_user', 'submit_during_activity', 'activity_id', 'coupon_expire_at', 'coupon_value', 'has_used', 'status', 'created_at', 'updated_at') |
184 | 189 |
list_filter = ('brand_id', 'submit_during_activity', 'activity_id', 'dupload', 'test_user', 'verifyResult', 'has_used', 'status') |
@@ -200,5 +205,6 @@ admin.site.register(SaleclerkInfo, SaleclerkInfoAdmin) |
||
200 | 205 |
# admin.site.register(BrandModelDistributorPriceInfo, BrandModelDistributorPriceInfoAdmin) |
201 | 206 |
admin.site.register(LatestAppInfo, LatestAppInfoAdmin) |
202 | 207 |
admin.site.register(LatestAppScreenInfo, LatestAppScreenInfoAdmin) |
208 |
+admin.site.register(ConsumeImpressionInfo, ConsumeImpressionInfoAdmin) |
|
203 | 209 |
admin.site.register(ConsumeInfoSubmitLogInfo, ConsumeInfoSubmitLogInfoAdmin) |
204 | 210 |
admin.site.register(ActivityInfo, ActivityInfoAdmin) |
@@ -0,0 +1,36 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+# Generated by Django 1.11.22 on 2019-07-21 15:19 |
|
3 |
+from __future__ import unicode_literals |
|
4 |
+ |
|
5 |
+from django.db import migrations, models |
|
6 |
+ |
|
7 |
+ |
|
8 |
+class Migration(migrations.Migration): |
|
9 |
+ |
|
10 |
+ dependencies = [ |
|
11 |
+ ('mch', '0038_modelinfo_image4'), |
|
12 |
+ ] |
|
13 |
+ |
|
14 |
+ operations = [ |
|
15 |
+ migrations.CreateModel( |
|
16 |
+ name='ConsumeImpressionInfo', |
|
17 |
+ fields=[ |
|
18 |
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|
19 |
+ ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')), |
|
20 |
+ ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')), |
|
21 |
+ ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')), |
|
22 |
+ ('clerk_id', models.CharField(blank=True, db_index=True, help_text='\u5e97\u5458\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='clerk_id')), |
|
23 |
+ ('brand_id', models.CharField(blank=True, db_index=True, help_text='\u54c1\u724c\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='brand_id')), |
|
24 |
+ ('model_id', models.CharField(blank=True, db_index=True, help_text='\u578b\u53f7\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='model_id')), |
|
25 |
+ ('serialNo', models.CharField(blank=True, db_index=True, help_text='\u5e8f\u5217\u53f7', max_length=16, null=True, verbose_name='serialNo')), |
|
26 |
+ ('sex', models.IntegerField(choices=[(0, '\u672a\u77e5'), (1, '\u7537'), (2, '\u5973')], default=0, help_text='\u6027\u522b', verbose_name='sex')), |
|
27 |
+ ('rage', models.IntegerField(choices=[(0, '\u672a\u77e5'), (1, '20\u5c81\u4ee5\u4e0b'), (2, '20-40\u5c81'), (2, '40-60\u5c81'), (2, '60\u5c81\u4ee5\u4e0a')], default=0, help_text='\u5e74\u9f84\u6bb5', verbose_name='rage')), |
|
28 |
+ ('identity', models.CharField(blank=True, help_text='\u8eab\u4efd', max_length=255, null=True, verbose_name='identity')), |
|
29 |
+ ('purpose', models.CharField(blank=True, help_text='\u7528\u9014', max_length=255, null=True, verbose_name='purpose')), |
|
30 |
+ ], |
|
31 |
+ options={ |
|
32 |
+ 'verbose_name': '\u5ba2\u6237\u5370\u8c61', |
|
33 |
+ 'verbose_name_plural': '\u5ba2\u6237\u5370\u8c61', |
|
34 |
+ }, |
|
35 |
+ ), |
|
36 |
+ ] |
@@ -410,6 +410,8 @@ class SaleclerkInfo(BaseModelMixin, SexModelMixin): |
||
410 | 410 |
'clerk_phone': self.clerk_phone, |
411 | 411 |
'num': self.num, |
412 | 412 |
'integral': self.integral, |
413 |
+ # TODO: |
|
414 |
+ 'month_integral': self.integral, |
|
413 | 415 |
'total_integral': self.total_integral, |
414 | 416 |
'status': self.user_status, |
415 | 417 |
'refused_reason': self.refused_reason, |
@@ -531,6 +533,58 @@ class LatestAppScreenInfo(BaseModelMixin): |
||
531 | 533 |
} |
532 | 534 |
|
533 | 535 |
|
536 |
+class ConsumeImpressionInfo(BaseModelMixin): |
|
537 |
+ UNKNOWN = 0 |
|
538 |
+ MALE = 1 |
|
539 |
+ FEMALE = 2 |
|
540 |
+ |
|
541 |
+ SEX_TUPLE = ( |
|
542 |
+ (UNKNOWN, u'未知'), |
|
543 |
+ (MALE, u'男'), |
|
544 |
+ (FEMALE, u'女'), |
|
545 |
+ ) |
|
546 |
+ |
|
547 |
+ LT20 = 1 |
|
548 |
+ GTE20LT40 = 2 |
|
549 |
+ GTE40LT60 = 2 |
|
550 |
+ GTE60 = 2 |
|
551 |
+ |
|
552 |
+ AGE_RANGE_TUPLE = ( |
|
553 |
+ (UNKNOWN, u'未知'), |
|
554 |
+ (LT20, u'20岁以下'), |
|
555 |
+ (GTE20LT40, u'20-40岁'), |
|
556 |
+ (GTE40LT60, u'40-60岁'), |
|
557 |
+ (GTE60, u'60岁以上'), |
|
558 |
+ ) |
|
559 |
+ |
|
560 |
+ clerk_id = models.CharField(_(u'clerk_id'), max_length=32, blank=True, null=True, help_text=u'店员唯一标识', db_index=True) |
|
561 |
+ |
|
562 |
+ brand_id = models.CharField(_(u'brand_id'), max_length=32, blank=True, null=True, help_text=u'品牌唯一标识', db_index=True) |
|
563 |
+ model_id = models.CharField(_(u'model_id'), max_length=32, blank=True, null=True, help_text=u'型号唯一标识', db_index=True) |
|
564 |
+ serialNo = models.CharField(_(u'serialNo'), max_length=16, blank=True, null=True, help_text=u'序列号', db_index=True) |
|
565 |
+ |
|
566 |
+ sex = models.IntegerField(_(u'sex'), choices=SEX_TUPLE, default=UNKNOWN, help_text=u'性别') |
|
567 |
+ rage = models.IntegerField(_(u'rage'), choices=AGE_RANGE_TUPLE, default=UNKNOWN, help_text=u'年龄段') |
|
568 |
+ identity = models.CharField(_(u'identity'), max_length=255, blank=True, null=True, help_text=u'身份') |
|
569 |
+ purpose = models.CharField(_(u'purpose'), max_length=255, blank=True, null=True, help_text=u'用途') |
|
570 |
+ |
|
571 |
+ class Meta: |
|
572 |
+ verbose_name = _(u'客户印象') |
|
573 |
+ verbose_name_plural = _(u'客户印象') |
|
574 |
+ |
|
575 |
+ def __unicode__(self): |
|
576 |
+ return unicode(self.pk) |
|
577 |
+ |
|
578 |
+ @property |
|
579 |
+ def data(self): |
|
580 |
+ return { |
|
581 |
+ 'sex': self.sex, |
|
582 |
+ 'rage': self.rage, |
|
583 |
+ 'identity': self.identity, |
|
584 |
+ 'purpose': self.purpose, |
|
585 |
+ } |
|
586 |
+ |
|
587 |
+ |
|
534 | 588 |
class ConsumeInfoSubmitLogInfo(BaseModelMixin): |
535 | 589 |
user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True) |
536 | 590 |
|
@@ -12,7 +12,7 @@ from TimeConvert import TimeConvert as tc |
||
12 | 12 |
from account.models import UserInfo |
13 | 13 |
from logs.models import MchInfoDecryptLogInfo, MchInfoEncryptLogInfo |
14 | 14 |
from integral.models import SaleclerkIntegralIncomeExpensesInfo, SaleclerkSubmitLogInfo |
15 |
-from mch.models import ActivityInfo, BrandInfo, DistributorInfo, ModelInfo, SaleclerkInfo |
|
15 |
+from mch.models import ActivityInfo, BrandInfo, ConsumeImpressionInfo, DistributorInfo, ModelInfo, SaleclerkInfo |
|
16 | 16 |
from statistic.models import (DistributorSaleStatisticInfo, ModelSaleStatisticInfo, ProvinceSaleStatisticInfo, |
17 | 17 |
SaleclerkSaleStatisticInfo, SaleStatisticInfo) |
18 | 18 |
from utils.algorithm.b64 import b64_decrypt |
@@ -721,3 +721,43 @@ def clerk_integral_list_api(request): |
||
721 | 721 |
'integrals': integrals, |
722 | 722 |
'total_integral': clerk.integral, |
723 | 723 |
}) |
724 |
+ |
|
725 |
+ |
|
726 |
+@logit |
|
727 |
+def clerk_consumer_impression_api(request): |
|
728 |
+ user_id = request.POST.get('user_id', '') |
|
729 |
+ brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID) |
|
730 |
+ model_id = request.POST.get('model_id', '') |
|
731 |
+ serialNo = request.POST.get('SerialNo', '') |
|
732 |
+ sex = request.POST.get('sex', 0) |
|
733 |
+ rage = request.POST.get('rage', 0) |
|
734 |
+ identity = request.POST.get('identity', '') |
|
735 |
+ purpose = request.POST.get('purpose', '') |
|
736 |
+ |
|
737 |
+ try: |
|
738 |
+ user = UserInfo.objects.get(user_id=user_id, status=True) |
|
739 |
+ except UserInfo.DoesNotExist: |
|
740 |
+ return response(SaleclerkStatusCode.CLERK_NOT_FOUND) |
|
741 |
+ |
|
742 |
+ try: |
|
743 |
+ brand = BrandInfo.objects.get(brand_id=brand_id) |
|
744 |
+ except BrandInfo.DoesNotExist: |
|
745 |
+ return response(ProductBrandStatusCode.BRAND_NOT_FOUND) |
|
746 |
+ |
|
747 |
+ try: |
|
748 |
+ clerk = SaleclerkInfo.objects.get(brand_id=brand.brand_id, unionid=user.unionid, status=True) |
|
749 |
+ except SaleclerkInfo.DoesNotExist: |
|
750 |
+ return response(SaleclerkStatusCode.CLERK_NOT_FOUND) |
|
751 |
+ |
|
752 |
+ ConsumeImpressionInfo.objects.create( |
|
753 |
+ clerk_id=clerk.clerk_id, |
|
754 |
+ brand_id=brand_id, |
|
755 |
+ model_id=model_id, |
|
756 |
+ serialNo=serialNo, |
|
757 |
+ sex=sex, |
|
758 |
+ rage=rage, |
|
759 |
+ identity=identity, |
|
760 |
+ purpose=purpose, |
|
761 |
+ ) |
|
762 |
+ |
|
763 |
+ return response() |