@@ -238,6 +238,8 @@ urlpatterns += [ |
||
| 238 | 238 |
url(r'^tj/distributor$', tj_views.tj_distributor, name='tj_distributor'), # 统计数据(经销商维度) |
| 239 | 239 |
url(r'^tj/consumer$', tj_views.tj_consumer, name='tj_consumer'), # 统计数据(消费者维度) |
| 240 | 240 |
url(r'^tj/generate$', tj_views.tj_generate, name='tj_generate'), # 统计数据生成 |
| 241 |
+ |
|
| 242 |
+ url(r'^v2/tj$', tj_views.v2_tj_distributor, name='v2_tj_distributor'), # 统计数据 |
|
| 241 | 243 |
] |
| 242 | 244 |
|
| 243 | 245 |
urlpatterns += [ |
@@ -0,0 +1,35 @@ |
||
| 1 |
+# -*- coding: utf-8 -*- |
|
| 2 |
+# Generated by Django 1.11.15 on 2018-10-11 05:26 |
|
| 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 |
+ ('statistic', '0008_auto_20181007_0322'),
|
|
| 12 |
+ ] |
|
| 13 |
+ |
|
| 14 |
+ operations = [ |
|
| 15 |
+ migrations.CreateModel( |
|
| 16 |
+ name='SaleclerkSaleStatisticInfo', |
|
| 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 |
+ ('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')),
|
|
| 23 |
+ ('distributor_id', models.CharField(blank=True, db_index=True, help_text='\u7ecf\u9500\u5546\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='distributor_id')),
|
|
| 24 |
+ ('distributor_name', models.CharField(blank=True, help_text='\u7ecf\u9500\u5546\u540d\u79f0', max_length=32, null=True, verbose_name='distributor_name')),
|
|
| 25 |
+ ('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')),
|
|
| 26 |
+ ('clerk_name', models.CharField(blank=True, help_text='\u5e97\u5458\u540d\u79f0', max_length=32, null=True, verbose_name='clerk_name')),
|
|
| 27 |
+ ('ymd', models.IntegerField(db_index=True, default=0, help_text='\u5e74\u6708\u65e5', verbose_name='ymd')),
|
|
| 28 |
+ ('num', models.IntegerField(default=0, help_text='\u6570\u91cf', verbose_name='num')),
|
|
| 29 |
+ ], |
|
| 30 |
+ options={
|
|
| 31 |
+ 'verbose_name': '[\u7ecf\u9500\u5546\u7ef4\u5ea6]\u9500\u552e\u5458\u9500\u91cf\u7edf\u8ba1', |
|
| 32 |
+ 'verbose_name_plural': '[\u7ecf\u9500\u5546\u7ef4\u5ea6]\u9500\u552e\u5458\u9500\u91cf\u7edf\u8ba1', |
|
| 33 |
+ }, |
|
| 34 |
+ ), |
|
| 35 |
+ ] |
@@ -129,7 +129,34 @@ class ProvinceSaleStatisticInfo(BaseModelMixin): |
||
| 129 | 129 |
return {
|
| 130 | 130 |
'province_code': self.province_code, |
| 131 | 131 |
'province_name': self.province_name, |
| 132 |
- 'ymd': self.ymd, |
|
| 132 |
+ # 'ymd': self.ymd, |
|
| 133 |
+ 'num': randnum() if settings.DEBUG_STATISTIC_DATA_FLAG else self.num, |
|
| 134 |
+ } |
|
| 135 |
+ |
|
| 136 |
+ |
|
| 137 |
+class SaleclerkSaleStatisticInfo(BaseModelMixin): |
|
| 138 |
+ brand_id = models.CharField(_(u'brand_id'), max_length=32, blank=True, null=True, help_text=u'品牌唯一标识', db_index=True) |
|
| 139 |
+ distributor_id = models.CharField(_(u'distributor_id'), max_length=32, blank=True, null=True, help_text=u'经销商唯一标识', db_index=True) |
|
| 140 |
+ distributor_name = models.CharField(_(u'distributor_name'), max_length=32, blank=True, null=True, help_text=u'经销商名称') |
|
| 141 |
+ clerk_id = models.CharField(_(u'clerk_id'), max_length=32, blank=True, null=True, help_text=u'店员唯一标识', db_index=True) |
|
| 142 |
+ clerk_name = models.CharField(_(u'clerk_name'), max_length=32, blank=True, null=True, help_text=u'店员名称') |
|
| 143 |
+ ymd = models.IntegerField(_(u'ymd'), default=0, help_text=u'年月日', db_index=True) # 例:20171208, tc.local_string(format='%Y%m%d'), 0 为全部 |
|
| 144 |
+ num = models.IntegerField(_(u'num'), default=0, help_text=u'数量') |
|
| 145 |
+ |
|
| 146 |
+ class Meta: |
|
| 147 |
+ verbose_name = _(u'[经销商维度]销售员销量统计') |
|
| 148 |
+ verbose_name_plural = _(u'[经销商维度]销售员销量统计') |
|
| 149 |
+ |
|
| 150 |
+ def __unicode__(self): |
|
| 151 |
+ return unicode(self.pk) |
|
| 152 |
+ |
|
| 153 |
+ @property |
|
| 154 |
+ def data(self): |
|
| 155 |
+ return {
|
|
| 156 |
+ 'distributor_name': self.distributor_name, |
|
| 157 |
+ 'salesman_id': self.clerk_id, |
|
| 158 |
+ 'salesman_name': self.clerk_name, |
|
| 159 |
+ # 'ymd': self.ymd, |
|
| 133 | 160 |
'num': randnum() if settings.DEBUG_STATISTIC_DATA_FLAG else self.num, |
| 134 | 161 |
} |
| 135 | 162 |
|
@@ -176,7 +203,7 @@ class ConsumeModelSaleStatisticInfo(BaseModelMixin): |
||
| 176 | 203 |
return {
|
| 177 | 204 |
'model_id': self.model_id, |
| 178 | 205 |
'model_name': self.model_name, |
| 179 |
- 'ymd': self.ymd, |
|
| 206 |
+ # 'ymd': self.ymd, |
|
| 180 | 207 |
'num': randnum() if settings.DEBUG_STATISTIC_DATA_FLAG else self.num, |
| 181 | 208 |
} |
| 182 | 209 |
|
@@ -11,7 +11,7 @@ from mch.models import BrandInfo, DistributorInfo, ModelInfo |
||
| 11 | 11 |
from statistic.models import (ConsumeDistributorSaleStatisticInfo, ConsumeModelSaleStatisticInfo, |
| 12 | 12 |
ConsumeProvinceSaleStatisticInfo, ConsumeSaleStatisticInfo, DistributorSaleStatisticInfo, |
| 13 | 13 |
ModelSaleStatisticInfo, ProvinceSaleStatisticInfo, RegisterStatisticInfo, |
| 14 |
- SaleStatisticInfo) |
|
| 14 |
+ SaleclerkSaleStatisticInfo, SaleStatisticInfo) |
|
| 15 | 15 |
from utils.rdm_utils import randnum |
| 16 | 16 |
|
| 17 | 17 |
|
@@ -202,3 +202,78 @@ def __tj_generate(ymd=None): |
||
| 202 | 202 |
brand_id=brand.brand_id, |
| 203 | 203 |
ymd=ymd, |
| 204 | 204 |
) |
| 205 |
+ |
|
| 206 |
+ |
|
| 207 |
+def ymdtj(brand_id, ymd, lastymd): |
|
| 208 |
+ # 周期内扫描用户人数 |
|
| 209 |
+ try: |
|
| 210 |
+ scan_user_count = ConsumeSaleStatisticInfo.objects.get(brand_id=brand_id, ymd=ymd).num |
|
| 211 |
+ except ConsumeSaleStatisticInfo.DoesNotExist: |
|
| 212 |
+ scan_user_count = 0 |
|
| 213 |
+ |
|
| 214 |
+ try: |
|
| 215 |
+ last_scan_user_count = ConsumeSaleStatisticInfo.objects.get(brand_id=brand_id, ymd=lastymd).num |
|
| 216 |
+ except ConsumeSaleStatisticInfo.DoesNotExist: |
|
| 217 |
+ last_scan_user_count = 0 |
|
| 218 |
+ |
|
| 219 |
+ # 与上个统计周期数据的用户人数比例 |
|
| 220 |
+ user_count_increase_pct = '%.2f' % scan_user_count * 100.0 / last_scan_user_count if last_scan_user_count != 0 else 0 |
|
| 221 |
+ |
|
| 222 |
+ # 周期内镜头销售支数 |
|
| 223 |
+ try: |
|
| 224 |
+ sell_volume_count = SaleStatisticInfo.objects.get(brand_id=brand_id, ymd=ymd).num |
|
| 225 |
+ except SaleStatisticInfo.DoesNotExist: |
|
| 226 |
+ sell_volume_count = 0 |
|
| 227 |
+ |
|
| 228 |
+ try: |
|
| 229 |
+ last_sell_volume_count = SaleStatisticInfo.objects.get(brand_id=brand_id, ymd=lastymd).num |
|
| 230 |
+ except SaleStatisticInfo.DoesNotExist: |
|
| 231 |
+ last_sell_volume_count = 0 |
|
| 232 |
+ |
|
| 233 |
+ # 与上个统计周期数据的销售支数比例 |
|
| 234 |
+ volume_count_increase_pct = '%.2f' % sell_volume_count * 100.0 / last_sell_volume_count if last_sell_volume_count != 0 else 0 |
|
| 235 |
+ |
|
| 236 |
+ # 统计周期内型号扫描排行数据,请按顺序返回 |
|
| 237 |
+ models = ConsumeModelSaleStatisticInfo.objects.filter(brand_id=brand_id, ymd=ymd, status=True).order_by('-num')
|
|
| 238 |
+ models = [m.data for m in models] |
|
| 239 |
+ |
|
| 240 |
+ # 统计周期内销售员排行数据,请按顺序返回 |
|
| 241 |
+ salesmen = SaleclerkSaleStatisticInfo.objects.filter(brand_id=brand_id, ymd=ymd, status=True).order_by('-num')
|
|
| 242 |
+ salesmen = [s.data for s in salesmen] |
|
| 243 |
+ |
|
| 244 |
+ # 统计周期内省份销量排行数据,请按顺序返回 |
|
| 245 |
+ provinces = ProvinceSaleStatisticInfo.objects.filter(brand_id=brand_id, ymd=ymd, status=True).order_by('position')
|
|
| 246 |
+ provinces = [p.data for p in provinces] |
|
| 247 |
+ |
|
| 248 |
+ return {
|
|
| 249 |
+ 'scan_user_count': scan_user_count, |
|
| 250 |
+ 'sell_volume_count': sell_volume_count, |
|
| 251 |
+ 'user_count_increase_pct': user_count_increase_pct, |
|
| 252 |
+ 'volume_count_increase_pct': volume_count_increase_pct, |
|
| 253 |
+ 'models': models, |
|
| 254 |
+ 'salesmen': salesmen, |
|
| 255 |
+ 'provinces': provinces, |
|
| 256 |
+ } |
|
| 257 |
+ |
|
| 258 |
+ |
|
| 259 |
+@logit |
|
| 260 |
+def v2_tj_distributor(request): |
|
| 261 |
+ brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
|
|
| 262 |
+ |
|
| 263 |
+ year = tc.local_string(format='%Y') |
|
| 264 |
+ month = tc.local_string(format='%Y%m') |
|
| 265 |
+ day = tc.local_string(format='%Y%m%d') |
|
| 266 |
+ |
|
| 267 |
+ lastyear = tc.local_string(tc.several_time_ago(years=1), format='%Y') |
|
| 268 |
+ lastmonth = tc.local_string(tc.several_time_ago(months=1), format='%Y%m') |
|
| 269 |
+ lastday = tc.local_string(tc.several_time_ago(days=1), format='%Y%m%d') |
|
| 270 |
+ |
|
| 271 |
+ year_data = ymdtj(brand_id, year, lastyear) |
|
| 272 |
+ month_data = ymdtj(brand_id, month, lastmonth) |
|
| 273 |
+ day_data = ymdtj(brand_id, day, lastday) |
|
| 274 |
+ |
|
| 275 |
+ return response(200, 'Get TJ Data Success', u'获取统计数据成功', data={
|
|
| 276 |
+ 'year_data': year_data, |
|
| 277 |
+ 'month_data': month_data, |
|
| 278 |
+ 'day_data': day_data, |
|
| 279 |
+ }) |