lang 3 жил өмнө
parent
commit
bebce45885

+ 45 - 8
Controller/CloudStorage.py

@@ -41,7 +41,7 @@ from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, OSS_ROLE_AR
 from Controller.CheckUserData import DataValid
 from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket, StsCrdModel, \
     ExperienceContextModel, Pay_Type, CDKcontextModel, Device_User, SysMassModel, SysMsgModel, UidPushModel, \
-    Unused_Uid_Meal, UIDMainUser, UserModel, PromotionRuleModel, VideoPlaybackTimeModel, CloudLogModel
+    Unused_Uid_Meal, UIDMainUser, UserModel, PromotionRuleModel, VideoPlaybackTimeModel, CloudLogModel, CouponModel
 from Object.AWS.S3Email import S3Email
 from Object.AliPayObject import AliPayObject
 from Object.AliSmsObject import AliSmsObject
@@ -54,6 +54,7 @@ from Object.m3u8generate import PlaylistGenerator
 from Object.WechatPayObject import WechatPayObject
 from django.db.models import Q, F, Count
 from Controller.PaymentCycle import Paypal
+from decimal import Decimal
 from Ansjer.config import SERVER_TYPE
 from Service.ModelService import ModelService
 
@@ -193,7 +194,7 @@ class CloudStorageView(View):
         mold = request_dict.get('mold', None)
         uid = request_dict.get('uid', None)
         lang = request_dict.get('lang', 'en')
-
+        nowTime = int(time.time())
         # DVR/NVR设备暂不返回云存套餐列表
         device_info_qs = Device_Info.objects.filter(Q(UID=uid), Q(Type__lte=4) | Q(Type=10001))
         if device_info_qs.exists():
@@ -238,7 +239,6 @@ class CloudStorageView(View):
                 res_c = {'area': area, 'items': items_list}
                 res.append(res_c)
             #是否促销
-            nowTime = int(time.time())
             promotion = PromotionRuleModel.objects.filter(status=1, startTime__lte=nowTime,
                                                           endTime__gte=nowTime).values('id','ruleConfig','ruleName',
                                                                                        'startTime','endTime','ruleDesc')
@@ -255,6 +255,11 @@ class CloudStorageView(View):
                 promotion = {
                     'is_promotion': 0
                 }
+
+            #优惠券
+            couponObj = CouponModel.objects.filter(userID_id=userID,use_status=0,distributeTime__lte=nowTime,
+                                                   valid_time__gt=nowTime).annotate(coupon_id=F('id')).values(
+                                                   "coupon_id","type","coupon_discount")
             result = {
                 'meals': res,
                 'extra':
@@ -262,7 +267,8 @@ class CloudStorageView(View):
                         'cloud_banner': SERVER_DOMAIN+'web/images/cloud_cn_banner.png',
                         'cloud_en_baner': SERVER_DOMAIN_SSL+'web/images/cloud_en_banner.png'
                     },
-                'promotion':promotion
+                'promotion':promotion,
+                'couponList':list(couponObj),
             }
             return response.json(0, result)
         else:
@@ -835,6 +841,10 @@ class CloudStorageView(View):
                     #     }
                     #     UIDMainUser.objects.create(**uid_main_dict)
 
+                    # 核销coupon
+                    if order_list[0]['coupon_id']:
+                        CouponModel.objects.filter(id=order_list[0]['coupon_id']).update(use_status=1)
+
                     order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id, promotion_rule_id=promotion_rule_id)
                     datetime = time.strftime("%Y-%m-%d", time.localtime())
                     sys_msg_text_list = ['温馨提示:尊敬的客户,您的'+UID+'设备在'+datetime+'已成功购买云存套餐', 'Dear customer,you already subscribed the cloud storage package successfully for device ' + UID + ' on '+ time.strftime("%b %dth,%Y", time.localtime())]
