@@ -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 | 
                + })  |