clerk_sale_decrypt_api

Kimi.Huang 5 年之前
父节点
当前提交
e654fbb36a
共有 2 个文件被更改,包括 375 次插入5 次删除
  1. 2 1
      api/urls.py
  2. 373 4
      page/sale_views.py

+ 2 - 1
api/urls.py

@@ -227,7 +227,8 @@ urlpatterns += [
227 227
 
228 228
 urlpatterns += [
229 229
     url(r'^clerk/submit$', oauth_views.clerk_submit_api, name='clerk_submit_api'),  # 店员信息提交
230
-    url(r'^clerk/sale/submit$', sale_views.clerk_sale_submit_api, name='clerk_sale_submit'),  # 店员销售信息提交
230
+    url(r'^clerk/sale/decrypt$', sale_views.clerk_sale_decrypt_api, name='clerk_sale_decrypt_api'),
231
+    url(r'^clerk/sale/submit$', sale_views.clerk_sale_submit_api, name='clerk_sale_submit_api'),  # 店员销售信息提交
231 232
     url(r'^clerk/integral/list$', sale_views.clerk_integral_list_api, name='clerk_integral_list_api'),  # 店员销售积分列表
232 233
 ]
233 234
 

+ 373 - 4
page/sale_views.py

@@ -10,27 +10,396 @@ from paginator import pagination
10 10
 from TimeConvert import TimeConvert as tc
11 11
 
12 12
 from account.models import UserInfo
13
+from logs.models import MchInfoDecryptLogInfo, MchInfoEncryptLogInfo
13 14
 from integral.models import SaleclerkIntegralIncomeExpensesInfo, SaleclerkSubmitLogInfo
14
-from mch.models import BrandInfo, DistributorInfo, ModelInfo, SaleclerkInfo
15
+from mch.models import ActivityInfo, BrandInfo, DistributorInfo, ModelInfo, SaleclerkInfo
15 16
 from statistic.models import (DistributorSaleStatisticInfo, ModelSaleStatisticInfo, ProvinceSaleStatisticInfo,
16 17
                               SaleclerkSaleStatisticInfo, SaleStatisticInfo)
18
+from utils.algorithm.b64 import b64_decrypt
19
+from utils.algorithm.caesar import caesar_decrypt
20
+from utils.algorithm.rsalg import rsa_decrypt
17 21
 from utils.error.errno_utils import (ProductBrandStatusCode, ProductDistributorStatusCode, ProductModelStatusCode,
18 22
                                      SaleclerkStatusCode)
19 23
 
20 24
 
25
+# CIPHER_ALGORITHM = ('CAESAR', 'B64', 'RSA')
26
+CIPHER_ALGORITHM = ('CAESAR', )
27
+
28
+CIPHER_PREFIX = {
29
+    'CAESAR': '0',
30
+    'B64': '1',
31
+    'RSA': '2',
32
+}
33
+
34
+
35
+@logit
36
+@transaction.atomic
37
+def clerk_sale_decrypt_api(request):
38
+    ciphertext = request.POST.get('ciphertext', '')
39
+
40
+    prefix, cipherlen, ciphertext = ciphertext.split('+', 2)
41
+
42
+    ciphertext = ciphertext[:int(cipherlen)]
43
+
44
+    if prefix == CIPHER_PREFIX['CAESAR']:
45
+        plaintext = caesar_decrypt(ciphertext)
46
+    elif prefix == CIPHER_PREFIX['B64']:
47
+        plaintext = b64_decrypt(ciphertext)
48
+    elif prefix == CIPHER_PREFIX['RSA']:
49
+        plaintext = rsa_decrypt(ciphertext)
50
+    else:
51
+        plaintext = ciphertext
52
+
53
+    # brand_id#model_id#distributor_id#sn#time
54
+    # AAAA#AAAAAA#AAAAA#AAAAAAAAAAAAAA#180224
55
+    brand_pk, model_pk, distributor_pk, sn, time = plaintext.split('#')
56
+
57
+    try:
58
+        brand = BrandInfo.objects.get(pk=brand_pk)
59
+    except BrandInfo.DoesNotExist:
60
+        brand = None
61
+
62
+    try:
63
+        model = ModelInfo.objects.get(pk=model_pk)
64
+    except ModelInfo.DoesNotExist:
65
+        model = None
66
+
67
+    mdli, created_at = MchInfoDecryptLogInfo.objects.get_or_create(ciphertext=ciphertext, defaults={
68
+        'brand_pk': brand_pk,
69
+        'model_pk': model_pk,
70
+        'distributor_pk': distributor_pk,
71
+        'sn': sn,
72
+        'decrypt_count': 1,
73
+    })
74
+
75
+    if not created_at:
76
+        mdli.decrypt_count += 1
77
+        mdli.save()
78
+
79
+    act = ActivityInfo.objects.filter(status=True).order_by('-pk').first()
80
+    has_unexpired_activity = True if act and act.has_unexpired_activity(model.model_uni_name) else False
81
+
82
+    coupon_info = {
83
+        'coupon_expire_at': act.final_coupon_expire_at(created_at=None),
84
+        'coupon_value': act.coupon_value,
85
+    } if has_unexpired_activity else {
86
+        'coupon_expire_at': '',
87
+        'coupon_value': 0,
88
+    }
89
+
90
+    # 红包
91
+    try:
92
+        elog = MchInfoEncryptLogInfo.objects.get(sn=sn)
93
+    except MchInfoEncryptLogInfo.DoesNotExist:
94
+        elog = None
95
+
96
+    user_id = request.POST.get('user_id', '')
97
+    lat = request.POST.get('lat', .0)
98
+    lon = request.POST.get('lon', .0)
99
+    brandID = brand_pk
100
+    modelID = model_pk
101
+    distributorID = distributor_pk
102
+    serialNo = sn
103
+
104
+    consumer_name = request.POST.get('consumer_name', '')
105
+    consumer_phone = request.POST.get('consumer_phone', '')
106
+
107
+    file_path = request.POST.get('file_path', '')
108
+
109
+    test_sn = serialNo in settings.TESTING_SNS
110
+
111
+    if lat == 'undefined':
112
+        lat = .0
113
+    if lon == 'undefined':
114
+        lon = .0
115
+
116
+    try:
117
+        user = UserInfo.objects.get(user_id=user_id, status=True)
118
+    except UserInfo.DoesNotExist:
119
+        return response(SaleclerkStatusCode.CLERK_NOT_FOUND)
120
+
121
+    try:
122
+        brand = BrandInfo.objects.get(pk=brandID)
123
+    except BrandInfo.DoesNotExist:
124
+        brand = None
125
+    except ValueError:
126
+        brand = None
127
+
128
+    if not brand:
129
+        try:
130
+            brand = BrandInfo.objects.get(brand_id=brandID)
131
+        except BrandInfo.DoesNotExist:
132
+            return response(ProductBrandStatusCode.BRAND_NOT_FOUND)
133
+
134
+    try:
135
+        model = ModelInfo.objects.get(pk=modelID)
136
+    except ModelInfo.DoesNotExist:
137
+        return response(ProductModelStatusCode.MODEL_NOT_FOUND)
138
+    except ValueError:
139
+        return response(ProductModelStatusCode.MODEL_NOT_FOUND)
140
+
141
+    try:
142
+        clerk = SaleclerkInfo.objects.select_for_update().get(brand_id=brand.brand_id, unionid=user.unionid, status=True)
143
+    except SaleclerkInfo.DoesNotExist:
144
+        return response(SaleclerkStatusCode.CLERK_NOT_FOUND)
145
+
146
+    if not clerk.is_auth:
147
+        return response(SaleclerkStatusCode.CLERK_NOT_AUTH)
148
+
149
+    try:
150
+        distributor = DistributorInfo.objects.get(distributor_id=clerk.distributor_id)
151
+    except DistributorInfo.DoesNotExist:
152
+        return response(ProductDistributorStatusCode.DISTRIBUTOR_NOT_FOUND)
153
+    except ValueError:
154
+        return response(ProductDistributorStatusCode.DISTRIBUTOR_NOT_FOUND)
155
+
156
+    # 店员提交记录
157
+    ssli = SaleclerkSubmitLogInfo.objects.create(
158
+        clerk_id=clerk.clerk_id,
159
+        brand_pk=brand.pk,
160
+        model_pk=modelID,
161
+        distributor_pk=distributorID,
162
+        code=serialNo,
163
+        consumer_name=consumer_name,
164
+        consumer_phone=consumer_phone,
165
+        lat=lat,
166
+        lon=lon,
167
+        image=file_path,
168
+        test_user=clerk.test_user,
169
+        test_sn=test_sn,
170
+    )
171
+
172
+    if settings.CHECK_TESTSN_ENABLED and test_sn:
173
+        return response(200, data={
174
+            'integral': 0,
175
+            'total_integral': clerk.integral,
176
+        })
177
+
178
+    if settings.CHECK_DUPLOAD_ENABLED:
179
+        try:
180
+            sci = SaleclerkIntegralIncomeExpensesInfo.objects.get(
181
+                brand_id=brand.brand_id,
182
+                model_id=model.model_id,
183
+                code=serialNo,
184
+                status=True
185
+            )
186
+        except SaleclerkIntegralIncomeExpensesInfo.DoesNotExist:
187
+            sci = None
188
+    else:
189
+        sci = None
190
+
191
+    if sci:
192
+        ssli.dupload = True
193
+        ssli.save()
194
+
195
+        try:
196
+            clerk = SaleclerkInfo.objects.get(clerk_id=sci.clerk_id, status=True)
197
+        except SaleclerkInfo.DoesNotExist:
198
+            clerk = None
199
+
200
+        return response(SaleclerkStatusCode.DUPLICATE_SUBMIT, data={
201
+            'franchiser_name': clerk.distributor_name,
202
+            'clerk_name': clerk.clerk_name,
203
+        } if clerk else {})
204
+
205
+    # 店员积分
206
+    integral = model.integral
207
+
208
+    clerk.num += 1
209
+    clerk.integral += integral
210
+    clerk.total_integral += integral
211
+    clerk.save()
212
+
213
+    # 店员积分记录
214
+    if integral > 0:
215
+        SaleclerkIntegralIncomeExpensesInfo.objects.create(
216
+            clerk_id=clerk.clerk_id,
217
+            type=SaleclerkIntegralIncomeExpensesInfo.INCOME,
218
+            brand_id=brand.brand_id,
219
+            brand_name=brand.brand_name,
220
+            model_id=model.model_id,
221
+            model_name=model.model_name,
222
+            distributor_id=distributor.distributor_id,
223
+            distributor_name=distributor.distributor_name,
224
+            code=serialNo,
225
+            consumer_name=consumer_name,
226
+            consumer_phone=consumer_phone,
227
+            lat=lat,
228
+            lon=lon,
229
+            image=file_path,
230
+            integral=integral,
231
+            left_integral=clerk.total_integral,
232
+            test_user=clerk.test_user,
233
+        )
234
+
235
+    # TODO: Make statistic async
236
+    if (not settings.CHECK_DUPLOAD_ENABLED) or (not clerk.test_user and not sci):
237
+        ymd = tc.local_string(format='%Y%m%d')
238
+
239
+        # 日销量统计
240
+        ssi, _ = SaleStatisticInfo.objects.select_for_update().get_or_create(
241
+            brand_id=brand.brand_id,
242
+            ymd=ymd,
243
+        )
244
+        ssi.num += 1
245
+        ssi.save()
246
+        # 月销量统计
247
+        ssi, _ = SaleStatisticInfo.objects.select_for_update().get_or_create(
248
+            brand_id=brand.brand_id,
249
+            ymd=ymd[:6],
250
+        )
251
+        ssi.num += 1
252
+        ssi.save()
253
+        # 年销量统计
254
+        ssi, _ = SaleStatisticInfo.objects.select_for_update().get_or_create(
255
+            brand_id=brand.brand_id,
256
+            ymd=ymd[:4],
257
+        )
258
+        ssi.num += 1
259
+        ssi.save()
260
+
261
+        # 型号销量统计
262
+        mssi, _ = ModelSaleStatisticInfo.objects.select_for_update().get_or_create(
263
+            brand_id=brand.brand_id,
264
+            model_id=model.model_id,
265
+            ymd=ymd,
266
+        )
267
+        mssi.model_name = model.model_name
268
+        mssi.num += 1
269
+        mssi.save()
270
+
271
+        mssi2, _ = ModelSaleStatisticInfo.objects.select_for_update().get_or_create(
272
+            brand_id=brand.brand_id,
273
+            model_id=model.model_id,
274
+            ymd=0,
275
+        )
276
+        mssi2.model_name = model.model_name
277
+        mssi2.num += 1
278
+        mssi2.save()
279
+
280
+        # 经销商销量统计
281
+        dssi, _ = DistributorSaleStatisticInfo.objects.select_for_update().get_or_create(
282
+            brand_id=brand.brand_id,
283
+            distributor_id=distributor.distributor_id,
284
+            ymd=ymd,
285
+        )
286
+        dssi.distributor_name = distributor.distributor_name
287
+        dssi.num += 1
288
+        dssi.save()
289
+
290
+        dssi2, _ = DistributorSaleStatisticInfo.objects.select_for_update().get_or_create(
291
+            brand_id=brand.brand_id,
292
+            distributor_id=distributor.distributor_id,
293
+            ymd=0,
294
+        )
295
+        dssi2.distributor_name = distributor.distributor_name
296
+        dssi2.num += 1
297
+        dssi2.save()
298
+
299
+        # 日省份销量统计
300
+        pssi, _ = ProvinceSaleStatisticInfo.objects.select_for_update().get_or_create(
301
+            brand_id=brand.brand_id,
302
+            province_code=distributor.distributor_province_code,
303
+            ymd=ymd,
304
+        )
305
+        pssi.province_name = distributor.distributor_province_name
306
+        pssi.num += 1
307
+        pssi.save()
308
+        # 月省份销量统计
309
+        pssi, _ = ProvinceSaleStatisticInfo.objects.select_for_update().get_or_create(
310
+            brand_id=brand.brand_id,
311
+            province_code=distributor.distributor_province_code,
312
+            ymd=ymd[:6],
313
+        )
314
+        pssi.province_name = distributor.distributor_province_name
315
+        pssi.num += 1
316
+        pssi.save()
317
+        # 年省份销量统计
318
+        pssi, _ = ProvinceSaleStatisticInfo.objects.select_for_update().get_or_create(
319
+            brand_id=brand.brand_id,
320
+            province_code=distributor.distributor_province_code,
321
+            ymd=ymd[:4],
322
+        )
323
+        pssi.province_name = distributor.distributor_province_name
324
+        pssi.num += 1
325
+        pssi.save()
326
+
327
+        # pssi2, _ = ProvinceSaleStatisticInfo.objects.select_for_update().get_or_create(
328
+        #     brand_id=brand.brand_id,
329
+        #     province_code=distributor.distributor_province_code,
330
+        #     ymd=0,
331
+        # )
332
+        # pssi2.province_name = distributor.distributor_province_name
333
+        # pssi2.num += 1
334
+        # pssi2.save()
335
+
336
+        # 日销售员销量统计
337
+        sssi, _ = SaleclerkSaleStatisticInfo.objects.select_for_update().get_or_create(
338
+            brand_id=brand.brand_id,
339
+            clerk_id=clerk.clerk_id,
340
+            ymd=ymd,
341
+        )
342
+        sssi.distributor_id = distributor.distributor_id
343
+        sssi.distributor_name = distributor.distributor_name
344
+        sssi.distributor_short_name = distributor.distributor_short_name
345
+        sssi.clerk_name = clerk.clerk_name
346
+        sssi.num += 1
347
+        sssi.save()
348
+        # 月销售员销量统计
349
+        sssi, _ = SaleclerkSaleStatisticInfo.objects.select_for_update().get_or_create(
350
+            brand_id=brand.brand_id,
351
+            clerk_id=clerk.clerk_id,
352
+            ymd=ymd[:6],
353
+        )
354
+        sssi.distributor_id = distributor.distributor_id
355
+        sssi.distributor_name = distributor.distributor_name
356
+        sssi.distributor_short_name = distributor.distributor_short_name
357
+        sssi.clerk_name = clerk.clerk_name
358
+        sssi.num += 1
359
+        sssi.save()
360
+        # 年销售员销量统计
361
+        sssi, _ = SaleclerkSaleStatisticInfo.objects.select_for_update().get_or_create(
362
+            brand_id=brand.brand_id,
363
+            clerk_id=clerk.clerk_id,
364
+            ymd=ymd[:4],
365
+        )
366
+        sssi.distributor_id = distributor.distributor_id
367
+        sssi.distributor_name = distributor.distributor_name
368
+        sssi.distributor_short_name = distributor.distributor_short_name
369
+        sssi.clerk_name = clerk.clerk_name
370
+        sssi.num += 1
371
+        sssi.save()
372
+
373
+    return response(200, data={
374
+        'plaintext': plaintext,
375
+        'logo_url': brand.brand_logo_url if brand else '',
376
+        'model_imgs': model.images if model else [],
377
+        'goodsInfo': {
378
+            'BrandID': brand_pk,
379
+            'Brand': brand.brand_name if brand else '',
380
+            'ModelID': model_pk,
381
+            'Model': (model.model_full_name or model.model_name) if model else '',
382
+            'DistributorID': distributor_pk,
383
+            'SerialNo': sn,
384
+        },
385
+        'has_unexpired_activity': has_unexpired_activity,
386
+        'coupon_info': coupon_info,
387
+        'redpack_info': elog.redpack_info if elog else {},
388
+        'integral': integral,
389
+        'total_integral': clerk.integral,
390
+    })
391
+
392
+
21 393
 @logit
22 394
 @transaction.atomic
23 395
 def clerk_sale_submit_api(request):
24 396
     user_id = request.POST.get('user_id', '')
25
-    iv = request.POST.get('iv', '')
26
-    encryptedData = request.POST.get('encryptedData', '')
27 397
     lat = request.POST.get('lat', .0)
28 398
     lon = request.POST.get('lon', .0)
29 399
     brandID = request.POST.get('BrandID', settings.KODO_DEFAULT_BRAND_PK)
30 400
     modelID = request.POST.get('ModelID', '')
31 401
     distributorID = request.POST.get('DistributorID', '')
32 402
     serialNo = request.POST.get('SerialNo', '')
33
-    verifyResult = request.POST.get('verifyResult', '')
34 403
 
35 404
     consumer_name = request.POST.get('consumer_name', '')
36 405
     consumer_phone = request.POST.get('consumer_phone', '')