@@ -892,7 +902,7 @@ class CloudStorageView(View):
             nowTime = int(time.time())
             order_list = order_qs.values("UID", "channel", "commodity_code", "rank", "isSelectDiscounts",
                                          "userID__userID",
-                                         "userID__username")
+                                         "userID__username","coupon_id")
             userid = order_list[0]['userID__userID']
             username = order_list[0]['userID__username']
             UID = order_list[0]['UID']
@@ -961,6 +971,10 @@ class CloudStorageView(View):
                 #     }
                 #     UIDMainUser.objects.create(**uid_main_dict)
 
+                # 核销coupon
+                if order_list[0]['coupon_id']:
+                    CouponModel.objects.filter(id=order_list[0]['coupon_id']).update(use_status=1)
+
                 order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id, promotion_rule_id=promotion_rule_id)
                 datetime = time.strftime("%Y-%m-%d", time.localtime())
                 sys_msg_text_list = ['温馨提示:尊敬的客户,您的' + UID + '设备在' + datetime + '已成功购买云存套餐',
@@ -1083,6 +1097,10 @@ class CloudStorageView(View):
                     #     }
                     #     UIDMainUser.objects.create(**uid_main_dict)
 
+                    # 核销coupon
+                    if order_list[0]['coupon_id']:
+                        CouponModel.objects.filter(id=order_list[0]['coupon_id']).update(use_status=1)
+
                     order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id, promotion_rule_id=promotion_rule_id)
                     datetime = time.strftime("%Y-%m-%d", time.localtime())
                     sys_msg_text_list = ['温馨提示:尊敬的客户,您的' + UID + '设备在' + datetime + '已成功购买云存套餐',
@@ -1109,6 +1127,7 @@ class CloudStorageView(View):
         pay_type = int(request_dict.get('pay_type', None))
         rank = request_dict.get('rank', None)
         is_select_discount = request_dict.get('is_select_discount', 0)
+        coupon_id = request_dict.get('coupon_id', 0)
         lang = request_dict.get('lang', 'en')
         if not uid or not channel or not pay_type or not rank:
             return response.json(444)
@@ -1161,6 +1180,24 @@ class CloudStorageView(View):
             return response.json(10041)
 
         orderID = CommonService.createOrderID()
+
+        #优惠券
+        if coupon_id:
+            couponObj = CouponModel.objects.filter(id=coupon_id, use_status=0, distributeTime__lte=nowTime,
+                                                   valid_time__gt=nowTime)
+            couponQuery = couponObj.values("id", "type", "coupon_discount")
+            if not couponQuery.exists():
+                return response.json(10049)
+            price = Decimal(price)
+            coupon_discount = Decimal(couponQuery[0]['coupon_discount'])
+            if couponQuery[0]['type'] == 1:  #折扣
+                price = coupon_discount/10 * price
+            elif couponQuery[0]['type'] == 2:  #抵扣
+                price = price - couponQuery[0]['coupon_discount']
+            if price < 0:
+                return response.json(10049)
+            couponObj.update(use_status=1)
+
         if pay_type == 1:
             # 订阅周期扣款
             if(smqs[0]['cycle_config_id']):
@@ -1172,7 +1209,7 @@ class CloudStorageView(View):
                                            price=price, currency=currency, addTime=nowTime, updTime=nowTime,
                                            pay_url=subInfo['url'], isSelectDiscounts=is_select_discount,
                                            commodity_code=commodity_code, commodity_type=commodity_type,
-                                           rank_id=rank, plan_id=subInfo['plan_id'])
+                                           rank_id=rank, plan_id=subInfo['plan_id'],coupon_id=coupon_id)
                 return response.json(0, {"redirectUrl": subInfo['url'], "orderID": orderID})
 
             #正常扣款
@@ -1210,7 +1247,7 @@ class CloudStorageView(View):
                                                price=price, currency=currency, addTime=nowTime, updTime=nowTime,
                                                pay_url=approval_url, isSelectDiscounts=is_select_discount,
                                                commodity_code=commodity_code, commodity_type=commodity_type,
-                                               rank_id=rank, paymentID=paymentID)
+                                               rank_id=rank, paymentID=paymentID,coupon_id=coupon_id)
                     return response.json(0, {"redirectUrl": approval_url, "orderID": orderID})
             return response.json(10, 'generate_order_false')
         elif pay_type == 2:
@@ -1253,7 +1290,7 @@ class CloudStorageView(View):
                                                price=price, currency=currency, addTime=nowTime, updTime=nowTime,
                                                pay_url=redirectUrl, isSelectDiscounts=is_select_discount,
                                                commodity_code=commodity_code, commodity_type=commodity_type,
-                                               rank_id=rank)
+                                               rank_id=rank,coupon_id=coupon_id)
 
                     return JsonResponse(status=200, data={'result_code': 0, 'reason': 'success',
                                                           'result': {"redirectUrl": redirectUrl, "orderID": orderID},

+ 146 - 5
Controller/PaymentCycle.py

@@ -1,5 +1,5 @@
 from Ansjer.config import PAYPAL_CRD,SERVER_DOMAIN,SERVER_DOMAIN_SSL
-from Model.models import PayCycleConfigModel,Order_Model, Store_Meal, UID_Bucket, PromotionRuleModel, Unused_Uid_Meal,Device_Info
+from Model.models import PayCycleConfigModel,Order_Model, Store_Meal, UID_Bucket, PromotionRuleModel, Unused_Uid_Meal,Device_Info, CouponModel
 from Service.CommonService import CommonService
 from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
 import requests
@@ -125,6 +125,8 @@ class PaypalCycleNotify(View):
             return self.do_paypal_cycle_return(request_dict, response)
         elif operation == 'paypalCycleNotify':  # paypal 周期付款回调
             return self.do_paypal_webhook_notify(request_dict,request, response)
+        elif operation == 'test':  # paypal 周期付款回调
+            return self.do_test(request_dict,request, response)
     def do_paypal_cycle_return(self, request_dict, response):
         lang = request_dict.get('lang', 'en')
         token = request_dict.get('token',None)
@@ -153,7 +155,7 @@ class PaypalCycleNotify(View):
 
             order_list = order_qs.values("UID", "channel", "commodity_code", "rank", "isSelectDiscounts",
                                          "userID__userID",
-                                         "userID__username")
+                                         "userID__username",'coupon_id')
             userid = order_list[0]['userID__userID']
             username = order_list[0]['userID__username']
             UID = order_list[0]['UID']
@@ -225,6 +227,10 @@ class PaypalCycleNotify(View):
                 #     }
                 #     UIDMainUser.objects.create(**uid_main_dict)
 
+                # 核销coupon
+                if order_list[0]['coupon_id']:
+                    CouponModel.objects.filter(id=order_list[0]['coupon_id']).update(use_status=1)
+
                 order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id,
                                 promotion_rule_id=promotion_rule_id,agreement_id=agreement_id)
                 datetime = time.strftime("%Y-%m-%d", time.localtime())
@@ -267,12 +273,147 @@ class PaypalCycleNotify(View):
         transmission_sig = header.get('paypal-transmission-sig',None)
         auth_algo = header.get('paypal-auth-algo',None)
         resource_type = json_obj.get('resource_type')
+
+        json_str = '{"id":"WH-22P96595RY482870W-2B701244WV459014K","event_version":"1.0","create_time":"2022-01-06T05:56:33.126Z","resource_type":"sale","event_type":"PAYMENT.SALE.COMPLETED","summary":"Payment completed for $ 0.02 USD","resource":{"billing_agreement_id":"I-CR65R6YXS3VA","amount":{"total":"0.02","currency":"USD","details":{"subtotal":"0.02"}},"payment_mode":"INSTANT_TRANSFER","update_time":"2022-01-06T05:56:18Z","create_time":"2022-01-06T05:56:18Z","protection_eligibility_type":"ITEM_NOT_RECEIVED_ELIGIBLE,UNAUTHORIZED_PAYMENT_ELIGIBLE","transaction_fee":{"currency":"USD","value":"0.02"},"protection_eligibility":"ELIGIBLE","links":[{"method":"GET","rel":"self","href":"https://api.sandbox.paypal.com/v1/payments/sale/2FE30648Y2273061H"},{"method":"POST","rel":"refund","href":"https://api.sandbox.paypal.com/v1/payments/sale/2FE30648Y2273061H/refund"}],"id":"2FE30648Y2273061H","state":"completed","invoice_number":""},"links":[{"href":"https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-22P96595RY482870W-2B701244WV459014K","rel":"self","method":"GET"},{"href":"https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-22P96595RY482870W-2B701244WV459014K/resend","rel":"resend","method":"POST"}]}'
+        header = "{'PATH_INFO': '/payCycle/paypalCycleNotify', 'wsgi.file_wrapper': <class 'gunicorn.http.wsgi.FileWrapper'>, 'CONTENT_LENGTH': '1226', 'wsgi.multiprocess': True, 'HTTP_PAYPAL_TRANSMISSION_TIME': '2022-01-06T05:56:36Z', 'wsgi.version': (1, 0), 'SERVER_NAME': '0.0.0.0', 'SCRIPT_NAME': '', 'SERVER_PROTOCOL': 'HTTP/1.0', 'REMOTE_PORT': '42322', 'HTTP_HTTP_X_FORWARDED_FOR': '173.0.80.116', 'RAW_URI': '/payCycle/paypalCycleNotify', 'HTTP_X_REAL_IP': '173.0.80.116', 'HTTP_X_B3_SPANID': 'f37d2832010b10f2', 'REMOTE_ADDR': '127.0.0.1', 'wsgi.input': <gunicorn.http.body.Body object at 0x7ff31a5b92b0>, 'HTTP_PAYPAL_TRANSMISSION_SIG': 'JI+rFKqe9YqufExp/aJxkyRWG3II+4t6CSCWLHqNrjcd/FP729G0s8lFMPixnGpUemj4+WsJTbu29G4ZR3zxl+CwrlKhPQxe0fE0mUw+/AaBa6THpnoXEVwz9spI/kbH3dNmSXePfW0D5+HyVmWgkac23icxi4G92ZmmszPBzBdcNIc3BumXGSfJwX19cchta0VY7GnD5ePvW1FstPp9eC7NyhDH11xDpvM2qZZqhxH6hahIywVNA0gyNydkYbkbjnD+hGC+HrKKMx0Tpw8eGxUHReWJIEsiw7YCPLBwZIab5PV/+L4A/LscK/JicOeDealP+SKPJICZvinLHDzK0Q==', 'HTTP_PAYPAL_TRANSMISSION_ID': '688538e0-6eb5-11ec-a473-05e6d85b61e7', 'gunicorn.socket': <socket.socket fd=24, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8082), raddr=('127.0.0.1', 42322)>, 'HTTP_PAYPAL_AUTH_ALGO': 'SHA256withRSA', 'HTTP_PAYPAL_AUTH_VERSION': 'v2', 'wsgi.url_scheme': 'http', 'wsgi.errors': <gunicorn.http.wsgi.WSGIErrorsWrapper object at 0x7ff31a5b9a58>, 'QUERY_STRING': '', 'wsgi.multithread': False, 'HTTP_CORRELATION_ID': 'b696eaa58ea49', 'HTTP_ACCEPT': '*/*', 'HTTP_USER_AGENT': 'PayPal/AUHD-214.0-56138150', 'CONTENT_TYPE': 'application/json', 'HTTP_PAYPAL_CERT_URL': 'https://api.sandbox.paypal.com/v1/notifications/certs/CERT-360caa42-fca2a594-7a8abba8', 'HTTP_CONNECTION': 'close', 'SERVER_PORT': '8082', 'HTTP_HOST': 'test.zositechc.cn:443', 'HTTP_X_FORWARDED_FOR': '173.0.80.116', 'SERVER_SOFTWARE': 'gunicorn/19.7.1', 'wsgi.run_once': False, 'REQUEST_METHOD': 'POST'}"
+
         if resource_type == 'plan':
             paypalrestsdk.configure(PAYPAL_CRD)
             response = paypalrestsdk.WebhookEvent.verify(
                 transmission_id, transmission_time, webhook_id, json_str, cert_url, transmission_sig, auth_algo)
 
-        logger.info('response----------------')
-        logger.info(response)
-        return HttpResponse(json_obj.get('id'))
 
+
+            logger.info('response----------------')
+            logger.info(response)
+            return HttpResponse(json_obj.get('id'))
+
+
+    def do_test(self, request_dict, request, response):
+
+        json_str = '{"id":"WH-22P96595RY482870W-2B701244WV459014K","event_version":"1.0","create_time":"2022-01-06T05:56:33.126Z","resource_type":"sale","event_type":"PAYMENT.SALE.COMPLETED","summary":"Payment completed for $ 0.02 USD","resource":{"billing_agreement_id":"I-CR65R6YXS3VA","amount":{"total":"0.02","currency":"USD","details":{"subtotal":"0.02"}},"payment_mode":"INSTANT_TRANSFER","update_time":"2022-01-06T05:56:18Z","create_time":"2022-01-06T05:56:18Z","protection_eligibility_type":"ITEM_NOT_RECEIVED_ELIGIBLE,UNAUTHORIZED_PAYMENT_ELIGIBLE","transaction_fee":{"currency":"USD","value":"0.02"},"protection_eligibility":"ELIGIBLE","links":[{"method":"GET","rel":"self","href":"https://api.sandbox.paypal.com/v1/payments/sale/2FE30648Y2273061H"},{"method":"POST","rel":"refund","href":"https://api.sandbox.paypal.com/v1/payments/sale/2FE30648Y2273061H/refund"}],"id":"2FE30648Y2273061H","state":"completed","invoice_number":""},"links":[{"href":"https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-22P96595RY482870W-2B701244WV459014K","rel":"self","method":"GET"},{"href":"https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-22P96595RY482870W-2B701244WV459014K/resend","rel":"resend","method":"POST"}]}'
+        header = "{'PATH_INFO': '/payCycle/paypalCycleNotify', 'wsgi.file_wrapper': <class 'gunicorn.http.wsgi.FileWrapper'>, 'CONTENT_LENGTH': '1226', 'wsgi.multiprocess': True, 'HTTP_PAYPAL_TRANSMISSION_TIME': '2022-01-06T05:56:36Z', 'wsgi.version': (1, 0), 'SERVER_NAME': '0.0.0.0', 'SCRIPT_NAME': '', 'SERVER_PROTOCOL': 'HTTP/1.0', 'REMOTE_PORT': '42322', 'HTTP_HTTP_X_FORWARDED_FOR': '173.0.80.116', 'RAW_URI': '/payCycle/paypalCycleNotify', 'HTTP_X_REAL_IP': '173.0.80.116', 'HTTP_X_B3_SPANID': 'f37d2832010b10f2', 'REMOTE_ADDR': '127.0.0.1', 'wsgi.input': <gunicorn.http.body.Body object at 0x7ff31a5b92b0>, 'HTTP_PAYPAL_TRANSMISSION_SIG': 'JI+rFKqe9YqufExp/aJxkyRWG3II+4t6CSCWLHqNrjcd/FP729G0s8lFMPixnGpUemj4+WsJTbu29G4ZR3zxl+CwrlKhPQxe0fE0mUw+/AaBa6THpnoXEVwz9spI/kbH3dNmSXePfW0D5+HyVmWgkac23icxi4G92ZmmszPBzBdcNIc3BumXGSfJwX19cchta0VY7GnD5ePvW1FstPp9eC7NyhDH11xDpvM2qZZqhxH6hahIywVNA0gyNydkYbkbjnD+hGC+HrKKMx0Tpw8eGxUHReWJIEsiw7YCPLBwZIab5PV/+L4A/LscK/JicOeDealP+SKPJICZvinLHDzK0Q==', 'HTTP_PAYPAL_TRANSMISSION_ID': '688538e0-6eb5-11ec-a473-05e6d85b61e7', 'gunicorn.socket': <socket.socket fd=24, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8082), raddr=('127.0.0.1', 42322)>, 'HTTP_PAYPAL_AUTH_ALGO': 'SHA256withRSA', 'HTTP_PAYPAL_AUTH_VERSION': 'v2', 'wsgi.url_scheme': 'http', 'wsgi.errors': <gunicorn.http.wsgi.WSGIErrorsWrapper object at 0x7ff31a5b9a58>, 'QUERY_STRING': '', 'wsgi.multithread': False, 'HTTP_CORRELATION_ID': 'b696eaa58ea49', 'HTTP_ACCEPT': '*/*', 'HTTP_USER_AGENT': 'PayPal/AUHD-214.0-56138150', 'CONTENT_TYPE': 'application/json', 'HTTP_PAYPAL_CERT_URL': 'https://api.sandbox.paypal.com/v1/notifications/certs/CERT-360caa42-fca2a594-7a8abba8', 'HTTP_CONNECTION': 'close', 'SERVER_PORT': '8082', 'HTTP_HOST': 'test.zositechc.cn:443', 'HTTP_X_FORWARDED_FOR': '173.0.80.116', 'SERVER_SOFTWARE': 'gunicorn/19.7.1', 'wsgi.run_once': False, 'REQUEST_METHOD': 'POST'}"
+
+        json_obj = json.loads(json_str)
+
+        # transmission_id = header.get('HTTP_PAYPAL_TRANSMISSION_ID',None)
+        # transmission_time = header.get('HTTP_PAYPAL_TRANSMISSION_TIME',None)
+        # webhook_id = '6TS30758D98835230'
+        # cert_url = header.get('HTTP_PAYPAL_CERT_URL',None)
+        # transmission_sig = header.get('HTTP_PAYPAL_TRANSMISSION_SIG',None)
+        # auth_algo = header.get('HTTP_PAYPAL_AUTH_ALGO',None)
+        # resource_type = json_obj.get('resource_type')
+
+        transmission_id = '688538e0-6eb5-11ec-a473-05e6d85b61e7'
+        transmission_time = '2022-01-06T05:56:36Z'
+        webhook_id = '6TS30758D98835230'
+        cert_url = 'https://api.sandbox.paypal.com/v1/notifications/certs/CERT-360caa42-fca2a594-7a8abba8'
+        transmission_sig = 'JI+rFKqe9YqufExp/aJxkyRWG3II+4t6CSCWLHqNrjcd/FP729G0s8lFMPixnGpUemj4+WsJTbu29G4ZR3zxl+CwrlKhPQxe0fE0mUw+/AaBa6THpnoXEVwz9spI/kbH3dNmSXePfW0D5+HyVmWgkac23icxi4G92ZmmszPBzBdcNIc3BumXGSfJwX19cchta0VY7GnD5ePvW1FstPp9eC7NyhDH11xDpvM2qZZqhxH6hahIywVNA0gyNydkYbkbjnD+hGC+HrKKMx0Tpw8eGxUHReWJIEsiw7YCPLBwZIab5PV/+L4A/LscK/JicOeDealP+SKPJICZvinLHDzK0Q=='
+        auth_algo = 'SHA256withRSA'
+        resource_type = json_obj.get('resource_type')
+
+        if resource_type == 'sale':
+            paypalrestsdk.configure(PAYPAL_CRD)
+            response = paypalrestsdk.WebhookEvent.verify(
+                transmission_id, transmission_time, webhook_id, json_str, cert_url, transmission_sig, auth_algo)
+            if response:
+                try:
+                    agreement_id = json_obj.get('resource')['billing_agreement_id']
+                    order_qs = Order_Model.objects.filter(agreement_id=agreement_id, status=0)
+
+                    if not order_qs:
+                        return False
+                    order_list = order_qs.values("UID", "channel", "commodity_code", "rank", "isSelectDiscounts",
+                                                 "userID__userID",
+                                                 "userID__username")
+                    return HttpResponse(order_list)
+
+                    userid = order_list[0]['userID__userID']
+                    username = order_list[0]['userID__username']
+                    UID = order_list[0]['UID']
+                    channel = order_list[0]['channel']
+                    rank = order_list[0]['rank']
+                    smqs = Store_Meal.objects.filter(id=rank). \
+                        values("day", "bucket_id", "bucket__storeDay", "expire")
+                    bucketId = smqs[0]['bucket_id']
+                    if not smqs.exists():
+                        print("not smqs")
+                        red_url = "{SERVER_DOMAIN_SSL}web/paid2/fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
+                        if lang != 'cn':
+                            red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(
+                                SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
+                        return HttpResponseRedirect(red_url)
+                    # ##
+                    ubqs = UID_Bucket.objects.filter(uid=UID).values("id", "bucket_id", "bucket__storeDay",
+                                                                     "bucket__region",
+                                                                     "endTime", "use_status")
+                    expire = smqs[0]['expire']
+
+                    if order_list[0]['isSelectDiscounts'] == 1:
+                        expire = smqs[0]['expire'] * 2
+                    # 是否有促销
+                    nowTime = int(time.time())
+                    promotion = PromotionRuleModel.objects.filter(status=1, startTime__lte=nowTime,
+                                                                  endTime__gte=nowTime).values('id', 'ruleConfig')
+                    if promotion.exists():
+                        promotion_rule_id = promotion[0]['id']
+                        expire = expire * 2
+                    with transaction.atomic():
+                        if ubqs.exists():
+                            ubq = ubqs[0]
+                            if ubq['use_status'] == 1 and ubq['bucket_id'] == bucketId:  # 套餐使用中并且相同套餐叠加过期时间
+                                endTime = CommonService.calcMonthLater(expire, ubq['endTime'])
+                                UID_Bucket.objects.filter(id=ubq['id']).update \
+                                    (uid=UID, channel=channel, bucket_id=bucketId,
+                                     endTime=endTime, updateTime=nowTime)
+                            else:  # 已过期或者不相同的套餐加入未使用的关联套餐表
+                                has_unused = Unused_Uid_Meal.objects.filter(uid=UID, bucket_id=bucketId).values("id")
+                                nums = 2 if order_list[0]['isSelectDiscounts'] == 1 else 1
+                                if promotion.exists():
+                                    nums = nums + 1
+                                if has_unused.exists():
+                                    Unused_Uid_Meal.objects.filter(id=has_unused[0]['id']).update(num=F('num') + nums)
+                                else:
+                                    Unused_Uid_Meal.objects.create(uid=UID, channel=channel, addTime=nowTime, num=nums,
+                                                                   expire=smqs[0]['expire'], bucket_id=bucketId)
+                                UID_Bucket.objects.filter(id=ubq['id']).update(has_unused=1)
+                            uid_bucket_id = ubq['id']
+                        else:
+                            endTime = CommonService.calcMonthLater(expire)
+                            ub_cqs = UID_Bucket.objects.create \
+                                (uid=UID, channel=channel, bucket_id=bucketId, endTime=endTime, addTime=nowTime,
+                                 updateTime=nowTime, use_status=1)
+                            uid_bucket_id = ub_cqs.id
+
+                        dvq = Device_Info.objects.filter(UID=UID, vodPrimaryUserID='', vodPrimaryMaster='')
+                        if dvq.exists():
+                            dvq_set_update_dict = {
+                                'vodPrimaryUserID': userid,
+                                'vodPrimaryMaster': username
+                            }
+                            dvq.update(**dvq_set_update_dict)
+
+                        # uid_main_exist = UIDMainUser.objects.filter(UID=UID)
+                        # if not uid_main_exist.exists():
+                        #     uid_main_dict = {
+                        #         'UID': UID,
+                        #         'user_id': userid
+                        #     }
+                        #     UIDMainUser.objects.create(**uid_main_dict)
+
+                        order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id,
+                                        promotion_rule_id=promotion_rule_id, agreement_id=agreement_id)
+                        datetime = time.strftime("%Y-%m-%d", time.localtime())
+                        sys_msg_text_list = ['温馨提示:尊敬的客户,您的' + UID + '设备在' + datetime + '已成功订阅云存套餐',
+                                             'Dear customer,you already subscribed the cloud storage package successfully for device ' + UID + ' on ' + time.strftime(
+                                                 "%b %dth,%Y", time.localtime())]
+
+                        CloudStorage.CloudStorageView.do_vod_msg_Notice(self, UID, channel, userid, lang,
+                                                                        sys_msg_text_list, 'SMS_219738485')
+                        return True
+                except Exception as e:
+                    print(repr(e))
+                    if order_qs:
+                        order_qs.update(status=10, promotion_rule_id=promotion_rule_id)
+                    return False
+        return False

+ 20 - 0
Model/models.py

@@ -624,6 +624,7 @@ class Order_Model(models.Model):
     promotion_rule_id = models.CharField(blank=True, max_length=64, default='', verbose_name='促销id')
     plan_id = models.CharField(default='', blank=True, max_length=64, verbose_name=u'paypal计划id')
     agreement_id = models.CharField(default='', blank=True, max_length=64, verbose_name=u'paypal协议id')
+    coupon_id = models.CharField(default='', blank=True, max_length=10, verbose_name=u'优惠券id')
 
     # 备用字段
     spare_4 = models.CharField(default='', blank=True, max_length=64, db_index=True, verbose_name=u'备用字段4')
@@ -638,6 +639,25 @@ class Order_Model(models.Model):
         verbose_name_plural = verbose_name
         ordering = ('-orderID',)
 
+class CouponModel(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='主键')
+    userID_id = models.CharField(default='', db_index=True, blank=True, max_length=32, verbose_name=u'用户ID')
+    use_status = models.SmallIntegerField(default=0, verbose_name='使用状态') #0未使用;1冻结;2已使用
+    type = models.SmallIntegerField(default=0, verbose_name='优惠类型') #1打折; 2抵扣
+    coupon_discount = models.DecimalField( max_digits=19, decimal_places=2, verbose_name='折扣力度')
+    distributeTime = models.IntegerField(verbose_name='发放到用户账户时间', default=0)
+    valid_time = models.PositiveIntegerField(default=9999999999, verbose_name='有效期间')  #超过有效期不可在使用;0永久
+    # use_limit = models.CharField(default=0, max_length=100, verbose_name='使用限制')  #0:所有服务都可使用; 1:云存;2:ai;
+    addTime = models.IntegerField(verbose_name='添加时间', default=0)
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'coupon'
+        verbose_name = u'优惠券'
+        verbose_name_plural = verbose_name
+
 class PayCycleConfigModel(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='主键')
     # name = models.CharField(default='',max_length=200, verbose_name='计划名字')

+ 2 - 0
Object/ResponseObject.py

@@ -105,6 +105,7 @@ class ResponseObject(object):
             10046: 'Sorry, users who have activated cloud storage packages do not support logout at the moment, please contact customer service',
             10047: 'Please delete all devices under your account first',
             10048: 'Subscribe to the failure',
+            10049: 'The coupon is not available',
         }
         data_cn = {
             0: '成功',
@@ -203,6 +204,7 @@ class ResponseObject(object):
             10046: '已开通云存的用户,暂不支持注销,请联系客服',
             10047: '请先删除您当前帐户下的所有设备',
             10048: '订阅失败',
+            10049: '该优惠券不可用',
         }
         if self.lang == 'cn':
             msg = data_cn