mopybird 2 years ago
parent
commit
117f918377
81 changed files with 729 additions and 12827 deletions
  1. 0 11
      apilib/monetary.py
  2. 0 1
      apps/web/agent/define.py
  3. 8 175
      apps/web/agent/models.py
  4. 0 1
      apps/web/agent/urls.py
  5. 0 52
      apps/web/agent/views.py
  6. 2 0
      apps/web/api/__init__.py
  7. 55 0
      apps/web/api/exceptions.py
  8. 182 0
      apps/web/api/models.py
  9. 304 0
      apps/web/api/utils.py
  10. 2 5
      apps/web/common/models.py
  11. 1 9
      apps/web/constant.py
  12. 3 66
      apps/web/core/__init__.py
  13. 0 1040
      apps/web/core/adapter/aoqiang.py
  14. 0 779
      apps/web/core/adapter/changyuan4.py
  15. 0 1886
      apps/web/core/adapter/jndz.py
  16. 2 2
      apps/web/core/auth/wechat.py
  17. 0 8
      apps/web/core/bridge/wechat/v3api.py
  18. 1 17
      apps/web/core/db.py
  19. 0 19
      apps/web/core/messages/sms.py
  20. 0 385
      apps/web/core/models.py
  21. 2 8
      apps/web/core/payment/base.py
  22. 2 2
      apps/web/core/payment/wechat.py
  23. 0 1
      apps/web/dealer/constant.py
  24. 10 219
      apps/web/dealer/models.py
  25. 1 23
      apps/web/dealer/transaction_deprecated.py
  26. 3 94
      apps/web/dealer/utils.py
  27. 10 39
      apps/web/dealer/views.py
  28. 0 889
      apps/web/eventer/aoqiang.py
  29. 0 41
      apps/web/eventer/base.py
  30. 0 5
      apps/web/eventer/dianchuan.py
  31. 0 2075
      apps/web/eventer/jndz.py
  32. 0 7
      apps/web/helpers.py
  33. 0 5
      apps/web/superadmin/urls.py
  34. 0 91
      apps/web/superadmin/views.py
  35. 2 54
      apps/web/user/models.py
  36. 1 9
      apps/web/user/tasks.py
  37. 3 99
      apps/web/user/transaction_deprecated.py
  38. 0 2
      apps/web/user/urls.py
  39. 3 9
      apps/web/user/utils.py
  40. 15 185
      apps/web/user/views.py
  41. 1 8
      configs/base.py
  42. 0 535
      library/RuralCreditUnion/pay.py
  43. 0 79
      library/jd/pay.py
  44. 3 347
      library/jdpsi/client.py
  45. 97 0
      library/sms/zthy.py
  46. 0 1
      script/build_python/build_for_wugang.py
  47. 0 354
      script/jdOpenTest.py
  48. 0 281
      script/jdTest.py
  49. 0 34
      script/merchantAddress.py
  50. 0 293
      script/sort_dealer.py
  51. 3 7
      script/system_ledger.py
  52. 0 380
      script/test.py
  53. 0 409
      script/transaction/1.txt
  54. 0 128
      script/transaction/jdBill.py
  55. 1 3
      script/upgrade/executed/fix_dirty_data.py
  56. 0 16
      script/upgrade/executed/update_bank.py
  57. 0 755
      script/upgrade/executed/upgrade_reactor_withdraw.py
  58. 0 16
      script/upgrade/update_bank.py
  59. 0 9
      script/upgrade/update_bank_with_patterns.py
  60. 0 60
      script/utils/upgrade_wechatminipay_app.py
  61. 0 61
      script/wx_mrechant.py
  62. 0 17
      static/administrator/js/config.router.js
  63. 0 60
      static/administrator/js/controllers/dealerManage.js
  64. 0 98
      static/administrator/js/controllers/merchantHistory.js
  65. 0 5
      static/administrator/tpl/blocks/nav.html
  66. 0 267
      static/administrator/tpl/dealerManage.html
  67. 0 43
      static/administrator/tpl/merchantHistory.html
  68. 0 65
      static/agents/customerParam.html
  69. 0 36
      static/app/index.html
  70. 0 1
      static/app/js/xyf.common.js
  71. 1 31
      static/app/location-edit.html
  72. 0 22
      static/app/wallet/wallet.html
  73. 0 1
      static/mock/dealer/groupInfo
  74. 0 9
      taskmanager/config_test.py
  75. 0 2
      taskmanager/mediator.py
  76. 0 4
      taskmanager/tasks.py
  77. 0 2
      testcase/unit/common.py
  78. 2 41
      testcase/unit/conftest.py
  79. 3 20
      testcase/unit/test_agent.py
  80. 6 12
      testcase/unit/test_dealer.py
  81. 0 2
      urls.py

+ 0 - 11
apilib/monetary.py

@@ -289,17 +289,6 @@ class Permillage(Ratio):
         return u'{amount}'.format(amount = quantize(self._amount, places='0.01'))
 
 
-class JDMerchantPermillage(Permillage):
-
-    def to_jd_params(self):
-        """
-        打印出来的是百分之多少 比如设定的是JDMerchantPermillage(6) 表示是千分之6
-        则使用str之后 显示的是 0.60
-        :return:
-        """
-        return u'{amount:.2f}'.format(amount=quantize((self * Decimal('0.1'))._amount, places='0.01'))
-
-
 class AccuracyRMB(RMB):
     """
     精度等级更高的RMB 算到0.01分 适用于单笔结账

+ 0 - 1
apps/web/agent/define.py

@@ -88,7 +88,6 @@ AgentConst.MAP_TYPE_TO_FIELD = {
     AGENT_INCOME_TYPE.DEALER_DEVICE_FEE: 'deviceBalance',
     AGENT_INCOME_TYPE.DEALER_WITHDRAW_FEE: 'withdrawBalance',
     AGENT_INCOME_TYPE.DEALER_CARD_FEE: 'trafficBalance',
-    AGENT_INCOME_TYPE.INSURANCE: 'insuranceBalance',
     AGENT_INCOME_TYPE.DEALER_API_QUOTA: 'apiQuotaBalance',
     AGENT_INCOME_TYPE.DEALER_DISABLE_AD: 'disableAdBalance'
 }

+ 8 - 175
apps/web/agent/models.py

@@ -5,41 +5,38 @@
     ~~~~~~~~~
 """
 
-import simplejson as json
 import datetime
 import itertools
 import logging
 import urllib
+from collections import namedtuple
 
+import simplejson as json
 from bson.objectid import ObjectId
 from django.conf import settings
 from django.utils.module_loading import import_string
 from mongoengine import MapField, LazyReferenceField, IntField
 from mongoengine.errors import DoesNotExist
 from mongoengine.fields import (StringField, DictField, BooleanField, DateTimeField, EmbeddedDocumentField,
-                                ListField, ReferenceField)
-
+                                ListField)
 from typing import Any, Dict, TYPE_CHECKING, Optional, cast
-from collections import namedtuple
 
 from apilib.monetary import RMB, sum_rmb, Permillage, Percent
 from apps.web.agent.define import AgentConst, AGENT_INCOME_SOURCE, AGENT_INCOME_TYPE
 from apps.web.agent.errors import PrimaryAgentDoesNotExist
 from apps.web.common.models import WithdrawRecord, CapitalUser, Balance, WithdrawBankCard
-
+from apps.web.common.transaction import WITHDRAW_PAY_TYPE
 from apps.web.constant import Const, AppPlatformType, DEALER_CONSUMPTION_AGG_KIND, MoniAppStatus
+from apps.web.core import PayAppType, APP_KEY_DELIMITER, ROLE
 from apps.web.core.db import Searchable, MonetaryField, StrictDictField, PermillageField, PercentField
-from apps.web.core.exceptions import InvalidParameter, NoAgentFound, NoManagerFound, MerchantError
+from apps.web.core.exceptions import InvalidParameter, NoAgentFound, NoManagerFound
 from apps.web.core.messages.sms import agentWithdrawSMSProvider
 from apps.web.core.models import WechatManagerApp, WechatAuthApp, BoundOpenInfo, AliApp, WechatPayApp, \
-    WechatMiniApp, WechatUserManagerApp, BankCard, \
-    WithdrawEntity, WechatUserSubscribeManagerApp, WechatDealerSubscribeManagerApp
-from apps.web.core import PayAppType, APP_KEY_DELIMITER, ROLE
+    WechatUserManagerApp, WithdrawEntity, WechatUserSubscribeManagerApp, WechatDealerSubscribeManagerApp
 from apps.web.core.payment import WithdrawGateway
 from apps.web.device.models import DeviceType
-from apps.web.management.models import Manager
-from apps.web.common.transaction import WITHDRAW_PAY_TYPE
 from apps.web.exceptions import UserServerException
+from apps.web.management.models import Manager
 
 logger = logging.getLogger(__name__)
 
@@ -88,7 +85,6 @@ class Agent(CapitalUser):
         ROLE.myuser: {
             AppPlatformType.ALIPAY: PayAppType.ALIPAY,
             AppPlatformType.WECHAT: PayAppType.WECHAT,
-            AppPlatformType.WECHAT_MINI: PayAppType.WECHAT_MINI
         }
     }
 
@@ -101,7 +97,6 @@ class Agent(CapitalUser):
     trafficBalance = MapField(field = EmbeddedDocumentField(Balance))
     adBalance = MapField(field = EmbeddedDocumentField(Balance))
     withdrawBalance = MapField(field = EmbeddedDocumentField(Balance))
-    insuranceBalance = MapField(field = EmbeddedDocumentField(Balance))
     apiQuotaBalance = MapField(field = EmbeddedDocumentField(Balance))
     disableAdBalance = MapField(field = EmbeddedDocumentField(Balance))
 
@@ -220,9 +215,6 @@ class Agent(CapitalUser):
 
     dealerBankWithdrawFee = BooleanField(verbose_name = u'经销商提现到银行卡的手续费,计算方式', default = False)
 
-    # 以下字段不在支持
-    bankcards = ListField(ReferenceField(BankCard), default = [])
-
     meta = {
         'indexes': [
             {
@@ -661,36 +653,6 @@ class Agent(CapitalUser):
         """
         return self.customizedWechatCashflowAllowable
 
-    def wechat_mini_env_pay_app(self, role = None, pay_app_type = None):
-        # type: (str, str)->WechatMiniApp
-
-        if not self.customizedWechatMiniAllowable:
-            primary_agent = self.primary_agent
-            if self.is_equal(primary_agent):
-                return self.inhouse_prime_agent.wechat_mini_env_pay_app(role, pay_app_type)
-            else:
-                return primary_agent.wechat_mini_env_pay_app(role, pay_app_type)
-
-        if self.customizedWechatMiniAllowable:
-            if not self.customizedCashflowAllowable:
-                raise Exception(u'第三方支付配置错误(1001)')
-
-            app = self.payAppWechatMini.fetch()
-            if app and app.enable and app.valid:
-                app.occupantId = str(self.id)
-                app.occupant = self
-                return app
-
-            app = self.wechatMiniApp  # type: WechatMiniApp
-            if app and app.enable and app.valid:
-                app.occupantId = str(self.id)
-                app.occupant = self
-                return app
-
-            raise Exception(u'第三方支付配置错误(1002)')
-        else:
-            return WechatMiniApp.get_null_app()
-
     def wechat_env_pay_app(self, role = None, pay_app_type = None):
         # type: (Optional[None, str], Optional[None, str])->Optional[cast(PayAppBase)]
 
@@ -733,14 +695,6 @@ class Agent(CapitalUser):
 
             return app
 
-        if app_pay_type == PayAppType.JD_AGGR:
-            app = self.my_jd_aggre_pay_app  # type: JDAggrePayApp
-
-            if not app.enable or not app.valid:
-                raise Exception(u'系统配置错误(第三方支付)')
-
-            return app
-
         raise Exception(u'系统配置错误(第三方支付)')
 
     def alipay_env_pay_app(self, role = None, pay_app_type = None):
@@ -782,52 +736,6 @@ class Agent(CapitalUser):
                 raise Exception(u'系统配置错误(第三方支付)')
             return app
 
-        if app_pay_type == PayAppType.JD_AGGR:
-            app = self.my_jd_aggre_pay_app  # type: JDAggrePayApp
-            if not app.enable or not app.valid:
-                raise Exception(u'系统配置错误(第三方支付)')
-            return app
-
-        raise Exception(u'系统配置错误(第三方支付)')
-
-    def jd_env_pay_app(self, role = None, pay_app_type = None):
-        assert not (role and pay_app_type), 'role and app_type must not have value in the same time.'
-
-        if not self.customizedCashflowAllowable:
-            if pay_app_type:
-                _pay_app_type = pay_app_type
-                _role = None
-            else:
-                custom = self.payType.get('custom', False)
-
-                if custom:
-                    if role in self.payType and AppPlatformType.JD in self.payType[role]:
-                        _pay_app_type = self.payType[role][AppPlatformType.JD]
-                        _role = None
-                    else:
-                        _pay_app_type = None
-                        _role = role
-                else:
-                    _pay_app_type = None
-                    _role = role
-
-            primary_agent = self.primary_agent
-            if self.is_equal(primary_agent):
-                return self.inhouse_prime_agent.jd_env_pay_app(_role, _pay_app_type)
-            else:
-                return primary_agent.jd_env_pay_app(_role, _pay_app_type)
-
-        if role:
-            app_pay_type = self.my_pay_type(role, AppPlatformType.JD)
-        else:
-            app_pay_type = pay_app_type
-
-        if app_pay_type == PayAppType.JD_AGGR:
-            app = self.my_jd_aggre_pay_app  # type: JDAggrePayApp
-            if not app.enable or not app.valid:
-                raise Exception(u'系统配置错误(第三方支付)')
-            return app
-
         raise Exception(u'系统配置错误(第三方支付)')
 
     def _check_wechat_withdraw(self):
@@ -1213,41 +1121,6 @@ class Agent(CapitalUser):
         app.occupantId = str(self.id)
         return app
 
-    @property
-    def jd_auth_app(self):
-        """
-        标识用户只用平台的公众号对应APPID. 部分用户由于前期原因配置了自己的
-        该接口仅做兼容
-        :return:
-        """
-        if self.jdAuthApp:
-            app = self.jdAuthApp  # type: JDAuthApp
-            app.occupantId = str(self.id)
-            return app
-        else:
-            primary_agent = self.primary_agent
-            if self.is_equal(primary_agent):
-                return self.inhouse_prime_agent.jdAuthApp
-            else:
-                return primary_agent.jdAuthApp
-
-    @property
-    def wechat_mini_auth_app(self):
-        if not self.customizedWechatMiniAllowable:
-            primary_agent = self.primary_agent
-            if self.is_equal(primary_agent):
-                return self.inhouse_prime_agent.wechat_mini_auth_app
-            else:
-                return primary_agent.wechat_mini_auth_app
-
-        app = self.wechatMiniApp
-
-        if not app.valid:
-            raise Exception(u'系统配置错误(第三方支付)')
-
-        app.occupantId = str(self.id)
-        return app
-
     def income_by_date(self, date, specific_source = None):
         """
         :param date:
@@ -1501,50 +1374,10 @@ class Agent(CapitalUser):
 
         return logo
 
-    def check_merchant_conditions(self):    # type:()->None
-        """ 商户确认开通前的检查 """
-        if not self.ledgerAppJDAggre:
-            raise MerchantError(u"商户尚未绑定,开通失败")
-
-    def confirm_merchant(self, source):
-        """ 商户已经是确认状态所需要处理的事情 """
-        if not source.support_jdaggre():
-            return
-
-        if not source.owner == self:
-            return
-
-        # 首先获取自己的商户
-        app = source.create_app()
-        self.ledgerAppJDAggre = app
-
-        return self.save()
-
-    def success_merchant(self):
-        """ 确认商户开通的动作 """
-        return
-
-    @property
-    def merchantRegister(self):
-        return self
-
     @property
     def abnormal(self):
         return self.status == self.Status.ABNORMAL
 
-    @property
-    def myLedgerMerchantApp(self):
-        """
-        商户分账APP
-        """
-        if not self.ledgerAppJDAggre:
-            if not self.payAppJDAggre:
-                return None
-            else:
-                return self.payAppJDAggre.fetch()
-
-        return self.ledgerAppJDAggre.fetch()
-
     @property
     def deviceIncomeShow(self):
         """

+ 0 - 1
apps/web/agent/urls.py

@@ -120,7 +120,6 @@ urlpatterns = patterns(
 
     # 设置代理商设备分成比例 分为商户收款和资金池收款
     url(r'^setDealerAgentProfitShare$', setDealerAgentProfitShare, name = 'setDealerAgentProfitShare'),
-    url(r'^setDealerAgentMerProfitShare$', setDealerAgentMerProfitShare, name='setDealerAgentMerProfitShare'),
 
     url(r'^getWalletWithdrawInfo$', getWalletWithdrawInfo, name = 'getWalletWithdrawInfo'),
 

+ 0 - 52
apps/web/agent/views.py

@@ -922,44 +922,6 @@ def setDealerAgentProfitShare(request):
         return JsonErrorResponse(description = u'经销商不存在,请刷新后再试')
 
 
-@error_tolerate(nil = DefaultJsonErrorResponse, logger = logger)
-@permission_required(ROLE.agent)
-def setDealerAgentMerProfitShare(request):
-    # type: (WSGIRequest)->JsonResponse
-
-    """
-    代理商设置经销商设备经营提成比例 当经销商使用商户收款时候
-    :param request:
-    :return:
-    """
-    payload = json.loads(request.body)
-    dealerId = payload["id"]
-    agentMerProfitShare = payload["agentMerProfitShare"]
-
-    agent = request.user                        # type: Agent
-    dealer = Dealer.objects.get(id=dealerId)    # type: Dealer
-
-    if dealer.agentId != str(agent.id):
-        return JsonErrorResponse(u"设置失败,权限错误")
-
-    maxProfitShare = Percent('50.0')
-    minProfitShare = Percent('0.0')
-    agentMerProfitShare = Percent(agentMerProfitShare)
-    if agentMerProfitShare < minProfitShare or agentMerProfitShare > maxProfitShare:
-        return JsonErrorResponse(description=u'分成比例错误,当前最大分成比例 {},最小分成比例 {}'.format(maxProfitShare, minProfitShare))
-
-    # 商户经营分成必须要求代理商拥有商户
-    if not agent.ledgerAppJDAggre:
-        return JsonResponse({"result": ErrorCode.AGENT_NEED_MERCHANT, "description": u"您当前尚未开通商户收款,无法设置商户经营分成"})
-
-    updated = dealer.set_agent_mer_profit_share(agentMerProfitShare)
-
-    if not updated:
-        return JsonErrorResponse(description = u'更新错误,请重试')
-
-    return JsonOkResponse(description=u"设置成功")
-
-
 @error_tolerate(nil = JsonErrorResponse(u'设备类型不支持'), logger = logger)
 @permission_required(ROLE.agent)
 def getPackageList(request):
@@ -1275,20 +1237,6 @@ def walletData(request):
             AGENT_INCOME_TYPE.DEALER_DEVICE_FEE: device_income_list
         })
 
-    insurance_income_list = list()
-    for source_key, balance in agent.insuranceBalance.iteritems():
-        if WithdrawGateway.is_ledger(source_key) and balance.balance != RMB(0):
-            insurance_income_list.append({
-                'id': source_key,
-                'balance': balance.balance,
-                'name': current_platform(source_key, inhouse_source_key),
-                'current': source_key == inhouse_source_key
-            })
-    if len(insurance_income_list) > 0:
-        payload.update({
-            AGENT_INCOME_TYPE.INSURANCE: insurance_income_list
-        })
-
     return JsonResponse({'result': 1, 'description': None, 'payload': payload})
 
 

+ 2 - 0
apps/web/api/__init__.py

@@ -0,0 +1,2 @@
+# -*- coding: utf-8 -*-
+# !/usr/bin/env python

+ 55 - 0
apps/web/api/exceptions.py

@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+# !/usr/bin/env python
+
+from apps.web.constant import ErrorCode
+
+class ApiException(Exception):
+    def __init__(self, errcode, errmsg, payload = {}):
+        self.errcode = errcode
+        self.payload = payload
+        self.errmsg = errmsg
+
+    def __repr__(self):
+        return 'api exception. errcode = {}, errmsg = {}, payload = {}'.format(
+            self.errcode, self.errmsg, str(self.payload))
+
+    def __str__(self):
+        return self.__repr__()
+
+    def to_response(self):
+        from apps.web.api.utils import api_error_response
+        return api_error_response(errcode = self.errcode, errmsg = self.errmsg, payload = self.payload)
+
+
+class ApiParameterError(ApiException):
+    def __init__(self, errmsg):
+        super(ApiParameterError, self).__init__(
+            errcode = ErrorCode.API_PARAMETER_ERROR, errmsg = errmsg)
+
+
+class ApiAuthException(ApiException):
+    def __init__(self, errmsg):
+        super(ApiAuthException, self).__init__(
+            errcode = ErrorCode.API_AUTH_ERROR, errmsg = errmsg, payload = {'auth_result': 1})
+
+
+class ApiAuthDeviceException(ApiException):
+    def __init__(self):
+        super(ApiAuthDeviceException, self).__init__(
+            errcode = ErrorCode.API_AUTH_DEVICE_ERROR, errmsg = u'无权操作设备', payload = {'auth_result': 3})
+
+
+class ApiNoDeviceException(ApiException):
+    def __init__(self):
+        super(ApiNoDeviceException, self).__init__(
+            errcode = ErrorCode.API_NO_DEVICE, errmsg = u'设备不存在')
+
+class ApiDeviceModeException(ApiException):
+    def __init__(self):
+        super(ApiDeviceModeException, self).__init__(
+            errcode = ErrorCode.API_NO_DEVICE, errmsg = u'当前设备不在API模式, 请切换API模式(经销商后台->API接口管理->API设备管理)')
+
+class ApiDeviceTypeError(ApiException):
+    def __init__(self, errmsg):
+        super(ApiDeviceTypeError, self).__init__(
+            errcode = ErrorCode.API_ERROR_DEVICE_TYPE, errmsg = errmsg)

+ 182 - 0
apps/web/api/models.py

@@ -0,0 +1,182 @@
+# -*- coding: utf-8 -*-
+# !/usr/bin/env python
+
+import datetime
+import logging
+
+from mongoengine import BooleanField, StringField, FloatField, DictField, DateTimeField
+from mongoengine.fields import IntField
+from typing import Optional
+
+from apps.web.constant import Const, ErrorCode
+from apps.web.core.db import Searchable
+
+logger = logging.getLogger(__name__)
+
+
+class APIServiceStartRecord(Searchable):
+    orderNo = StringField(verbose_name = u'订单编号', default = None, unique = True)
+    devNo = StringField(verbose_name = u'设备编号', default = u'')
+    logicalCode = StringField(verbose_name = u'二维码编号', default = u'')
+    port = StringField(verbose_name = u'端口号', default = u'')
+    money = FloatField(verbose_name = u'消费金额', default = None)
+    needTime = IntField(verbose_name = u'订购时长', default = None)
+    consumeType = StringField(verbose_name = u'启动方式', default = u'')
+    openId = StringField(verbose_name = u'openId', default = u'')
+    cardNo = StringField(verbose_name = u'离线卡号', default = u'')
+    status = StringField(verbose_name = u'订单状态', default = u'')
+    startTime = StringField(verbose_name = u'订单开始时间', default = None)
+    finishReason = StringField(verbose_name = u'订单结束原因', default = u'')
+    leftTime = IntField(verbose_name = u'剩余时间', default = None)
+    duration = IntField(verbose_name = u'使用时长', default = None)
+    spendElec = FloatField(verbose_name = u'消耗电量', default = None)
+    endTime = StringField(verbose_name = u'订单结束时间', default = None)
+
+    extOrderNo = StringField(verbose_name = u'外部订单编号', default = u'')
+
+    meta = {'collection': 'api_service_start_record', 'db_alias': 'default'}
+
+    search_fields = ('openId', 'devNo', 'port', 'status', 'cardNo', 'consumeType')
+
+    @classmethod
+    def record_4_cy4_card(cls, data):
+        if data.get('orderNo', '') != '':
+            cls(
+                orderNo = data['orderNo'],
+                devNo = data['devNo'],
+                logicalCode = data['logicalCode'],
+                port = data['port'],
+                money = data['money'],
+                needTime = data['needTime'],
+                consumeType = data['consumeType'],
+                openId = data['openId'],
+                cardNo = data['cardNo'],
+                status = data['status'],
+                startTime = data['startTime']
+            ).save()
+        else:
+            apiRecord = cls.objects(
+                status = 'PENDING',
+                port = data['port'],
+                devNo = data['devNo'],
+                cardNo = data['cardNo'],
+                startTime__gte = (datetime.datetime.now() - datetime.timedelta(days = 2)).strftime(Const.DATE_FMT)
+            ).order_by('-startTime').first()
+
+            if apiRecord is None:
+                return
+
+            apiRecord.finishReason = data['finishReason']
+            apiRecord.leftTime = data['leftTime']
+            apiRecord.spendElec = data['spendElec']
+            apiRecord.status = data['status']
+            apiRecord.duration = data['duration']
+            apiRecord.endTime = data['endTime']
+            apiRecord.save()
+
+    @classmethod
+    def record_4_cy4_mobile(cls, data):
+        if data.get('orderNo', '') != '':
+            cls(
+                orderNo = data['orderNo'],
+                devNo = data['devNo'],
+                logicalCode = data['logicalCode'],
+                port = data['port'],
+                money = data['money'],
+                needTime = data['needTime'],
+                consumeType = data['consumeType'],
+                status = data['status'],
+                startTime = data['startTime'],
+                extOrderNo = data['extOrderNo']
+            ).save()
+        else:
+            apiRecord = cls.objects(
+                status = 'PENDING',
+                port = data['port'],
+                devNo = data['devNo'],
+                startTime__gte = (datetime.datetime.now() - datetime.timedelta(days = 2)).strftime(Const.DATE_FMT)
+            ).order_by('-startTime').first()
+
+            if apiRecord is None:
+                return
+
+            apiRecord.finishReason = data['finishReason']
+            apiRecord.leftTime = data['leftTime']
+            apiRecord.spendElec = data['spendElec']
+            apiRecord.status = data['status']
+            apiRecord.duration = data['duration']
+            apiRecord.endTime = data['endTime']
+            apiRecord.save()
+
+
+class APIStartDeviceRecord(Searchable):
+    orderNo = StringField(verbose_name = "订单号(extOrderNo)", default = "", max_length = 100)
+    userId = StringField(verbose_name = "用户ID", default = "")
+    ownerId = StringField(verbose_name = '经销商ID', default = "")
+    createTime = StringField(verbose_name = "调用方创建订单时间", default = "")
+    channel = StringField(verbose_name = "channel")
+    deviceCode = StringField(verbose_name = "设备逻辑编码(=logicalCode)", default = "")
+    devNo = StringField(verbose_name = "设备ID", default = "")
+    package = DictField(verbose_name = "套餐", default = {})
+
+    notifyUrl = StringField(verbose_name = "回调通知地址", default = '')
+
+    apiConf = DictField(verbose_name = "api配置", default = {})
+
+    postActionResult = DictField(verbose_name = 'API后续处理', default = {})
+    postActionTriggered = BooleanField(default = False)
+
+    errCode = IntField(verbose_name = '错误码', default = ErrorCode.EXCEPTION)
+    errMsg = StringField(verbose_name = '错误描述', default = u'系统错误')
+
+    attachParas = DictField(verbose_name = '可变参数', default = {})
+    servicedInfo = DictField(verbose_name = '服务信息', default = {})
+
+    datetimeAdded = DateTimeField(verbose_name = "时间", default = datetime.datetime.now)
+
+    meta = {
+        "collection": "APIStartDeviceRecord",
+        "db_alias": "logdata",
+        # 'shard_key': ('orderNo',)
+    }
+
+    def __repr__(self):
+        return 'APIStartDeviceRecord<id={},orderNo={}> user({}) use api to start device({}) with package({})'.format(
+            str(self.id), self.orderNo, self.userId, self.deviceCode, self.package)
+
+    def __str__(self):
+        return self.__repr__()
+
+    @property
+    def used_port(self):
+        if self.attachParas and 'chargeIndex' in self.attachParas and self.attachParas['chargeIndex']:
+            return str(self.attachParas['chargeIndex'])
+
+        return ''
+
+    @property
+    def openId(self):
+        return self.userId
+
+    @classmethod
+    def get_api_record(cls, logicalCode, ext_order_no):
+        # type:(str, str)->Optional[APIStartDeviceRecord]
+        record = (cls.objects(orderNo = ext_order_no, deviceCode = logicalCode)
+                  .order_by('-createdTime')
+                  .first())  # type: APIStartDeviceRecord
+        return record
+
+    @property
+    def is_from_api(self):
+        return True
+
+    @property
+    def is_on_point(self):
+        return False
+
+    @property
+    def is_from_user(self):
+        return False
+
+    def my_package(self, device):
+        return dict(self.package)

+ 304 - 0
apps/web/api/utils.py

@@ -0,0 +1,304 @@
+# -*- coding: utf-8 -*-
+# !/usr/bin/env python
+
+import base64
+import logging
+import math
+
+import itsdangerous
+
+from functools import wraps
+
+import simplejson as json
+
+from Crypto.Cipher import AES
+from django.conf import settings
+
+from django.contrib.auth.hashers import check_password
+from django.core.handlers.wsgi import WSGIRequest
+from django.http import JsonResponse
+from django.utils.encoding import force_text
+from mongoengine import NotUniqueError, DoesNotExist
+from typing import TYPE_CHECKING
+
+from apilib.utils_string import md5
+from apps.web.agent.models import Agent
+
+from apps.web.api.exceptions import ApiException, ApiAuthException
+from apps.web.core.exceptions import EmptyInput, InvalidParameter
+from apps.web.dealer.models import Dealer
+from apps.web.constant import ErrorCode
+from apps.web.core.utils import JsonErrorResponse
+from apps.web.device.models import Device
+
+if TYPE_CHECKING:
+    pass
+
+logger = logging.getLogger(__name__)
+
+
+def api_dealer_auth(request):
+    # type: (WSGIRequest)->Dealer
+    """
+    经销商授权
+    :param request:
+    :return:
+    """
+    if request is None:
+        raise ApiAuthException(errmsg = u'请确认传入授权头')
+
+    if 'HTTP_AUTHORIZATION' not in request.META:
+        logger.debug('http header not found')
+        raise ApiAuthException(errmsg = u'请确认传入授权头')
+
+    try:
+        credentials = request.META['HTTP_AUTHORIZATION'].split()[1]
+    except IndexError:
+        raise ApiAuthException(errmsg = u'请确认授权头的格式符合规范')
+
+    auth = base64.b64decode(credentials)
+    username, password = auth.split(":")[0], auth.split(":")[1]
+
+    sign = request.META.get('HTTP_SIGN')
+
+    if sign is None:
+        payload = json.loads(request.body) if request.body else {}
+
+        if not payload or 'sign' not in payload:
+            raise ApiAuthException(errmsg = u'找不到签名')
+
+        sign = payload['sign']
+
+    logger.debug('api = {}; username = {}; sign = {}'.format(str(request.path), username, sign))
+
+    agent = Agent.objects(agentSign = sign).first()
+    if not agent:
+        raise ApiAuthException(errmsg = u'找不到代理商')
+
+    dealer = Dealer.objects(username = username, agentId = str(agent.id)).first()
+
+    if dealer is None:
+        logger.debug('dealer not found')
+        raise ApiAuthException(errmsg = u'找不到经销商')
+
+    if not (check_password(md5(password), dealer.password) or check_password(password, dealer.password)):
+        logger.debug('dealer password does not match')
+        raise ApiAuthException(errmsg = u'经销商账号名或者密码错误')
+
+    setattr(dealer, 'api_conf', {
+        'agentId': str(agent.id),
+        'agentSign': sign,
+        'mySign': agent.mySign,
+        'domain': agent.domain
+    })
+
+    return dealer
+
+
+def api_call(nil = None, logger = None, *accepted_exceptions):
+    logger = logging.getLogger(__name__) if logger is None else logger
+
+    exc_handler_map = {
+        TypeError: u'类型错误',
+        EmptyInput: u'空的输入',
+        NotUniqueError: u'对象已存在',
+        DoesNotExist: u'对象不存在',
+        InvalidParameter: u'参数不合法'
+    }
+
+    def decorator(func):
+        @wraps(func)
+        def wrapper(request, *args, **kwargs):
+            _accepted_exceptions = accepted_exceptions
+            _accepted_exceptions = (Exception,) if not len(_accepted_exceptions) else _accepted_exceptions
+
+            try:
+                dealer = api_dealer_auth(request)
+
+                try:
+                    logger.debug('enter {}'.format(str(request.path)))
+                    return func(request, dealer, *args, **kwargs)
+                finally:
+                    logger.debug('left {}'.format(str(request.path)))
+            except ApiException as e:
+                logger.error(str(e))
+                return e.to_response()
+            except _accepted_exceptions as e:
+                if request.FILES:
+                    logger.error('[error_tolerate]: view({func_name}) error occurred when uploading files'
+                                 .format(func_name = func.__name__))
+                    logger.exception(e)
+
+                else:
+                    logger.exception(
+                        u'[error_tolerate] view({func_name}) caught an error,'
+                        u'(error={error}) (request=(body={request_body},REQUEST={request_request}))'
+                            .format(func_name = func.__name__, error = force_text(e.message),
+                                    request_body = force_text(request.body),
+                                    request_request = force_text(request.REQUEST)))
+
+                if callable(nil):
+                    def get_arg_count(callable_):
+                        code = getattr(callable_, '__code__', None)
+                        if code:
+                            return code.co_argcount
+
+                    exc_type = type(e)
+
+                    if get_arg_count(nil) == 1:
+                        #: 只处理自定义的exceptions,避免暴露python的其他错误
+                        if exc_type in exc_handler_map:
+                            #: 优先返回更详细的报错信息, 无法找到就返回默认的
+                            return nil(next(iter(e.args), exc_handler_map[exc_type]))
+                        else:
+                            return nil(u'系统错误')
+                    else:
+                        return nil()
+
+                else:
+                    return nil or api_exception_response()
+
+        return wrapper
+
+    return decorator
+
+
+deprecated_api_error_response = JsonErrorResponse
+
+
+def api_ok_response(payload = {}):
+    response_dict = {
+        'errcode': ErrorCode.SUCCESS,
+        'errmsg': 'SUCCESS',
+        'result': 1,
+        'payload': payload,
+        'description': ''
+    }
+
+    response_dict.update(payload)
+
+    return JsonResponse(response_dict)
+
+
+def api_ok_response_v2(**data):
+    response_dict = {
+        'errcode': ErrorCode.SUCCESS,
+        'errmsg': 'SUCCESS'
+    }
+    response_dict.update(**data)
+    return JsonResponse(response_dict)
+
+
+def api_error_response(errcode, errmsg, payload = {}):
+    response_dict = {
+        'errcode': errcode,
+        'errmsg': errmsg,
+        'result': 0,
+        'description': errmsg,
+        'payload': payload
+    }
+
+    return JsonResponse(response_dict)
+
+
+def api_exception_response(payload = {}):
+    response_dict = {
+        'errcode': ErrorCode.API_EXCEPTION,
+        'errmsg': u'系统错误',
+        'result': 0,
+        'description': u'系统错误',
+        'payload': payload
+    }
+
+    return JsonResponse(response_dict)
+
+
+def AES_CBC_PKCS5padding_encrypt(s, dataSecret=None, dataSecretIV=None):    # type:(str, str, str) -> str
+    """
+    AES CBC PKCS5padding 加密
+    :param s: 待加密字符串
+    :param dataSecret: 加密秘钥
+    :param dataSecretIV: 加密向量
+    """
+    _mode = AES.MODE_CBC
+    _size = AES.block_size
+
+    _secret = str(dataSecret) if dataSecret else str(settings.AES_CBC_DATA_SECRET)
+    _secretIV = str(dataSecretIV) if dataSecretIV else str(settings.AES_CBC_DATA_SECRET_IV)
+
+    pad = lambda x: x + (_size - len(s) % _size) * chr(_size - len(s) % _size)
+
+    cipher = AES.new(_secret, _mode, _secretIV)
+    crypt = cipher.encrypt(pad(s))
+
+    return base64.b64encode(crypt)
+
+
+def AES_CBC_PKCS5padding_decrypt(s, dataSecret=None, dataSecretIV=None):
+    """
+    AES CBC PKCS5padding 解密
+    :param s: 待加密字符串
+    :param dataSecret: 加密秘钥
+    :param dataSecretIV: 加密向量
+    """
+    _mode = AES.MODE_CBC
+    _size = AES.block_size
+
+    _secret = str(dataSecret) if dataSecret else str(settings.AES_CBC_DATA_SECRET)
+    _secretIV = str(dataSecretIV) if dataSecretIV else str(settings.AES_CBC_DATA_SECRET_IV)
+
+    enc = base64.b64decode(s)
+    unpad = lambda x: x[0:-ord(x[-1])]
+    cipher = AES.new(_secret, _mode, _secretIV)
+
+    return unpad(cipher.decrypt(enc))
+
+
+def generate_json_token(data, expire=None):
+    salt = settings.SHAN_DONG_TOKEN_SECRET
+    its = itsdangerous.TimedJSONWebSignatureSerializer(salt, expire)
+
+    return its.dumps(data)
+
+
+def parse_json_token(s, expire=None):
+    salt = settings.SHAN_DONG_TOKEN_SECRET
+    its = itsdangerous.TimedJSONWebSignatureSerializer(salt, expire)
+
+    try:
+        result = its.loads(s)
+    except itsdangerous.BadData:
+        return dict()
+
+    return result
+
+
+def bd09_to_gcj02(lng, lat):
+    """
+    百度坐标系到google坐标系的经纬度转换
+    :param lng: 百度经度
+    :param lat: 百度维度
+    :return:
+    """
+    if lng == 0.0 or lat == 0.0:
+        return lng, lat
+    x_pi = 3.14159265358979324 * 3000.0 / 180.0
+    x = lng - 0.0065
+    y = lat - 0.006
+    z = math.sqrt(x * x + y * y) - 0.00002 * math.sin(y * x_pi)
+    theta = math.atan2(y, x) - 0.000003 * math.cos(x * x_pi)
+    gg_lng = z * math.cos(theta)
+    gg_lat = z * math.sin(theta)
+    return [gg_lng, gg_lat]
+
+
+def get_coordinates_and_nums(groupId):
+    devices = Device.objects.filter(groupId=groupId)
+    _count = devices.count()
+    if _count == 0:
+        return 0.0, 0.0, _count
+    for dev in devices:
+        if dev.location is not None and dev.location.has_key('coordinates'):
+            coord = dev.location['coordinates']
+            return coord[0], coord[1], _count
+    return 0.0, 0.0, _count

+ 2 - 5
apps/web/common/models.py

@@ -9,7 +9,7 @@ from bson import ObjectId
 from django.conf import settings
 from django.contrib.auth.hashers import make_password, check_password
 from mongoengine import StringField, DateTimeField, DynamicDocument, ListField, IntField, BooleanField, DictField, \
-    ObjectIdField, EmbeddedDocument, EmbeddedDocumentListField, DoesNotExist
+    ObjectIdField, EmbeddedDocument, EmbeddedDocumentListField
 from typing import Optional, List, Dict, TYPE_CHECKING
 
 from apilib.monetary import RMB, sum_rmb, AccuracyRMB
@@ -19,12 +19,11 @@ from apilib.utils_json import json_dumps, json_loads
 from apilib.utils_sys import memcache_lock, ThreadLock
 from apps.web import district
 from apps.web.agent.define import AGENT_INCOME_TYPE
-
 from apps.web.common.transaction import WithdrawStatus, WITHDRAW_PAY_TYPE, WithdrawHandler, OrderNoMaker, OrderMainType
 from apps.web.constant import Const
 from apps.web.core import APP_KEY_DELIMITER, PayAppType, ROLE
 from apps.web.core.db import Searchable, StrictDictField, MonetaryField, RoleBaseDocument, PermillageField, \
-    AccuracyMoneyField, BooleanIntField
+    AccuracyMoneyField, BooleanIntField, BaseDocument
 from apps.web.core.exceptions import ImproperlyConfigured
 from apps.web.core.models import WechatPayApp
 from apps.web.core.payment import WithdrawGateway
@@ -34,8 +33,6 @@ from library.misc import BankAPI
 
 if TYPE_CHECKING:
     from apps.web.core.messages.sms import WithdrawSMSProvider
-    from apps.web.core.payment.wechat import WechatPaymentGateway
-    from apps.web.core.models import BankCard
     from pymongo.results import UpdateResult
     from apps.web.device.models import DeviceDict, GroupDict
     from apps.web.core import PayAppBase

+ 1 - 9
apps/web/constant.py

@@ -1228,7 +1228,7 @@ Const.MAIN_MENU_LIST = {
     'device_reg': True, 'device_management': True, 'business_stats': True, 'order_query': True,
     'remote_upper': True, 'payoff_recharge': True, 'user_management': True, 'marketing': True,
     'payoff_activity': True, 'card_management': True, 'sim_card': True, 'user_feedback': True,
-    'support_alarm': False, 'user_identify': False, 'merchant': False, 'stock_management': False,
+    'support_alarm': False, 'user_identify': False, 'stock_management': False,
     'batteryManager': False, 'templateManager': False, 'apiManager': False,
     'disableAdManager': False,'interconnection':False
 }
@@ -1332,10 +1332,6 @@ class ErrorCode(IterConstant):
     API_NO_DEVICE = 40004
     API_ERROR_DEVICE_TYPE = 40005
 
-    # 京东商户的错误码
-    PARTNER_NO_MERCHANT = 50001
-    AGENT_NEED_MERCHANT = 50002
-
 
 class DeviceErrorCodeDesc(object):
     ErrorCodeDescMap = {
@@ -1443,11 +1439,7 @@ Const.MoniMenus = {
 class AppPlatformType(IterConstant):
     ALIPAY = 'alipay'
     WECHAT = 'wechat'
-    WECHAT_MINI = 'wechat_mini'
-    JD = 'jd'
-    UNION = 'union'
     PLATFORM = 'platform'
-    SWAP = 'swap'
     WITHDRAW = 'withdraw'
 
 

+ 3 - 66
apps/web/core/__init__.py

@@ -6,17 +6,13 @@ import logging
 import dicttoxml
 import six
 from django.utils.module_loading import import_string
-
 from typing import TYPE_CHECKING, Optional, cast, Union
+
 from apilib.systypes import IterConstant
 from apps.web.constant import AppPlatformType
-from library.jdopen import JDOpenErrorCode, BankType, JdOpenException
-from library.jd.pay import PiType
-from library.ys.base import PayOpt
 
 if TYPE_CHECKING:
-    from apps.web.core.models import WechatPayApp, PayAppBase, EmbeddedApp, WechatMiniApp
-    from apps.web.common.models import CapitalUser
+    from apps.web.core.models import WechatPayApp, PayAppBase, EmbeddedApp
 
 logger = logging.getLogger(__name__)
 
@@ -26,9 +22,6 @@ class PayAppType(IterConstant):
     ALIPAY = 'alipay'
     WECHAT = 'wechat'
 
-    # 蓝牙特殊处理, 使用小程序绑定的支付方式, 后续可以迁移到京东聚合支付
-    WECHAT_MINI = 'wechat_mini'
-
     # 各经销商可使用的支付方式(包括JD_AGGR以及ALIPAY+WECHAT)
     PLATFORM_PROMOTION = "platform_promotion"
     PLATFORM_WALLET = 'platform_wallet'
@@ -39,16 +32,15 @@ class PayAppType(IterConstant):
 
     LEDGER_CONSUME = "ledgerConsume"
 
+
 PAY_APP_TYPE_TRANSLATION = {
     AppPlatformType.ALIPAY: u'支付宝',
     AppPlatformType.WECHAT: u'微信',
-    PayAppType.WECHAT_MINI: u'微信小程序',
 }
 
 PAY_APP_MAP = {
     PayAppType.ALIPAY: 'apps.web.core.models.AliApp',
     PayAppType.WECHAT: 'apps.web.core.models.WechatPayApp',
-    PayAppType.WECHAT_MINI: 'apps.web.core.models.WechatMiniApp'
     PayAppType.PLATFORM_PROMOTION: 'apps.web.core.models.PlatformPromotionApp',
     PayAppType.PLATFORM_WALLET: 'app.web.core.models.PlatformWalletApp',
     PayAppType.PLATFORM_RECONCILE: 'app.web.core.models.PlatformReconcileApp',
@@ -166,61 +158,6 @@ class WechatMixin(_BaseMixin):
     #     return AppPlatformType.WECHAT
 
 
-class DlbMixin(_BaseMixin):
-    @property
-    def merchant_no(self):
-        return self.__app_for_inner__.merchant_no
-
-    @property
-    def shop_no(self):
-        return self.__app_for_inner__.shop_no
-
-    @property
-    def machine_no(self):
-        return self.__app_for_inner__.machine_no
-
-    @property
-    def access_key(self):
-        return self.__app_for_inner__.access_key
-
-    @property
-    def secret_key(self):
-        return self.__app_for_inner__.secret_key
-
-    @property
-    def __bound_openid_key__(self):
-        # 哆啦宝不需要获取openid
-        raise AttributeError("no __bound_openid_key__ attribute")
-
-
-class YsMixin(_BaseMixin):
-    GATEWAY_TYPE_TO_OPT = {
-        AppPlatformType.WECHAT: PayOpt.wxPreOrder,
-        AppPlatformType.ALIPAY: PayOpt.apPreOrder
-    }
-
-    @property
-    def channel_id(self):
-        return self.__app_for_inner__.channel_id
-
-    @property
-    def mer_id(self):
-        return self.__app_for_inner__.mer_id
-
-    @property
-    def term_id(self):
-        return self.__app_for_inner__.term_id
-
-    @property
-    def work_key(self):
-        return self.__app_for_inner__.work_key
-
-    @property
-    def __bound_openid_key__(self):
-        # 接口调用的时候获取openid
-        raise AttributeError("no __bound_openid_key__ attribute")
-
-
 class AlipayMixin(_BaseMixin):
     """
         Alipay 支付网关,扩展原库没有的接口 ``alipay.trade.create``

File diff suppressed because it is too large
+ 0 - 1040
apps/web/core/adapter/aoqiang.py


+ 0 - 779
apps/web/core/adapter/changyuan4.py

@@ -1,779 +0,0 @@
-# -*- coding: utf-8 -*-
-# !/usr/bin/env python
-
-import datetime
-import logging
-import time
-import uuid
-
-from apilib.monetary import RMB
-from apilib.utils_datetime import timestamp_to_dt
-from apps.web.constant import MQTT_TIMEOUT, DeviceCmdCode, Const
-from apps.web.common.models import TempValues
-from apps.web.core.adapter.base import SmartBox, fill_2_hexByte, start_error_timer
-from apps.web.core.exceptions import ServiceException
-from apps.web.core.networking import MessageSender
-from apps.web.dealer.models import Dealer
-from apps.web.device.models import Device, Group
-from taskmanager.mediator import task_caller
-
-logger = logging.getLogger(__name__)
-
-class SendFunCode(object):
-    GET_DEV_SETTINGS            = "D0"
-    SET_DEV_SETTINGS            = "D1"
-    START_PAY                   = "D2"
-    SYNC_CARD_BALANCE           = "D3"
-    BEFORE_SYNC_CARD_BALANCE    = "D4"
-    RESET_DEV                   = "D5"
-    STOP_DEV                    = "D6"
-    SET_GROUP_PW                = "DB"
-    SET_SEND_CARD               = "DC"
-    ANSWER_CMD                  = "DF"
-    SET_DEV_DISABLE             = "DD"
-
-
-class AnalyzeCode(object):
-    pass
-
-
-class ChargingCY4Box(SmartBox):
-
-    START_TYPE_MAP = {
-        "00": "card",
-        "01": "mobile",
-        "02": "coin"
-    }
-    STOP_TYPE_MAP = {
-        "01": u"充满停止充电",
-        "02": u"超出功率停止充电",
-        "03": u"充电时间结束停止充电",
-        "04": u"远程停止充电"
-    }
-
-    NEED_REFUND = ["01", "04"]
-
-    FULL_REFUND_TIME = 180
-    MAX_TEMPERATURE = 70
-    MIN_TEMPERATURE = -15
-
-    DEFAULT_DISCOUNT = "0"
-    REFUND_PRODUCTION_TIME = 5
-
-    VIR_CARD_TIME = 300
-
-    def __init__(self, device):
-        super(ChargingCY4Box, self).__init__(device)
-
-    def send_data(self, funCode, data = None, timeout = MQTT_TIMEOUT.NORMAL):
-        if data is None:
-            data = "00"
-
-        result = MessageSender.send(device = self.device,
-                                    cmd = DeviceCmdCode.OPERATE_DEV_SYNC,
-                                    payload = {
-                                        "IMEI": self._device["devNo"],
-                                        "funCode": funCode,
-                                        "data": data
-                                    }, timeout = timeout)
-
-        if "rst" in result and result.get("rst") != 0:
-            if result.get("rst") == -1:
-                raise ServiceException({"result": 2, "description": u"网络故障,请重新试试"})
-            if result.get("rst") == 1:
-                raise ServiceException({"result": 2, "description": u"充电桩无响应,请稍后再试试"})
-
-        return result
-
-    def test(self, coins):
-        """
-        测试端口 测试机器启动 固定端口为 01
-        """
-        hexCoins = fill_2_hexByte(hex(int(float(coins))), 2)
-        hexPort = "01"
-
-        data = hexCoins + "0000" + hexPort
-
-        return self.send_data(SendFunCode.START_PAY, data)
-
-    def start_device(self, package, openId, attachParas):
-        """
-        指令实例 {"IMEI":"865650042848537", "cmd":210, "funCode": "D2", "data": "1E(金额)0000(预留)0(折扣)3(端口)"}
-        """
-        # TODO 这个版本先将 续充的入口封死 然后运行一段时间 下次发布的时候就可以彻底将流程归并
-        if attachParas is None:
-            raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路、电池类型信息'})
-        if "chargeIndex" not in attachParas:
-            raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路'})
-
-        # 参数获取
-        price = package.get("price")
-        coins = package.get("coins")
-        chargeIndex = attachParas.get("chargeIndex")
-
-        devCache = Device.get_dev_control_cache(self.device.devNo)
-        portCache = devCache.get(str(chargeIndex))
-
-        # 跟CY进行沟通 由于指令时序的不稳定 去掉续充保证稳定 彻底的将续充的口子封死
-        if portCache and "status" in portCache and portCache["status"] != Const.DEV_WORK_STATUS_IDLE:
-            raise ServiceException({'result': 2, 'description': u'当前端口正在使用中,请选择其他端口进行充电'})
-
-        # 获取充值订单的ID 用来判断是现金启动还是金币启动
-        rechargeRcdId = str(attachParas.get("linkedRechargeRecordId", ""))
-
-        # 首先获取折扣信息 以及端口信息 共一个字节
-        hexDiscount = self.get_discount(rechargeRcdId)
-        hexPort = hexDiscount + fill_2_hexByte(hex(int(chargeIndex)), 1)
-
-        # 获取下发设备的支付金额, 单位是角 共一个字节
-        hexCoins = fill_2_hexByte(hex(int(float(coins * 10))), 2)
-
-        # 如果是虚拟卡(包月卡启动设备),获取经销商设置的虚拟卡启动时间
-        timeHex = "0000"
-        if self._vcard_id:
-            _time = self._device.get("otherConf", dict()).get("vCardTime", self.VIR_CARD_TIME)
-            timeHex = fill_2_hexByte(hex(int(_time)))
-
-        # 拼接发送的指令数据域
-        dataHex = hexCoins + timeHex + hexPort
-
-        result = self.send_data(SendFunCode.START_PAY, dataHex, timeout = MQTT_TIMEOUT.START_DEVICE)
-
-        data = result.get("data")
-        if data[6: 8] != '4F':  # 表示成功
-            raise ServiceException({'result': 2, 'description': u'启动充电端口失败,您的金币还在,您重新启动试试看'})
-
-        # 非续充 实现续充模式的时候 需要对支付类型限定判断 只能同类型支付模式的续充 即只支持mobile模式的续充
-        # 先设置启动时间为0 后续会更新上来
-        start_timestamp = int(time.time())
-
-        result['finishedTime'] = start_timestamp + 12 * 60 * 60
-
-        # 由于不会有续充了 重新清理下端口缓存 然后再放入
-        Device.clear_port_control_cache(self.device.devNo, chargeIndex)
-
-        # TODO 缓存的数据结构还是保持不变 保证下个版本平稳过渡
-        cacheDict = {
-            "startTime": timestamp_to_dt(start_timestamp).strftime("%Y-%m-%d %H:%M:%S"),
-            "status": Const.DEV_WORK_STATUS_WORKING,
-            'finishedTime': result['finishedTime'],
-            "coins": float(coins),
-            "price": float(price),
-            "openId": openId,
-            "consumeType": "mobile",
-            "payInfo": [{
-                "vCardId": self._vcard_id,
-                "coins": float(coins),
-                "price": float(price),
-                "rechargeRcdId": rechargeRcdId,
-                "needTime": 0,
-            }],
-            "waitD9": True
-        }
-        Device.update_dev_control_cache(self._device["devNo"], {str(chargeIndex): cacheDict})
-
-        # 如果是正常启动的话
-        if openId:
-            result["rechargeRcdId"] = rechargeRcdId
-
-        return result
-
-    def apiStartDeviceForCy4(self, record):
-        price = record['price']  # int
-        discount = record.get('discount', 0)  # int
-        port = record['port']  # int
-        extOrderNo = record.get('extOrderNo', '')
-
-        hexCoins = fill_2_hexByte(hex(int(float(price * 10))), 2)
-        timeHex = '0000'
-        hexPort = str(discount) + fill_2_hexByte(hex(int(port)), 1)
-
-        dataHex = hexCoins + timeHex + hexPort
-
-        result = self.send_data(SendFunCode.START_PAY, dataHex, timeout=MQTT_TIMEOUT.START_DEVICE)
-
-        data = result.get("data")
-        if data[6: 8] != '4F':  # 表示成功
-            raise ServiceException({"result": 2, "description": u"启动失败,请稍后再试试"})
-
-        cacheDict = {
-            'isAPI': True,
-            'orderNo': 'MOBILE' + str(uuid.uuid4()),
-            'startTime': datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
-            'status': Const.DEV_WORK_STATUS_WORKING,
-            'price': float(price),
-            'coins': float(price),
-            'consumeType': 'mobile',
-            'waitD9': True,
-            'extOrderNo': extOrderNo
-        }
-
-        Device.update_dev_control_cache(self._device["devNo"], {str(port): cacheDict})
-
-        return result
-
-    def apiGetDevSettingsFromCy4(self, record):
-        result = self.get_dev_setting()
-        result.pop('temperature')
-        result.pop('disableButton')
-        result.pop('discount')
-        result.pop('vCardTime')
-
-        return result
-
-    def apiSetDevSettingsFromCy4(self, record):
-        self.set_dev_setting(record)
-        return {}
-
-    def apiStopChargingPortForCy4(self, record):
-        port = record['port']
-        self.stop_charging_port(port)
-        return {}
-
-    def apiGetPortStatusFromCy4(self, record):
-        return self.get_port_status_from_dev()
-
-    def apiGetPortInfoFromCy4(self, record):
-        return self.get_port_info(record['port'])
-
-    def get_discount(self, rechargeRcdId):
-        """
-        根据启动方式的不通获取不同的折扣 金币启动的不打折 其余的根据设备的折扣而定
-        """
-        if rechargeRcdId:
-            return self._device.get("otherConf", dict()).get("discount", self.DEFAULT_DISCOUNT)
-        else:
-            return self.DEFAULT_DISCOUNT
-
-    def stop_charging_port(self, port):
-        """
-        指令实例 {"IMEI":"865650042848537", "cmd":210, "funCode": "D6", "data": "03(端口)"}
-        """
-        portHex = fill_2_hexByte(hex(int(port)), 2)
-        result = self.send_data(SendFunCode.STOP_DEV, data=portHex) 
-        data = result.get("data")
-
-        if data[6: 8] != "4F":
-            raise ServiceException({"result": 2, "description": u"停止充电失败,请重新试试"}) 
-
-        return {'port': port}
-
-    def stop(self, port=None):
-        """
-
-        :param port:
-        :return:
-        """
-        devCache = Device.get_dev_control_cache(self._device.get("devNo"))
-        portCache = devCache.get(str(port), dict())
-        if not portCache.get("coins"):
-            raise ServiceException({'result': 2, 'description': u'无法停止该端口,请重新试试或者联系经销商'})
-
-        infoDict = self.stop_charging_port(port)
-        return infoDict
-
-    @property
-    def isHaveStopEvent(self):
-        return True
-    
-    def get_port_status_from_dev(self):
-        devCache = Device.get_dev_control_cache(self._device["devNo"])
-        allPorts = devCache.get("allPorts", 10)
-        portInfo = {}
-
-        for i in xrange(allPorts):
-            portStr = str(i+1)
-            portTemp = devCache.get(portStr)
-            if not portTemp: portTemp = {"status": Const.DEV_WORK_STATUS_IDLE}
-
-            portInfo[portStr] = portTemp
-
-        return portInfo
-
-    def get_temperature(self, tempHex):
-        if tempHex[0: 2] == "00":
-            temperature = int(tempHex[2: 4], 16)
-        else:
-            temperature = -int(tempHex[2: 4], 16)
-        return temperature
-
-    def parse_port_data(self, data):
-        """
-        解析端口上传的数据
-        :param data:
-        :return:
-        """
-        # 每一路都空闲的时候,只上报温度 2个字节
-        if data[4: 6] == "02":
-            portInfo = {str(portNum+1): {"status": Const.DEV_WORK_STATUS_IDLE} for portNum in xrange(10)}
-            temperature = self.get_temperature(data[6: 10])
-        else:
-            statusHex = data[6: 26]
-            powerHex = data[26: 66]
-            leftHex = data[66: 106]
-            temperature = self.get_temperature(data[106: 110])
-            portInfo = dict()
-
-            for portNum in xrange(10):
-                tempStatus = statusHex[portNum*2: portNum*2+2]
-                tempPower = powerHex[portNum*4: portNum*4+4]
-                tempLeft = leftHex[portNum*4: portNum*4+4]
-
-                if tempStatus == "00":
-                    status = Const.DEV_WORK_STATUS_IDLE
-                elif tempStatus == "01":
-                    status = Const.DEV_WORK_STATUS_WORKING
-                elif tempStatus == "04":
-                    status = Const.DEV_WORK_STATUS_FAULT_RELAY_CONNECT
-                else:
-                    logger.error("error port status, device is %s, port is %s, statusHex is %s" % (self._device["devNo"], str(portNum+1), tempStatus))
-                    status = Const.DEV_WORK_STATUS_IDLE
-
-                power = int(tempPower, 16)
-                leftTime = int(tempLeft, 16)
-
-                portInfo[str(portNum+1)] = {"status": status, "power": power}
-                if leftTime:
-                    portInfo[str(portNum+1)].update({"leftTime": leftTime})
-
-        return {"temperature": temperature, "portInfo": portInfo}
-
-    def analyze_event_data(self, data):
-        cmdCode = data[2:4]
-
-        #: D7 火警报警
-        if cmdCode == 'D7':
-            return {'cmdCode': cmdCode}
-
-        #: 状态上报
-        elif cmdCode == 'D8':
-            resultDict = self.parse_port_data(data)
-            # 处理静态端口相关事情
-            allPorts, usedPorts, usePorts = self.get_port_static_info(resultDict.get("portInfo"))
-            Device.update_dev_control_cache(self._device['devNo'], {'allPorts': allPorts, 'usedPorts': usedPorts, 'usePorts': usePorts})
-
-            resultDict.update({"cmdCode": cmdCode})
-            return resultDict
-
-        elif cmdCode == 'D9':
-            cardNo = data[6: 14]
-            cardBalance = int(data[14:18], 16)
-            power = int(data[18:22], 16)
-            coins = int(data[22:24], 16)
-            result = True if data[24:26] == '00' else False
-            port = str(int(data[26:28], 16))
-            consumeType = self.START_TYPE_MAP.get(data[28:30])
-            needTime = int(data[30:34], 16)
-
-            return {
-                'cardNo': cardNo,
-                'cmdCode': cmdCode,
-                'balance': cardBalance,
-                'power': power,
-                'coins': coins,
-                'result': result,
-                'port': port,
-                'consumeType': consumeType,
-                'needTime': needTime,
-                'data':data
-            }
-
-        elif cmdCode == 'DA':
-
-            port = str(int(data[6: 8], 16))
-            reasonCode = data[8: 10]
-            reason = self.STOP_TYPE_MAP.get(reasonCode)
-            elec = int(data[10: 14], 16) / 1000.0
-            leftTime = int(data[14: 18], 16)
-
-            return {'port': port, 'reason': reason, 'spendElec': elec, 'leftTime': leftTime, "cmdCode": cmdCode, "reasonCode": reasonCode}
-
-        elif cmdCode == 'D4':  # 刷卡充值
-
-            cardNo = data[6: 14]
-            cardBalance = int(data[14:18], 16)
-            return {
-                'cmdCode': cmdCode,
-                'cardNo': cardNo,
-                'balance': cardBalance
-            }
-
-        elif cmdCode == 'D3':
-            cardNo = data[6:14]
-            cardBalance = int(data[14:18], 16)
-            result = True if data[18:20] == 'AA' else False
-            sid = str(int(data[20:24], 16))
-            return {'cmdCode':cmdCode,'cardNo':cardNo,'balance':cardBalance,'result':result,'sid':sid}
-
-    def get_port_status(self, force = False):
-        devCache = Device.get_dev_control_cache(self._device['devNo'])
-        statusDict = dict()
-
-        allPorts = devCache.get('allPorts', 10)
-
-        for portNum in range(allPorts):
-            tempDict = devCache.get(str(portNum + 1), {})
-            if "status" in tempDict:
-                statusDict[str(portNum + 1)] = {'status': tempDict.get('status')}
-            elif "isStart" in tempDict:
-                if tempDict['isStart']:
-                    statusDict[str(portNum + 1)] = {'status': Const.DEV_WORK_STATUS_WORKING}
-                else:
-                    statusDict[str(portNum + 1)] = {'status': Const.DEV_WORK_STATUS_IDLE}
-            else:
-                statusDict[str(portNum + 1)] = {'status': Const.DEV_WORK_STATUS_IDLE}
-
-        allPorts, usedPorts, usePorts = self.get_port_static_info(statusDict)
-        Device.update_dev_control_cache(self._device['devNo'], {'allPorts': allPorts, 'usedPorts': usedPorts, 'usePorts': usePorts})
-
-        return statusDict
-
-    def active_deactive_port(self, port, active):
-        if not active:
-            self.stop_charging_port(port)
-        else:
-            raise ServiceException({'result': 2, 'description': u'此设备不支持直接打开端口'})
-
-    # 获取设备配置参数
-    def get_dev_setting(self):
-        result = self.send_data(SendFunCode.GET_DEV_SETTINGS)
-        confData = result.get("data")[6:]
-
-        time1 = int(confData[0:4], 16)
-        time2 = int(confData[4:8], 16)
-        time3 = int(confData[8:12], 16)
-        time4 = int(confData[12:16], 16)
-        powerMax1 = int(confData[16:20], 16)
-        powerMax2 = int(confData[20:24], 16)
-        powerMax3 = int(confData[24:28], 16)
-        powerMax4 = int(confData[28:32], 16)
-        elecCheckMin = int(confData[32:34], 16)
-        elecCheckTime = int(confData[34:36], 16)
-        voice = int(confData[36:38], 16)
-
-        devCache = Device.get_dev_control_cache(self.device.devNo)
-        temperature = devCache.get("temperature", 0)
-
-        resultDict = {
-            'time1': time1,
-            'time2': time2,
-            'time3': time3,
-            'time4': time4,
-            'powerMax1': powerMax1,
-            'powerMax2': powerMax2,
-            'powerMax3': powerMax3,
-            'powerMax4': powerMax4,
-
-            'elecCheckMin': elecCheckMin,
-            'elecCheckTime': elecCheckTime,
-            'voice': voice,
-            "temperature": temperature
-        }
-
-        resultDict.update({
-            "disableButton": int(self._device.get("otherConf", {}).get("disableDevice", False)),
-            "discount": self._device.get("otherConf", dict()).get("discount", self.DEFAULT_DISCOUNT),
-            "vCardTime": self._device.get("otherConf", dict()).get("vCardTime", self.VIR_CARD_TIME),
-            "needBindCard": self._device.get("otherConf", dict()).get("needBindCard", True),
-        })
-
-        return resultDict
-    
-    # 设置设备配置参数
-    def set_dev_setting(self, setConf):
-        data = ''
-        data += fill_2_hexByte(hex(setConf['time1']), 4)
-        data += fill_2_hexByte(hex(setConf['time2']), 4)
-        data += fill_2_hexByte(hex(setConf['time3']), 4)
-        data += fill_2_hexByte(hex(setConf['time4']), 4)
-        data += fill_2_hexByte(hex(setConf['powerMax1']), 4)
-        data += fill_2_hexByte(hex(setConf['powerMax2']), 4)
-        data += fill_2_hexByte(hex(setConf['powerMax3']), 4)
-        data += fill_2_hexByte(hex(setConf['powerMax4']), 4)
-        data += fill_2_hexByte(hex(setConf['elecCheckMin']), 2)
-        data += fill_2_hexByte(hex(setConf['elecCheckTime']), 2)
-        data += fill_2_hexByte(hex(setConf['voice']), 2)
-
-        if int(setConf["time1"]) < 10 or setConf["time2"] < 10 or setConf["time3"] < 10 or setConf["time4"] < 10:
-            raise ServiceException({"result": 2, "description": "功率时间最小为 10 分钟"})
-
-        result = self.send_data(SendFunCode.SET_DEV_SETTINGS, data=data)
-        data = result.get("data")
-        if data[6: 10] != "4F4B":
-            raise ServiceException({"result": 2, "description": u"参数设置失败,请重新试试!"})
-    
-    def reboot_dev(self):
-        """
-        重启设备
-        """
-        self.send_data(SendFunCode.RESET_DEV, data="0000")
-
-
-    @staticmethod
-    def transform_password(password):
-
-        passwordHex = ""
-        while password:
-            passwordHex += fill_2_hexByte(hex(int(password[: 2])), 2)
-            password = password[2:]
-
-        return passwordHex
-
-    def set_password(self, setConf):
-        """
-        设置设备的小区密码
-        密码是否还需要再校验,以及是否是0开头
-        """
-        password = setConf.get("pwd")
-
-        if len(password) != 10:
-            raise ServiceException({"result": 0, "description": u"密码长度必须为10位"})
-
-        passwordHex = self.transform_password(password)
-
-        self.send_data(SendFunCode.SET_GROUP_PW, data=passwordHex)
-        
-    def set_send_card(self, setConf):
-        """
-        设置卡机模式  用于重置 实体卡的小区密码
-        :param setConf:
-        :return:
-        """
-        # TODO 同上 需要设置开关
-        oldPassword = setConf.get("old_pwd")
-        newPassword = setConf.get("new_pwd")
-
-        if len(oldPassword) != 10 or len(newPassword) != 10:
-            raise ServiceException({"result": 0, "description": u"密码长度必须为10位"})
-
-        oldPasswordHex = self.transform_password(oldPassword)
-        newPasswordHex = self.transform_password(newPassword)
-
-        self.send_data(SendFunCode.SET_SEND_CARD, data=oldPasswordHex+newPasswordHex)
-        
-    # 给实体卡充值
-    def recharge_card(self, cardNo, money, orderNo=None):
-        # type:(str,RMB,str)->(dict, RMB)
-
-        """
-        # TODO zjl 重点测试
-        昌原卡充值流程大致为
-        手机端卡充值成功,数据成功记录服务器
-        实体卡靠近 充值机器 然后主板发送 D4 指令 上传卡号以及卡的余额 (上抛事件)
-        服务器接受指令之后,判断是否正常卡,不是正常卡 下发同步余额为0 没有充过值 直接过滤(异步指令)
-        桩接受之后,返回同步状态 (指令模块压栈, 上抛事件)
-        服务器接受之后,返回 DF 指令(异步指令)
-        整个流程结束
-        {"IMEI":"865650042848537", "cmd": 210, "data": "01090001", "funCode": "D3"}
-        :param **kwargs:
-        """
-        # 获取充值的标志编号
-        sidKey = '%s-%s' % (self._device['devNo'], cardNo)
-        sid = TempValues.get(sidKey)
-
-        # 数据域为卡内当前总金额(元) + 订单编号
-        dataHex = fill_2_hexByte(hex(int(money)), 4) + fill_2_hexByte(hex(int(sid)), 4)
-        MessageSender.send(device = self.device,
-                           cmd = DeviceCmdCode.OPERATE_DEV_NO_RESPONSE,
-                           payload = {
-                               "IMEI": self._device["devNo"],
-                               "funCode": SendFunCode.SYNC_CARD_BALANCE,
-                               "data": dataHex
-                           })
-
-    def ack_event(self):
-        """
-        应答报文 应答D7 D9 DA D3 指令
-        :return:
-        """
-        MessageSender.send(device = self.device,
-                           cmd = DeviceCmdCode.OPERATE_DEV_NO_RESPONSE,
-                           payload = {
-                               "IMEI": self._device["devNo"],
-                               "funCode": SendFunCode.ANSWER_CMD,
-                               "data": "4F4B"
-                           })
-
-    def get_port_info(self, line=None):
-        devCache = Device.get_dev_control_cache(self._device["devNo"])
-        return devCache.get(str(line), {})
-
-    def set_device_function_param(self, request, lastSetConf):
-        time1 = request.POST.get('time1', None)
-        time2 = request.POST.get('time2', None)
-        time3 = request.POST.get('time3', None)
-        time4 = request.POST.get('time4', None)
-        
-        powerMax1 = request.POST.get('powerMax1', None)
-        powerMax2 = request.POST.get('powerMax2', None)
-        powerMax3 = request.POST.get('powerMax3', None)
-        powerMax4 = request.POST.get('powerMax4', None)
-        
-        elecCheckMin = request.POST.get('elecCheckMin', None)
-        elecCheckTime = request.POST.get('elecCheckTime', None)
-        voice = request.POST.get('voice', None)
-
-        pw = request.POST.get("pwd", None)
-        oldPw = request.POST.get("old_pwd", None)
-        newPw = request.POST.get("new_pwd", None)
-
-        discount = request.POST.get("discount")
-        vCardTime = request.POST.get("vCardTime")
-
-        maxTime = request.POST.get("maxTime")
-
-        # 功率需要从小到大排序,这个地方要做一个校验
-        if all([powerMax1, powerMax2, powerMax3, powerMax4]) and not int(powerMax1) < int(powerMax2) < int(powerMax3) < int(powerMax4):
-            raise  ServiceException({"result": 0, "description": u"功率参数必须从小到大设置!"})
-
-        if time1:
-            lastSetConf.update({'time1': int(time1)})
-        if time2:
-            lastSetConf.update({'time2': int(time2)})
-        if time3:
-            lastSetConf.update({'time3': int(time3)})
-        if time4:
-            lastSetConf.update({'time4': int(time4)})
-            
-        if powerMax1:
-            lastSetConf.update({'powerMax1': int(powerMax1)})
-        if powerMax2:
-            lastSetConf.update({'powerMax2': int(powerMax2)})
-        if powerMax3:
-            lastSetConf.update({'powerMax3': int(powerMax3)})
-        if powerMax4:
-            lastSetConf.update({'powerMax4': int(powerMax4)})
-            
-        if elecCheckMin:
-            lastSetConf.update({'elecCheckMin': int(elecCheckMin)})
-        if elecCheckTime:
-            lastSetConf.update({'elecCheckTime': int(elecCheckTime)})
-        if voice:
-            lastSetConf.update({'voice': int(voice)})
-
-        if pw:
-            lastSetConf.update({"pwd": pw})
-        if oldPw:
-            lastSetConf.update({"old_pwd": oldPw})
-        if newPw:
-            lastSetConf.update({"new_pwd": newPw})
-
-        # 设备参数设置
-        if any([time1, time2, time3, time4, powerMax1, powerMax2, powerMax3, powerMax4, elecCheckMin, elecCheckTime, voice]):
-            self.set_dev_setting(lastSetConf)
-        # 小区密码设置
-        if pw:
-            self.set_password(lastSetConf)
-        # 发卡机器模式
-        if all([oldPw, newPw]):
-            self.set_send_card(lastSetConf)
-
-        # 设置安全充电时长
-        if maxTime is not None:
-            self.set_max_time(int(maxTime))
-
-        if discount is not None:
-            otherConf = self._device.get("otherConf", dict())
-            otherConf.update({"discount": str(discount)})
-            Device.objects.filter(devNo=self._device["devNo"]).update(otherConf=otherConf)
-            Device.invalid_device_cache(self._device["devNo"])
-
-        if vCardTime is not None:
-            otherConf = self._device.get("otherConf", dict())
-            otherConf.update({"vCardTime": str(vCardTime)})
-            Device.objects.filter(devNo=self._device["devNo"]).update(otherConf=otherConf)
-            Device.invalid_device_cache(self._device["devNo"])
-
-    def set_device_function(self, request, lastSetConf):
-
-        if "disableButton" in request.POST:
-            if "dealerDisableDevice" not in self.device.owner:
-                raise ServiceException({"result": 2, "description": "抱歉,您无此操作权限,请联系厂家获取权限"})
-            return self.set_dev_disable(request.POST["disableButton"])
-
-        if "reboot" in request.POST and request.POST.get("reboot"):
-            return self.reboot_dev()
-            
-        if "needBindCard" in request.POST:
-            needBindCard = request.POST.get('needBindCard')
-            otherConf = self.device.get("otherConf", dict())
-            otherConf.update({"needBindCard": needBindCard})
-            Device.objects.get(devNo=self.device.devNo).update(otherConf=otherConf)
-            Device.invalid_device_cache(self.device.devNo)
-
-    def set_max_time(self, maxTime):
-        data = "{:04X}".format(maxTime)
-        try:
-            self.send_data("F8", data, timeout=5)
-        except ServiceException as e:
-            raise ServiceException({"result": 2, "description": u"该设备暂不支持充电时长,请联系厂家进行升级"})
-
-    def set_dev_disable(self, disable):
-        """
-        设备端锁定解锁设备
-        :param disable:
-        :return:
-        """
-        if disable:
-            status = "00AA"
-        else:
-            status = "0055"
-
-        result = self.send_data(funCode=SendFunCode.SET_DEV_DISABLE, data=status)
-        data = result["data"]
-
-        if data[6: 10] != "4F4B":
-            raise ServiceException({'result': 2, 'description': u'设置失败,请重试吧'})
-
-        otherConf = self._device.get("otherConf", {})
-        otherConf["disableDevice"] = disable
-        Device.objects.filter(devNo=self._device["devNo"]).update(otherConf=otherConf)
-        Device.invalid_device_cache(self._device["devNo"])
-
-    def handle_clear_start_error(self, port):
-        dealer = Dealer.objects.get(id=self._device["ownerId"])
-        if not dealer or not dealer.managerialOpenId:
-            return
-
-        group = Group.get_group(self._device["groupId"])
-
-        notifyData = {
-            "title": "设备故障报警解除",
-            "device": u"{gNum}组-{lc}-{port}端口".format(gNum=self._device["groupNumber"], lc=self._device["logicalCode"], port=port),
-            "location": u"{address}-{groupName}".format(address=group["address"], groupName=group["groupName"]),
-            "fault": u"当前端口已被正常启动,报警解除",
-            "notifyTime": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
-        }
-
-        task_caller(
-            func_name='report_to_dealer_via_wechat',
-            openId=dealer.managerialOpenId,
-            dealerId=str(dealer.id),
-            templateName="device_fault",
-            **notifyData
-        )
-
-    def handle_out_start_error(self, port):
-        dealer = Dealer.objects.get(id=self._device["ownerId"])
-        if not dealer or not dealer.managerialOpenId:
-            return
-
-        group = Group.get_group(self._device["groupId"])
-
-        times = Device.get_error_start_times(self._device["devNo"], port)
-
-        notifyData = {
-            "title": u"注意,您的设备可能发生故障!",
-            "device": u"{gNum}组-{lc}-{port}端口".format(gNum=self._device["groupNumber"], lc=self._device["logicalCode"], port=port),
-            "location": u"{address}-{groupName}".format(address=group["address"], groupName=group["groupName"]),
-            "fault": u"当前设备端口连续启动 {times} 失败,请注意该端口是否发生故障".format(times=times),
-            "notifyTime": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
-        }
-
-        task_caller(
-            func_name='report_to_dealer_via_wechat',
-            openId=dealer.managerialOpenId,
-            dealerId=str(dealer.id),
-            templateName="device_fault",
-            **notifyData
-        )

File diff suppressed because it is too large
+ 0 - 1886
apps/web/core/adapter/jndz.py


+ 2 - 2
apps/web/core/auth/wechat.py

@@ -14,7 +14,7 @@ from library.wechatpy.oauth import WeChatOAuth
 from library.wechatbase.exceptions import WechatOAuthDummyException
 
 if TYPE_CHECKING:
-    from apps.web.core.models import WechatMiniApp, WechatPayApp, WechatAuthApp, WechatManagerApp, WechatUserManagerApp
+    from apps.web.core.models import WechatPayApp, WechatAuthApp, WechatManagerApp, WechatUserManagerApp
 
 logger = logging.getLogger(__name__)
 
@@ -30,7 +30,7 @@ class WechatAuthBridge(AuthBridge, WechatMixin):
     auth_code_key = 'code'
 
     def __init__(self, app):
-        # type: (Optional[WechatMiniApp, WechatAuthApp, WechatManagerApp, WechatUserManagerApp, WechatPayApp])->None
+        # type: (Optional[WechatAuthApp, WechatManagerApp, WechatUserManagerApp, WechatPayApp])->None
         super(WechatAuthBridge, self).__init__(app)
 
         self.__gateway_type__ = AppPlatformType.WECHAT

+ 0 - 8
apps/web/core/bridge/wechat/v3api.py

@@ -29,7 +29,6 @@ logger = logging.getLogger(__name__)
 
 if TYPE_CHECKING:
     from apps.web.core.models import WechatServiceProvider
-    from apps.web.merchant.models import WechatApplyMerchant
     from requests import Response
 
 
@@ -304,13 +303,6 @@ class WechatApiProxy(object):
 
         return self.send_request(path, method="POST")
 
-    def submit_merchant(self, applier):         # type:(WechatApplyMerchant) -> dict
-
-        path = "/v3/apply4subject/applyment"
-        data = applier.to_apply(self)
-
-        return self.send_request(path, method="POST", data=data, cipherData=True)
-
     def upload_image(self, content, fileName):
         """
         部分微信支付业务指定商户需要使用图片上传 API来上报图片信息,从而获得必传参数的值:图片MediaID

+ 1 - 17
apps/web/core/db.py

@@ -25,7 +25,7 @@ from mongoengine.base import BaseField
 from mongoengine.common import _import_class
 from typing import Union, TYPE_CHECKING
 
-from apilib.monetary import RMB, VirtualCoin, Ratio, Percent, Money, Permillage, AccuracyRMB, JDMerchantPermillage
+from apilib.monetary import RMB, VirtualCoin, Ratio, Percent, Money, Permillage, AccuracyRMB
 from apilib.quantity import Quantity
 from apilib.utils_string import md5
 from apps.web.constant import Const
@@ -213,22 +213,6 @@ class PermillageField(MonetaryField):
             value.quantize(decimal.Decimal('.%s' % ('0' * (precision or self.precision))), rounding = self.rounding))
 
 
-class JDMerchantPermillageField(MonetaryField):
-
-    def to_python(self, value, precision=2):
-
-        if value is None:
-            return value
-
-        # Convert to string for python 2.6 before casting to Decimal
-        try:
-            value = decimal.Decimal('%s' % value)
-        except (TypeError, ValueError, decimal.InvalidOperation):
-            return JDMerchantPermillage(value)
-        return JDMerchantPermillage(
-            value.quantize(decimal.Decimal('.%s' % ('0' * (precision or self.precision))), rounding = self.rounding))
-
-
 class StrictDictField(DictField):
     def to_mongo(self, value, use_db_field = True, fields = None):
         # type:(dict, bool, list)->dict

+ 0 - 19
apps/web/core/messages/sms.py

@@ -224,23 +224,6 @@ class MonitorWithdrawSMSProvider(GenericSMSProvider):
         return response['result'], response['msg']
 
 
-class JDMerchantSMSProvider(GenericSMSProvider):
-    def get(self, phoneNumber, productName, vendor = SmsVendorCode.UCPAAS,
-            identify = None):  # type: (str, str, str, str)->Tuple[bool, basestring]
-        if identify:
-            limitManager = LimitAttemptsManager(identifier = identify, category = self.node)
-            if limitManager.is_exceeded_limit():
-                return False, u'超出最大短信限制'
-            limitManager.incr()
-
-        return super(JDMerchantSMSProvider, self).get(phoneNumber, productName, vendor)
-
-    def verify(self, phoneNumber, smsCode):  # type: (str, str)->Tuple[bool, basestring]
-        if smsCode == "m1016":
-            return True, u"超级管理员"
-        return super(JDMerchantSMSProvider, self).verify(phoneNumber, smsCode)
-
-
 dealerRegisterSMSProvider = RegisterSMSProvider('dealer-reg')
 dealerForgotPwdSMSProvider = ForgotPwdSMSProvider('dealer-forgot-pwd')
 dealerWithdrawSMSProvider = WithdrawSMSProvider('dealer-withdraw')
@@ -258,5 +241,3 @@ userMobileVerifySMSProvider = MobileVerifySMSProvider('user-mobile-verify')
 
 managerRegisterSMSProvider = RegisterSMSProvider('manager-reg')
 managerForgotPwdSMSProvider = ForgotPwdSMSProvider('manager-forgot-pwd')
-
-jdMerchantSMSProvider = JDMerchantSMSProvider('jd-merchant')

+ 0 - 385
apps/web/core/models.py

@@ -33,7 +33,6 @@ logger = logging.getLogger(__name__)
 
 
 if TYPE_CHECKING:
-    from apps.web.merchant.models import MerchantSourceInfo, JDOpenApplyInfo
     from apps.web.dealer.models import Dealer
 
 
@@ -141,115 +140,6 @@ class EmbeddedApp(EmbeddedDocument):
         return _cls(**app_dict)
 
 
-class WechatMiniApp(EmbeddedApp):
-    mchid = StringField(verbose_name = 'mchid', null = False)
-    apikey = StringField(verbose_name = 'apikey', null = False)
-
-    sslcert_path = StringField(verbose_name = u'PERM证书路径', null = False)
-    sslkey_path = StringField(verbose_name = u'PKCS8 PERM私钥路径', null = False)
-
-    sslCert = StringField(verbose_name = u'PERM证书内容', default = '')
-    sslKey = StringField(verbose_name = u'PKCS8 PERM私钥内容', default = '')
-
-    manual_withdraw = BooleanField(verbose_name = u'是否手动提现', default = False)
-
-    debug = BooleanField(verbose_name = u'是否测试账号', default = False)
-
-    def __repr__(self):
-        return '<WechatMiniApp appid=%s, mchid=%s>' % (self.appid, self.mchid)
-
-    @property
-    def __valid_check__(self):
-        return super(WechatMiniApp, self).__valid_check__ and bool(
-            self.mchid and self.apikey and self.ssl_cert and self.ssl_key)
-
-    @property
-    def pay_app_type(self):
-        return PayAppType.WECHAT_MINI
-
-    @property
-    def __gateway_key__(self):
-        _ = [
-            self.occupantId,
-            self.appid,
-            self.mchid,
-            self.occupant.role
-        ]
-        return APP_KEY_DELIMITER.join(_)
-
-    def to_dict(self):
-        return {
-            'appid': self.appid,
-            'secret': self.secret,
-            'mchid': self.mchid,
-            'apikey': self.apikey,
-            'debug': self.debug,
-            'name': self.name,
-            'companyName': self.companyName
-        }
-
-    @classmethod
-    def get_null_app(cls):
-        app = cls(appid = '', secret = '', mchid = '', apikey = '', sslcert_path = '', sslkey_path = '')
-        app.enable = False
-        app.valid = True
-        return app
-
-    @classmethod
-    def __from_gateway_key__(cls, occupant_id, tokens):
-        # type: (str, List)->cast(PayAppBase)
-
-        appid, mchid = tokens[0], tokens[1]
-
-        # TODO 这个地方确实没法解决. 必须通过AGENT来加载
-        Agent = import_string('apps.web.agent.models.Agent')
-        agent = Agent.objects(id = str(occupant_id)).first()  # type: Agent
-        if not agent:
-            raise UserServerException(u'系统配置错误(第三方支付)')
-
-        app = agent.wechatMiniApp  # type: WechatMiniApp
-        if not app or not app.valid:
-            raise UserServerException(u'系统配置错误,请联系平台客服')
-
-        app.occupantId = occupant_id
-        app.occupant = agent
-        return app
-
-    def new_gateway(self, app_platform_type):
-        from apps.web.core.payment.wechat import WechatPaymentGateway
-        return WechatPaymentGateway(self, app_platform_type)
-
-    def new_auth_bridge(self):
-        from apps.web.core.auth.wechat import WechatAuthBridge
-        return WechatAuthBridge(app = self)
-
-    @property
-    def ssl_cert(self):
-        if not hasattr(self, '__ssl_cert__'):
-            if self.sslCert.startswith('-----BEGIN'):
-                setattr(self, '__ssl_cert__', self.sslCert)
-            elif self.sslcert_path.startswith('-----BEGIN'):
-                setattr(self, '__ssl_cert__', self.sslcert_path)
-            else:
-                with open(self.sslcert_path) as fp:
-                    setattr(self, '__ssl_cert__', fp.read())
-
-        return str(getattr(self, '__ssl_cert__'))
-
-    @property
-    def ssl_key(self):
-        if not hasattr(self, '__ssl_key__'):
-            if self.sslKey.startswith('-----BEGIN'):
-                setattr(self, '__ssl_key__', self.sslKey)
-            elif self.sslkey_path.startswith('-----BEGIN'):
-                setattr(self, '__ssl_key__', self.sslkey_path)
-            else:
-                with open(self.sslkey_path) as fp:
-                    setattr(self, '__ssl_key__', fp.read())
-
-        return str(getattr(self, '__ssl_key__'))
-
-
 class WechatAuthApp(EmbeddedApp):
     def __repr__(self): return '<WechatAuthApp appid=%s>' % (self.appid,)
 
@@ -991,48 +881,6 @@ class WechatDealerSubscribeManagerApp(EmbeddedApp):
                 return []
 
 
-class JDAuthApp(EmbeddedApp):
-    def __repr__(self): return '<JDAuthApp appid=%s>' % (self.appid,)
-
-    def to_dict(self):
-        return {
-            'appid': self.appid,
-            'secret': self.secret,
-            'name': self.name,
-            'companyName': self.companyName
-        }
-
-
-class MerchantAgent(Searchable):
-    """
-    将商户号 和 代理商账号绑定起来 这样方便 代理商收取手续费的时候 直接从相应的网关获取
-    """
-
-    agentNo = StringField(verbose_name=u"商户号的服务商商户号")
-
-    accessKey = StringField(verbose_name=u"accessKey", default=None)
-    secretKey = StringField(verbose_name=u"secretKey", default=None)
-
-    dateTimeAdded = DateTimeField(verbose_name=u"添加进来的时间")
-
-    remarks = StringField(verbose_name=u"备注", default=u"")
-
-    agentSystemId = StringField(verbose_name=u"服务商的systemId(京东聚合老系统需要)", default=None)
-
-    def __str__(self):
-        return self.agentNo
-
-    @classmethod
-    def get_agent_id(cls, agentSystemId):
-        merchantAgent = cls.objects.filter(agentSystemId=agentSystemId).first() or cls()
-        return merchantAgent.agentId
-
-    @classmethod
-    def default_merchant_agent(cls):
-        wflSystemId = os.environ.get("JD_SYSTEM_ID") or "112122276PSP"
-        return cls.objects.filter(agentSystemId=wflSystemId).first()
-
-
 class PayAppBase(Searchable):
     meta = {
         'abstract': True
@@ -1147,35 +995,6 @@ class PayAppBase(Searchable):
     def new_withdraw_gateway(self, is_ledger = True, gateway_version = None):
         raise NotImplementedError('must implement new_withdraw_gateway')
 
-    @property
-    def split_id(self):
-        raise NotImplementedError('must implement split_id')
-
-    def refund_bill_split_list(self, partition_map):
-        raise NotImplementedError('must implement refund_bill_split_list')
-
-    def bill_split_rule(self, partition_map):
-        raise NotImplementedError('must implement refund_bill_split_list')
-
-
-class JosShopInfo(EmbeddedDocument):
-    """
-    京东云支付的相关信息
-    其中门店ID很关键
-    """
-    # 品牌ID 查看方式 品牌管理 -> 品牌认证 -> 品牌ID
-    brandId = StringField(verbose_name = u"京东引流 品牌ID", default = "13499")
-    # 企业BID 查看方式 品牌管理 -> 企业认证 -> 企业BID
-    bizId = StringField(verbose_name = u"京东引流 企业BID", default = "100000000006317")
-    # 外部门店ID 重要
-    # 这个门店的编号直接影响用户的欠款去向 千万注意
-    # jos后台的逻辑是 通过 exStoreId 查找到
-    # 绑定的京东商户, 通过京东商户找到绑定的钱包 最后用户付款的钱直接到对应钱包里面
-    exStoreId = StringField(verbose_name = u"京东引流的外部门店ID,需要web端操作绑定", required = True)
-    # 和门店相关联的商品的ID 商品发布后一定需要关联门店,可以多个门店关联一个商品 也可以一个商品关联多个门店
-    exSkuId = StringField(verbose_name = u"京东引流的外部商品ID,需要web端操作绑定", default = "100001")
-    brandName = StringField(verbose_name = u"品牌名称, 需要和品牌ID对应", default = u"微付乐")
-    tradeName = StringField(verbose_name = u"商品名称,需要和商品ID对应", default = u"测试商品")
 
 class WechatPayApp(PayAppBase):
     """
@@ -1755,159 +1574,6 @@ class LedgerConsumeApp(PayAppBase):
         return app
 
 
-
-
-
-
-class JDOpenPayApp(PayAppBase):
-    customerNum = StringField(verbose_name = u'商户编号', unique = True, required = True, null = False)
-    shopNum = StringField(verbose_name = u'店铺编号', required = True, null = False)
-
-    accessKey = StringField(verbose_name=u"accessKey", default=None)
-    secretKey = StringField(verbose_name=u"secretKey", default=None)
-
-    agent = LazyReferenceField(document_type=MerchantAgent)
-
-    meta = {
-        'indexes': [
-            {
-                'fields': ['customerNum'], 'unique': True
-            },
-            {
-                'fields': ['wxSubMchId']
-            }
-        ],
-        'collection': 'jdopen_pay_app',
-        'db_alias': 'default'
-    }
-
-    def __repr__(self):
-        return '<JDOpenPayApp customerNum={} shopNum={}>'.format(self.customerNum, self.shopNum)
-
-    @property
-    def __valid_check__(self):
-        # return bool(self.customerNum) and bool(self.shopNum)
-        return bool(self.customerNum)
-
-    @property
-    def pay_app_type(self):
-        return PayAppType.JD_OPEN
-
-    @property
-    def __gateway_key__(self):
-        _ = [
-            self.occupantId,
-            self.customerNum,
-            self.occupant.role
-        ]
-        return APP_KEY_DELIMITER.join(_)
-
-    @classmethod
-    def get_null_app(cls):
-        app = cls(merchant_no = '')
-        app.enable = False
-        app.valid = True
-        return app
-
-    @classmethod
-    def __from_gateway_key__(cls, occupant_id, tokens):
-        # type: (str, List)->cast(PayAppBase)
-        customerNum = tokens[0]
-        app = cls.objects(customerNum = customerNum).first()  # type: JDOpenPayApp
-        if not app:
-            raise UserServerException(u'系统配置错误,请联系平台客服')
-
-        app.occupantId = occupant_id
-
-        try:
-            app.role = tokens[1]
-        except:
-            app.role = ROLE.agent
-
-        return app
-
-    def new_gateway(self, app_platform_type):
-        from apps.web.core.payment.jdopen import JDOpenPaymentGateway
-        return JDOpenPaymentGateway(self, app_platform_type)
-
-    def to_dict(self, shadow = True):
-        return {
-            'id': str(self.id),
-            'customerNum': self.customerNum,
-            'companyName': self.companyName,
-            'appName': self.appName,
-            'remarks': self.remarks
-        }
-
-    @classmethod
-    def get_or_create_by_merchant(cls, source):   # type: (JDOpenApplyInfo) -> JDOpenPayApp
-        app = cls.objects.filter(agentNum=source.agentNum, customerNum=source.customerNum)
-        if not app:
-            app = cls(agentNum=source.agentNum, customerNum=source.customerNum)
-
-        app.settleNum = source.settleNum
-        app.shopNum = source.shopNum
-        app.accessKey, app.secretKey = source.get_access_and_secret()
-
-        return app.save()
-
-    @property
-    def split_id(self):
-        return self.customerNum
-
-    def bill_split_rule(self, partition_map):
-        """
-
-        分账list必须全部包括收款方和分账方,分账金额保留两位小数,且分账金额相加需等于订单金额
-        :return:
-        """
-
-        partitions = list(flatten(partition_map.values()))
-
-        rv = []
-
-        for partition in partitions:
-            if RMB(partition['money']) > RMB(0):
-                rv.append({
-                    'customerNum': partition['merchantId'],
-                    'amount': str(RMB(partition['money']))
-                })
-
-        if len(rv) <= 1:
-            return None, None, None
-        else:
-            return 'FIXED', 'RECEIVER', rv
-
-    def refund_bill_split_list(self, partition_map):
-        """
-        京东退款分账规则:
-        1、即使退款为0, 也必须带上拉起支付的商户号
-        2、所以参与支付分账的商户, 即使金额为0, 也必须带上
-        :return:
-        """
-
-        ownerPartition = partition_map.get(PARTITION_ROLE.OWNER)[0]
-
-        if 'merchantId' not in ownerPartition:
-            return None
-
-        partitions = list(flatten(partition_map.values()))
-
-        rv = []
-
-        for partition in partitions:
-            if 'merchantId' in partition:
-                rv.append({
-                    'customerNum': partition['merchantId'],
-                    'amount': str(abs(RMB(partition['money'])))
-                })
-
-        if len(rv) <= 1:
-            return None
-        else:
-            return rv
-
-
 class ManualPayApp(PayAppBase):
     """
     客户线下打款后, 超级管理员建立充值记录
@@ -1958,57 +1624,6 @@ class ManualPayApp(PayAppBase):
         return app
 
 
-class SwapPayApp(PayAppBase):
-    """
-    互联互通支付APP
-    """
-
-    def __repr__(self):
-        return '<swap pay App>'
-
-    @property
-    def __valid_check__(self):
-        return True
-
-    def new_gateway(self, app_platform_type):
-        from apps.web.core.payment.manual import ManualPaymentGateway
-        return ManualPaymentGateway(self, app_platform_type)
-
-    @property
-    def pay_app_type(self):
-        return PayAppType.SWAP
-
-    @property
-    def __gateway_key__(self):
-        _ = [
-            self.occupantId,
-            self.occupant.role
-        ]
-        return APP_KEY_DELIMITER.join(_)
-
-    @classmethod
-    def get_null_app(cls):
-        app = cls()
-        app.enable = True
-        app.valid = True
-        return app
-
-    @classmethod
-    def __from_gateway_key__(cls, occupant_id, tokens):
-        # type: (str, List)->cast(PayAppBase)
-
-        app = cls.get_null_app()  # type: SwapPayApp
-
-        app.occupantId = occupant_id
-
-        try:
-            app.role = tokens[1]
-        except:
-            app.role = ROLE.agent
-
-        return app
-
-
 class WechatComponentApp(DynamicDocument):
     appid = StringField(verbose_name='appid', default='', required=True)
     secret = StringField(verbose_name="secretId", default='', required=True)

+ 2 - 8
apps/web/core/payment/base.py

@@ -13,7 +13,7 @@ from apilib.systypes import IterConstant
 from apps.web.core import PAY_APP_MAP, APP_KEY_DELIMITER, PayAppType, BaseAppProxy
 
 if TYPE_CHECKING:
-    from apps.web.core.models import WechatMiniApp, PayAppBase
+    from apps.web.core.models import PayAppBase
     from apps.web.core.payment import PaymentGatewayT
     from apps.web.common.transaction.pay import RechargeRecordT
 
@@ -62,7 +62,7 @@ class _PaymentGateway(BaseAppProxy):
         app_cls = import_string(pay_app_name)
 
         factory_fun = getattr(app_cls, '__from_gateway_key__')
-        app = factory_fun(occupant_id, tokens)  # type: Optional[cast(PayAppBase), WechatMiniApp]
+        app = factory_fun(occupant_id, tokens)  # type: Optional[cast(PayAppBase)]
         return app
 
 
@@ -124,12 +124,6 @@ class PaymentGateway(_PaymentGateway):
     def withdraw_source_key(self):
         return self.occupant.withdraw_source_key(self.app)
 
-    def bill_split_rule(self, partition_map):
-        return self.app.bill_split_rule(partition_map)
-
-    def refund_bill_split_list(self, partition_map):
-        return self.app.refund_bill_split_list(partition_map)
-
 
 class WithdrawGateway(_PaymentGateway):
     """

+ 2 - 2
apps/web/core/payment/wechat.py

@@ -35,7 +35,7 @@ from library.wechatpy.pay import WeChatPay
 from library.wechatbase.exceptions import WeChatPayException
 
 if TYPE_CHECKING:
-    from apps.web.core.models import WechatMiniApp
+    pass
 
 logger = logging.getLogger(__name__)
 logging.getLogger('dicttoxml').setLevel(logging.WARNING)
@@ -152,7 +152,7 @@ class WechatPayMixin(WechatMixin):
 
 class WechatPaymentGateway(PaymentGateway, WechatPayMixin):
     def __init__(self, app, gateway_type = AppPlatformType.WECHAT):
-        # type: (Union[WechatPayApp, WechatMiniApp], AppPlatformType)->None
+        # type: (Union[WechatPayApp], AppPlatformType)->None
         """
         :param app: WechatPayApp
         """

+ 0 - 1
apps/web/dealer/constant.py

@@ -10,7 +10,6 @@ class TodoTypeEnum(Enum):
     待办消息的种类
     """
     SMS_TODO = 1, u"流量卡待办", None
-    MER_TODO = 2, u"商户待办", "apps.web.dealer.utils.MerchantTodo"
 
     @classmethod
     def choices(cls):

+ 10 - 219
apps/web/dealer/models.py

@@ -16,33 +16,32 @@ from django.conf import settings
 from django.core.cache import cache
 from mongoengine import EmbeddedDocument, StringField, BooleanField, EmbeddedDocumentField, MapField, DynamicDocument, \
     DateTimeField, Document, IntField, ListField, DictField, FloatField, ObjectIdField, EmbeddedDocumentListField, \
-    LazyReferenceField, DynamicEmbeddedDocument, GenericLazyReferenceField
+    LazyReferenceField, DynamicEmbeddedDocument
 from typing import Dict, AnyStr, Any, List, Optional, TYPE_CHECKING
 
 from apilib.monetary import RMB, Percent, sum_rmb, Permillage
-from apilib.systypes import IterConstant, StrEnum
-from apilib.utils_string import cn, md5
+from apilib.systypes import IterConstant
+from apilib.utils_string import cn
 from apilib.utils_url import add_query
 from apps.web.agent.models import Agent, MoniAppPoint
 from apps.web.common.models import UserSearchable, MonthlyPackageTemp
 from apps.web.common.models import WithdrawRecord, CapitalUser, Balance
 from apps.web.common.transaction import OrderNoMaker, OrderMainType, DealerPaySubType, WITHDRAW_PAY_TYPE, RefundSubType
 from apps.web.constant import TYPE_ADJUST_USER_VIRTUAL_CARD, DEALER_CONSUMPTION_AGG_KIND, \
-    DEALER_CONSUMPTION_AGG_KIND_TRANSLATION, Const, APP_TYPE, AppPlatformType
+    DEALER_CONSUMPTION_AGG_KIND_TRANSLATION, Const, APP_TYPE
 from apps.web.core import PayAppType, ROLE, APP_KEY_DELIMITER
 from apps.web.core.db import Searchable, MonetaryField, PercentField, PermillageField
-from apps.web.core.exceptions import UpdateError, ServiceException, InvalidParameter, MerchantError
-from apps.web.dealer.constant import TodoDone, TodoTypeEnum, LinkageSwitchEnum
+from apps.web.core.exceptions import UpdateError, ServiceException, InvalidParameter
 from apps.web.core.messages.sms import dealerWithdrawSMSProvider, dealerMonitorWithdrawSMSProvider
-from apps.web.core.models import BoundOpenInfo, BankCard, SwapPayApp
+from apps.web.core.models import BoundOpenInfo
 from apps.web.core.payment import WithdrawGateway
+from apps.web.dealer.constant import TodoDone, TodoTypeEnum, LinkageSwitchEnum
 from apps.web.dealer.define import DEALER_INCOME_SOURCE, DEALER_INCOME_TYPE, DealerConst, \
     DEALER_INCOME_SOURCE_TRANSLATION
 from apps.web.device.models import Device, Group, GroupDict, DeviceType
 from apps.web.helpers import get_app, get_user_manager_agent
 from apps.web.utils import concat_dealer_access_entry_url, concat_front_end_url, concat_server_end_url
 
-
 if TYPE_CHECKING:
     from apps.web.common.transaction import WithdrawHandler
     from apps.web.core.payment import PaymentGateway
@@ -129,15 +128,6 @@ class Dealer(CapitalUser):
         'fukuan': False
     }
 
-    DEFAULT_PAY_TYPE = {
-        ROLE.myuser: {
-            AppPlatformType.ALIPAY: PayAppType.ALIPAY,
-            AppPlatformType.WECHAT: PayAppType.WECHAT,
-            AppPlatformType.JD: PayAppType.JD_AGGR,
-            AppPlatformType.WECHAT_MINI: PayAppType.WECHAT_MINI
-        }
-    }
-
     CACHE_KEY = 'dealer-info-{id}'
     CacheMgr = DealerCacheMgr
 
@@ -153,10 +143,6 @@ class Dealer(CapitalUser):
 
     payOpenIdMap = MapField(EmbeddedDocumentField(BoundOpenInfo))
 
-    cardNo = StringField(verbose_name = "银行卡号", default = "")
-    bankName = StringField(verbose_name = "银行名称", default = "")
-    cardHolder = StringField(verbose_name = "持卡人名称", default = "")
-
     isRead = StringField(verbose_name = "是否已经读了消息", default = "N")
     noPassReason = StringField(verbose_name = "未通过原因", default = "")
     cibMerchant = BooleanField(verbose_name = "是否立即生效", default = False)
@@ -255,8 +241,6 @@ class Dealer(CapitalUser):
 
     domain = StringField(verbose_name = u'api推送地址url', default = '')
 
-    payAppType = StringField(verbose_name = u'商户类型', default = None)
-
     monitorPhone = StringField(verbose_name = u"提现审批员的手机号", default = "", max_length = 32)
 
     currencyCoins = BooleanField(verbose_name = u'金币是否通用(deprecated)', default = True)
@@ -645,14 +629,13 @@ class Dealer(CapitalUser):
         else:
             return str(self.username)
 
-
-
     @property
     def auto_withdraw_bound_open_id(self):
         from apps.web.helpers import get_wechat_auth_bridge
 
         auth_bridge = get_wechat_auth_bridge(source = self, app_type = APP_TYPE.WECHAT_WITHDRAW)
         return self.get_bound_pay_openid(auth_bridge.bound_openid_key)
+
     @property
     def auto_withdraw_bank_account(self):
         return self.withdrawOptions.get('bankAccount', None)
@@ -875,103 +858,6 @@ class Dealer(CapitalUser):
         return APP_KEY_DELIMITER.join(
             [WithdrawGateway.NO_LEDGER_PREFIX, pay_app.pay_app_type, getattr(pay_app, '__gateway_key__')])
 
-    def handle_with_partners(self, partners):
-        # type:(list) -> list
-        """
-        处理 合伙人 完成一些参数校验
-        :param partners:
-        :return:
-        """
-        if not partners:
-            return list()
-        new_partners = list(partners)
-        if self.payByMerchant:
-            return self.handle_with_merchant_partner(new_partners)
-        else:
-            return self.handle_with_normal_partner(new_partners)
-
-    def handle_with_merchant_partner(self, partners):
-        # type:(list) -> list
-        """
-        处理 合伙人 完成一些参数校验 不存在的情况下不要新建
-        :param partners:
-        :return:
-        """
-        mobileMap = {_partner['tel']: _partner for _partner in partners}
-        newPartners = list()
-
-        dealers = Dealer.objects.filter(username__in=mobileMap.keys(), agentId=self.agentId)
-
-        # 总人数鉴定
-        if len(dealers) != len(partners):
-            notRegisterDealers = set(mobileMap.keys()) - set([_.username for _ in dealers])
-            raise ServiceException({"result": 0, "description": u"合伙人尚未注册,请在注册合伙人 {} 为经销商!".format(notRegisterDealers)})
-
-        # 同一个代理商下 经销商username唯一
-        for _dealer in dealers:
-            if _dealer == self:
-                raise ServiceException({"result": 0, "description": u'合伙人<{}>不能是经销商本人'.format(_dealer.username)})
-
-            # 分成不为0的商户必须 配有京东APP收款
-            if not _dealer.payAppJDAggre and int(mobileMap[_dealer.username]["percent"]) > 0:
-                raise ServiceException({"result": 0, "description": u'合伙人<{}>必须开通商户号'.format(_dealer.username)})
-
-            # 将ID添加进去
-            _partner = mobileMap.get(str(_dealer.username))
-            _partner.update({"id": str(_dealer.id)})
-            newPartners.append(_partner.copy())
-
-        # TODO 合伙人添加的时候 应该是只是添加 而并不是有权限去修改诸如昵称一类的信息
-        return newPartners
-
-    def handle_with_normal_partner(self, partners):
-        # type:(list) -> list
-        """
-        处理 合伙人 完成一些参数校验
-
-        对于普通的合伙人校验逻辑还是和之前的一样 有则更新 没有创建
-        :param partners:
-        :return:
-        """
-        from apps.web.dealer.utils import create_partner, update_partner
-        mobileList = [_partner['tel'] for _partner in partners]
-        dealers = Dealer.objects.filter(username__in = mobileList, agentId = self.agentId)
-        partnerDict = {}
-        for dealer in dealers:
-            if dealer == self:
-                raise ServiceException({"result": 0, "description": u'合伙人<{}>不能是经销商本人'.format(dealer.username)})
-            partnerDict[dealer.username] = dealer
-
-        for partner in partners:
-            if partner['tel'] not in partnerDict:
-                newDealer = create_partner(
-                    username = partner['tel'],
-                    password = md5("1234567"),
-                    agentId = self.agentId,
-                    nickname = partner['name'],
-                    annualTrafficCost = self.annualTrafficCost,
-                    agentProfitShare = self.agentProfitShare
-                )
-
-                partner['id'] = str(newDealer.id)
-            else:
-                dealerId = str(partnerDict[partner['tel']].id)
-
-                updated = update_partner(
-                    dealerId = ObjectId(dealerId),
-                    agentId = self.agentId,
-                    nickname = partner['name'],
-                    agentProfitShare = self.agentProfitShare
-                )
-
-                if not updated:
-                    raise ServiceException({"result": 0, "description": u"合伙人(%s)信息更新失败" % partnerDict[partner['tel']]})
-                partner['id'] = dealerId
-
-            partner['percent'] = str(partner['percent'])
-
-        return partners
-
     @classmethod
     def get_cooperative_dealer_ids(cls, dealerId):
         rcds = Group.get_collection().find({'partnerList.id': dealerId})
@@ -997,9 +883,6 @@ class Dealer(CapitalUser):
 
     @property
     def is_inhouse_wallet(self):
-        if self.payByMerchant:  # 经销商配置了自己商户号的,不能自动充值
-            return False
-
         app = get_app(source = self, app_type = APP_TYPE.WECHAT_ENV_PAY, role = ROLE.myuser)
         return getattr(app, 'inhouse', False)
 
@@ -1026,26 +909,7 @@ class Dealer(CapitalUser):
         :param clientEnv: 客户端的环境
         :return:
         """
-        if self.payByMerchant:
-            # 开启商户的经销商 不能使用
-            return False
-
-        from apps.web.helpers import get_app
-        if clientEnv == "wechat":
-            app_type = APP_TYPE.WECHAT_ENV_PAY
-        elif clientEnv == "jd":
-            app_type = APP_TYPE.JD_ENV_PAY
-        else:
-            return None
-
-        app = get_app(source=self, app_type=app_type, role=ROLE.myuser)
-        # 首先判断是否是 我们自己的资金池 判断方式为 app的agent为平台agent
-        # 再其次判断是否是京东支付 否则用户记账会记在不通的平台上 容易被经销商发现
-        if app.occupantId == settings.MY_PRIMARY_AGENT_ID and app.pay_app_type == PayAppType.JD_AGGR:
-            return app
-
-        # 不满足条件的 都不允许使用
-        return None
+        return False
 
     def limit_filter_date(self, startTime, endTime):
         # type:(str, str)->(str, str)
@@ -1521,57 +1385,6 @@ class DealerDict(dict):
         return self['nickname']
 
 
-# 经销商商户相关信息
-class Merchant(DynamicDocument):
-    """
-    TODO 经销商商户相关信息. 升级需要, 下个版本后删除
-    """
-    ownerId = StringField(verbose_name = "经销商ID", default = "")
-    merchantType = StringField(verbose_name = "商户类型", default = "")
-    merchantName = StringField(verbose_name = "持卡人姓名", default = "")
-    provinceID = StringField(verbose_name = "省id", default = "")
-    provinceName = StringField(verbose_name = "省名称", default = "")
-    cityID = StringField(verbose_name = "市id", default = "")
-    cityName = StringField(verbose_name = "市名称", default = "")
-    address = StringField(verbose_name = "详细地址", default = "")
-    localLicensePhoto = StringField(verbose_name = "营业执照", default = "")
-    legalPerson = StringField(verbose_name = "负责人姓名", default = "")
-    idCode = StringField(verbose_name = "身份证", default = "")
-    email = StringField(verbose_name = "邮箱地址", default = "")
-    principalMobile = StringField(verbose_name = "商店名称", default = "")
-    validateCode = StringField(verbose_name = "商店名称", default = "")
-    localIndentityPhoto1 = StringField(verbose_name = "身份证第一面", default = "")
-    localIndentityPhoto2 = StringField(verbose_name = "身份证第二面", default = "")
-
-    accountCode = StringField(verbose_name = "公司账号银行账号", default = "")
-    parentBankName = StringField(verbose_name = "银行名称", default = "")
-    subBankName = StringField(verbose_name = "银行支行名称", default = "")
-    cardType = StringField(verbose_name = "卡类型", default = "")
-    bankCardType = StringField(verbose_name = "银行卡内部卡类型", default = "")
-    bankProvinceID = StringField(verbose_name = "开户地区省id", default = "")
-    bankProvinceName = StringField(verbose_name = "开户地区省name", default = "")
-    bankCityID = StringField(verbose_name = "开户地区市id", default = "")
-    bankCityName = StringField(verbose_name = "开户地区市name", default = "")
-    cnapsCode = StringField(verbose_name = "开户地区市name", default = "")
-
-    localAccountPhoto = StringField(verbose_name = "开户许可证", default = "")
-    getPicUrl = StringField(verbose_name = "URl", default = "")
-    dateTimeAdded = DateTimeField(default = datetime.datetime.now, verbose_name = '添加进来的时间')
-
-    manual = BooleanField(verbose_name = u"该卡是否仅手动提现", default = False)
-
-    accountType = StringField(verbose_name = u'卡类型(个人账号,对公账号)', default = BankCard.AccountType.PERSONAL)
-
-    # allowed = BooleanField(verbose_name=u"是否是提现的卡", default=False)
-
-
-    meta = {"collection": "Merchant", "db_alias": "default"}
-
-    @classmethod
-    def get_collection(cls):
-        return cls._get_collection()
-
-
 class UpscoreRecord(Document):
     logicalCode = StringField(verbose_name = "设备逻辑编号", default = '')
     devNo = StringField(verbose_name = "设备编号")
@@ -1734,11 +1547,6 @@ class DealerRechargeRecord(Searchable):
         if 'extraInfo' not in payload:
             payload['extraInfo'] = {}
 
-        if payment_gateway.pay_app_type == PayAppType.SAOBEI:
-            payload['extraInfo'].update({
-                'payTime': str(datetime.datetime.now().strftime('%Y%m%d%H%M%S'))
-            })
-
         payload['status'] = cls.PayState.UnPaid
 
         identifier = identifier if identifier else str(user.id)
@@ -2078,13 +1886,7 @@ class OnSale(DynamicDocument):
             'img': '/app/img/marketing/inputMobile.jpg',
             'showType': 'onlyOne-web'
         },
-        #u"京东新人1分购": {
-        #    "onClickUrl": "/user/onsaleJdNewUser",
-        #    "desc": u"",
-        #    "expression": "",
-        #    "img": "https://resource.washpayer.com/uploaded/marketing/jd.jpg",
-        #    "showType": "onlyOne"
-        #},
+
         u'包年包月优惠多多': {
             'onClickUrl': '/user/onsaleTicketList',
             'desc': u'适用所有设备类型,用户优惠充值,活动期间始终弹出此推广创意,即使用户已经充值优惠过了。(用户点击推广活动后,会跳转到对应设备的充值页面。需要提前在优惠设置中,把对应的地址下的充值套餐配置好)',
@@ -2814,7 +2616,6 @@ class PermissionRule(Searchable):  # 权限配置表
 
 
 class TodoMessage(Searchable):
-
     title = StringField(verbose_name=u"标题")
     content = StringField(verbose_name=u"内容")
     type = IntField(verbose_name=u"待办的种类", choices=TodoTypeEnum.choices())
@@ -2826,7 +2627,6 @@ class TodoMessage(Searchable):
 
     popOnlyOnce = BooleanField(verbose_name=u"登录后台只显示一次", default=True)
 
-
     def to_dict(self):
         return {
             "id": self.id,
@@ -2875,15 +2675,6 @@ class TodoMessage(Searchable):
 
         return dataList
 
-    @classmethod
-    def merchant_message(cls, user):
-        # type: (RoleBaseDocument)->dict
-        if user.role == ROLE.dealer:
-            messages = cls.get_todo_message(user, [TodoTypeEnum.MER_TODO.code])
-            return messages[0] if len(messages) > 0 else {}
-        else:
-            return {}
-
     @classmethod
     def sim_expire_message(cls, ownerId, expireCount):
         params = {

+ 1 - 23
apps/web/dealer/transaction_deprecated.py

@@ -2,23 +2,18 @@
 # !/usr/bin/env python
 
 import logging
-import uuid
 
 from django.conf import settings
-from pymongo.errors import DuplicateKeyError
 from typing import TYPE_CHECKING
 
 from apilib.monetary import RMB
 from apilib.utils_sys import memcache_lock
-from apps.web.agent.models import Agent
-from apps.web.constant import USER_RECHARGE_TYPE
 from apps.web.core import PayAppType
 from apps.web.core.exceptions import ServiceException
 from apps.web.core.payment import PaymentGateway
 from apps.web.dealer.define import REFUND_NOTIFY_URL
-from apps.web.dealer.models import RefundDealerRechargeRecord, DealerRechargeRecord, Dealer
+from apps.web.dealer.models import RefundDealerRechargeRecord, DealerRechargeRecord
 from apps.web.exceptions import UserServerException
-from library.jd.exceptions import JDPayException
 from library.wechatbase.exceptions import WeChatPayException
 
 logger = logging.getLogger(__name__)
@@ -123,23 +118,6 @@ class RefundCash(object):
 
                     logger.info('WECHAT Refund request successfully! return = {}'.format(result))
 
-                elif payGateway.pay_app_type == PayAppType.JD_AGGR:
-                    # 经销商支付是资金池模式, 不存在分账, 所以不需要分账信息
-                    try:
-                        result = payGateway.refund_to_user(
-                            out_trade_no = self.outTradeNo,
-                            out_refund_no = refundOrder.orderNo,
-                            refund_fee = self.refundFee,
-                            total_fee = self.totalFee,
-                            refund_reason = u'退费',
-                            notify_url = REFUND_NOTIFY_URL.JD_AGGRE_REFUND_BACK)
-                    except JDPayException as e:
-                        logger.info('refund failed , refund orderNo = {} reason = {}'.format(refundOrder.orderNo, e))
-                        refundOrder.fail(errorCode = e.errCode, errorDesc = e.errMsg)
-                        raise UserServerException('{}({})'.format(e.errMsg, e.errCode))
-
-                    logger.info('JDAGGRE Refund request successfully! return = {}'.format(result))
-
                 else:
                     refundOrder.fail(errorDesc = u"不支持的退款模式")
                     raise UserServerException(u"不支持的退款模式")

+ 3 - 94
apps/web/dealer/utils.py

@@ -25,14 +25,12 @@ from apps.web.dealer.models import DealerRechargeRecord, ItemType, Dealer, Virtu
 from apps.web.device.models import Group, Device, StockRecord
 
 from apps.web.management.models import Manager
-from apps.web.merchant.constant import MerchantStatus
-from apps.web.merchant.models import MerchantSourceInfo
 from apps.web.utils import DealerLoginPageResponseRedirect, DealerMainPageResponseRedirect, \
     SubAccountLoginResponseRedirect, concat_front_end_url
 
 if TYPE_CHECKING:
     from library.memcache_backend import CustomizedMemcachedCacheBackend
-    from apps.web.core.payment import WechatPaymentGateway, JDAggrePaymentGateway, SaobeiPaymentGateway
+    from apps.web.core.payment import WechatPaymentGateway
     from apps.web.device.models import DeviceRentOrder
 
 logger = logging.getLogger(__name__)
@@ -394,22 +392,6 @@ class VirtualCardBuilder(object):
         return result
 
 
-class JDOpenMerchant(object):
-    """`
-    经销商 商户开户 目前特指京东平台
-    """
-    HOST = "https://psi.jd.com"
-
-    def __init__(self):
-        pass
-
-    def __str__(self):
-        pass
-
-    def __repr__(self):
-        pass
-
-
 def create_dealer_sim_charge_order(payment_gateway, dealer, devItems, payType = "pay", can_used_balance = None):
     from apps.web.common.transaction import DealerPaySubType
     from apps.web.core import ROLE
@@ -622,7 +604,7 @@ def create_dealer_charge_order_for_api(dealer, **kw):
     total_fee = RMB.yuan_to_fen(total_yuan)
 
     payment_gateway = get_inhourse_wechat_env_pay_gateway(
-        ROLE.dealer)  # type: Union[WechatPaymentGateway, JDAggrePaymentGateway, SaobeiPaymentGateway]
+        ROLE.dealer)  # type: Union[WechatPaymentGateway]
 
     agent = payment_gateway.occupant
 
@@ -676,7 +658,7 @@ def create_dealer_charge_order_for_disable_ad(dealer, devList):
     dealerId = dealer.bossId
 
     payment_gateway = get_inhourse_wechat_env_pay_gateway(
-        ROLE.dealer)  # type: Union[WechatPaymentGateway, JDAggrePaymentGateway, SaobeiPaymentGateway]
+        ROLE.dealer)  # type: Union[WechatPaymentGateway]
 
     agent = payment_gateway.occupant
 
@@ -883,76 +865,3 @@ class TodoProcessor(object):
     @classmethod
     def check_has_done(cls, todo):
         return False, False
-
-
-class MerchantTodo(TodoProcessor):
-    @classmethod
-    def insert_todo(cls, user):
-        # type: (Dealer)->Optional[TodoMessage]
-
-        # 已经申请过商户的 就不再处理了
-        if MerchantSourceInfo.get_source_record(user).status == MerchantStatus.SUCCESS:
-            logger.info("dealer <{}> has apply merchant!".format(user.id))
-            return None
-
-        try:
-            todo = TodoMessage.objects.get(ownerId = str(user.id),
-                                           type = TodoTypeEnum.MER_TODO.code)  # type: TodoMessage
-        except DoesNotExist:
-            if user.supports('forceMerchant'):
-                msg = u'根据国家相关政策,商户收款需提交身份证、银行卡等相关信息,请尽快完成商户开通。'
-            else:
-                msg = u'根据国家相关政策,商户收款需提交身份证、银行卡等相关信息,请尽快完成商户开通,否则可能会影响您的正常收款和提现。'
-            todo = TodoMessage(
-                title = u"商户开通提醒",
-                content = msg,
-                type = TodoTypeEnum.MER_TODO.code,
-                link = concat_front_end_url(uri = '/dealer/index.html#/merchant'),
-                ownerId = str(user.id),
-                expiredTime = datetime.datetime(2099, 1, 1)
-            ).save()
-        else:
-            todo.done = TodoDone.INIT
-            todo.expiredTime = datetime.datetime(2099, 1, 1)
-            todo.save()
-
-        return todo
-
-    @classmethod
-    def check_has_done(cls, todo):  # type:(TodoMessage) -> (bool, bool)
-        """
-        返回参数是两个 是否完成 和是否需要强制显示
-        """
-        dealer = Dealer.objects.get(id=todo.ownerId)
-        merchant = MerchantSourceInfo.get_source_record(dealer)     # type: MerchantSourceInfo
-
-        # 商户是成功状态的时候 任务完成 无需强制执行
-        if merchant.merchantStatus == int(MerchantStatus.SUCCESS):
-            return True, False
-
-        # 正在京东那边审核的 无需强制执行
-        if merchant.merchantStatus == int(MerchantStatus.WAITING):
-            return False, False
-
-        # 没有提交资料的 需要强制执行
-        if merchant.merchantStatus == int(MerchantStatus.INIT):
-            return False, "forceMerchant" in dealer.features
-
-        # 提交失败的 需要强制执行
-        if merchant.merchantStatus == int(MerchantStatus.FAIL):
-            return False, "forceMerchant" in dealer.features
-
-        # 申请成功了 但是没有切换的
-        if merchant.merchantStatus == int(MerchantStatus.CONFIRM):
-            return False, False
-
-        if merchant.merchantStatus == int(MerchantStatus.AUTH_WAITING):
-            return False, False
-
-        if merchant.merchantStatus == int(MerchantStatus.AUTH_APPLY_SUCCESS):
-            return False, "forceMerchant" in dealer.features
-
-        if merchant.merchantStatus == int(MerchantStatus.AUTH_SUCCESS):
-            return False, False
-
-        return False, False

+ 10 - 39
apps/web/dealer/views.py

@@ -47,7 +47,6 @@ from apps import serviceCache, reportCache
 from apps.common.utils import get_start_and_end_by_month, get_start_and_end_by_year, get_date_range
 from apps.thirdparties.aliyun import AliyunSlider
 from apps.web.agent.models import Agent
-
 from apps.web.api.models import APIStartDeviceRecord
 from apps.web.common.models import District, DEFAULT_DEALER_FEATURES, WithdrawRecord, OperatorLog, \
     MonthlyPackageTemp, WithdrawBankCard
@@ -61,7 +60,7 @@ from apps.web.constant import (
     DEALER_CONSUMPTION_AGG_KIND_TRANSLATION,
     DEALER_CONSUMPTION_AGG_KIND, DEALER_CONSUMPTION_AGG_KIND_UNIT,
     MONTH_DATE_KEY,
-    FAULT_RECORD_STATUS, APP_TYPE, AppPlatformType, PollRecordDefine, TYPE_ADJUST_USER_VIRTUAL_CARD, DeviceCmdCode,
+    FAULT_RECORD_STATUS, APP_TYPE, PollRecordDefine, TYPE_ADJUST_USER_VIRTUAL_CARD, DeviceCmdCode,
     ErrorCode, RECHARGE_CARD_TYPE, RECHARGE_RECORD_VIA_TRANSLATION, skip_package_unit_verify_list,
     skip_package_range_verify_list, skip_package_params_verify_list, USER_RECHARGE_TYPE, CONSUMETYPE,
     support_policy_weifule, support_policy_device)
@@ -84,7 +83,7 @@ from apps.web.core.messages.sms import (
     dealerBindWalletWechatSMSProvider,
     dealerEditMonitorSMSProvider,
     dealerMonitorWithdrawSMSProvider)
-from apps.web.core.models import OfflineTask, WechatPayApp, WechatAuthApp
+from apps.web.core.models import OfflineTask, WechatPayApp
 from apps.web.core.networking import MessageSender
 from apps.web.core.payment import WithdrawGateway, PaymentGateway
 from apps.web.core.payment.wechat import WechatPaymentGateway
@@ -94,7 +93,7 @@ from apps.web.dealer import OfflineTaskType
 from apps.web.dealer.define import DEALER_INCOME_SOURCE, DEALER_INCOME_SOURCE_TRANSLATION, DEALER_INCOME_TYPE, \
     PAY_NOTIFY_URL, DEALER_BIND_WECHAT_URL, DEALER_BIND_WALLET_WECHAT_URL
 from apps.web.dealer.models import (
-    Dealer, UpscoreRecord, Merchant, DealerRechargeRecord,
+    Dealer, UpscoreRecord, DealerRechargeRecord,
     OnSale, OnSaleRecord, VirtualCard,
     ElecPriceTemplate, ItemType,
     SubAccount, DealerMessage, Complaint, AdjustUserVirtualCardRecord, ExchangeOrder, DealerAddr, UpCardScoreRecord,
@@ -120,7 +119,6 @@ from apps.web.helpers import get_wx_config, current_platform, get_app, \
     get_wechat_user_manager_mp_proxy, \
     remove_some_desc_for_consume, get_inhourse_wechat_env_pay_gateway
 from apps.web.management.models import Manager
-from apps.web.merchant.models import MerchantSourceInfo
 from apps.web.report.models import (
     DevReport, GroupReport, DealerReport,
     GroupDailyStat, DealerMonthlyStat, DealerDailyStat, DeviceDailyStat
@@ -131,11 +129,12 @@ from apps.web.report.utils import (
     to_quantity,
     translate_income,
     translate_consumption)
+from apps.web.south_intf.swap_carcharger import SwapContract
 from apps.web.south_intf.zhejiang_fire import Company
 from apps.web.south_intf.zhejiang_fire import handler_event_to_zhejiang
 from apps.web.user.models import RechargeRecord, ConsumeRecord, MyUser, CardConsumeRecord, Card, \
-    CardRechargeRecord, CardRechargeOrder, UserVirtualCard, ServiceProgress, VCardConsumeRecord, \
-    VirtualCardRechargeRecord, BlackListUsers, SwapCardRecord, UniqueUser
+    CardRechargeRecord, CardRechargeOrder, UserVirtualCard, ServiceProgress, VirtualCardRechargeRecord, BlackListUsers, \
+    SwapCardRecord, UniqueUser
 from apps.web.user.transaction_deprecated import refund_cash
 from apps.web.user.utils import check_black_user, BatteryInfo
 from apps.web.user.utils2 import get_paginate
@@ -147,11 +146,8 @@ from apps.web.utils import (permission_required, LimitAttemptsManager,
                             FrontEndResponseRedirect, ExternalResponseRedirect, DealerBindIdResponseRedirect,
                             ViewValidator, record_operation_behavior)
 from apps.web.wrapper import request_limit_by_user
-from library.jd.pay import PiType
-from library.saobei import SaobeiException
-from taskmanager.mediator import task_caller
-from apps.web.south_intf.swap_carcharger import SwapContract
 from library.wechatbase.exceptions import WeChatException
+from taskmanager.mediator import task_caller
 
 logger = logging.getLogger(__name__)
 
@@ -163,9 +159,6 @@ if TYPE_CHECKING:
     from collections import Iterable
     from apps.web.core.db import Query
     from apps.web.common.models import UserSearchable
-    from apps.web.core.payment.jdaggre import JDAggrePaymentGateway
-    from apps.web.core.payment.saobei import SaobeiPaymentGateway
-    from apps.web.core.payment import DlbPaymentGateway
     from apps.web.core.adapter.bolai_gateway import ChargingGatewayBox
     from apps.web.core.adapter.bolai_node import ChargingBox
     from apps.web.core.adapter.huiteng import washerHTBox
@@ -427,9 +420,6 @@ def dealerRegister(request):
 
         payload['features'] = DEFAULT_DEALER_FEATURES
         
-        if 'merchant' in agent.features:
-            payload['features'].append('merchant')
-
         try:
             Dealer.create_user(
                 username = username,
@@ -969,7 +959,6 @@ def groupInfo(request):
 
             # 添加 合伙人商户的状态给前台显示 如果合伙人商户的状态是 初始状态 需要为合伙人绑定银行卡
             partner = Dealer.objects.get(id=partner["id"])
-            partner["merchantStatus"] = int(MerchantSourceInfo.get_source_record(partner).status)
 
         district = District.get_district(group['districtId'])
 
@@ -4367,7 +4356,7 @@ def payGateway(request):
         payment_gateway = PaymentGateway.from_gateway_key(
             record.gateway,
             record.payGatewayKey,
-            record.payAppType)  # type: Optional[WechatPaymentGateway, DlbPaymentGateway, SaobeiPaymentGateway, JDAggrePaymentGateway]
+            record.payAppType)  # type: Optional[WechatPaymentGateway]
 
         logger.info('dealer wechat charge: gateway = %s; orderNo = %s, totalFee = %s' % (
             repr(payment_gateway), order_no, record.totalFee))
@@ -4411,10 +4400,6 @@ def payGateway(request):
         logger.exception(e)
         return JsonErrorResponse(description = e.tip)
 
-    except SaobeiException as e:
-        logger.exception(e)
-        return JsonErrorResponse(description = e.tip)
-
     except Exception as e:
         logger.exception(e)
         return JsonErrorResponse(description=u'系统开小差了,请刷新后再试')
@@ -4572,7 +4557,7 @@ def createSimRechargeOrder(request):
     devNoList = set(request.POST.getlist('list[]'))
 
     payment_gateway = get_inhourse_wechat_env_pay_gateway(
-        ROLE.dealer)  # type: Union[WechatPaymentGateway, JDAggrePaymentGateway]
+        ROLE.dealer)  # type: Union[WechatPaymentGateway]
 
     record = create_dealer_sim_charge_order(payment_gateway, current_user, devNoList)
 
@@ -5265,14 +5250,6 @@ def unbindDevice(request):
         if dev.ownerId != owner_id:
             return JsonResponse({"result": 0, "description": u"不是您的设备,不能够解绑", 'payload': {}})
 
-        # 如果是对接丰图平台的设备,将平台上的该设备删除
-        if dev.owner.supports("supportFengTu"):
-            from apps.web.api.ft_north.utils import deleteDeviceReport
-            deleteDeviceReport(dev.devNo)
-        if dev.owner.supports("supportBeiJingFengTai"):
-            from apps.web.south_intf.bj_north.utils import delete_device_info
-            delete_device_info(dev.devNo)
-
         try:
             Device.un_register(dev=dev, operator=request.user.human_id)
 
@@ -6938,13 +6915,7 @@ def wechatEntry(request):
     else:
         return ErrorResponseRedirect(error=u'参数错误(10002)')
 
-    if isinstance(app, SaobeiPayApp):
-        redirect = request.GET.get('redirect')
-        redirect = add_query(redirect, {
-            'openId': ''
-        })
-        return FrontEndResponseRedirect(redirect)
-    elif isinstance(app, WechatPayApp):
+    if isinstance(app, WechatPayApp):
         auth_bridge = WechatAuthBridge(app)  # type: WechatAuthBridge
     else:
         return ErrorResponseRedirect(error=u'参数错误(10003)')

+ 0 - 889
apps/web/eventer/aoqiang.py

@@ -1,889 +0,0 @@
-# -*- coding: utf-8 -*-
-# !/usr/bin/env python
-import logging
-from decimal import Decimal
-
-import datetime
-import time
-from mongoengine import DoesNotExist
-
-from apilib.monetary import Ratio, RMB, VirtualCoin
-from apilib.utils_datetime import to_datetime
-from apilib.utils_string import make_title_from_dict
-from apps.web.agent.models import Agent
-from apps.web.constant import Const, DEALER_CONSUMPTION_AGG_KIND
-from apps.web.core.accounting import Accounting
-from apps.web.core.device_define.jndz import CMD_CODE, SWIPE_CARD_PARAM_OP, SWIPE_CARD_RES
-from apps.web.core.exceptions import ServiceException
-from apps.web.dealer.models import Dealer
-from apps.web.device.models import Group, Device
-from apps.web.eventer import EventBuilder
-from apps.web.eventer.base import FaultEvent, WorkEvent
-from apps.web.eventer.errors import InvalidOption, NoCommandHandlerAvailable
-from apps.web.report.utils import record_consumption_stats
-from apps.web.south_intf.platform import notify_event_to_north
-from apps.web.south_intf.zhejiang_fire import send_event_to_zhejiang
-from apps.web.user.models import VCardConsumeRecord, CardRechargeOrder, ServiceProgress, MyUser, \
-    UserVirtualCard, Card, ConsumeRecord
-from apps.web.api.models import APIStartDeviceRecord
-from apps.web.user.transaction_deprecated import refund_money
-from apps.web.south_intf.zhongtian import report_zhongtian_service_complete, report_zhongtian_refund
-
-logger = logging.getLogger(__name__)
-
-class builder(EventBuilder):
-    def __getEvent__(self, device_event):
-        event_data = self.deviceAdapter.analyze_event_data(device_event['data'])
-
-        if event_data is None:
-            return None
-
-        if not event_data.has_key('cmdCode'):
-            return
-
-        if 'duration' in device_event:
-            event_data.update({'duration': device_event['duration']})
-
-        if event_data['cmdCode'] in [ CMD_CODE.SWIPE_CARD_10,
-                                    CMD_CODE.DEVICE_SUBMIT_CHARGE_FINISHED_06,
-                                    CMD_CODE.DEVICE_SUBMIT_CHARGE_FINISHED_v2_16,
-                                    CMD_CODE.DEVICE_SUBMIT_OFFLINE_COINS_20 ]:
-
-            return ChargingJNDZWorkEvent(self.deviceAdapter, event_data)
-
-        if event_data['cmdCode'] in [
-            CMD_CODE.DEVICE_SUBMIT_DEVICE_FAULT_0A,
-            CMD_CODE.DEVICE_FAULT_TEMPERATURE,
-            CMD_CODE.DEVICE_FAULT_POWER,
-            CMD_CODE.DEVICE_FAULT_SMOKE,
-            CMD_CODE.DEVICE_ELEC,
-        ]:
-            return JNDZEventerFailure(self.deviceAdapter, event_data)
-
-
-class JNDZEventerFailure(FaultEvent):
-    def do(self, **args):
-        cmdCode = self.event_data.get("cmdCode")
-        faultType=self.event_data.get("FaultCode")
-        desc=self.event_data.get("statusInfo", "")
-
-        # 保证原有的故障处理逻辑不变
-        if cmdCode == CMD_CODE.DEVICE_SUBMIT_DEVICE_FAULT_0A:
-            super(JNDZEventerFailure, self).do()
-
-        group = Group.get_group(self.device.groupId)
-
-        titleList = [
-            {u"告警名称": desc},
-            {u"地址名称": group["groupName"]}
-        ]
-
-        title = make_title_from_dict(titleList)
-        # 接下来的都是整机告警,这个地方需要通知到经销商
-        # TODO  zjl  需要知道 这个告警标志位是否有具体含义
-        self.notify_dealer(
-            "device_fault",
-            title=title,
-            device=u" 号设备".format(self.device.logicalCode),
-            faultType=desc,
-            notifyTime=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
-            fault=desc
-        )
-
-        # 记录错误故障
-        self.record(
-            faultCode=cmdCode,
-            description=desc,
-            title=faultType,
-            detail=faultType,
-        )
-
-class ChargingJNDZWorkEvent(WorkEvent):
-    def time_ratio_pricing(self, value, leftTime, actualNeedTime):
-        return value * Ratio(leftTime) * Ratio( 1 / float(actualNeedTime))
-
-    def get_backCoins(self, coins, leftTime, actualNeedTime):
-        return self.time_ratio_pricing(value=coins, leftTime=leftTime, actualNeedTime=actualNeedTime)
-
-    def get_backMoney(self, money, leftTime, actualNeedTime):
-        return self.time_ratio_pricing(value=money, leftTime=leftTime, actualNeedTime=actualNeedTime)
-
-
-    def do(self, **args):
-        devNo = self.device['devNo']
-        logger.info('JingNengDianZi charging event detected, devNo=%s,curInfo=%s' % (devNo, self.event_data))
-
-        cmdCode = self.event_data['cmdCode']
-
-        #: 刷卡消费的,分为扣费和退费两种
-        if cmdCode == CMD_CODE.SWIPE_CARD_10:
-            cardNo = self.event_data['cardNo']
-            preFee = RMB(self.event_data['preFee'])
-
-            #: 操作符,是充值还是减少 <- (00, 01)
-            oper = self.event_data['oper']
-
-            card = self.update_card_dealer_and_type(cardNo)
-
-            #: 经销商限制ID卡, 如果满足直接return
-            if not card:
-                return
-
-            self.event_data['openId'] = card.openId
-            self.event_data['cardId'] = str(card.id)
-            self.event_data['startTime'] = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
-            Device.update_dev_control_cache(devNo, self.event_data)
-
-            #: 首先检查订单,并进行充值
-            #: 用户首先在手机客户端充值,需要这个时刻刷卡上报事件将充值的订单同步上来
-            card_recharge_order = CardRechargeOrder.get_last_to_do_one(str(card.id))
-            result = self.recharge_id_card(card = card,
-                                           rechargeType = 'append',
-                                           order = card_recharge_order)
-
-            card.reload()
-
-            logger.info('JingNengDianZi cmdNo(10) - cardNo=%s, openId=%s, result=%s, preFee=%s, curinfo=%s' % (cardNo, card.openId, result, preFee, self.event_data))
-
-            # TODO 这个地方为了同时满足劲能电子和霍珀的需求 先使用特性 vCardNeedBind 后续需要统一规则
-            try:
-                dealer = Dealer.get_dealer(card.dealerId)
-                agent = Agent.objects.get(id=dealer.get("agentId"))
-                features = agent.features
-            except Exception as e:
-                features = list()
-
-            if "vCardNeedBind" in features:
-                virtual_card = card.bound_virtual_card
-            else:
-                virtual_card = card.related_virtual_card
-
-            #如果虚拟卡已经绑定,需要检查下今天是否可用,如果可用,有限使用虚拟卡
-            vCardCanUse = False
-            package = {'coins':float(preFee),'unit':u'分钟','time':180}
-            if virtual_card is not None and card.openId is not None:
-                devObj = Device.objects.get(devNo = devNo)
-                cardMin = devObj.otherConf.get('cardMin',None)
-                if cardMin is not None:
-                    package = {'coins':float(preFee),'unit':u'分钟','time':int(cardMin)}
-                    vCardCanUse = virtual_card.can_use_today(package) 
-                        
-            #: 扣费
-            if oper == SWIPE_CARD_PARAM_OP.DECR_00:
-
-                if card.openId == '' or card.frozen:
-                    res = SWIPE_CARD_RES.INVALID_CARD_02
-                    leftBalance = RMB(0)
-                    return self.response_use_card(res, leftBalance)
-                #如果虚拟卡可用,卡的费用不要扣掉,仅仅做记录,但是虚拟卡的额度需要扣掉
-                elif vCardCanUse:
-                    # 记录卡消费记录以及消费记录
-                    orderNo, cardOrderNo = self.record_consume_for_card(card, money=RMB(0.0),desc = u'使用绑定的虚拟卡')
-
-                    group = Group.get_group(self.device['groupId'])
-
-                    consumeRcd = virtual_card.consume(openId=card.openId, group=group, dev=self.device,
-                                                      package=package,
-                                                      attachParas={}, nickname=card.cardName)
-
-                    # 记录当前服务的progress.没有上报端口号,所以先用-1标记,表示端口未知。端口等消费的时候会报上来
-                    ServiceProgress.register_card_service(self.device, -1, card,
-                                                          {
-                                                              'orderNo': orderNo,
-                                                              'money': self.event_data['preFee'],
-                                                              'coin': self.event_data['preFee'], 'needTime': 0,
-                                                              'cardOrderNo': cardOrderNo,
-                                                              'consumeRcdId': str(consumeRcd.id)
-                                                          })
-                    
-                    self.consume_money_for_card(card, money=RMB(0.0))
-                    
-                    if consumeRcd is None:#如果额度没有扣除成功,就用卡
-                        pass                        
-                    else:
-                        self.response_use_card(SWIPE_CARD_RES.SUCCESS_00, leftBalance=0)
-                        # 通知微信,已经扣费
-                        self.notify_balance_has_consume_for_card(card, preFee,desc=u'使用绑定的虚拟卡')
-                        return 
-                
-                elif result['balance'] < preFee:
-                    res = SWIPE_CARD_RES.BALANCE_NOT_ENOUGH_01
-                    leftBalance = result['balance']
-                    return self.response_use_card(res, leftBalance)
-
-                else:
-
-                    # 记录卡消费记录以及消费记录
-                    orderNo, cardOrderNo = self.record_consume_for_card(card, preFee)
-
-                    # 记录当前服务的progress.没有上报端口号,所以先用-1标记,表示端口未知。端口等消费的时候会报上来
-                    ServiceProgress.register_card_service(self.device, -1, card,
-                                                          {
-                                                              'orderNo': orderNo,
-                                                              'money': self.event_data['preFee'],
-                                                              'coin': self.event_data['preFee'], 'needTime': 0,
-                                                              'cardOrderNo': cardOrderNo
-                                                          })
-
-                    res = SWIPE_CARD_RES.SUCCESS_00
-                    leftBalance = result['balance']
-                    
-                    self.consume_money_for_card(card, preFee)
-
-                    leftBalance -= preFee
-
-                    self.response_use_card(res, leftBalance)
-
-                    # 通知微信,已经扣费
-                    self.notify_balance_has_consume_for_card(card, preFee)
-
-            # 退费.卡的退费比较特殊:如果需要按照电量进行扣费退费,需要在设备管理后台,设置成按电量方式计费。然后把卡的余额回收关闭掉。
-            #充电结束后,上报事件,然后把钱退到卡里。如果是按照时间计费(霍柏的特殊),完全由设备决定,设备告诉我退费,我就退。针对霍柏
-            #绑定虚拟卡的情况下,按照时间退费,需要直接取消掉余额回收,靠结束事件触发结束
-            elif oper == SWIPE_CARD_PARAM_OP.INCR_01:
-                if virtual_card is not None:
-                    pass
-                else:
-                    dev = Device.objects.get(devNo = self.device['devNo'])
-                    billingType = dev.otherConf.get('billingType', 'time')
-                    if billingType != 'time':
-                        logger.debug('dev<{}> billing type is elec. not to card refund.')
-                        return
-
-                    res = SWIPE_CARD_RES.SUCCESS_00
-
-                    self.response_use_card(res, card.balance + preFee)
-
-                    self.refund_money_for_card(preFee, str(card.id))
-
-                    # 通知微信,已经退费
-                    self.notify_user(card.managerialOpenId, 'refund_coins', **{
-                        'title': u'退币完成!您的卡号是%s,卡别名:%s' % (card.cardNo, card.nickName),
-                        'backCount': u'金币:%s' % preFee,
-                        'finishTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
-                    })
-            else:
-                raise InvalidOption('oper has be to 00 or 01, %s was given' % (oper,))
-
-        #: 结束的命令
-        elif cmdCode in [CMD_CODE.DEVICE_SUBMIT_CHARGE_FINISHED_06, CMD_CODE.DEVICE_SUBMIT_CHARGE_FINISHED_v2_16]:
-            lineInfo = Device.update_port_control_cache(devNo, self.event_data)
-            group = Group.get_group(self.device['groupId'])
-            dealer = Dealer.objects(id=group['ownerId']).first()
-            if not dealer:
-                logger.error('dealer is not found, dealerId=%s' % group['ownerId'])
-                return
-
-            agent = Agent.objects(id=dealer.agentId).first()
-            if not agent:
-                logger.error('agent is not found, agentId=%s' % dealer.agentId)
-                return
-
-            if not lineInfo.has_key('coins'):
-                return
-
-            if self.event_data.has_key('duration') and self.event_data['duration'] > 0:
-                usedTime = self.event_data['duration']
-            else:
-                if (not lineInfo) or (not lineInfo.has_key('startTime')):
-                    return
-
-                startTime = to_datetime(lineInfo['startTime'])
-                nowTime = datetime.datetime.now()
-                if startTime > nowTime:#如果web服务器时间和事件监控服务器时间不一致,导致开始时间比事件时间还大
-                    usedTime = 0
-                else:
-                    usedTime = int(round(((nowTime - startTime).total_seconds() / 60.0)))
-
-            cardId = lineInfo.get('cardId', '')
-            vCardId = lineInfo.get('vCardId', None)
-            money = RMB(lineInfo['coins'])
-            price = lineInfo.get('price', 0.0)
-            leftTime = self.event_data['leftTime']
-            billingType = lineInfo.get('billingType', 'time')
-            consumeType = lineInfo.get('consumeType', '')
-            refundProtection = lineInfo.get('refundProtection', 0)
-            refundProtectionTime = lineInfo.get('refundProtectionTime', 5)
-            backCoins, backPrice = RMB(0.0), RMB(0.0)
-            # todo 初始化, 防止变量before assignment
-            needTime = 0
-            leftTimeStr = ''
-
-            try:
-                #: 刷卡或者万一缓存重启了,出现needElec为空的,作为1000度电吧,就会一定使用设备上报的电量
-                if lineInfo.get('elec', 0.0) < lineInfo.get('needElec', 0.0):
-                    spendElec = round(lineInfo['needElec'] - lineInfo['elec'], 2)
-                else:
-                    spendElec = 0.0
-
-                if leftTime == 65535:
-                    actualNeedTime = 0
-                    backCoins = money
-                    backPrice = price
-                    usedTime = 0
-                    spendElec = 0.0
-                else:
-                    actualNeedTime = usedTime + leftTime
-                    leftTimeStr = leftTime
-
-                    if 'alt_tech_refund_mode' in agent.features and billingType == 'time':
-                        needTime = lineInfo['needTime']
-                        # 剩余时间不满 60 按照 0 算, 不满 120 按照 60 算...
-                        calcleftTime = (int(leftTime) // 60) * 60
-                        backCoins = money * (float(calcleftTime) / float(actualNeedTime))
-
-                    elif billingType == 'time':
-                        needTime = lineInfo['needTime']
-                        backCoins = money * (float(leftTime) / float(actualNeedTime))
-
-                    else:
-                        needElec, elec  = Decimal(lineInfo.get('needElec', 1000)), Decimal(str(lineInfo.get('elec')))
-                        ratio = (needElec - elec) / needElec
-                        backCoins = RMB(money.amount - money.amount * ratio)
-
-                # refundProtection 开关, 控制 refundProtectionTime 内全额退款
-                if (refundProtection == 1 and usedTime < refundProtectionTime) and backCoins != 0:
-                    backCoins = money
-
-                if backCoins > money:
-                    backCoins = money
-
-                backPrice = round(price * float(backCoins) / float(money), 2)
-
-                #: 扫码的方式
-                if cardId == '' and vCardId is None and consumeType != 'coin':
-                    #: 这里需要考虑API调用的和普通使用场景
-                    if 'extOrderNo' in lineInfo:
-                        record = APIStartDeviceRecord.get_api_record(self.device['logicalCode'], lineInfo['extOrderNo'])
-                        if not record:
-                            logger.debug('cannot find api start device record')
-                            return
-
-                        if record.postActionTriggered:
-                            logger.debug('api({}) post action has done.'.format(lineInfo['extOrderNo']))
-                            return
-
-                        # 中天的结束状态匹配
-                        reasonCode = self.event_data['reasonCode']
-                        if reasonCode == '0B':
-                            reasonCode = '03'
-                        elif reasonCode == '03':
-                            reasonCode = '04'
-                        else:
-                            pass
-
-                        # 中天空载需要这样写
-                        if leftTime == 65535:
-                            leftTime = lineInfo['needTime']
-
-                        report_zhongtian_service_complete(
-                            event_code = '16',
-                            record=record,
-                            orderNo=lineInfo['extOrderNo'],
-                            deviceCode=self.device['logicalCode'],
-                            groupName=group['groupName'],
-                            address=group['address'],
-                            actualNeedTime=lineInfo['needTime'],
-                            leftTime=leftTime,
-                            finishedState=reasonCode
-                        )
-                        record.update(servicedInfo={'spendElec': str(spendElec), 'backCoins': '0'})
-
-                        if self.device.is_auto_refund:
-                            coins = VirtualCoin(lineInfo['coins'])
-                            money = RMB(lineInfo['price'])
-
-                            backCoins = self.get_backCoins(coins=coins, leftTime=leftTime,
-                                                           actualNeedTime=lineInfo['needTime'])
-                            backMoney = self.get_backMoney(money=money, leftTime=leftTime,
-                                                           actualNeedTime=lineInfo['needTime'])
-
-                            report_zhongtian_refund(
-                                eventCode = '16',
-                                record=record,
-                                orderNo=lineInfo['extOrderNo'],
-                                deviceCode=self.device['logicalCode'],
-                                groupName=group['groupName'],
-                                address=group['address'],
-                                backMoney=str(backMoney),
-                                backCoins=str(backCoins),
-                                actualNeedTime=lineInfo['needTime'],
-                                leftTime=leftTime,
-                                finishedState=reasonCode
-                            )
-                            record.update(servicedInfo={'spendElec': str(spendElec), 'backCoins': str(backCoins)})
-                    else:
-                        openId = lineInfo['openId']
-
-                        billingType = lineInfo.get('billingType', 'time')
-                        if billingType == 'time':
-                            leftTimeStr = leftTime if leftTime != 65535 else lineInfo['needTime']
-                            title = u"\\n\\n结束原因:\\t\\t{reason}\\n\\n设备编号:\\t\\t{logicalCode}-{port}\\n\\n设备地址:\\t\\t{address}\\n\\n消费时间:\\t\\t动态功率计算{actualNeedTime}分钟\\n\\n剩余时间:\\t\\t{leftTimeStr}分钟".format(
-                                reason=self.event_data["reason"],
-                                logicalCode=self.device["logicalCode"],
-                                port=self.event_data["port"],
-                                address=group["address"],
-                                actualNeedTime=actualNeedTime,
-                                leftTimeStr=leftTimeStr
-                            )
-                        else:
-                            title = u"\\n\\n结束原因:\\t\\t{reason}\\n\\n设备编号:\\t\\t{logicalCode}-{port}\\n\\n设备地址:\\t\\t{address}\\n\\n购买电量:\\t\\t{needElec}\\n\\n消耗电量:\\t\\t{spendElec}".format(
-                                reason=self.event_data["reason"],
-                                logicalCode=self.device["logicalCode"],
-                                port=self.event_data["port"],
-                                address=group["address"],
-                                needElec=lineInfo.get("needElec", 1000),
-                                spendElec=spendElec)
-
-                        # 通知充电完成
-                        user = MyUser.objects(openId=openId, groupId=self.device['groupId']).first()
-                        self.notify_user(
-                            managerialOpenId=user.managerialOpenId if user else "",
-                            templateName="service_complete",
-                            title=title,
-                            service=u"充电服务",
-                            finishTime=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
-                            remark = u'谢谢您的支持')
-
-                        consumeDict = {'chargeIndex': lineInfo['port'],
-                                 'reason': lineInfo['reason'],
-                                  'actualNeedTime':u'动态功率计算为%s分钟' % actualNeedTime,
-                                 'duration':usedTime}
-
-                        if billingType == 'time':
-                            leftTimeStr = leftTime if leftTime != 65535 else lineInfo['needTime']
-                            consumeDict.update({'leftTime': leftTimeStr, 'needTime': u'扫码订购%s分钟' % lineInfo['needTime']})
-                            consumeDict.update({'elec': spendElec})
-                        else:
-                            consumeDict.update({'needElec': lineInfo['needElec']})
-                            consumeDict.update({'elec':spendElec})
-                            consumeDict.update({'elecFee':self.calc_elec_fee(spendElec)})
-
-                        # 如果需要退款,计算退款数据.
-                        if not self.device.is_auto_refund:
-                            consumeDict.update({DEALER_CONSUMPTION_AGG_KIND.COIN: money.mongo_amount})
-                            ServiceProgress.update_progress_and_consume_rcd(
-                                self.device['ownerId'],
-                                {'open_id': openId, 'device_imei': self.device['devNo'],
-                                 'port': lineInfo['port'], 'isFinished': False}, consumeDict
-                            )
-                        else:
-                            if group.get('isFree', False) is True:
-                                backCoins = RMB('0.0')
-                                desc = u'免费充电。'
-                            else:
-                                desc = u''
-
-                            # 扫码退钱, 退到个人账号
-                            refund_money(self.device, backCoins, lineInfo['openId'])
-
-                            consumeDict.update({
-                                DEALER_CONSUMPTION_AGG_KIND.REFUNDED_COINS: backCoins.mongo_amount,
-                                DEALER_CONSUMPTION_AGG_KIND.COIN: (money - backCoins).mongo_amount
-                            })
-
-                            ServiceProgress.update_progress_and_consume_rcd(
-                                self.device['ownerId'],
-                                {'open_id': openId, 'device_imei': self.device['devNo'],
-                                 'port': lineInfo['port'], 'isFinished': False}, consumeDict)
-
-                            if billingType == 'time':
-                                leftTimeStr = leftTime if leftTime != 65535 else lineInfo['needTime']
-                                desc += u'您使用的%s号端口充电,共付款:%s元,充电预定时间为:%s分钟,剩余时间:%s分钟,给您退款:%s元' % (
-                                    lineInfo['port'], money, lineInfo['needTime'], leftTimeStr, backCoins)
-                            else:
-                                desc += u'您使用的%s号端口充电,共付款:%s元,充电预定电量为:%s度,使用:%s度,给您退款:%s元' % (
-                                    lineInfo['port'], money, lineInfo.get('needElec', 1), spendElec, backCoins)
-
-                            self.notify_user(user.managerialOpenId if user else '', 'refund_coins', **{
-                                'title': desc,
-                                'backCount': u'金币:%s' % backCoins,
-                                'finishTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
-                            })
-
-                #: 使用的是虚拟卡
-                elif vCardId is not None:
-                    billingType = lineInfo.get('billingType', 'time')
-                    if billingType == 'time':
-                        leftTimeStr = leftTime if leftTime != 65535 else lineInfo['needTime']
-                        title = u"\\n\\n结束原因:\\t\\t{reason}\\n\\n设备编号:\\t\\t{logicalCode}-{port}\\n\\n设备地址:\\t\\t{address}\\n\\n消费时间:\\t\\t动态功率计算{actualNeedTime}分钟\\n\\n剩余时间:\\t\\t{leftTimeStr}分钟".format(
-                            reason=self.event_data["reason"],
-                            logicalCode=self.device["logicalCode"],
-                            port=self.event_data["port"],
-                            address=group["address"],
-                            actualNeedTime=actualNeedTime,
-                            leftTimeStr=leftTimeStr
-                        )
-                    else:
-                        title = u"\\n\\n结束原因:\\t\\t{reason}\\n\\n设备编号:\\t\\t{logicalCode}-{port}\\n\\n设备地址:\\t\\t{address}\\n\\n购买电量:\\t\\t{needElec}\\n\\n消耗电量:\\t\\t{spendElec}".format(
-                            reason=self.event_data["reason"],
-                            logicalCode=self.device["logicalCode"],
-                            port=self.event_data["port"],
-                            address=group["address"],
-                            needElec=lineInfo.get("needElec", 1000),
-                            spendElec=spendElec
-                        )
-
-                    # 通知充电完成
-                    try:
-                        vCard = UserVirtualCard.objects.get(id=vCardId)
-                    except DoesNotExist:
-                        logger.info('can not find the vCard id = %s' % vCardId)
-                        return
-
-                    self.notify_user(
-                        managerialOpenId=self.get_managerialOpenId_by_openId(lineInfo["openId"]),
-                        templateName="service_complete",
-                        title=title,
-                        service=u"充电服务",
-                        finishTime=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
-                        remark = u'谢谢您的支持'
-                    )
-
-                    consumeDict = {'chargeIndex': lineInfo['port'], 
-                             'reason': lineInfo['reason'],
-                             'actualNeedTime':u'动态功率计算为%s分钟' % actualNeedTime,
-                             'duration':usedTime}
-                    consumeDict.update({'elec': spendElec})
-
-                    if billingType != 'time':
-                        consumeDict.update({'elec':spendElec})
-                        consumeDict.update({'elecFee':self.calc_elec_fee(spendElec)})
-                        
-                    ServiceProgress.update_progress_and_consume_rcd(
-                        self.device['ownerId'],
-                        {'open_id': lineInfo['openId'], 'device_imei': self.device['devNo'],
-                         'port': lineInfo['port'], 'isFinished': False}, consumeDict
-                    )
-
-                    consumeRcdId = lineInfo.get('consumeRcdId', None)
-                    if consumeRcdId is None:
-                        logger.info('can not find consume rcd id')
-                        return
-                    # 尝试进行虚拟卡退费
-                    try:
-                        vCardConsumeRcd = VCardConsumeRecord.objects.get(id=consumeRcdId)
-                    except DoesNotExist, e:
-                        logger.info('can not find the consume rcd id = %s' % consumeRcdId)
-                    else:
-                        vCard.refund_quota(vCardConsumeRcd, usedTime, spendElec, backCoins.mongo_amount)
-
-                #: 刷的实体卡
-                elif cardId != '':
-                    card = Card.objects.get(id=cardId)
-
-                    agent = Agent.objects.get(id=card.agentId)
-
-                    virtual_card = card.bound_virtual_card
-
-                    consumeDict = {'chargeIndex': lineInfo['port'],
-                                   'reason': lineInfo['reason'],
-                                   'actualNeedTime': u'动态功率计算为%s分钟' % actualNeedTime,
-                                   'duration': usedTime}
-                    consumeDict.update({'elec': spendElec})
-
-                    if billingType == 'time':
-                        self.notify_user(
-                            managerialOpenId=card.managerialOpenId,
-                            templateName="service_complete",
-                            title=u"\\n\\n结束原因:\\t\\t{reason}\\n\\n设备编号:\\t\\t{logicalCode}-{port}\\n\\n设备地址:\\t\\t{address}\\n\\n消费卡号:\\t\\t{cardNo}\\n\\n持卡姓名:\\t\\t{cardName}\\n\\n消费时间:\\t\\t动态功率计算{actualNeedTime}分钟\\n\\n剩余时间:\\t\\t{leftTimeStr}分钟".format(
-                                reason=self.event_data["reason"],
-                                logicalCode=self.device["logicalCode"],
-                                port=self.event_data["port"],
-                                address=group["address"],
-                                cardNo=card.cardNo,
-                                cardName=card.cardName,
-                                actualNeedTime=actualNeedTime,
-                                leftTimeStr=leftTimeStr
-                            ),
-                            service=u"充电服务",
-                            finishTime=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
-                            remark = u'谢谢您的支持')
-
-                        if 'huopo_card_time_refund' in agent.features and virtual_card is None:
-                            consumeDict.update({
-                                DEALER_CONSUMPTION_AGG_KIND.CONSUME_CARD: (money - backCoins).mongo_amount,
-                                DEALER_CONSUMPTION_AGG_KIND.REFUND_CARD: backCoins.mongo_amount
-                            })
-                            ServiceProgress.update_progress_and_consume_rcd(
-                                self.device['ownerId'],
-                                {'cardId': cardId, 'device_imei': self.device['devNo'],
-                                 'port': lineInfo['port'], 'isFinished': False},
-                                {'chargeIndex': lineInfo['port'], 'leftTime': leftTimeStr,
-                                 'needTime': u'刷卡订购%s分钟' % needTime if virtual_card is None else u'绑定虚拟卡订购%s分钟' % needTime, 
-                                 'reason': lineInfo['reason'],
-                                 'elec': spendElec, 'duration': usedTime,
-                                 'actualNeedTime': u'动态功率计算为%s分钟' % actualNeedTime,
-                                 'elecFee':self.calc_elec_fee(spendElec),
-                                 'refundedMoney': str(backCoins)
-                                 })
-                        else:
-                            ServiceProgress.update_progress_and_consume_rcd(
-                                self.device['ownerId'],
-                                {'cardId': cardId, 'device_imei': self.device['devNo'],
-                                 'port': lineInfo['port'], 'isFinished': False},
-                                {'chargeIndex': lineInfo['port'], 'leftTime': leftTimeStr,
-                                 'needTime': u'刷卡订购%s分钟' % needTime if virtual_card is None else u'绑定虚拟卡订购%s分钟' % needTime, 
-                                 'reason': lineInfo['reason'],
-                                 'elec': spendElec, 'duration': usedTime,
-                                 'actualNeedTime': u'动态功率计算为%s分钟' % actualNeedTime,
-                                 'elecFee':self.calc_elec_fee(spendElec)})
-
-                        if 'huopo_card_time_refund' in agent.features:
-                            if virtual_card is None:
-                                self.refund_money_for_card(backCoins, str(card.id))
-                                desc = u'您使用的%s号端口充电,共付款:%s元,充电预定时间为:%s分钟,使用:%s分钟,给您退款:%s元' % (
-                                    lineInfo['port'], money, needTime, usedTime, backCoins)
-
-                                self.notify_user(card.managerialOpenId if card else '', 'refund_coins', **{
-                                    'title': desc,
-                                    'backCount': u'金币:%s' % backCoins,
-                                    'finishTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')})
-                            else:
-                                consumeRcdId = lineInfo.get('consumeRcdId', None)
-                                if consumeRcdId is None:
-                                    logger.info('can not find consume rcd id')
-                                    return
-                                # 尝试进行虚拟卡退费
-                                try:
-                                    vCardConsumeRcd = VCardConsumeRecord.objects.get(id=consumeRcdId)
-                                except DoesNotExist, e:
-                                    logger.info('can not find the consume rcd id = %s' % consumeRcdId)
-                                else:
-                                    virtual_card.refund_quota(vCardConsumeRcd, usedTime, spendElec, backCoins.mongo_amount)
-                        # 非霍珀特性
-                        else:
-                            consumeRcdId = lineInfo.get('consumeRcdId', None)
-
-                            # 不是虚拟卡启动的直接结束掉
-                            if consumeRcdId is None:
-                                logger.info('can not find consume rcd id')
-                                return
-                            # 尝试进行虚拟卡退费
-                            try:
-                                vCardConsumeRcd = VCardConsumeRecord.objects.get(id=consumeRcdId)
-                            except DoesNotExist, e:
-                                logger.info('can not find the consume rcd id = %s' % consumeRcdId)
-                            else:
-                                virtual_card.refund_quota(vCardConsumeRcd, usedTime, spendElec, backCoins.mongo_amount)
-
-                        return
-                    else:
-                        self.notify_user(
-                            managerialOpenId=card.managerialOpenId,
-                            templateName="service_complete",
-                            title=u"\\n\\n结束原因:\\t\\t{reason}\\n\\n设备编号:\\t\\t{logicalCode}-{port}\\n\\n设备地址:\\t\\t{address}\\n\\n消费卡号:\\t\\t{cardNo}\\n\\n持卡姓名:\\t\\t{cardName}\\n\\n购买电量:\\t\\t{needElec}\\n\\n消耗电量:\\t\\t{spendElec}".format(
-                                reason=self.event_data["reason"],
-                                logicalCode=self.device["logicalCode"],
-                                port=self.event_data["port"],
-                                address=group["address"],
-                                cardNo=card.cardNo,
-                                cardName=card.cardName,
-                                needElec=lineInfo.get("needElec"),
-                                spendElec=spendElec
-                            ),
-                            service=u"充电服务",
-                            finishTime=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
-                            remark = u'谢谢您的支持')
-
-                        consumeDict = {'chargeIndex': lineInfo['port'], 'leftTime': leftTimeStr,
-                                       'reason': lineInfo['reason'],
-                                       'elec': spendElec, 'duration': usedTime, 'needElec': lineInfo['needElec']}
-                        consumeDict.update({'elecFee':self.calc_elec_fee(spendElec)})
-
-                        if not self.device.is_auto_refund:
-                            ServiceProgress.update_progress_and_consume_rcd(
-                                self.device['ownerId'],
-                                {'cardId': cardId, 'device_imei': self.device['devNo'],
-                                 'port': lineInfo['port'], 'isFinished': False}, consumeDict
-                            )
-                        else:
-                            if virtual_card is None: # 扫码退钱, 退到个人卡号
-                                self.refund_money_for_card(backCoins, str(card.id))
-
-                                consumeDict.update({
-                                    DEALER_CONSUMPTION_AGG_KIND.REFUND_CARD: backCoins.mongo_amount,
-                                    DEALER_CONSUMPTION_AGG_KIND.CONSUME_CARD: (money - backCoins).mongo_amount
-                                })
-
-                                desc = u'您使用的%s号端口充电,共付款:%s元,充电预定电量为:%s度,使用:%s度,给您退款:%s元' % (
-                                    lineInfo['port'], money, lineInfo.get('needElec', 0.0), spendElec, backCoins)
-
-                                self.notify_user(card.managerialOpenId if card else '', 'refund_coins', **{
-                                    'title': desc,
-                                    'backCount': u'金币:%s' % backCoins,
-                                    'finishTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
-                                })
-                            else:
-                                consumeRcdId = lineInfo.get('consumeRcdId', None)
-                                if consumeRcdId is None:
-                                    logger.info('can not find consume rcd id')
-                                    return
-
-                                # 尝试进行虚拟卡退费
-                                try:
-                                    vCardConsumeRcd = VCardConsumeRecord.objects.get(id=consumeRcdId)
-                                except DoesNotExist, e:
-                                    logger.info('can not find the consume rcd id = %s' % consumeRcdId)
-                                else:
-                                    virtual_card.refund_quota(vCardConsumeRcd, usedTime, spendElec, backCoins.mongo_amount)
-
-                            ServiceProgress.update_progress_and_consume_rcd(
-                                self.device['ownerId'],
-                                {'open_id': lineInfo['openId'], 'device_imei': self.device['devNo'],
-                                 'port': lineInfo['port'], 'isFinished': False}, consumeDict)
-
-                #: 消费类型为金币,则
-                elif consumeType == 'coin':
-                    CoinConsumeRcd = ConsumeRecord.objects.get(
-                        orderNo = lineInfo['consumeOrderNo'])  # type: ConsumeRecord
-                    CoinConsumeRcd.servicedInfo['elec'] = spendElec
-                    CoinConsumeRcd.servicedInfo['actualNeedTime'] = u'动态功率计算为%s分钟' % actualNeedTime
-                    CoinConsumeRcd.servicedInfo['needTime'] = u'投币订购%s分钟' % needTime
-                    CoinConsumeRcd.servicedInfo['reason'] = lineInfo['reason']
-                    CoinConsumeRcd.servicedInfo['chargeIndex'] = lineInfo['port']
-                    CoinConsumeRcd.finishedTime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
-                    CoinConsumeRcd.save()
-
-                    valueDict = {
-                        DEALER_CONSUMPTION_AGG_KIND.ELEC: spendElec,
-                        DEALER_CONSUMPTION_AGG_KIND.ELECFEE: self.calc_elec_fee(spendElec)
-                    }
-
-                    status = CoinConsumeRcd.update_agg_info(valueDict)
-                    if status:
-                        record_consumption_stats(CoinConsumeRcd)
-                    else:
-                        logger.error(
-                            '[update_progress_and_consume_rcd] failed to update_agg_info record=%r' % (CoinConsumeRcd,))
-
-            except Exception as e:
-                logger.exception('deal with jingneng devNo=%s event e=%s' % (devNo, e))
-            finally:
-                Device.clear_port_control_cache(devNo, str(self.event_data['port']))
-                dataDict = {'backMoney': backPrice, 'backCoins': str(backCoins.mongo_amount)}
-                if lineInfo.has_key('orderNo'):
-                    dataDict.update({'orderNo': lineInfo['orderNo']})
-                notify_event_to_north(self.dealer, self.device, level = Const.EVENT_NORMAL,
-                                      desc = self.event_data['reason'], dataDict=dataDict)
-                send_event_to_zhejiang(self.dealer, self.device, self.event_data)
-
-
-        #: 启动了端口,主要记录下投币数据
-        elif cmdCode == CMD_CODE.DEVICE_SUBMIT_OFFLINE_COINS_20:
-            consumeType = self.event_data['consumeType']
-            if consumeType == 'coin':
-                self.event_data.update({'startTime': datetime.datetime.now().strftime(Const.DATETIME_FMT)})
-
-                # 记录该端口累计需要的时间和钱,cardId
-                Device.update_port_control_cache(self.device['devNo'], self.event_data)
-
-                Accounting.recordOfflineCoin(self.device,
-                                             int(time.time()),
-                                             int(self.event_data['coins']),
-                                             port = self.event_data.get('port', None))
-
-                self.event_data.update({'needElec': self.event_data['elec']})
-                self.event_data.update({'consumeOrderNo': self.record_consume_for_coin(RMB(self.event_data['coins']))})
-                Device.update_port_control_cache(self.device['devNo'], self.event_data)
-
-            elif consumeType == 'card':
-                port = self.event_data['port']
-
-                consumeDict = {'chargeIndex': port, 'elec': self.event_data['elec'],
-                               'money': self.event_data['coins'], 'needTime': u'刷卡订购%s分钟' % self.event_data['needTime']}
-                queryDict = {'device_imei': self.device['devNo'],
-                             'port': -1, 'isFinished': False,
-                             'cardId': {'$ne': ''}, 'start_time': {'$gte': int(time.time()) - 3600}}
-                progressDict = {'port': port}
-
-                ServiceProgress.update_progress_and_consume_rcd(ownerId=self.device['ownerId'], queryDict=queryDict,
-                                                                consumeDict=consumeDict, updateConsume=True,
-                                                                progressDict=progressDict)
-
-                # 找出对应的卡的ID记录到端口内存数据
-                queryDict.update(progressDict)
-                rcds = ServiceProgress.get_collection().find(queryDict, {'cardId': 1, 'open_id': 1, "consumeOrder": 1},
-                                                             sort=[('start_time', -1)])
-                if rcds.count() == 0:
-                    return
-
-                rcd = rcds[0]
-                dev = Device.objects.get(devNo=self.device['devNo'])
-                billingType = dev.otherConf.get('billingType', 'time')
-
-                # 刷卡虚拟卡启动的时候,将consumeRcd 写入到缓存 退费的时候使用
-                consumeRcdId = rcd.get("consumeOrder", dict()).get("consumeRcdId")
-                if consumeRcdId:
-                    self.event_data.update({"consumeRcdId": consumeRcdId})
-
-                self.event_data.update({'billingType': billingType})
-                self.event_data.update({'cardId': rcd['cardId']})
-                self.event_data.update({'openId': rcd['open_id']})
-
-                cInfo = Device.get_dev_control_cache(devNo)
-                lastPortInfo = cInfo.get(str(port), {})
-                # 钱需要累计
-                lastCoins = lastPortInfo.get('coins', 0.0)
-                self.event_data.update({'coins': self.event_data['coins'] + lastCoins})
-
-                # 电量需要累加
-                lastNeedElec = lastPortInfo.get('needElec', 0.0)
-                self.event_data.update({'needElec': self.event_data['elec'] + lastNeedElec})
-
-                # 时间需要累加
-                lastNeedTime = lastPortInfo.get('needTime', 0.0)
-                self.event_data.update({'needTime': self.event_data['needTime'] + lastNeedTime})
-
-                self.event_data.update({'startTime': datetime.datetime.now().strftime(Const.DATETIME_FMT)})
-                self.event_data.update({'isStart': True, 'status': Const.DEV_WORK_STATUS_WORKING})
-
-                #: 记录该端口累计需要的时间和钱,cardId
-                Device.update_port_control_cache(self.device['devNo'], self.event_data)
-
-            elif consumeType == 'server':
-                port = self.event_data['port']
-                #: 记录该端口累计需要的时间和钱
-                Device.update_port_control_cache(self.device['devNo'], self.event_data)
-
-                consumeDict = {'chargeIndex': self.event_data['port'], 'elec': self.event_data['elec'],
-                               'needTime': u'订购%s分钟' % self.event_data['needTime']}
-                queryDict = {'device_imei': self.device['devNo'],
-                             'port': port, 'isFinished': False,
-                             'start_time': {'$gte': int(time.time()) - 3600}}
-                progressDict = {'port': self.event_data['port']}
-
-                ServiceProgress.update_progress_and_consume_rcd(ownerId=self.device['ownerId'],
-                                                                queryDict=queryDict, consumeDict=consumeDict,
-                                                                updateConsume=True, progressDict=progressDict)
-
-            # todo 功率过低告警还没做完
-            # openId = self.event_data['openId']
-            # if openId is not None:
-            #     user = MyUser.objects(openId=openId, groupId = self.device['groupId']).first()
-            #
-            #     report_to_user_low_power_wechat.delay(self.notify_low_power_to_user(user, 1, 20), 15)
-
-
-        else:
-            raise NoCommandHandlerAvailable('[JNDZ]] no command handler for cmd %s, curDevInfo=%s' % (cmdCode, self.event_data))
-
-    def response_use_card(self, res, leftBalance):
-        # 启动失败需要把金币还回去
-        try:
-            self.deviceAdapter.response_use_card(res, leftBalance)
-        except ServiceException as e:
-            logger.exception(e)
-            raise JNDZEventerFailure('failed to connect to device')
-
-    # todo 功率过低告警还没做完
-    # def notify_low_power_to_user(self, user, port, power):
-    #     self.notify_user(user.managerialOpenId if user else '', 'device_fault', **{
-    #         'title': u'设备充电功率过小预警',
-    #         'device': u'二维码编号:%s, 端口:%s' % (self.device['logicalCode'], port),
-    #         'location': u'您的电动车充电所在地',
-    #         'fault': u'端口功率过小, 当前功率检测: %s 瓦, 可能会影响正常充电。' % power,
-    #         'notifyTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
-    #     })
-
-

+ 0 - 41
apps/web/eventer/base.py

@@ -17,7 +17,6 @@ from apilib.monetary import VirtualCoin, RMB, Ratio
 from apilib.utils_string import make_title_from_dict
 from apilib.utils_sys import memcache_lock
 from apps.web.agent.models import Agent
-from apps.web.api.ykt_north.view import custQueryConsume,custquery
 from apps.web.south_intf.shangdong_platform import ShanDongNorther
 from apps.web.common.transaction import UserConsumeSubType
 from apps.web.constant import Const, FAULT_LEVEL, DeviceCmdCode, ErrorCode, DeviceErrorCodeDesc, \
@@ -855,46 +854,6 @@ class WorkEvent(Event):
         except Exception as e:
             logger.info(e)
 
-    def query_to_ykt_norther(self,cardNo):
-        resutl = custquery(cardNo)
-        code = resutl['resultCode']
-        if code == u'000000':
-            cardInfo = {
-                "customerId":resutl['result']['customerId'],
-                "userName":resutl['result']['userName'],
-                "userCode":resutl['result']['userCode'],
-                "oddFare":resutl['result']['oddFare'],
-                "custStatus":resutl['result']['custStatus'],
-                "cardNo":cardNo,
-            }
-            return{'code':code,'message':resutl['resultMsg'],'cardInfo':cardInfo}
-        elif code == u'999999':
-            return {'code': code, 'message': resutl['resultMsg'], 'cardInfo': {}}
-        elif code == u'555555':
-            return {'code': code, 'message': '刷卡异常', 'cardInfo': {}}
-
-    def notify_to_ykt_norther(self,cardSnr,orderNo,tradeFare,tradeDate):
-        """
-        刷卡后上报信息到一网通平台
-        如果推送失败会一直推送
-        """
-
-        circulation = 3
-        # 推送
-        while circulation>0:
-            result = custQueryConsume(cardSnr,orderNo,tradeFare,tradeDate)
-            resultCode = result.get('resultCode')
-            if resultCode == "000000":
-                circulation = 0
-            else:
-                circulation -= 1
-        return {
-            'resultCode':result.get('resultCode'),
-            'resultMsg':result.get('resultMsg'),
-            'orderNo':result.get('orderNo'),
-            'oddFare':result.get('oddFare')
-        }
-
     def refund_net_pay(self, user, lineInfo, refundedMoney, refundCoins, consumeDict, is_cash):
         # type: (MyUser, dict, RMB, VirtualCoin, dict, bool)->None
 

+ 0 - 5
apps/web/eventer/dianchuan.py

@@ -919,11 +919,6 @@ class DIANCHUANInductorEvent(FaultEvent):
         })
         super(DIANCHUANInductorEvent, self).do(**args)
 
-        # 判断经销是否支持,如果支持就上报给平台
-        if self.device.owner.supports("supportFengTu"):
-            from apps.web.api.ft_north.utils import alarmReport
-            alarmReport(self.device.devNo, faultName)
-
 
 class DIANCHUANAlertEvent(FaultEvent):
     def __Analyze_alert_data(self, data):

File diff suppressed because it is too large
+ 0 - 2075
apps/web/eventer/jndz.py


+ 0 - 7
apps/web/helpers.py

@@ -323,13 +323,6 @@ def get_platform_reconcile_pay_gateway():
     return PlatformPromotionApp.get_app().new_gateway(AppPlatformType.PLATFORM)
 
 
-def get_swap_env_pay_gateway(source):
-    app = get_app(source = source,
-                  app_type = APP_TYPE.SWAP_ENV_PAY,
-                  vistor = DealerCustomizedBrandVisitor)  # type: Optional[SwapPayApp]
-    return app.new_gateway(AppPlatformType.SWAP)
-
-
 def get_manual_pay_gateway(dealer):
     my_app = ManualPayApp.get_null_app()
     my_app.occupantId = str(dealer.id)

+ 0 - 5
apps/web/superadmin/urls.py

@@ -189,10 +189,6 @@ urlpatterns = patterns('',
 
                        url(r'^submitComplaint', submitComplaint, name='submitComplaint'),
 
-                       url(r'^getMerchantInfo', getMerchantInfo, name='getMerchantInfo'),
-                       url(r'^refreshMerchantInfo', refreshMerchantInfo, name='refreshMerchantInfo'),
-                       url(r'^wechatReplay', wechatReplay, name='wechatReplay'),
-
                        url(r'^getInsuranceOrder', getInsuranceOrder, name='getInsuranceOrder'),
                        url(r'^refundInsuranceOrder', refundInsuranceOrder, name='refundInsuranceOrder'),
                        url(r'^rentDevice', rentDevice, name='rentDevice'),
@@ -209,7 +205,6 @@ urlpatterns = patterns('',
                        url(r'^refundCashFromRecharge$', refundCashFromRecharge, name='refundCashFromRecharge'),
 
                        url(r'^setServiceButtonStatus$', setServiceButtonStatus, name='setServiceButtonStatus'),
-                       url(r'^getMerchantLog$', getMerchantLog, name='getMerchantLog'),
 
                        url(r'^getDealerBanks$', getDealerBanks, name='getDealerBanks'),
 

+ 0 - 91
apps/web/superadmin/views.py

@@ -48,9 +48,6 @@ from apps.web.device.timescale import SignalManager
 from apps.web.exceptions import UserServerException
 from apps.web.helpers import get_manual_pay_gateway
 from apps.web.management.models import Manager, DeviceReplacement
-from apps.web.merchant.constant import MerchantStatus
-from apps.web.merchant.models import MerchantSourceInfo, MerchantLog
-from apps.web.merchant.utils import get_wechat_proxy, MerchantApplyProxy
 from apps.web.promotion.models import InsuranceOrder
 from apps.web.superadmin import OfflineTaskType
 from apps.web.superadmin.models import SuperManager, WebLog
@@ -2826,94 +2823,6 @@ def submitComplaint(request):
         return JsonErrorResponse(description = u'接口回复失败')
 
 
-@error_tolerate(nil = DefaultJsonErrorResponse)
-@permission_required(ROLE.supermanager)
-def getMerchantInfo(request):
-    ownerId = request.GET.get("id")
-    dealer = Dealer.objects.get(id=ownerId)
-
-    merchant = MerchantSourceInfo.get_source_record(dealer)     # type: MerchantSourceInfo
-
-    payload = {
-        "id": str(merchant.id), "merchantType": merchant.merchantType, "status": merchant.merchantStatus, "regEmail": merchant.regEmail, "merchantNo": merchant.merchantNo,
-        "errorMsg": merchant.errorDescription,
-        "subMerchantId": merchant.wxSource.subMerchantId, "applymentId": merchant.wxSource.applymentId, "createdTime": merchant.dateTimeAdded,
-        "updateTime": merchant.dateTimeUpdated, "certificate": merchant.get_certificate_info(), "settle": merchant.get_settlement_info(),
-        "business": merchant.get_business_info()
-    }
-
-    return JsonOkResponse(payload = payload)
-
-
-@error_tolerate(nil = DefaultJsonErrorResponse)
-@permission_required(ROLE.supermanager)
-def wechatReplay(request):
-    merchant = MerchantSourceInfo.objects.get(id=request.GET["id"])     # type: MerchantSourceInfo
-
-    if merchant.merchantStatus in [
-        MerchantStatus.INIT, MerchantStatus.WAITING, MerchantStatus.FAIL,
-        MerchantStatus.CONFIRM, MerchantStatus.SUCCESS, MerchantStatus.AUTH_WAITING
-    ]:
-        return JsonErrorResponse(description=u"当前状态无需重新上传")
-
-    if merchant.merchantStatus == MerchantStatus.AUTH_SUCCESS:
-
-        return JsonErrorResponse(description=u"当前状态无需重新上传")
-
-    wxApplier = merchant.wxSource
-
-    if wxApplier.applymentId:
-        proxy = get_wechat_proxy()
-        proxy.cancel_merchant_apply(applyId=wxApplier.applymentId)
-
-    wxApplier.applymentId = ""
-    wxApplier.qrCodeData = ""
-    wxApplier.save()
-
-    merchant.status = int(MerchantStatus.CONFIRM)
-    merchant.save()
-
-    mer = MerchantSourceInfo.objects.get(id=merchant.id)
-
-    MerchantApplyProxy(mer).submit_wechat()
-
-    return JsonOkResponse()
-
-
-@error_tolerate(nil = DefaultJsonErrorResponse)
-@permission_required(ROLE.supermanager)
-def refreshMerchantInfo(request):
-    _id = request.GET.get("id")
-    try:
-        merchant = MerchantSourceInfo.objects.get(id=_id)
-    except DoesNotExist:
-        return JsonErrorResponse(u"未查询到商户信息")
-
-    proxy = MerchantApplyProxy(merchant)
-    proxy.query_merchant_audit()
-    proxy.query_auth_audit()
-    return JsonOkResponse()
-
-
-@error_tolerate(nil=DefaultJsonErrorResponse)
-@permission_required(ROLE.supermanager)
-def getMerchantLog(request):
-
-    """
-    获取商户的日志申请记录
-    """
-    _id = request.GET.get('id')
-    pageIndex = request.GET.get("pageIndex", 1)
-    pageSize = request.GET.get("pageSize", 10)
-
-    dataList = list()
-    query = MerchantLog.objects.filter(merchantId=_id).order_by('-dateTimeAdded')
-    for log in query.paginate(pageIndex=pageIndex, pageSize=pageSize):
-        dataList.append(log.to_dict())
-
-    return JsonOkResponse(payload={"total": query.count(), "dataList": dataList})
-
-
 @error_tolerate(nil = DefaultJsonErrorResponse)
 @permission_required(ROLE.supermanager)
 def rentDevice(request):

+ 2 - 54
apps/web/user/models.py

@@ -1399,47 +1399,6 @@ class RechargeRecordDict(dict):
 
         return partition_map
 
-    def attach_split_info(self, partitions):
-        agent_partitions = partitions.get(PARTITION_ROLE.AGENT, list())
-        if agent_partitions:
-            for agentShare in agent_partitions:
-                if RMB(agentShare['money']) > RMB(0):
-                    agent = Agent.objects.get(id = agentShare["id"])
-                    _email = agent.get_merchant_split_id()
-                    if not _email:
-                        logger.error(u"分账代理商未开通商户,agent id = {}".format(agentShare["id"]))
-                        raise UserServerException(u"分账代理商未开通商户")
-                    agentShare['merchantId'] = _email
-
-        partner_partitions = partitions.get(PARTITION_ROLE.PARTNER, list())
-        if partner_partitions:
-            for partnerShare in partner_partitions:
-                if RMB(partnerShare['money']) > RMB(0):
-                    dealer = Dealer.objects.get(id = partnerShare["id"])
-                    _email = dealer.get_merchant_split_id()
-
-                    if not _email:
-                        logger.error(u"分账代理商未开通商户,dealer id = {}".format(partnerShare["id"]))
-                        raise UserServerException(u"分账合伙人未开通商户")
-
-                    partnerShare['merchantId'] = _email
-
-        owner_partitions = partitions.get(PARTITION_ROLE.OWNER, list())
-
-        assert len(owner_partitions) == 1, u'经销商只能有一个'
-
-        ownerShare = owner_partitions[0]
-
-        if Percent(ownerShare["share"]) < Percent(1):
-            raise ValueError(u"dealer jd share should not lt 0.01")
-
-        if RMB(ownerShare['money']) <= RMB(0):
-            raise UserServerException(u"经销商商户配置错误")
-
-        ownerShare['merchantId'] = self.owner.get_merchant_split_id()
-
-        return partitions
-
     def calc_refund_partitions(self, pay_split_map):
         totalMoney = self.money
 
@@ -1922,11 +1881,7 @@ class RechargeRecord(OrderRecordBase):
             'withdrawSourceKey': gateway.withdraw_source_key()
         })
 
-        if gateway.pay_app_type in [PayAppType.WECHAT, PayAppType.WECHAT_MINI, PayAppType.ALIPAY]:
-            payload['extraInfo'].update({
-                'payOpenId': context.user.get_bound_pay_openid(gateway.bound_openid_key)
-            })
-        elif gateway.pay_app_type == PayAppType.JD_AGGR and gateway.gateway_type in [AppPlatformType.WECHAT, AppPlatformType.ALIPAY]:
+        if gateway.pay_app_type in [PayAppType.WECHAT, PayAppType.ALIPAY]:
             payload['extraInfo'].update({
                 'payOpenId': context.user.get_bound_pay_openid(gateway.bound_openid_key)
             })
@@ -2029,13 +1984,7 @@ class RechargeRecord(OrderRecordBase):
         if 'extraInfo' not in payload:
             payload['extraInfo'] = {}
 
-        if payment_gateway.pay_app_type in [PayAppType.WECHAT, PayAppType.WECHAT_MINI, PayAppType.ALIPAY]:
-            payload['extraInfo'].update({
-                'payOpenId': user.get_bound_pay_openid(payment_gateway.bound_openid_key)
-            })
-
-        elif payment_gateway.pay_app_type == PayAppType.JD_AGGR and \
-                payment_gateway.gateway_type in [AppPlatformType.WECHAT, AppPlatformType.ALIPAY]:
+        if payment_gateway.pay_app_type in [PayAppType.WECHAT, PayAppType.ALIPAY]:
             payload['extraInfo'].update({
                 'payOpenId': user.get_bound_pay_openid(payment_gateway.bound_openid_key)
             })
@@ -2216,7 +2165,6 @@ class RechargeRecord(OrderRecordBase):
             logger.exception(e)
 
     def new_refund_cash_order(self, refund_order): # type: (RefundMoneyRecord)->RechargeRecord
-
         payload = {}
 
         for field in self.__class__._fields_ordered:

+ 1 - 9
apps/web/user/tasks.py

@@ -24,6 +24,7 @@ from apps.web.user.models import RechargeRecord, UserVirtualCard, RefundMoneyRec
 from apps.web.promotion.models import InsuranceOrder, Insurance
 from apps.web.user.transaction import post_pay
 from apps.web.user.transaction_deprecated import refund_post_pay
+from apps.web.user.utils import get_consume_order
 from apps.web.utils import concat_front_end_url
 
 if TYPE_CHECKING:
@@ -350,12 +351,3 @@ def pull_refund_order():
             puller(refundOrder).pull(payGateway, payOrder, refund_post_pay)
         except Exception as e:
             logger.exception(e)
-
-
-def pull_consume_order_timeout(orderNo):
-    """
-    拉取消费订单是否会被超时
-    """
-    order = get_consume_order(orderNo)  # type: ConsumeRecord
-    if order.status == order.Status.WAIT_CONF:
-        order.to_failure(desc=u"订单支付超时")

+ 3 - 99
apps/web/user/transaction_deprecated.py

@@ -7,12 +7,11 @@ import time
 import uuid
 
 from pymongo.errors import DuplicateKeyError
-from typing import TYPE_CHECKING, Dict, Union, Any
+from typing import TYPE_CHECKING, Dict, Any
 
 from apilib.monetary import VirtualCoin, RMB
-from apps.web.common.transaction import OrderNoMaker, OrderMainType, RefundSubType
 from apps.web.common.transaction.pay import RefundManager
-from apps.web.constant import USER_RECHARGE_TYPE, PARTITION_ROLE, RechargeRecordVia
+from apps.web.constant import USER_RECHARGE_TYPE, RechargeRecordVia
 from apps.web.core import PayAppType, ROLE
 from apps.web.core.exceptions import ParameterError
 from apps.web.core.payment import PaymentGateway
@@ -22,10 +21,7 @@ from apps.web.device.models import Group
 from apps.web.exceptions import UserServerException
 from apps.web.user.conf import REFUND_NOTIFY_URL
 from apps.web.user.models import MyUser, RechargeRecord, RefundMoneyRecord
-
 from library.alipay import AliException
-from library.jd.exceptions import JDPayException
-from library.jdopen import JdOpenException
 from library.wechatbase.exceptions import WeChatPayException
 
 logger = logging.getLogger(__name__)
@@ -338,41 +334,7 @@ class RetryRefundCash(object):
 
         refund_order_record = self.refundOrder.refund_order_record
         if not refund_order_record:
-            if 'billSplitOfOwner' in self.paySubOrder.attachParas:  # 老的商户分账模式
-                if "billSplitList" in self.paySubOrder.attachParas:
-                    owner_split = self.paySubOrder.attachParas['billSplitOfOwner']
-                    owner_split['merchantId'] = owner_split.pop('splitBillMerchantEmail')
-                    owner_split['money'] = owner_split.pop('splitBillAmount')
-
-                    split_map = {
-                        PARTITION_ROLE.OWNER: [owner_split],
-                        PARTITION_ROLE.AGENT: [],
-                        PARTITION_ROLE.PARTNER: []
-                    }
-
-                    for spliter in self.paySubOrder.attachParas['billSplitList']:
-                        spliter['merchantId'] = spliter.pop('splitBillMerchantEmail')
-                        spliter['money'] = spliter.pop('splitBillAmount')
-
-                        if spliter['role'] == PARTITION_ROLE.AGENT:
-                            split_map[PARTITION_ROLE.AGENT].append(spliter)
-                        elif spliter['role'] == PARTITION_ROLE.PARTNER:
-                            split_map[PARTITION_ROLE.PARTNER].append(spliter)
-                        else:
-                            raise UserServerException(u'错误的分账角色')
-                else:
-                    owner_split = self.paySubOrder.attachParas['billSplitOfOwner']
-                    owner_split['merchantId'] = owner_split.pop('splitBillMerchantEmail')
-                    owner_split['money'] = owner_split.pop('splitBillAmount')
-
-                    split_map = {
-                        PARTITION_ROLE.OWNER: [owner_split],
-                        PARTITION_ROLE.AGENT: [],
-                        PARTITION_ROLE.PARTNER: []
-                    }
-            else:
-                split_map = proxy.partition_map
-
+            split_map = proxy.partition_map
             refund_order_record = self.paySubOrder.new_refund_cash_order(
                 self.refundOrder, split_map)  # type: RechargeRecord
 
@@ -381,7 +343,6 @@ class RetryRefundCash(object):
 
         # 扣除实体的金额(用户或者实体卡)
         frozen_callable(self.refundOrder, **kwargs)
-        # self.deduct_from_refund_order(self.refundOrder)
 
         try:
             if payGateway.pay_app_type == PayAppType.ALIPAY:
@@ -414,63 +375,6 @@ class RetryRefundCash(object):
                     raise UserServerException('{}({})'.format(e.errMsg, e.errCode))
 
                 logger.info('WECHAT Refund request successfully! return = {}'.format(result))
-
-            elif payGateway.pay_app_type == PayAppType.JD_AGGR:
-                try:
-                    result = payGateway.refund_to_user(
-                        out_trade_no = self.outTradeNo, out_refund_no = self.refundOrder.orderNo,
-                        refund_fee = self.refundFee,
-                        total_fee = self.totalFee, refund_reason = u'退费',
-                        refund_url = REFUND_NOTIFY_URL.WECHAT_REFUND_BACK,
-                        billSplitList = payGateway.refund_bill_split_list(refund_order_record.partition_map))
-                except JDPayException as e:
-                    logger.info('refund failed , refund orderNo = {} reason = {}'.format(self.refundOrder.orderNo, e))
-                    self.refundOrder.fail(errorCode = e.errCode, errorDesc = e.errMsg)
-                    raise UserServerException('{}({})'.format(e.errMsg, e.errCode))
-
-                logger.info('JDAGGRE Refund request successfully! return = {}'.format(result))
-
-            elif payGateway.pay_app_type == PayAppType.RCU:
-                # RUC 河南农村信用社 这个暂时不修改 不做回调处理 申请成功即认为成功
-                result = payGateway.refund_to_user(
-                    out_trade_no = self.outTradeNo, out_refund_no = self.refundOrder.orderNo,
-                    refund_fee = self.refundFee,
-                    total_fee = self.totalFee, refund_reason = u'退费')
-                if result['TransStatus'] not in ['1', '2']:  # 只要结果不是交易失败 或者交易撤销 都算退款成功
-                    finishedTime = datetime.datetime.now()
-
-                    matched = self.refundOrder.succeed("", finishedTime = finishedTime)
-                    if matched:
-                        refund_post_pay(self.refundOrder, finishedTime)
-
-                        self.refundOrder.update(attachParas__refund_to_user = result)
-                        logger.debug('RCU Refund request successfully! return = {}'.format(result))
-                    else:
-                        raise UserServerException(u'已经有退款订单正在运行')
-                else:
-                    logger.info('refund failed , refund orderNo = {} reason = {}'.format(self.refundOrder.orderNo,
-                                                                                         result['TransStatus']))
-                    self.refundOrder.fail(errorCode = result["TransStatus"])
-
-                    raise UserServerException(result["TransStatus"])
-
-            elif payGateway.pay_app_type == PayAppType.JD_OPEN:
-                try:
-                    result = payGateway.refund_to_user(
-                        out_trade_no = self.outTradeNo,
-                        out_refund_no = self.refundOrder.orderNo,
-                        refund_fee = self.refundFee,
-                        total_fee = self.totalFee,
-                        refund_reason = u'退费',
-                        callbackUrl = REFUND_NOTIFY_URL.JDOPEN_REFUND_BACK,
-                        ledgerInfoList = payGateway.refund_bill_split_list(refund_order_record.partition_map))
-                except JdOpenException as e:
-                    logger.info('refund failed , refund orderNo = {} reason = {}'.format(self.refundOrder.orderNo, e))
-                    self.refundOrder.fail(errorCode = e.errCode, errorDesc = e.errMsg)
-                    raise UserServerException('{}({})'.format(e.errMsg, e.errCode))
-
-                logger.info('JDAGGRE Refund request successfully! return = {}'.format(result))
-
             else:
                 self.refundOrder.fail(errorDesc = u"不支持的退款模式")
                 raise UserServerException(u"不支持的退款模式")

+ 0 - 2
apps/web/user/urls.py

@@ -281,8 +281,6 @@ urlpatterns = patterns('', *[
     url(r'^getMyMonthlyPackage$', getUserMonthlyPackage, name='getUserMonthlyPackage'),
     url(r'^getMonthlyPackageUseDetail$', getMonthlyPackageUseDetail,
         name='getMonthlyPackageUseDetail'),
-    url(r'^onsaleJdNewUser$', onsaleJdNewUser, name='onsaleJdNewUser'),
-    url(r'^onsaleJdNewUserReturn$', onsaleJdNewUserReturn, name='onsaleJdNewUserReturn'),
 
     # 农村信用社支付
     url(r'^supportPayment$', supportPayment, name='supportPayment'),

+ 3 - 9
apps/web/user/utils.py

@@ -207,15 +207,9 @@ def get_homepage_response(platform_type, user, dev, chargeIndex, product_agent):
 def auth_wechat_pay_app(user, dealer, product_agent, state, redirect_uri):
     # type:(MyUser, Dealer, Agent, UserAuthState, str)->Optional[HttpResponseRedirect]
 
-    if dealer.payByMerchant:
-        app = get_app(source = dealer,
-                      app_type = APP_TYPE.WECHAT_ENV_PAY,
-                      vistor = DealerCustomizedBrandVisitor,
-                      role = ROLE.myuser)
-    else:
-        app = get_app(source = product_agent,
-                      app_type = APP_TYPE.WECHAT_ENV_PAY,
-                      role = ROLE.myuser)  # type: PayAppBase
+    app = get_app(source = product_agent,
+                  app_type = APP_TYPE.WECHAT_ENV_PAY,
+                  role = ROLE.myuser)  # type: PayAppBase
 
     if isinstance(app, WechatPayApp):
         auth_bridge = WechatAuthBridge(app)  # type: WechatAuthBridge

+ 15 - 185
apps/web/user/views.py

@@ -26,12 +26,11 @@ from typing import TYPE_CHECKING, cast, Optional, Union, Tuple, Dict
 from voluptuous.error import MultipleInvalid
 
 from apilib.monetary import VirtualCoin, RMB
-from apilib.utils import fix_dict
 from apilib.utils_datetime import to_datetime, timestamp_to_dt
 from apilib.utils_json import JsonResponse
 from apilib.utils_string import cn
 #: ad
-from apilib.utils_sys import memcache_lock, MemcachedLock
+from apilib.utils_sys import memcache_lock
 from apilib.utils_url import add_query, before_frag_add_query
 from apps import serviceCache
 from apps.common.utils import coordinateHandler
@@ -49,14 +48,13 @@ from apps.web.core.auth.ali import AlipayAuthBridge
 from apps.web.core.auth.wechat import WechatAuthBridge
 from apps.web.core.bridge import WechatClientProxy
 from apps.web.core.exceptions import ServiceException, InvalidParameter, InvalidFileSize, \
-    InvalidFileName, JOSError, InterceptException
+    InvalidFileName, InterceptException
 from apps.web.core.file import AliOssFileUploader
 from apps.web.core.helpers import ActionDeviceBuilder
 from apps.web.core.messages.sms import userMobileVerifySMSProvider
-from apps.web.core.models import WechatPayApp, BoundOpenInfo, JDAggrePayApp, WechatAuthApp
-
+from apps.web.core.models import WechatPayApp, BoundOpenInfo, WechatAuthApp
 from apps.web.core.sysparas import SysParas
-from apps.web.core.utils import DefaultJsonErrorResponse, async_operation_no_catch
+from apps.web.core.utils import DefaultJsonErrorResponse
 from apps.web.core.utils import JsonErrorResponse, JsonOkResponse
 from apps.web.dealer.models import Dealer, OnSale, OnSaleRecord, VirtualCard, Complaint, \
     DealerMessage
@@ -67,7 +65,7 @@ from apps.web.device.models import GroupDict
 from apps.web.device.utils import device_control_cache_key
 from apps.web.exceptions import UserServerException
 from apps.web.helpers import get_ali_auth_bridge, get_wx_config, get_wechat_auth_bridge, \
-    get_user_manager_agent, get_app, DealerCustomizedBrandVisitor, start_device_lock_key
+    get_user_manager_agent, get_app, start_device_lock_key
 from apps.web.management.models import Manager
 from apps.web.services.bluetooth.service import ActionBtDeviceBuilder
 #: user
@@ -78,29 +76,24 @@ from apps.web.user.conf import USER_AUTH_REDIRECT_URL, PAY_NOTIFY_URL
 from apps.web.user.models import MyUser, ConsumeRecord, RechargeRecord, ServiceProgress, Card, CardRechargeRecord, \
     CardConsumeRecord, CardRechargeOrder, UserVirtualCard, VCardConsumeRecord, \
     RefundMoneyRecord, MoniUser, VirtualCardRechargeRecord, SwapCardRecord, MonthlyPackage, \
-    EndUserLocation, Redpack,MyUserDetail
+    EndUserLocation, Redpack, MyUserDetail
 from apps.web.user.transaction import post_pay
 from apps.web.user.transaction_deprecated import refund_post_pay
 from apps.web.user.utils import (
     get_homepage_response, auth_wechat_pay_app,
     auth_wechat_manager_app, login_required,
     user_last_time_use_ended_cache, parse_auth_payload, batteryInfo,
-    is_need_renew, check_user_tel, check_black_user, PayParam, BUILDER_MAP, RechargeRecordBuilder,
-    RedpackBuilder)
+    is_need_renew, check_user_tel, check_black_user, PayParam, BUILDER_MAP, RedpackBuilder)
 from apps.web.user.utils2 import get_user_not_complete_order
 from apps.web.user.validation import feedbackSchema
 from apps.web.utils import (
-    detect_alipay_client, detect_wechat_client, permission_required, error_tolerate, detect_jdpay_client,
-    ErrorResponseRedirect,
-    NotSupportedPlatformResponseRedirect, detect_jdjr_client, get_start_key_status, set_start_key_status,
+    detect_alipay_client, detect_wechat_client, permission_required, error_tolerate, ErrorResponseRedirect,
+    NotSupportedPlatformResponseRedirect, get_start_key_status, set_start_key_status,
     NetDeviceResponseRedirect, AdAccessResponseRedirect, ExternalResponseRedirect,
-    FrontEndResponseRedirect, concat_server_end_url, UserCenterResponseRedirect, concat_user_cardTicketList_entry_url,
+    FrontEndResponseRedirect, concat_server_end_url, concat_user_cardTicketList_entry_url,
     record_operation_behavior, get_client_ip, WechatAuthDummyRedirect, trace_call, concat_user_recharge_url)
 from apps.web.wrapper import request_limit_by_user
 from library.alipay.exceptions import AliException
-from library.dlb import DlbException
-from library.jd.exceptions import JDException
-from library.jdopen.exceptions import JdOpenException
 from library.wechatbase.exceptions import WechatOAuthDummyException
 from taskmanager.mediator import task_caller
 
@@ -437,7 +430,7 @@ def wxpayBaseAccess(request):
     """
 
     def authorize(app, request):
-        # type: (Optional[WechatPayApp, JDAggrePayApp], WSGIRequest)->None
+        # type: (Optional[WechatPayApp], WSGIRequest)->None
 
         if isinstance(app, WechatPayApp):
             code = request.GET.get('code', None)
@@ -448,24 +441,6 @@ def wxpayBaseAccess(request):
             openId = auth_bridge.authorize(code)
             user.set_bound_pay_openid(auth_bridge.bound_openid_key, openId = openId)
             user.save()
-        elif isinstance(app, JDAggrePayApp):
-            if app.boundAppId and app.boundSecret:
-                code = request.GET.get('code', None)
-                if not code:
-                    raise InvalidParameter(u'参数错误,请重新扫码({})'.format(ErrorCode.AUTH_CODE_IS_NULL))
-
-                auth_bridge = WechatAuthBridge(WechatAuthApp(appid = app.boundAppId, secret = app.boundSecret))
-                openId = auth_bridge.authorize(code)
-                user.set_bound_pay_openid(auth_bridge.bound_openid_key, openId = openId)
-                user.save()
-            else:
-                openId = request.GET.get('openId', None)
-                if openId is None:
-                    raise UserServerException(u'参数错误,请重新扫码({})'.format(ErrorCode.AUTH_ERROR))
-
-                auth_bridge = JDAggreAuthBridge(app, AppPlatformType.WECHAT)
-                user.set_bound_pay_openid(auth_bridge.bound_openid_key, openId = openId)
-                user.save()
 
     try:
         if 'code' not in request.GET and 'openId' not in request.GET:
@@ -481,15 +456,9 @@ def wxpayBaseAccess(request):
 
         product_agent = Agent.objects(id = str(state.productAgentId)).get()
 
-        if dev.owner.payByMerchant:
-            app = get_app(source = dev.owner,
-                          app_type = APP_TYPE.WECHAT_ENV_PAY,
-                          vistor = DealerCustomizedBrandVisitor,
-                          role = ROLE.myuser)
-        else:
-            app = get_app(source = product_agent,
-                          app_type = APP_TYPE.WECHAT_ENV_PAY,
-                          role = ROLE.myuser)  # type: PayAppBase
+        app = get_app(source = product_agent,
+                      app_type = APP_TYPE.WECHAT_ENV_PAY,
+                      role = ROLE.myuser)  # type: PayAppBase
 
         authorize(app, request)
 
@@ -4465,98 +4434,6 @@ def onsaleTicketList(request):
     return JsonResponse({"result": 1, "description": '', "payload": {'url': encodeUrl}})
 
 
-@permission_required(ROLE.myuser)
-def onsaleJdNewUser(request):
-    """
-    京东的用户的拉新活动
-    主要处理三件事情
-    1. 获取经销商的京东拉新的配置资格
-    2. 获取经销商配置的京东拉新的 活动金币兑换比值
-    3. 引用接口 对京东进行预下单 获取预下单的链接返回前台跳转支付即可
-    :param request:
-    :return:
-    """
-    onsaleId = request.GET.get("onsaleId")
-    logicalCode = request.GET.get("logicalCode")
-    dev = Device.get_dev_by_l(logicalCode)
-
-    # 再次检查用户的资格
-    if OnSaleRecord.objects.filter(
-            onsaleId = onsaleId,
-            userId = request.user.openId
-    ).count():
-        return JsonErrorResponse(description = u"您已参加活动,无法重复参加哦")
-
-    # 再次查验活动的有效性 防止用户停留界面后点击
-    nowTime = datetime.datetime.now()
-    onsale = OnSale.objects.filter(
-        status = 'start',
-        dealerId = dev.ownerId,
-        logicalCodeList = logicalCode,
-        startTime__lte = nowTime,
-        endTime__gte = nowTime
-    ).first()
-
-    # 客户端的前置检查
-    if detect_wechat_client(request):
-        clientEnv = "wechat"
-    elif detect_alipay_client(request):
-        return JsonErrorResponse(description = u"暂不支持支付宝,请使用微信扫码参加活动")
-    elif detect_jdpay_client(request) or detect_jdjr_client(request):
-        clientEnv = "jd"
-    else:
-        return JsonErrorResponse(description = u"暂不支持该扫码方式,请使用微信扫码参加活动")
-
-    # TODO 获取经销商 配置的拉新活动的 比值
-    money = RMB(2.01)
-    coins = VirtualCoin(onsale.detailDict.get("coins", 2))
-
-    # 调用jos支付接口 获取预下单的链接
-    # 3.1 先建立JOS支付的订单
-    try:
-        record = RechargeRecordBuilder.new_jd_new_user_recharge_record(request.user, dev, money, coins, clientEnv,
-                                                                       onsale)
-    except JOSError as je:
-        return JsonErrorResponse(description = je.message)
-
-    return JsonResponse({"result": 1, "description": "", "payload": {"url": record.extraInfo["josLink"]}})
-
-
-def onsaleJdNewUserReturn(request):
-    """
-    京东会有一个支付成功之后的return的url界面 在这个界面之中 记录下用户的充值行为
-    注意 这个并不是支付结果通知 而是支付之后的返回界面
-    <QueryDict: {u'orderId': [u'197770777103'], u'orderPrice': [u'0.01'], u'payId': [u'6eec85163b934c309581242eec73d9cb'], u'l': [u'zjl'], u'appId': [u'jd_m_hym']}>
-    :param request:
-    :return:
-    """
-    logicalCode = request.GET.get("logicalCode")
-    openId = request.GET.get("openId")
-    onsaleId = request.GET.get("onsaleId")
-
-    # TODO 这个地方可以丢上一个poller 主动拉取结果 但没必要
-    orderNo = request.GET.get("orderNo")
-
-    # 记录下该用户已经参加了活动
-    try:
-        OnSaleRecord(
-            onsaleId = onsaleId,
-            userId = openId,
-            nickName = request.user.nickname,
-            addedTime = datetime.datetime.now(),
-            onsaleDetail = {}
-        ).save()
-    except Exception as e:
-        logger.exception(e)
-
-    if logicalCode:
-        homePageRedirect = NetDeviceResponseRedirect(l = logicalCode)
-    else:
-        homePageRedirect = UserCenterResponseRedirect()
-
-    return homePageRedirect
-
-
 @permission_required(ROLE.myuser)
 def sendCodeForVerify(request):
     # type: (WSGIRequest)->JsonResponse
@@ -5594,7 +5471,7 @@ def payGateway(request):
     except UserServerException as e:
         logger.error(e.message)
         return JsonErrorResponse(e.message)
-    except (AliException, DlbException, JDException, JdOpenException) as e:
+    except AliException as e:
         logger.error(str(e))
         return JsonErrorResponse(description=e.message)
     except Exception as e:
@@ -6272,9 +6149,6 @@ def gatewayEntry(request):
 
     # 首先判断登录的平台 只有微信扫码的需要获取其支付的openId
     if detect_wechat_client(request):
-        if pay_gateway.pay_app_type == PayAppType.RCU:
-            return RCU_process(payParam)
-
         if pay_gateway.pay_app_type == PayAppType.WECHAT:
             authBridge = WechatAuthBridge(pay_gateway.app)
 
@@ -6283,51 +6157,11 @@ def gatewayEntry(request):
                 return get_pay_gateway_redirect(payParam, adLink)
             else:
                 return get_auth_redirect(payParam, authBridge, adLink)
-
-        elif pay_gateway.pay_app_type == PayAppType.JD_AGGR:
-
-            app = pay_gateway.app
-            if app.boundAppId and app.boundSecret:
-
-                authBridge = WechatAuthBridge(WechatAuthApp(appid = app.boundAppId, secret = app.boundSecret))
-
-                payOpenId = curUser.get_bound_pay_openid(authBridge.bound_openid_key)
-                if payOpenId:
-                    return get_pay_gateway_redirect(payParam, adLink)
-                else:
-                    return get_auth_redirect(payParam, authBridge, adLink)
-            else:
-                authBridge = JDAggreAuthBridge(app, AppPlatformType.WECHAT)
-
-                payOpenId = curUser.get_bound_pay_openid(authBridge.bound_openid_key)
-                if payOpenId:
-                    return get_pay_gateway_redirect(payParam, adLink)
-                else:
-                    return get_auth_redirect(payParam, authBridge, adLink)
-
-        # 哆啦宝支付、易生支付、扫呗支付的时候 不需要获取鉴权openId
-        elif pay_gateway.pay_app_type == PayAppType.DLB:
-            return get_pay_gateway_redirect(payParam, adLink)
-
-        elif pay_gateway.pay_app_type == PayAppType.SAOBEI:
-            return get_pay_gateway_redirect(payParam, adLink)
-
-        elif pay_gateway.pay_app_type == PayAppType.YS:
-            return get_pay_gateway_redirect(payParam, adLink)
-
         else:
             return JsonErrorResponse(description = u"平台配置错误,请稍后再试")
 
     # 支付宝平台登录
     elif detect_alipay_client(request):
-        if pay_gateway.pay_app_type == PayAppType.RCU:
-            if pay_gateway.pay_app_type == PayAppType.RCU:
-                return RCU_process(payParam)
-
-        return get_pay_gateway_redirect(payParam, adLink)
-
-    # 京东平台登录
-    elif detect_jdpay_client(request) or detect_jdjr_client(request):
         return get_pay_gateway_redirect(payParam, adLink)
 
     # 其他平台暂时不支持
@@ -6461,10 +6295,6 @@ def supportPayment(request):
     if dealer is None:
         return JsonErrorResponse(description = u'该设备未注册,暂时无法使用支付宝或者微信支付, 请投币(1013)')
 
-    if dealer.customizedMerchantApp and dealer.customizedMerchantApp.pay_app_type == PayAppType.RCU:
-        return JsonOkResponse(
-            payload = {"supportPayment": PayAppType.RCU, 'payUrl': dealer.customizedMerchantApp.authCodeUrl})
-
     return JsonOkResponse(description = u'无商户配置')
 
 

+ 1 - 8
configs/base.py

@@ -441,8 +441,7 @@ TELL_MANAGER = True
 
 WECHAT_PUSH_ENABLED = True
 
-SERVICE_DOMAIN = enum_define(MINI_WECHAT = 'miniw',
-                             USER = 'MyUser',
+SERVICE_DOMAIN = enum_define(USER = 'MyUser',
                              DEALER = 'Dealer',
                              SUBACCOUNT = 'SubAccount',
                              AGENT = 'Agent',
@@ -552,12 +551,6 @@ JWT_SERVICE_DOMAIN_MAP = {
 }
 
 JWT_AUTH = {
-    'miniw': {
-        'PAYLOAD_TO_USER': 'apps.web.miniuser.auth.payload_to_user',
-        'USER_TO_PAYLOAD': 'apps.web.miniuser.auth.user_to_payload',
-        'USER_KEY': 'openId',
-        'SECRET': '9ca1d0f956cf323666b3a4a037696703',
-    },
     SERVICE_DOMAIN.USER: {
         'PAYLOAD_TO_USER': 'apps.web.user.auth.payload_to_user',
         'USER_TO_PAYLOAD': 'apps.web.user.auth.user_to_payload',

File diff suppressed because it is too large
+ 0 - 535
library/RuralCreditUnion/pay.py


+ 0 - 79
library/jd/pay.py

@@ -503,82 +503,3 @@ class JDAggrePay(object):
 
         result = self.post(endpoint = '/m/queryrefund', data = data)
         return result
-
-
-class JDJosPay(JDAggrePay):
-    """
-    JD JOS 支付的相关接口 加解密方式和JDAGGRE一直 但是部分字段实现不一致
-    """
-    def api_trade_query(self, out_trade_no=None, trade_no=None):
-        shopInfo = getattr(self, "shopInfo", None)
-        assert out_trade_no or trade_no, 'out_trade_no and trade_no must not be empty at the same time'
-        assert shopInfo, "shop info must be confided to josPayApp"
-
-        businessData = OrderedDict([
-            ("brandId", shopInfo.brandId),
-            ("brandName", shopInfo.brandName),
-            ("tradeName", shopInfo.tradeName),
-            ("bizId", shopInfo.bizId)
-        ])
-
-        params = {
-            'merchantNo': str(self.merchant_no),
-            'businessCode': 'MEMBER',
-            'shopId': shopInfo.exStoreId,
-            'version': 'V3.0',
-            'businessData': json.dumps(businessData, separators=(",", ":")),
-            'outTradeNo': str(out_trade_no),
-        }
-
-        if trade_no:
-            params.update({'trandNo': trade_no})
-
-        sign = self.sign(params, ['systemId', 'sign'])
-        cipher_json = self.encrypt(params, ['systemId', 'sign'])
-
-        data = {
-            'systemId': self.systemId,
-            'merchantNo': self.merchant_no,
-            'cipherJson': cipher_json,
-            'sign': sign
-        }
-
-        result = self.post(endpoint='/m/querytrade', data=data)
-        return result
-
-
-    def api_trade_refund(self, outTradeNo, outRefundNo, amount, **kwargs):
-
-        shopInfo = getattr(self, "shopInfo", None)
-        assert outTradeNo and outRefundNo, 'outTradeNo and tradeNo must not be empty'
-        assert shopInfo, "shop info must be confided to josPayApp"
-
-        businessData = OrderedDict([
-            ("brandId", shopInfo.brandId),
-            ("brandName", shopInfo.brandName),
-            ("tradeName", shopInfo.tradeName),
-            ("bizId", shopInfo.bizId)
-        ])
-
-        params = {
-            "merchantNo": str(self.merchant_no),
-            "businessCode": "MEMBER",
-            "version": "V3.0",
-            "outTradeNo": str(outTradeNo),
-            "outRefundNo": str(outRefundNo),
-            "amount": amount,
-            "operId": kwargs.get("operId") or "SYSTEM_AUTO",
-            "shopId": shopInfo.exStoreId,
-            'businessData': json.dumps(businessData, separators=(",", ":")),
-        }
-        sign = self.sign(params, ['systemId', "sign"])
-        cipher_json = self.encrypt(params, ["systemId", "sign"])
-
-        data = {
-            'systemId': self.systemId,
-            'merchantNo': self.merchant_no,
-            'cipherJson': cipher_json,
-            'sign': sign
-        }
-        result = self.post(endpoint='/m/refund', data=data)
-        return result

+ 3 - 347
library/jdpsi/client.py

@@ -1,350 +1,6 @@
-# coding=utf-8
-import base64
-import datetime
-import hashlib
-import json
-import logging
-import random
-import time
-from binascii import hexlify
-from collections import Iterable
-from urlparse import urljoin
-
-import requests
-from Crypto.Cipher import DES3
-
-from apilib.monetary import JDMerchantPermillage
-from library.jdpsi.constants import JdPsiErrorCode, ACCESS_KEY
-from library.jdpsi.exceptions import JdPsiException
+# -*- coding: utf-8 -*-
+# !/usr/bin/env python
 
+import logging
 
 logger = logging.getLogger(__name__)
-
-
-class MyEncoder(json.JSONEncoder):
-
-    def default(self, obj):
-        if isinstance(obj, JDMerchantPermillage):
-            return obj.to_jd_params()
-        return super(MyEncoder, self).default(obj)
-
-
-class JdPsiMerchantClient(object):
-    BASE_URL = "https://psi.jd.com"
-
-    def __init__(self, accessKey=None):
-        self.accessKey = accessKey or ACCESS_KEY
-
-    def pad(self):
-        pass
-
-    @staticmethod
-    def sign(*args):
-        h = hashlib.md5()
-        h.update("".join((str(_)for _ in args)))
-        return h.hexdigest()
-
-    @staticmethod
-    def pad(rawJson):
-        # 转换为字节数组
-        rawBytes = bytes.encode(rawJson, encoding="utf-8")
-        rawBytesLen = len(rawBytes)
-
-        # 计算补位
-        x = (rawBytesLen + 4) % 8
-        y = 0 if x == 0 else 8 - x
-
-        # 将有效数据长度byte[]添加到原始byte数组的头部
-        resultBytes = bytearray(rawBytesLen + 4 + y)
-        resultBytes[0] = (rawBytesLen >> 24) & 0xFF
-        resultBytes[1] = (rawBytesLen >> 16) & 0xFF
-        resultBytes[2] = (rawBytesLen >> 8) & 0xFF
-        resultBytes[3] = rawBytesLen & 0xFF
-
-        # 填充补位数据
-        for i in range(rawBytesLen):
-            resultBytes[4 + i] = ord(rawBytes[i])
-
-        for i in range(y):
-            resultBytes[rawBytesLen + 4 + i] = 0x00
-
-        return bytes(resultBytes)
-
-    def encrypt(self, raw):
-        plaintext = json.dumps(raw, sort_keys=True, separators=(',', ':'), cls=MyEncoder)
-
-        key = base64.b64decode(self.accessKey)
-
-        cipher = DES3.new(key, DES3.MODE_ECB)
-        encrypt_bytes = cipher.encrypt(JdPsiMerchantClient.pad(plaintext))
-        return hexlify(encrypt_bytes)
-
-    def _handle_result(self, res, **kwargs):
-        try:
-            result = json.loads(res.content.decode('utf-8', 'ignore'), strict=False)
-        except (TypeError, ValueError, json.JSONDecodeError):
-            logger.debug(u'错误的解析结构', exc_info=True)
-            result = res
-
-        if "code" not in result:
-            return result
-
-        if result["code"] == JdPsiErrorCode.SUCCESS:
-            return result
-
-        if result["code"] in []:
-            return self._request(kwargs["path"], kwargs["agentNo"], kwargs["entity"], kwargs["images"], kwargs["signField"])
-
-        raise JdPsiException(
-                errCode='{}'.format(result["code"]),
-                errMsg=result["message"],
-                client=self,
-            )
-
-    def _request(self, path, agentNo, entity, images=None, signField=None):
-
-        # 添加 签名标签
-        if signField and isinstance(signField, Iterable):
-            sign = JdPsiMerchantClient.sign(*(entity.get(_) for _ in signField))
-            entity.update({"sign": sign})
-
-        # 组织报文
-        data = {
-            "agentNo": agentNo,
-            "entity": self.encrypt(entity)
-        }
-
-        # 图片文件
-        if images and isinstance(images, dict):
-            files = {_k: (_k, _v, "image/png") for _k, _v in images.items()}
-        else:
-            files = None
-
-        url = urljoin(JdPsiMerchantClient.BASE_URL, path)
-
-        try:
-            res = requests.post(url=url, data=data, files=files)
-        except requests.Timeout:
-            raise JdPsiException(
-                errCode='timeout',
-                errMsg="timeout",
-                client=self
-            )
-        else:
-            try:
-                res.raise_for_status()
-            except requests.RequestException as rre:
-                raise JdPsiException(
-                    errCode='HTTP{}'.format(res.status_code),
-                    errMsg=rre.message,
-                    client=self,
-                    request=rre.request,
-                    response=rre.response
-                )
-
-        return self._handle_result(
-            res, path=path, agentNo=agentNo, entity=entity, images=images, signField=signField
-        )
-
-    def create_customer(
-            self, agentNo, blicUrla, lepUrla, lepUrlb, lepUrlc, img, enterimg, innerimg, cardPhoto, settleManPhotoFront,
-            settleManPhotoBack, settleHoldingIDCard,
-            companyType, serialNo, regEmail, regPhone, blicCardType, blicCompanyName, abMerchantName, indTwoCode, blicProvince,
-            blicCity, blicAddress, blicLongTerm, blicValidityStart, blicValidityEnd, lepCardType, lepName, lepCardNo, lepLongTerm,
-            lepValidityStart, lepValidityEnd, contactName, contactPhone, contactEmail, contactProvince, contactCity, contactAddress,
-            ifPhyStore, storeProvince, storeCity, storeAddress, settleToCard, priatePublic, bankName, subBankCode, bankAccountNo,
-            bankAccountName, settleCardPhone, settlementPeriod, directoryList,
-            occUrla=None, blicUscc=None, blicScope=None, merchantNo=None
-    ):
-        images = {
-            "blicUrla": blicUrla,
-            "lepUrla": lepUrla,
-            "lepUrlb": lepUrlb,
-            "lepUrlc": lepUrlc,
-            "img": img,
-            "enterimg": enterimg,
-            "innerimg": innerimg,
-            "cardPhoto": cardPhoto,
-            "settleManPhotoFront": settleManPhotoFront,
-            "settleManPhotoBack": settleManPhotoBack,
-            "settleHoldingIDCard": settleHoldingIDCard
-        }
-        occUrla and images.update({"occUrla": occUrla})
-
-        entity = {
-            "companyType": companyType,
-            "serialNo": serialNo,
-            "agentNo": agentNo,
-            "regEmail": regEmail,
-            "regPhone": regPhone,
-            "blicCardType": blicCardType,
-            "blicCompanyName": blicCompanyName,
-            "abMerchantName": abMerchantName,
-            "indTwoCode": indTwoCode,
-            "blicProvince": blicProvince,
-            "blicCity": blicCity,
-            "blicAddress": blicAddress,
-            "blicLongTerm": blicLongTerm,
-            "blicValidityStart": blicValidityStart,
-            "blicValidityEnd": blicValidityEnd,
-            "lepCardType": lepCardType,
-            "lepName": lepName,
-            "lepCardNo": lepCardNo,
-            "lepLongTerm": lepLongTerm,
-            "lepValidityStart": lepValidityStart,
-            "lepValidityEnd": lepValidityEnd,
-            "contactName": contactName,
-            "contactPhone": contactPhone,
-            "contactEmail": contactEmail,
-            "contactProvince": contactProvince,
-            "contactCity": contactCity,
-            "contactAddress": contactAddress,
-            "ifPhyStore": ifPhyStore,
-            "storeProvince": storeProvince,
-            "storeCity": storeCity,
-            "storeAddress": storeAddress,
-            "settleToCard": settleToCard,
-            "priatePublic": priatePublic,
-            "bankName": bankName,
-            "subBankCode": subBankCode,
-            "bankAccountNo": bankAccountNo,
-            "bankAccountName": bankAccountName,
-            "settleCardPhone": settleCardPhone,
-            "settlementPeriod": settlementPeriod,
-            "directoryList": directoryList
-        }
-        blicUscc and entity.update({"blicUscc": blicUscc})
-        blicScope and entity.update({"blicScope": blicScope})
-        merchantNo and entity.update({"merchantNo": merchantNo})
-
-        logger.info("[create_customer] agentNo={}, entity={}".format(
-            agentNo, entity
-        ))
-
-        path = "/merchant/enterSingle"
-        return self._request(path=path, agentNo=agentNo, entity=entity, images=images, signField=[
-            "serialNo", "lepCardNo", "bankAccountNo", "settleCardPhone"
-        ])
-
-    def create_product(self, agentNo, serialNo, merchantNo, productId, payToolId, mfeeType, mfee=None, ladderList=None):
-        """
-        创建 结算 支付 产品
-        """
-        logger.info("[create_product] agentNo={}, serialNo={}, merchantNo={}, productId={}, payToolId={}, mfeeType={}, mfee={}, ladderList={}".format(
-            agentNo, serialNo, merchantNo, productId, payToolId, mfeeType, mfee, ladderList
-        ))
-
-        entity = {
-            "agentNo": agentNo,
-            "serialNo": serialNo,
-            "merchantNo": merchantNo,
-            "productId": productId,
-            "payToolId": payToolId,
-            "mfeeType": mfeeType
-        }
-        if mfee:
-            entity.update({"mfee": mfee})
-        if ladderList:
-            entity.update({"ladderList": ladderList})
-
-        path = "/merchant/applySingle"
-        return self._request(path=path, agentNo=agentNo, entity=entity, signField=[
-            "serialNo", "agentNo", "merchantNo", "productId", "payToolId"
-        ])
-
-    def query_product(self, agentNo, serialNo, merchantNo):
-        """
-        查询产品信息
-        """
-        logger.info("[query_product] agentNo={}, serialNo={}, merchantNo={}".format(
-            agentNo, serialNo, merchantNo
-        ))
-
-        entity = {
-            "agentNo": agentNo,
-            "serialNo": serialNo,
-            "merchantNo": merchantNo
-        }
-        path = "/merchant/status/queryApplySingle"
-        return self._request(path=path, agentNo=agentNo, entity=entity, signField=[
-            "serialNo", "merchantNo"
-        ])
-
-    def query_secret_key(self, agentNo, serialNo, merchantNo):
-        """
-        查询产品秘钥
-        """
-        logger.info("[query_secret_key] agentNo={}, serialNo={}, merchantNo={}".format(
-            agentNo, serialNo, merchantNo
-        ))
-
-        entity = {
-            "serialNo": serialNo,
-            "merchantNo": merchantNo,
-        }
-
-        path = "/merchant/status/queryMerchantKeys"
-        return self._request(path=path, agentNo=agentNo, entity=entity, signField=[
-            "serialNo", "merchantNo"
-        ])
-
-    def query_bill_file(self, agentNo, merchantNo, billDate=None):
-        """
-        查询账单 的下载地址
-        """
-        logger.info("[query_bill_file] billDate={}, merchantNo={}, agentNo={}".format(billDate, merchantNo, agentNo))
-
-        billDate = billDate or datetime.datetime.now().strftime("%Y%m%d")
-        entity = {
-            "serialNo": "{}{}".format(int(time.time() * 1000), random.randint(1000, 9999)),
-            "agentNo": agentNo,
-            "billDate": billDate,
-            "merchantNo": merchantNo
-        }
-
-        path = "/agentmerchant/download"
-
-        return self._request(path=path, agentNo=agentNo, entity=entity, signField=["billDate", "agentNo"])
-
-    def query_settle(self, agentNo, startTime, endTime, pageNum=1, pageSize=10, orderStatus="", merchantNo=None):
-        """
-        查询 商户的结算信息
-        """
-        logger.info("[query_settle] merchantNo={}, agentNo={}, startTime={}, endTime={}, orderStatus={}".format(
-            merchantNo, agentNo, startTime, endTime, orderStatus
-        ))
-
-        entity = {
-            "agentNo": agentNo,
-            "merchantNo": merchantNo,
-            "pageNum": pageNum,
-            "pageSize": pageSize,
-            "queryStartTime": startTime,
-            "queryEndTime": endTime,
-            "orderStatus": orderStatus,
-        }
-
-        path = "/merchant/status/queryMerchantsSettle"
-        return self._request(path=path, agentNo=agentNo, entity=entity, signField=[
-            "agentNo", "merchantNo", "queryStartTime", "queryEndTime", "orderStatus", "pageNum", "pageSize"
-        ])
-
-    def query_sub_channel(self, agentNo, merchantNo, productCode=None):
-        logger.info("[query_sub_channel] merchantNo={}, agentNo={}, productCode={}".format(
-            merchantNo, agentNo, productCode
-        ))
-
-        # 查询编号固定是401
-        productCode = productCode or "401"
-
-        entity = {
-            "agentNo": agentNo,
-            "merchantNo": merchantNo,
-            "productCode": str(productCode),
-        }
-        path = "/merchant/status/queryMerchantWXNo"
-
-        return self._request(path=path, agentNo=agentNo, entity=entity, signField=[
-            "agentNo", "merchantNo", "productCode"
-        ])
-

+ 97 - 0
library/sms/zthy.py

@@ -0,0 +1,97 @@
+# -*- coding: utf-8 -*-
+# !/usr/bin/env python
+
+import logging
+import time
+from hashlib import md5
+
+import simplejson as json
+
+import requests
+from requests import ConnectionError
+from simplejson import JSONDecodeError
+
+logger = logging.getLogger(__name__)
+
+from library.sms import SmsSender
+
+
+class Sender(SmsSender):
+    BASE_URL = 'https://api.mix2.zthysms.com'
+
+    USERNAME_INDUSTRY = 'whdyhy'
+    PASSWORD_INDUSTRY = 'T7HvCv0J'
+
+    USERNAME_MARKET = 'whdyyx'
+    PASSWORD_MARKET = 'D0HOFFn6'
+
+    TEMPLATE = {
+        'CAPTCHA_TEMPLATE_ID': u'尊敬的用户,您本次的验证码为:{},2分钟内有效。如非本人操作,请忽略本信息。',
+        'SMS_NOTIFY_EXPIRED_DEVICE_TEMPLATEID': u'尊敬的用户, {}, 届时将无法使用支付宝或微信支付, 请您尽快续费, 祝您生活愉快。已经续费请忽略本消息。',
+        'EDIT_MONITOR_ID': u'正在编辑审核人。您本次的验证码为:{},2分钟有效。',
+        'DEALER_MONITOR_WITHDRAW_ID': u'尊敬的用户,您监管的账号需要验证码,本次的验证码为:{},2分钟有效。',
+        'MERCHANT_NOTIFY': u'尊敬的用户,根据央行相关政策,使用银联、微信支付、支付宝等支付机构收款需商家提交身份证、银行卡等相关证件,'
+                           u'请于{}之前登录后台系统完成提交,逾期会影响您的收款和提现,如已开通请忽略。'
+    }
+
+    def __init__(self):
+        pass
+
+    def send(self, phoneNumber, templateName, msg, productName, verifyCode = False):
+        """
+        :param phoneNumber:
+        :param templateName:
+        :param msg:
+        :param productName:
+        :return: dict
+        """
+
+        url = '{}/v2/sendSms'.format(self.BASE_URL)
+
+        logger.debug('productName = %s; templateName = %s; msg = %s' % (productName, templateName, msg))
+
+        msg_template = self.TEMPLATE[templateName]
+        send_msg = u'【{}】{}'.format(productName, msg_template.format(msg))
+
+        headers = {
+            'Accept': 'application/json',
+            'Content-Type': 'application/json;charset=utf-8'
+        }
+
+        tKey = int(time.time())
+        password = md5('{}{}'.format(md5(self.PASSWORD_INDUSTRY).hexdigest().lower(), tKey)).hexdigest().lower()
+
+        body = {
+            'username': self.USERNAME_INDUSTRY,
+            'password': password,
+            'tKey': tKey,
+            'mobile': phoneNumber,
+            'content': send_msg,
+            'time': '',
+            'ext': 0,
+            'extend': ''
+        }
+
+        logger.debug(body)
+
+        try:
+            result = requests.post(url, data = json.dumps(body), headers = headers, timeout = 15, verify = False)
+            response = result.json()
+
+            logger.debug('send sms response=(code={} msg={} msgId={} contNum={}), mobile={}'.format(
+                response.get("code", ""), response.get("msg", "").encode('utf-8'),
+                response.get('msgId'), response.get('contNum'), phoneNumber))
+
+            if response.get("code") != 200:
+                if response.get("code") == 4004:
+                    return {'result': False, 'msg': u'手机号码错误'}
+                else:
+                    return {'result': False, 'msg': u'请求验证码失败, 请稍后再试'}
+            else:
+                return {'result': True, 'msg': 'success'}
+        except JSONDecodeError as e:
+            logger.exception(e)
+            return {'result': False, 'msg': u'短信服务器繁忙,请稍后重试'}
+        except ConnectionError as e:
+            logger.exception(e)
+            return {'result': False, 'msg': u'短信服务器不可用,请稍后重试'}

+ 0 - 1
script/build_python/build_for_wugang.py

@@ -48,7 +48,6 @@ dirs = [
         'apps/web/eventer',
         'apps/web/knowledge',
         'apps/web/management',
-        'apps/web/miniuser',
         'apps/web/report',
         'apps/web/services',
         'apps/web/superadmin',

File diff suppressed because it is too large
+ 0 - 354
script/jdOpenTest.py


+ 0 - 281
script/jdTest.py

@@ -1,281 +0,0 @@
-# coding=utf-8
-import os
-from collections import OrderedDict
-
-
-os.environ.update({"DJANGO_SETTINGS_MODULE": "configs.testing"})
-from base import init_env
-
-
-init_env(False)
-
-from apps.web.dealer.models import Dealer
-from apps.web.merchant.models import MerchantSourceInfo
-from library.jd import JDAggrePay
-
-
-# from apps.web.device.models import Device
-# from apps.web.core.services import ActionDeviceBuilder
-from apps.web.core.exceptions import ServiceException
-
-# dev = Device.get_dev("862167050126352")
-# box = ActionDeviceBuilder.create_action_device(dev)
-#
-#
-# # 测试几个获取功能
-# test_function = [
-#     # 启动 2号
-#     ("02A7", "000000000000000000000A00000A", u"启动2号端口"),
-#     # 停止 2号
-#     ("02D6", "01", u"停止2号端口"),
-#     # 获取当前电流
-#     ("01B3", "01", u"获取当前电流"),
-#     # 获取标准电流
-#     ("01C3", "01", u"获取标准电流"),
-#     # 获取总投币消费
-#     ("01C1", "01", u"获取总投币消费"),
-#     # 获取刷卡消费
-#     ("01C2", "01", u"获取刷卡消费"),
-#     # 获取空载时间
-#     ("01E6", "01", u"获取空载时间"),
-#     # 获取空载功率
-#     ("01E4", "01", u"获取空载功率"),
-#     # 获取功率分档
-#     ("01F2", "01", u"获取功率分档"),
-#     # 获取时间计费规则
-#     ("01B8", "01", u"获取时间计费规则"),
-#     # 获取电量计费规则
-#     ("01F7", "01", u"获取电量计费规则"),
-#     # 获取端口状态
-#     ("01ED", "0100", u"获取端口状态"),
-#     # 获取端口详情
-#     ("02EF", "00", u"获取2号端口详情"),
-#     # 获取端口实时电量
-#     ("01E9", "01", u"获取端口实时电量")
-#
-# ]
-#
-# for _fun in test_function:
-#     try:
-#         box._send_data(_fun[0], _fun[1], timeout=10)
-#     except ServiceException:
-#         print _fun[2]
-#         break
-#
-# username = "18637193073"
-# dealer = Dealer.objects.get(username=username)
-# sourceRecord = MerchantSourceInfo.get_source_record(str(dealer.id))
-# payload = sourceRecord.to_dict()
-#
-# # 待确认的状态的时候,提供用户测试支付的url
-# merchantAgent = sourceRecord.merchantAgent.fetch()
-#
-# pay = JDAggrePay(
-#     merchant_no=sourceRecord.merchantNo,
-#     desKey=sourceRecord.desKey,
-#     saltMd5Key=sourceRecord.mdKey,
-#     systemId=merchantAgent.agentSystemId
-# )
-# url = pay.create_pay_static_url(notify_url=None)
-# print url
-
-#
-# dev = Device.get_dev("866262048861487")
-# box = ActionDeviceBuilder.create_action_device(dev)
-# box._stop("5", 0)
-# box._stop("4", 0)
-# box._stop("3", 0)
-# box._stop("2", 0)
-# box._stop("1", 0)
-#
-#
-# from apps.web.merchant.models import MerchantSourceInfo
-# record = MerchantSourceInfo()
-# record2 = MerchantSourceInfo()
-#
-# fields = [
-#     "merchantType",
-#     "bankCardCode",
-#     "bankCardName",
-#     "bankCardSubCode",
-#     "bankCardSubName",
-#     "bankCardUrl",
-#     "identifyCardAUrl",
-#     "identifyCardAddr",
-#     "identifyCardArea",
-#     "identifyCardAreaCode",
-#     "identifyCardBUrl",
-#     "identifyCardCUrl",
-#     "identifyCardCity",
-#     "identifyCardCityCode",
-#     "identifyCardCode",
-#     "identifyCardEndTime",
-#     "identifyCardLongTime",
-#     "identifyCardName",
-#     "identifyCardProvince",
-#     "identifyCardProvinceCode",
-#     "identifyCardStartTime",
-#     "shopAddr",
-#     "shopArea",
-#     "shopAreaCode",
-#     "shopCity",
-#     "shopCityCode",
-#     "shopProvince",
-#     "shopProvinceCode",
-#     "storeAUrl",
-#     "storeBUrl",
-#     "storeCUrl",
-#     "storeShotName",
-# ]
-
-
-import pandas as pd
-import datetime
-
-
-#
-# df = pd.DataFrame(data=records)
-# groupBygroup = list()
-# for _key, _v in df.groupby(u"地址"):
-#
-#     itemOrderList = [
-#         (u"", _key)
-#     ]
-#
-#     for __k, __v in _v.groupby(u"支付类型"):
-#         itemOrderList.append((__k, __v[u"分得金额"].astype(float).sum()))
-    # groupBygroup.append(
-    #     OrderedDict([
-    #         (u"地址", _key),
-    #         (u"分得金额", _v[u"分得金额"].astype(float).sum()),
-    #         (u"总金额", _v[u"总金额"].astype(float).sum()),
-    #         (u"订单数量", len(_v))
-    #     ])
-    # )
-#     itemOrderList.append((u"分得金额", _v[u"分得金额"].astype(float)))
-#     groupBygroup.append(OrderedDict(itemOrderList))
-# df2 = pd.DataFrame(data=groupBygroup)
-#
-#
-# writer = pd.ExcelWriter("C:/Users/Administrator/Desktop/test.xlsx")
-# df.to_excel(writer, sheet_name="1")
-# df2.to_excel(writer, sheet_name="2", index=False)
-#
-# writer.save()
-
-# dev = Device.get_dev("866262048861487")
-# box = ActionDeviceBuilder.create_action_device(dev)
-# box._stop("5", 0)
-# box._stop("4", 0)
-# box._stop("3", 0)
-# box._stop("2", 0)
-# box._stop("1", 0)
-#
-#
-# from apps.web.merchant.models import MerchantSourceInfo
-# record = MerchantSourceInfo()
-# record2 = MerchantSourceInfo()
-#
-# fields = [
-#     "merchantType",
-#     "bankCardCode",
-#     "bankCardName",
-#     "bankCardSubCode",
-#     "bankCardSubName",
-#     "bankCardUrl",
-#     "identifyCardAUrl",
-#     "identifyCardAddr",
-#     "identifyCardArea",
-#     "identifyCardAreaCode",
-#     "identifyCardBUrl",
-#     "identifyCardCUrl",
-#     "identifyCardCity",
-#     "identifyCardCityCode",
-#     "identifyCardCode",
-#     "identifyCardEndTime",
-#     "identifyCardLongTime",
-#     "identifyCardName",
-#     "identifyCardProvince",
-#     "identifyCardProvinceCode",
-#     "identifyCardStartTime",
-#     "shopAddr",
-#     "shopArea",
-#     "shopAreaCode",
-#     "shopCity",
-#     "shopCityCode",
-#     "shopProvince",
-#     "shopProvinceCode",
-#     "storeAUrl",
-#     "storeBUrl",
-#     "storeCUrl",
-#     "storeShotName",
-# ]
-
-
-
-
-# data = {
-#     'businessCode': 'MEMBER',#
-#     'subTradeType': 'SALE',     #
-#     'merchantNo': '115825387',#
-#     'tradeRefundNo': u'',
-#     'payFinishTime': '20210419115823',
-#     'couponAmount': 0,
-#     'currency': 'RMB',#
-#     'amount': 1,
-#     'version': 'V3.0',
-#     'outRefundNo': u'',
-#     'outTradeNo': '20210419115814PQ0000000888999PU0',
-#     'tradeNo': '167218067175',
-#     'payStatus': 'FINISH',
-#     'resultCode': 'SUCCESS',
-#     'piAmount': 1,
-#     'merchantCouponAmount': 0
-# }
-
-# from apps.web.common.transaction.pay.jdaggre import JDJosPayRecordPoller
-# from apps.web.user.models import RechargeRecord
-# record = RechargeRecord.objects.get(orderNo="20210420121631PQ0000000888999TU3")
-# from apps.web.core.payment import PaymentGateway
-# payment_gateway = PaymentGateway.from_gateway_key(
-#     record.gateway,
-#     record.payGatewayKey,
-#     record.payAppType)  # type: cast(PaymentGateway)
-# from pprint import pprint
-#
-# pprint(JDJosPayRecordPoller("", "", "", "", "").action_of_pay(payment_gateway, record))
-
-
-# from apps.web.core.adapter.huopo import MoneyCaculation
-
-
-
-# print MoneyCaculation(duration="1410", unit=u"分钟", package={"1": {"maxHour": 24, "price": 2, "unit": u"小时"}}).calculate()
-
-# from library.jd.pay import JDJosPay
-# from apps.web.core.payment import PaymentGateway
-# from apps.web.user.models import RechargeRecord
-#
-# recharge_record = RechargeRecord.objects.get(id="60890caf977059b6795415ae")
-#
-# payGateway = PaymentGateway.from_gateway_key(
-#     recharge_record.gateway,
-#     recharge_record.payGatewayKey,
-#     recharge_record.payAppType)
-#
-# payApp = payGateway.app
-# josPayApp = payApp.josPayApp.fetch()  # type: JDAggrePayApp
-#
-# client = JDJosPay(
-#     josPayApp.merchant_no,
-#     josPayApp.desKey,
-#     josPayApp.saltMd5Key,
-#     josPayApp.systemId,
-#     josPayApp.debug
-# )
-#
-# setattr(client, "shopInfo", josPayApp.shopInfo)
-#
-# result = client.api_trade_refund(recharge_record.orderNo, "1234567890112333", 1)
-# print 1
-# print result

+ 0 - 34
script/merchantAddress.py

@@ -1,34 +0,0 @@
-# coding=utf-8
-import os
-
-from base import init_env
-
-
-os.environ["DJANGO_SETTINGS_MODULE"] = "configs.dev_zjl"
-
-
-init_env(False)
-
-import csv
-
-from apps.web.merchant.models import WxMerchantAddress
-
-
-def load_city_code():
-    with open("cityCode.csv", "r") as f:
-        r = csv.DictReader(f, fieldnames=["code", "name"])
-        for row in r:
-            code, name = row["code"], row["name"]
-            name = name.replace(u"中国,", "")
-            if name.startswith(","):
-                name = "{}{}".format(name[1:3], name)
-
-            nameSplit = name.split(",")
-            if len(nameSplit) != 3:
-                continue
-
-            name = "".join(nameSplit)
-            WxMerchantAddress(code = code, name = name).save()
-
-
-

+ 0 - 293
script/sort_dealer.py

@@ -1,293 +0,0 @@
-# coding=utf-8
-import datetime
-
-import pandas as pd
-import matplotlib.pyplot as plt
-from matplotlib.font_manager import FontProperties
-from pylab import mpl
-
-from apps.web.core.bridge.wechat.v3api import WechatApiProxy
-from apps.web.core.models import WechatServiceProvider
-from apps.web.core.networking import MessageSender
-from apps.web.device.models import DeviceDict
-from apps.web.merchant.models import MerchantSourceInfo
-
-
-def make_autopct(total):
-    def my_autopct(pct):
-        val = int(round(pct*total/100.0))
-        # 同时显示数值和占比的饼图
-        return '{p:.2f}%  ({v:d})'.format(p=pct,v=val)
-    return my_autopct
-
-
-def parse_data1():
-    """
-    解析数据
-    """
-    # 读取数据
-    df = pd.read_csv("dealerMerchantStatus1.csv", header=0)
-
-    # 标准化画布
-    plt.axes(aspect='equal')
-
-    allCount = df.id.count()
-
-    #
-    df.merStatus.value_counts().sort_values().plot.pie(autopct=make_autopct(allCount), fontsize=10, counterclock=False, explode=(0.2,0.3,0.4,0.2, 0))
-
-    # df.set_index('merStatus', inplace=True)
-    plt.title(u'商户开通整体情况', fontsize=16, fontweight='bold')
-    plt.ylabel(u"发出邀请总人数 {}".format(df["merStatus"].count()), fontsize=16, fontweight='bold')
-
-    plt.show()
-
-
-def parse_data2():
-    """
-    解析数据
-    """
-    # 读取数据
-    df = pd.read_csv("dealerMerchantStatus1.csv", header=0)
-
-    # 标准化画布
-    plt.axes(aspect='equal')
-
-    # 条件筛选出未开通商户的
-    online4 =  df[df["merStatus"] == 4].onlineCount.sum()
-    online3 =  df[df["merStatus"] == 3].onlineCount.sum()
-    online2=  df[df["merStatus"] == 2].onlineCount.sum()
-    online1 =  df[df["merStatus"] == 1].onlineCount.sum()
-    online0 =  df[df["merStatus"] == 0].onlineCount.sum()
-
-    allOnline = df.onlineCount.sum()
-
-    s = pd.Series([
-        online0,
-        online1,
-        online2,
-        online3,
-        online4,
-    ],[
-        u"未提交资料",
-        u"京东入驻中",
-        u"申请失败",
-        u"申请成功(微信审核)",
-        u"已经切换"
-    ]
-    )
-
-    s.sort_values().plot.pie(autopct=make_autopct(allOnline), fontsize=10, counterclock=False, explode=(0.3,0,0,0,0))
-
-    plt.title(u"设备分布图", fontsize=16, fontweight='bold')
-    plt.ylabel(u"设备总数{}".format(allOnline), fontsize=16, fontweight='bold')
-    #
-    plt.show()
-
-
-def parse_data3():
-    """
-    最后登录
-    """
-    # 读取数据
-    df = pd.read_csv("dealerMerchantStatus1.csv", header=0)
-
-    # 标准化画布
-    plt.axes(aspect='equal')
-
-    # 找出所有没有提交资料的经销商
-    df = df[df["merStatus"] == 0]
-
-    # 比较登录日期
-    now = datetime.datetime.now()
-    login14 = df[df.lastLogin.astype('datetime64') >= now - datetime.timedelta(days=14)].onlineCount.sum()
-
-    login15_30 = df[(df.lastLogin.astype('datetime64') < now - datetime.timedelta(days=14)) & (df.lastLogin.astype('datetime64') >= now - datetime.timedelta(days=30))].onlineCount.sum()
-    login30_90 = df[(df.lastLogin.astype('datetime64') < now - datetime.timedelta(days=30)) & (df.lastLogin.astype('datetime64') >= now - datetime.timedelta(days=90))].onlineCount.sum()
-    login90 = df[(df.lastLogin.astype('datetime64') < now - datetime.timedelta(days=90))].onlineCount.sum()
-
-    allCount = df.onlineCount.sum()
-
-
-    s = pd.Series([
-        login14,
-        login15_30,
-        login30_90,
-        login90,
-    ], [
-        u"14天以内",
-        u"14天到30天",
-        u"30天到90天",
-        u"3个月以上"
-    ])
-
-    s.sort_values().plot.pie(autopct=make_autopct(allCount), fontsize=10, counterclock=False, explode=(0.3,0.3,0.3,0))
-
-    plt.title(u"最后登录分布图(设备)", fontsize=16, fontweight='bold')
-    plt.ylabel(u"总数{}".format(allCount), fontsize=16, fontweight='bold')
-    #
-    plt.show()
-
-
-def parse_data4():
-
-    # 读取数据
-    df = pd.read_csv("dealerMerchantStatus1.csv", header=0)
-
-    # 读取所有的里歌经销商ID
-    with open("lgdid") as f:
-        lg = f.read().split()
-    with open('hpdid') as f:
-        hp = f.read().split()
-
-    ids = lg + hp
-    # 标准化画布
-    # plt.axes(aspect='equal')
-
-    # 分种类经销商
-    df0 = df[df.merStatus == 0]
-    df1 = df[df.merStatus == 1]
-    df2 = df[df.merStatus == 2]
-    df3 = df[df.merStatus == 3]
-    df4 = df[df.merStatus == 4]
-
-
-    num_list = [
-        df0.onlineCount.sum(),
-        df1.onlineCount.sum(),
-        df2.onlineCount.sum(),
-        df3.onlineCount.sum(),
-        df4.onlineCount.sum(),
-    ]
-
-    num_list1 = [
-        df0[df0.id.isin(ids)].onlineCount.sum(),
-        df1[df1.id.isin(ids)].onlineCount.sum(),
-        df2[df2.id.isin(ids)].onlineCount.sum(),
-        df3[df3.id.isin(ids)].onlineCount.sum(),
-        df4[df4.id.isin(ids)].onlineCount.sum(),
-    ]
-
-    # 比较登录日期
-    name_list = [u"未提交", u"入驻中", u"设备失败", u"入驻成功(微信申请)", u"已切换"]
-    x = list(range(len(name_list)))
-
-    total_width, n = 0.6, 2
-    width = total_width / n
-    plt.bar(x, num_list, width=width, label=u"设备总数量", fc="b")
-
-    for a, b in zip(x, num_list):  # 柱子上的数字显示
-        plt.text(a, b, '%.3f' % b, ha='center', va='bottom', fontsize=10)
-
-    for i in range(len(x)):
-        x[i] = x[i] + width
-    plt.bar(x, num_list1, width=width, label=u"霍珀里歌", tick_label=name_list, fc="r")
-    plt.xlabel(u"类型", fontsize=10)
-    plt.ylabel(u"设备数量", fontsize=10)
-    plt.title(u"霍珀里歌", fontsize=15)
-    for a, b in zip(x, num_list1):  # 柱子上的数字显示
-        plt.text(a, b, '%.3f' % b, ha='center', va='bottom', fontsize=10)
-    plt.legend(fontsize=8)
-    plt.show()
-
-
-def parse_data5():
-    """
-    最后登录
-    """
-    # 读取数据
-    df = pd.read_csv("dealerMerchantStatus1.csv", header=0)
-
-    # 读取所有的里歌经销商ID
-    with open("lgdid") as f:
-        lg = f.read().split()
-    with open('hpdid') as f:
-        hp = f.read().split()
-
-    ids = lg + hp
-    # 标准化画布
-    # plt.axes(aspect='equal')
-
-    # 分种类经销商
-    df0 = df[df.merStatus == 0]
-    df1 = df[df.merStatus == 1]
-    df2 = df[df.merStatus == 2]
-    df3 = df[df.merStatus == 3]
-    df4 = df[df.merStatus == 4]
-
-
-    num_list = [
-        df0.onlineCount.count(),
-        df1.onlineCount.count(),
-        df2.onlineCount.count(),
-        df3.onlineCount.count(),
-        df4.onlineCount.count(),
-    ]
-
-    num_list1 = [
-        df0[df0.partnerId == "[]"].onlineCount.count(),
-        df1[df1.partnerId == "[]"].onlineCount.count(),
-        df2[df2.partnerId == "[]"].onlineCount.count(),
-        df3[df3.partnerId == "[]"].onlineCount.count(),
-        df4[df4.partnerId == "[]"].onlineCount.count(),
-    ]
-
-    # 比较登录日期
-    name_list = [u"未提交", u"入驻中", u"设备失败", u"入驻成功(微信申请)", u"已切换"]
-    x = list(range(len(name_list)))
-
-    total_width, n = 0.6, 2
-    width = total_width / n
-    plt.bar(x, num_list, width=width, label=u"申请数量", fc="b")
-
-    for a, b in zip(x, num_list):  # 柱子上的数字显示
-        plt.text(a, b, '%d' % b, ha='center', va='bottom', fontsize=10)
-
-    for i in range(len(x)):
-        x[i] = x[i] + width
-    plt.bar(x, num_list1, width=width, label=u"没有合伙人", tick_label=name_list, fc="r")
-    plt.xlabel(u"类型", fontsize=10)
-    plt.ylabel(u"设备数量", fontsize=10)
-    plt.title(u"没有合伙人情况", fontsize=15)
-    for a, b in zip(x, num_list1):  # 柱子上的数字显示
-        plt.text(a, b, '%d' % b, ha='center', va='bottom', fontsize=10)
-    plt.legend(fontsize=8)
-    plt.show()
-
-
-def aa():
-    """
-    """
-
-    from apps.web.dealer.models import TodoMessage, Dealer
-    from apps.web.device.models import Device
-
-    num = 0
-    for t in TodoMessage.objects.filter(title=u"商户开通提醒"):
-        if num >= 1:
-            break
-
-        if Device.objects.filter(ownerId=t.ownerId).count() >= 10:
-            continue
-
-        dealer = Dealer.objects.get(id=t.ownerId)   # type: Dealer
-
-        if "forceMerchant" in dealer.features:
-            continue
-
-        dealer.features.append("forceMerchant")
-        dealer.save()
-        print("dealerId = {}".format(dealer.id))
-        num += 1
-
-
-
-
-
-
-
-
-
-
-if __name__ == '__main__':
-    parse_data3()

+ 3 - 7
script/system_ledger.py

@@ -109,13 +109,9 @@ def _create_recharge():
     dev = Device.get_dev_by_l(logicalCode)  # type: DeviceDict
     group = Group.get_group(groupId)    # type: GroupDict
     dealer = Dealer.objects.get(id=ownerId)
-    if dealer.payByMerchant:
-        source = dealer
-        visitor = DealerCustomizedBrandVisitor
-    else:
-        product_agent = get_user_manager_agent(dealer)
-        source = product_agent
-        visitor = AgentCustomizedBrandVisitor
+    product_agent = get_user_manager_agent(dealer)
+    source = product_agent
+    visitor = AgentCustomizedBrandVisitor
 
     funName = "get_{}_env_pay_gateway".format("wechat")
     get_env_pay_gateway_func = import_string("apps.web.helpers.{}".format(funName))

+ 0 - 380
script/test.py

@@ -1,380 +0,0 @@
-# -*- coding: utf-8 -*-
-# !/usr/bin/env python
-import datetime
-import os
-import sys
-
-from base import init_env
-
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "configs.testing")
-
-init_env(interactive = False)
-from apps.web.eventer.jndz import is_server_refund
-from apps.web.user.transaction_deprecated import refund_cash
-from apps.web.core.payment import WithdrawGateway
-from apps.web.constant import USER_RECHARGE_TYPE
-from apps.web.report.ledger import Ledger
-
-from apps.web.core.helpers import ActionDeviceBuilder
-
-from apilib.monetary import Percent, RMB, VirtualCoin
-from apps.web.dealer.define import DEALER_INCOME_SOURCE
-from apps.web.dealer.models import Dealer, DealerRechargeRecord
-from apps.web.core import ROLE, PayAppType
-from apps.web.agent.models import Agent
-from apps.web.dealer.proxy import record_income_proxy
-from apilib.utils_json import json_loads
-from apps.web.device.models import Device, Group, DeviceType, DeviceCacheMgr, DeviceDict
-# from apps.web.utils import set_or_incr_cache
-# from apps import serviceCache
-from apps.web.user.models import ConsumeRecord, RechargeRecord, VCardConsumeRecord, Card, CardConsumeRecord
-
-# from apps.web.dealer.tasks import report_daily_report_to_dealer_via_wechat
-# report_daily_report_to_dealer_via_wechat()
-
-# set_or_incr_cache(serviceCache, "test", 1, 360)
-# orders = VCardConsumeRecord.objects(dealerId__nin=[None,'']).all()
-#
-# for order in orders:
-#     print order.dev_type_name, order.device, order.dev_type_code, order.group, order.owner
-# from apps.web.dealer.tasks import dealer_auto_charge_sim_card
-# dealer_auto_charge_sim_card()
-# device = Device.objects(logicalCode='602499').first()
-# dealer = Dealer.objects(id = '5b9ae99ad89a177846459999').first()
-# group = Group.get_group('5ba35e7396a03703f0c3d2ca')
-# sim_recharge = DealerRechargeRecord.objects(id = '630889c034f2d00976295214').first()
-from apps.web.core.models import WechatPayApp, AliApp, JDAggrePayApp, JDOpenPayApp
-
-# income_record = RechargeRecord.issue_from_auto_sim_order(dealer, sim_recharge, device, group)
-# income_record = RechargeRecord.objects(id = '63088d5c9c531030e6cf5572').first() # type: RechargeRecord
-#
-# record_income_proxy(DEALER_INCOME_SOURCE.AUTO_SIM, income_record, {
-#     "owner": [
-#         {
-#             "money": income_record.money.mongo_amount,
-#             "role": "owner",
-#             "share": Percent("100.0"),
-#             "id": str(dealer.id)
-#         }
-#     ],
-#     'partner': []
-# })
-
-# agent = Agent.objects(id = settings.MY_PRIMARY_AGENT_ID).first()  # type: Agent
-#
-# print '========== agent = {} ==============='.format(str(agent.id))
-#
-# print repr(agent.my_wechat_pay_app)
-# print repr(agent.my_ali_pay_app)
-# print repr(agent.my_jd_aggre_pay_app)
-#
-# for dealer in Dealer.objects(agentId = settings.MY_PRIMARY_AGENT_ID).limit(100):
-#     assert dealer.current_wallet_withdraw_source_key == agent.current_wallet_withdraw_source_key, u'error'
-#
-# for agent in Agent.objects(customizedWechatCashflowAllowable = True, id__ne=settings.MY_PRIMARY_AGENT_ID):
-#     print '========== agent = {} ==============='.format(str(agent.id))
-#
-#     print repr(agent.my_wechat_pay_app)
-#     print repr(agent.my_ali_pay_app)
-#     print repr(agent.my_jd_aggre_pay_app)
-#
-#     for dealer in Dealer.objects(agentId = str(agent.id)).limit(100):
-#         assert dealer.current_wallet_withdraw_source_key == agent.current_wallet_withdraw_source_key, u'error2'
-#
-# for agent in Agent.objects(id = '596efac78732d64d61430cd7'):
-#     try:
-#         app = agent.my_wechat_pay_app
-#         test_app = WechatPayApp.objects(id = str(app.id)).first()  # type: WechatPayApp
-#         test_app.occupantId = str(agent.id)
-#         test_app.role = ROLE.agent
-#         print test_app.occupant
-#         assert test_app.occupant.id == agent.id, 'sss'
-#     except Exception as e:
-#         print str(agent.id), 'wechat'
-#
-#     try:
-#         app = agent.my_ali_pay_app
-#         if app:
-#             test_app = AliApp.objects(id = str(app.id)).first()  # type: AliApp
-#             test_app.occupantId = str(agent.id)
-#             test_app.role = ROLE.agent
-#             print test_app.occupant
-#
-#             assert test_app.occupant.id == agent.id, 'sss'
-#     except Exception as e:
-#         print str(agent.id), 'ali'
-#
-#     try:
-#         app = agent.my_jd_aggre_pay_app
-#         if app:
-#             test_app = JDAggrePayApp.objects(id = str(app.id)).first()  # type: JDAggrePayApp
-#             test_app.occupantId = str(agent.id)
-#             test_app.role = ROLE.agent
-#             print test_app.occupant
-#             assert test_app.occupant.id == agent.id, 'sss'
-#     except Exception as e:
-#         print str(agent.id), 'jd'
-
-# dev = Device.get_dev('861714052017435')
-# box = ActionDeviceBuilder.create_action_device(dev)
-# print box.get_policy_for_user()
-#
-# all = set()
-#
-# for record in DealerRechargeRecord.objects(
-#         __raw__ = {'name': {'$regex': '自动续费'}}).all():  # type: DealerRechargeRecord
-#     all.add(record.dealerId)
-#
-# print all
-# from apps.web.dealer.tasks import dealer_auto_charge_sim_card
-#
-# dealer_auto_charge_sim_card()
-#
-# owner = Dealer.objects(id = '5b9ae99ad89a177846459999').first()
-#
-# print owner
-#
-# driverCodes = set()
-# for item in Device.get_collection().aggregate([{'$match': {}}, {'$group': {'_id': '$driverCode'}}]):
-#     driverCodes.add(item['_id'])
-#
-# driverCodes.add(None)
-# driverCodes.add('')
-#
-# print driverCodes
-
-import time
-
-# for device in Device.objects(driverCode = '300001').limit(100):
-#     try:
-#         start = time.time()
-#
-#         recommend, all = DeviceType.find_candidate(device, owner)
-#
-#         end = time.time()
-#
-#         print '{} {} {} {} {} {} {} {} {}\r\n'.format(
-#             end - start,
-#             device.logicalCode,
-#             device.driverCode,
-#             device.driverVersion,
-#             device.mf,
-#             device.coreVer,
-#             device.softVer,
-#             [item['code'] for item in recommend],
-#
-# # for driverCode in driverCodes:
-# #     print driverCode
-# #     for device in Device.objects(driverCode = driverCode).limit(100):
-# #         try:
-# #             start = time.time()
-# #
-# #             recommend, all = DeviceType.find_candidate(device, owner)
-# #
-# #             end = time.time()
-# #
-# #             print '{} {} {} {} {} {} {} {} {}\r\n'.format(
-# #                 end - start,
-# #                 device.logicalCode,
-# #                 device.driverCode,
-# #                 device.driverVersion,
-# #                 device.mf,
-# #                 device.coreVer,
-# #                 device.softVer,
-# #                 [item['code'] for item in recommend],
-# #                 [item['code'] for item in all])
-# #         except Exception as e:
-# #             print str(e)      [item['code'] for item in all])
-#     except Exception as e:
-#         print str(e)
-#
-# from apps.web.core.payment.base import WithdrawGateway
-# from apps.web.common.models import WithdrawRecord
-#
-# record = WithdrawRecord.objects(order='20220926181535WDA177846459999ABR').first()
-# withdraw_gateway = WithdrawGateway.from_withdraw_gateway_key(record.withdrawGatewayKey, record.extras.get('gateway_version', 'v1'))
-#
-# query_result = withdraw_gateway.get_transfer_result_via_changes(record.order)
-#
-# print query_result
-
-
-# devices = Device.objects().all().order_by("-id").limit(500)
-# for device in devices:
-#     cache_info = DeviceCacheMgr.get_device_cache(device.devNo)
-#     if cache_info:
-#         dev_dict = json_loads(cache_info)
-#         if 'logicalCode' in dev_dict and not dev_dict['logicalCode']:
-#             print device.devNo
-#             Device.invalid_device_cache(device.devNo)
-# from apps.web.dealer.tasks import dealer_auto_charge_sim_card
-# dealer_auto_charge_sim_card()
-# devObj = Device.objects(logicalCode = 'G475515').first()
-# dealer = Dealer.objects(id = '5b2225ae8732d63662f97a72').first()
-#
-# recommends, alls = DeviceType.find_candidate(devObj, dealer)
-# for recommend in recommends:
-#     print 'recommend: {} - {}'.format(recommend['name'], recommend['code'])
-#
-# for item in alls:
-#     print 'all: {} - {}'.format(item['name'], item['code'])
-
-# record = RechargeRecord.objects.get(id = '59570ca58732d65f74c639bb')  # type: RechargeRecord
-# # ledger = Ledger(USER_RECHARGE_TYPE.RECHARGE, record)
-# # ledger.execute(journal = False, stats = True, check = False)
-# refund_cash(record, RMB('1.00'), VirtualCoin(0))
-#
-# while True:
-#     rechargeRcdId = '634d09837855409ce4a2fd2f'
-#
-#     record = RechargeRecord.objects.get(id = rechargeRcdId)  # type: RechargeRecord
-#
-#     if not record.is_success():
-#         print('{} state is {}.'.format(str(record), record.result))
-#         break
-#
-#     if record.is_ledgered:
-#         print('{} has been ledgered.'.format(str(record)))
-#         break
-#
-#     ledgerTime = None if (
-#         not WithdrawGateway.is_ledger(record.withdraw_source_key)) else datetime.datetime.now()
-#
-#     ledger = Ledger(USER_RECHARGE_TYPE.RECHARGE, record, ledgerTime = ledgerTime)
-#     ledger.execute(journal = False, stats = True, check = False)
-#
-#     break
-
-# skip = 0
-# limit = 2000
-# count = 0
-#
-# QUIT = False
-#
-# rv = []
-#
-# while True:
-#     orders = CardConsumeRecord.objects().order_by('-id').skip(skip).limit(limit)
-#     count = 0
-#
-#     for order in orders:  # type: CardConsumeRecord
-#         count = count + 1
-#
-#         if order.dateTimeAdded <= datetime.datetime(2022, 9, 30, 0, 0, 0):
-#             QUIT = True
-#             break
-#
-#         if order.devNo not in rv:
-#             dev = Device.get_dev(order.devNo)  # type: DeviceDict
-#             if dev and dev.driverCode in ['100202', '100206']:
-#                 rv.append(order.devNo)
-#                 print 'has {}.'.format(len(rv))
-#
-#     if QUIT:
-#         break
-#
-#     print("next {}".format(skip))
-#
-#     skip = skip + limit
-#
-#     if count == 0:
-#         break
-#
-# print rv
-# rv_time = []
-# rv_elec = []
-# dealerids_time = set()
-# dealerids_elec = set()
-# agents = [_ for _ in Agent.objects()]
-# for agent in agents:
-#     if not Card.objects(agentId = str(agent.id)).first():
-#         continue
-#
-#     dealers = [_ for _ in Dealer.objects(agentId = str(agent.id))]
-#     for dealer in dealers:
-#         if dealer.supports('support_new_card_proc'):
-#             continue
-#
-#         devices = [_ for _ in Device.objects(ownerId = str(dealer.id))]
-#         for device in devices:  # type: Device
-#             billingType = device.otherConf.get('billingType', 'time')
-#             if is_server_refund(billingType, Device.get_dev(device.devNo), dealer, agent):
-#                 print '{} server refund is true.'.format(device)
-#
-#                 if billingType == 'time':
-#                     rv_time.append(device.devNo)
-#                     dealerids_time.add(str(dealer.id))
-#                 else:
-#                     rv_elec.append(device.devNo)
-#                     dealerids_elec.add(str(dealer.id))
-#             else:
-#                 print '{} server refund is false.'.format(device)
-#
-#
-# devices = [_ for _ in Device.objects(driverCode__in = ['100202', '100206'], ownerId__nin = [None, ''])]
-#
-# print "hello"
-#
-# dealers = {}
-# agents = {}
-#
-# rv_time = set()
-# dealerids_time = set()
-# rv_elec = set()
-# dealerids_elec = set()
-#
-# for device in devices:  # type: Device
-#     devDict = Device.get_dev(device.devNo) # type: DeviceDict
-#     if not devDict.online:
-#         continue
-#
-#     if device.ownerId in dealers:
-#         dealer = dealers.get(device.ownerId)
-#     else:
-#         dealer = Dealer.objects(id = device.ownerId).first()
-#
-#     if not dealer:
-#         continue
-#
-#     if dealer.supports('support_new_card_proc'):
-#         continue
-#
-#     if dealer.agentId in agents:
-#         agent = agents.get(dealer.agentId)
-#     else:
-#         agent = Agent.objects(id = dealer.agentId).first()
-#
-#     if not agent:
-#         continue
-#
-#     if not Card.objects(agentId = str(agent.id)).first():
-#         continue
-#
-#     billingType = device.otherConf.get('billingType', 'time')
-#     if is_server_refund(billingType, Device.get_dev(device.devNo), dealer, agent):
-#         print '{} server refund is true.'.format(device)
-#
-#         if billingType == 'time':
-#             rv_time.add(device.devNo)
-#             dealerids_time.add(str(dealer.id))
-#         else:
-#             rv_elec.add(device.devNo)
-#             dealerids_elec.add(str(dealer.id))
-#     else:
-#         print '{} server refund is false.'.format(device)
-# print rv_time
-# print dealerids_time
-# print rv_elec
-# print dealerids_elec
-# dealer = Dealer.objects(id = '5b9ae99ad89a177846459999').first()
-# 
-# 
-# app = JDOpenPayApp.objects(id = '635bbae869f046a0846dba72').first()
-# dealer.merchantApp = app
-# dealer.payAppType = PayAppType.JD_OPEN
-# dealer.save()
-from apilib.utils_datetime import to_datetime
-from apps.web.device.timescale import PowerManager
-items = PowerManager.instence().get(devNo='863488058609218', port=3, sTime=to_datetime('2022-11-08 11:30:00'), eTime=to_datetime('2022-11-08 12:30:00'),
-                                        interval = 300)
-print 'aaa'

File diff suppressed because it is too large
+ 0 - 409
script/transaction/1.txt


+ 0 - 128
script/transaction/jdBill.py

@@ -1,128 +0,0 @@
-# -*- coding: utf-8 -*-
-# !/usr/bin/env python
-
-import csv
-import datetime
-import getopt
-import os
-import sys
-
-import requests
-
-PROJECT_ROOT = os.path.join(os.path.abspath(os.path.split(os.path.realpath(__file__))[0] + "/.."), '..')
-sys.path.insert(0, PROJECT_ROOT)
-
-from script.base import init_env
-
-os.environ["DJANGO_SETTINGS_MODULE"] = "configs.production_local"
-
-init_env(False)
-
-from apps.web.merchant.utils import JDMerchant
-from django.conf import settings
-
-
-def download_bill_file(merchantNo, start, end):
-    st = datetime.datetime.strptime(start, "%Y-%m-%d")
-
-    if end:
-        et = datetime.datetime.strptime(end, "%Y-%m-%d")
-    else:
-        et = datetime.datetime.now()
-
-    _dirPath = os.path.join(settings.PROJECT_ROOT, "script/jdBill/{}".format(merchantNo))
-    if not os.path.exists(_dirPath):
-        os.makedirs(_dirPath)
-
-    while True:
-        if (et - st).days == 0:
-            break
-
-        billDate = st.strftime("%Y%m%d")
-        st = st + datetime.timedelta(days=1)
-        try:
-            _downloadPath = JDMerchant.query_bill_file(merchantNo, billDate=billDate)
-        except Exception as e:
-            print "{} {}".format(billDate, e)
-            continue
-
-        response = requests.get(url=_downloadPath)
-        content = response.content
-
-        with open(os.path.join(_dirPath, "bill_{}.zip".format(billDate)), "wb") as f:
-            f.write(content)
-
-
-def download_settle_file(merchantNo, start, end):
-    dataRows = list()
-
-    st = datetime.datetime.strptime(start, "%Y-%m-%d")
-
-    if end:
-        et = datetime.datetime.strptime(end, "%Y-%m-%d")
-    else:
-        et = datetime.datetime.now()
-
-    _dirPath = os.path.join(settings.PROJECT_ROOT, "script/jdSettle/{}".format(merchantNo))
-    if not os.path.exists(_dirPath):
-        os.makedirs(_dirPath)
-
-    days = (et - st).days
-
-    for _index in range(days):
-        _date = st + datetime.timedelta(_index)
-        _dateStr = _date.strftime("%Y-%m-%d")
-        _settleDataList = list()
-
-        result = JDMerchant.query_settle(
-            agentNo="112122276",
-            startTime=_dateStr,
-            endTime=_dateStr,
-            merchantNo=merchantNo,
-        )
-
-        if "dataList" not in result or not result["dataList"]:
-            continue
-
-        _settleData = result["dataList"][0]
-
-        dataRows.append(_settleData)
-
-    with open(os.path.join(_dirPath, "settle.csv"), "w") as f:
-        wr = csv.DictWriter(f, fieldnames=[
-            "settleDate", "merchantNo", "merchantName", "settleType",
-            "settlementAmount", "settleAccountNo", "orderStatus", "remark"
-        ])
-
-        wr.writeheader()
-        wr.writerows(dataRows)
-
-
-if __name__ == '__main__':
-    try:
-        options, args = getopt.getopt(sys.argv[1:], 's:e:m:',
-                                      ['start=', 'end=', 'merchantNo='])
-    except getopt.GetoptError as e:
-        print(str(e))
-        sys.exit()
-
-    start = None
-    end = None
-    merchantNo = None
-
-    for name, value in options:
-        if name in ('-s', '--start'):
-            start = value
-
-        if name in ('-e', '--end'):
-            end = value
-
-        if name in ('-m', '--merchantNo'):
-            merchantNo = str(value)
-
-    print 'start = {}'.format(start)
-    print 'end = {}'.format(end)
-    print 'merchant no = {}'.format(merchantNo)
-
-    download_bill_file(merchantNo, start, end)
-    download_settle_file(merchantNo, start, end)

+ 1 - 3
script/upgrade/executed/fix_dirty_data.py

@@ -12,7 +12,7 @@ sys.path.insert(0, PROJECT_ROOT)
 import click
 
 from script.base import init_env
-from apps.web.dealer.models import Dealer, Merchant
+from apps.web.dealer.models import Dealer
 from apps.web.device.models import Device, Group
 from apps.web.user.models import ConsumeRecord, RechargeRecord, MyUser
 
@@ -28,10 +28,8 @@ def fixWithdrawRecord():
     """提现记录增加字段"""
     click.echo(u'正在添加缺失字段')
     for withdrawRecord in WithdrawRecord.objects:
-        merchant = Merchant.objects(id=withdrawRecord.merchantId).first()
         dealer = Dealer.objects(id=withdrawRecord.ownerId).first()
         withdrawRecord.userTel = dealer.username if dealer is not None else u'默认号码'
-        withdrawRecord.cardUserName = merchant.merchantName if merchant is not None else u'我'
         withdrawRecord.subBankName = withdrawRecord.parentBankName
         withdrawRecord.save()
     click.echo('ok!')

+ 0 - 16
script/upgrade/executed/update_bank.py

@@ -3,19 +3,3 @@
 """
 
 """
-from apps.web.core.models import BankCard
-from apps.web.dealer.models import Merchant
-from script.base import *
-
-merchants = Merchant.objects()
-
-for merchant in merchants:
-    payload = {
-        'ownerId': merchant.ownerId,
-        'cardType': merchant.cardType,
-        'bankName': merchant.parentBankName,
-        'cardNo': merchant.accountCode,
-        'holderName': merchant.merchantName,
-        'branchName': merchant.subBankName
-    }
-    BankCard(**payload).save()

+ 0 - 755
script/upgrade/executed/upgrade_reactor_withdraw.py

@@ -1,755 +0,0 @@
-# -*- coding: utf-8 -*-
-# !/usr/bin/env python
-
-"""
-将重复的用户按组归并
-"""
-import datetime
-import os
-import sys
-
-import mongoengine
-from bson import ObjectId
-from mongoengine import StringField, ReferenceField, IntField, DateTimeField, BooleanField, EmbeddedDocument
-from typing import Union
-
-PROJECT_ROOT = os.path.join(os.path.abspath(os.path.split(os.path.realpath(__file__))[0] + "/.."), '..')
-sys.path.insert(0, PROJECT_ROOT)
-
-import os
-
-os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'configs.production')
-
-from script.base import init_env
-
-init_env(interactive = False)
-
-from apps.web.agent.define import AGENT_INCOME_TYPE
-from apps.web.core.db import MonetaryField, Searchable
-from apps.web.common.models import WithdrawRecord, Balance
-from apps.web.constant import Const
-from apps.web.core import ROLE
-from apps.web.common.transaction import WithdrawStatus, WITHDRAW_PAY_TYPE
-from apps.web.agent.models import Agent
-from apps.web.core.models import WechatPayApp, AliApp, BankCard
-from apilib.monetary import Ratio, RMB
-from apps.web.dealer.define import DEALER_INCOME_TYPE
-from apps.web.dealer.models import Dealer, Merchant
-from apps.web.core.payment.wechat import WechatPaymentGateway
-
-
-class WechatAppOld(EmbeddedDocument):
-    meta = {
-        'abstract': True
-    }
-
-    @property
-    def occupant(self):
-        return getattr(self, '__occupant__', None)
-
-    @occupant.setter
-    def occupant(self, occupant):
-        setattr(self, '__occupant__', occupant)
-
-
-class AliAppOld(WechatAppOld):
-    meta = {'abstract': True}
-
-    @property
-    def alipay_enable(self):
-        return getattr(self, '__alipay_enable__')
-
-    @alipay_enable.setter
-    def aplipay_eable(self, alipay_enable):
-        setattr(self, '__alipay_enable__', alipay_enable)
-
-
-class _WechatMiniApp(WechatAppOld):
-    appid = StringField(verbose_name = 'appid', null = False)
-    secret = StringField(verbose_name = "secretId", null = False, max_length = 32)
-
-    mchid = StringField(verbose_name = 'mchid', null = False)
-    apikey = StringField(verbose_name = 'apikey', null = False)
-
-    sslcert_path = StringField(verbose_name = '证书pem格式', null = False)
-    sslkey_path = StringField(verbose_name = '证书密钥pem格式', null = False)
-
-    manual_withdraw = BooleanField(verbose_name = u'是否手动提现', default = False)
-
-    def __repr__(self):
-        return '<WechatMiniPaymentApp appid=%s, mchid=%s>' % (self.appid, self.mchid)
-
-    def to_dict(self):
-        return {
-            'appid': self.appid,
-            'secret': self.secret,
-            'mchid': self.mchid,
-            'apikey': self.apikey,
-            'sslcert_path': self.sslcert_path,
-            'sslkey_path': self.sslkey_path,
-            'manual_withdraw': self.manual_withdraw
-        }
-
-    @property
-    def valid(self):
-        return self.appid and self.secret and self.mchid and self.sslkey_path and self.sslcert_path and self.apikey
-
-    @staticmethod
-    def get_null_app():
-        return _WechatMiniApp(appid = '', secret = '', mchid = '', apikey = '', sslcert_path = '', sslkey_path = '')
-
-    def __eq__(self, other):
-        # type: (Union[WechatPayApp, _WechatPaymentApp, _WechatMiniApp])->bool
-        if not isinstance(other, WechatPayApp) \
-                and not isinstance(other, _WechatPaymentApp) \
-                and isinstance(other, _WechatMiniApp):
-            return False
-
-        if other.appid != self.appid:
-            return False
-
-        if other.mchid != self.mchid:
-            return False
-
-        if other.secret != self.secret:
-            return False
-
-        if other.apikey != self.apikey:
-            return False
-
-        if other.sslcert_path != self.sslcert_path:
-            return False
-
-        if other.sslkey_path != self.sslkey_path:
-            return False
-
-        return True
-
-
-class _WechatPaymentApp(WechatAppOld):
-    appid = StringField(verbose_name = 'appid', null = False)
-    secret = StringField(verbose_name = "secretId", null = False, max_length = 32)
-
-    mchid = StringField(verbose_name = 'mchid', null = False)
-    apikey = StringField(verbose_name = 'apikey', null = False)
-    sslcert_path = StringField(verbose_name = '证书pem格式', null = False)
-    sslkey_path = StringField(verbose_name = '证书密钥pem格式', null = False)
-    rootca_path = StringField(verbose_name = 'CA证书')
-
-    manual_withdraw = BooleanField(verbose_name = u'是否手动提现', default = False)
-
-    def __repr__(self):
-        return '<WechatPaymentApp appid=%s>' % (self.appid,)
-
-    def to_dict(self):
-        def encrypt(url): return '******' if url else ''
-
-        return {
-            'appid': self.appid,
-            'secret': self.secret,
-            'mchid': self.mchid,
-            'apikey': self.apikey,
-            'sslcert_path': self.sslcert_path,
-            'sslkey_path': self.sslkey_path,
-            'rootca_path': self.rootca_path,
-        }
-
-    @property
-    def valid(self):
-        return self.appid and self.secret and self.mchid and self.sslkey_path and self.sslcert_path and self.apikey
-
-    @staticmethod
-    def get_null_app():
-        return _WechatPaymentApp(appid = '', secret = '', mchid = '',
-                                 apikey = '',
-                                 sslcert_path = '', sslkey_path = '',
-                                 rootca_path = '', manual_withdraw = False)
-
-    def __eq__(self, other):
-        # type: (Union[WechatPayApp, _WechatPaymentApp, _WechatMiniApp])->bool
-        if not isinstance(other, WechatPayApp) \
-                and not isinstance(other, _WechatPaymentApp) \
-                and isinstance(other, _WechatMiniApp):
-            return False
-
-        if other.appid != self.appid:
-            return False
-
-        if other.mchid != self.mchid:
-            return False
-
-        if other.secret != self.secret:
-            return False
-
-        if other.apikey != self.apikey:
-            return False
-
-        if other.sslcert_path != self.sslcert_path:
-            return False
-
-        if other.sslkey_path != self.sslkey_path:
-            return False
-
-        return True
-
-
-class _AliPaymentApp(AliAppOld):
-    appid = StringField(verbose_name = '支付宝appid', default = '')
-    public_key_path = StringField(verbose_name = '支付宝账户公钥', default = '')
-    alipayPublicKeyContent = StringField(verbose_name = '支付宝公钥文本')
-    appPublicKeyContent = StringField(verbose_name = '应用公钥文本')
-    app_private_key_path = StringField(verbose_name = '支付宝应用私钥', default = '')
-    shadow = BooleanField(verbose_name = u'是否沙箱版本支付宝', default = False)
-
-    def __repr__(self):
-        return '<AliPaymentApp appid=%s>' % (self.appid,)
-
-    def to_dict(self):
-        return {
-            'appid': self.appid,
-            'public_key_path': self.public_key_path,
-            'hasAlipayAppKeyPair': bool(self.app_private_key_path is not ''),
-            'alipayPublicKeyContent': self.alipayPublicKeyContent,
-            'appPublicKeyContent': self.appPublicKeyContent,
-            'app_private_key_path': self.app_private_key_path,
-            'debug': self.shadow
-        }
-
-    @staticmethod
-    def get_null_app():
-        return _AliPaymentApp(appid = '', public_key_path = '', app_private_key_path = '', shadow = False)
-
-    @property
-    def valid(self):
-        return self.appid and self.public_key_path and self.app_private_key_path
-
-    @property
-    def alipay_enable(self):
-        return getattr(self, '__alipay_enable__')
-
-    @alipay_enable.setter
-    def aplipay_eable(self, alipay_enable):
-        setattr(self, '__alipay_enable__', alipay_enable)
-
-    def __eq__(self, other):
-        # type: (Union[_AliPaymentApp, AliApp])->bool
-        if not isinstance(other, _AliPaymentApp) and not isinstance(other, AliApp):
-            return False
-
-        if other.appid != self.appid:
-            return False
-
-        if other.app_private_key_path != self.app_private_key_path:
-            return False
-
-        if other.public_key_path != self.public_key_path:
-            return False
-
-        return True
-
-
-class AgentWithdrawRecord(Searchable):
-    """
-        status:
-            0 <==> '已提交申请'
-            1 <==> '提现成功'
-            2 <==> '处理中'
-            3 <==> '提现失败'
-    """
-
-    ownerId = StringField(verbose_name = "代理商id")
-    phone = StringField(verbose_name = "持卡人电话", default = "")
-    payType = StringField(verbose_name = "支付方式", default = "")
-    agentName = StringField(verbose_name = "代理商姓名", default = "")
-    cardUserName = StringField(verbose_name = "持卡人姓名", default = "")
-    agentBalance = MonetaryField(verbose_name = "代理商当前余额", default = RMB('0.00'))
-    accountCode = StringField(verbose_name = "提现银行卡号", default = "")
-    order = StringField(verbose_name = "订单号", default = "")
-    amount = MonetaryField(verbose_name = "提现金额", default = RMB('0.00'))
-    serviceFee = MonetaryField(verbose_name = "服务费", default = RMB('0.00'))
-    actualPay = MonetaryField(verbose_name = "实际金额", default = RMB('0.00'))
-    withdrawBankCard = ReferenceField(BankCard)
-    status = IntField(verbose_name = "状态", default = WithdrawStatus.SUBMITTED)
-    remarks = StringField(verbose_name = "备注", default = "")
-    postTime = DateTimeField(verbose_name = "请求时间", default = datetime.datetime.now)
-    finishedTime = StringField(verbose_name = "完成时间", default = "")
-    parentBankName = StringField(verbose_name = "银行名称", default = "")
-    subBankName = StringField(verbose_name = "银行支行名称", default = "")
-
-    meta = {
-        'indexes': ['ownerId'],
-        'collection': 'AgentWithdrawRecord',
-        'db_alias': 'default'
-    }
-
-
-def do_error():
-    WithdrawRecord._meta.update({'auto_create_index': False})
-
-    for record in WithdrawRecord.objects.filter(order = None): # type: WithdrawRecord
-        record.order = WithdrawRecord.make_no(ROLE.dealer, record.ownerId)
-        record.withdrawGatewayKey = ''
-        record.save()
-
-    duplicate_records = WithdrawRecord.get_collection().aggregate([
-        {'$group': {
-            '_id': {'firstField': "$order"},
-            'uniqueIds': {'$addToSet': "$_id"},
-            'count': {'$sum': 1}
-        }},
-        {'$match': {
-            'count': {'$gt': 1}
-        }}
-    ], allowDiskUse = True)
-
-    for duplicate_record in duplicate_records:
-        if duplicate_record['count'] >= 2:
-            print "duplicate ids = %s" % str(duplicate_record['uniqueIds'])
-            WithdrawRecord.get_collection().remove(
-                {'_id': {'$in': duplicate_record['uniqueIds'][0:duplicate_record['count'] - 1]}})
-
-    WithdrawRecord._meta.update({'auto_create_index': True})
-
-
-def fill_agent():
-    def reactor_app(agent):
-        __modified = False
-
-        if agent.customizedWechatCashflowAllowable:
-            wechat_app = getattr(agent, 'wechatPayApp', None)
-            if not wechat_app:
-                print 'configure error for no wechat. agent = {agentId}'.format(agentId = str(agent.id))
-            else:
-                wechat_app = _WechatPaymentApp(**dict(wechat_app))  # type: _WechatPaymentApp
-                if not wechat_app.valid:
-                    print 'configure error for invalid wechat. agent = {agentId}'.format(agentId = str(agent.id))
-                else:
-                    db_app = WechatPayApp.objects(appid = wechat_app.appid,
-                                                  mchid = wechat_app.mchid).first()  # type: WechatPayApp
-                    if not db_app:
-                        pay_app = WechatPayApp(**wechat_app.to_dict()).save()  # type: WechatPayApp
-                        agent.payAppWechat = pay_app
-                        __modified = True
-                    elif wechat_app == db_app:
-                        agent.payAppWechat = db_app
-                        __modified = True
-                    else:
-                        print 'configure error for wechat not equal db. appid = {appid}, mchid = {mchid}'.format(
-                            appid = wechat_app.appid,
-                            mchid = wechat_app.mchid)
-        else:
-            # print 'not customize wechat app. id = %s' % str(agent.id)
-            return
-
-        if agent.customizedAlipayCashflowAllowable:
-            ali_app = getattr(agent, 'aliPayApp', None)
-            if not ali_app:
-                print 'configure error for no ali. agent = {agentId}'.format(agentId = str(agent.id))
-            else:
-                ali_app = _AliPaymentApp(**dict(ali_app))  # type: _AliPaymentApp
-                if not ali_app.valid:
-                    print 'configure error for invalid ali. agent = {agentId}'.format(agentId = str(agent.id))
-                else:
-                    db_app = AliApp.objects(appid = ali_app.appid).first()  # type: AliApp
-                    if not db_app:
-                        pay_app = AliApp(appid = ali_app.appid,
-                                         public_key_path = ali_app.public_key_path,
-                                         alipayPublicKeyContent = ali_app.alipayPublicKeyContent,
-                                         appPublicKeyContent = ali_app.appPublicKeyContent,
-                                         app_private_key_path = ali_app.app_private_key_path,
-                                         shadow = ali_app.shadow).save()  # type: AliApp
-                        agent.payAppAli = pay_app
-                        __modified = True
-                    elif ali_app == db_app:
-                        agent.payAppAli = db_app
-                        __modified = True
-                    else:
-                        print 'configure error for ali not equal db. ali appid = {appid}'.format(appid = ali_app.appid)
-
-    def reactor_pay_openid(agent):
-        payOpenId = getattr(agent, 'payOpenId', '')
-        payAppId = getattr(agent, 'payAppId', '')
-
-        if payAppId and payOpenId:
-            agent.set_bound_pay_openid(payAppId, openId = payOpenId)
-
-    def reactor_balance(agent):
-        try:
-            custom_gateway_key = WechatPaymentGateway(agent.wechat_agent_pay_app).key
-            platform_gateway_key = WechatPaymentGateway(agent.platform_wechat_pay_app).key
-
-            agent.adBalance = {platform_gateway_key: Balance(balance = RMB(0), frozenBalance = RMB(0))}
-            agent.trafficBalance = {platform_gateway_key: Balance(balance = RMB(0), frozenBalance = RMB(0))}
-            agent.deviceBalance = {custom_gateway_key: Balance(balance = RMB(0), frozenBalance = RMB(0))}
-            agent.withdrawBalance = {custom_gateway_key: Balance(balance = RMB(0), frozenBalance = RMB(0))}
-
-            balance = RMB(getattr(agent, 'balance', '0.00'))
-            if balance <= RMB('0.00'):
-                return
-
-            ad = RMB(getattr(agent.incomeMap, 'ad', 0))
-            sim = RMB(getattr(agent.incomeMap, 'dealer_card_fee', 0))
-            withdraw = RMB(getattr(agent.incomeMap, 'dealer_withdraw_fee', 0))
-            device = RMB(getattr(agent.incomeMap, 'dealer_device_fee', 0))
-
-            if ad > RMB(0) and sim == RMB(0) and withdraw == RMB(0) and device == RMB(0):
-                agent.adBalance = {platform_gateway_key: Balance(balance = balance, frozenBalance = RMB(0))}
-                return
-
-            if sim > RMB(0) and ad == RMB(0) and withdraw == RMB(0) and device == RMB(0):
-                agent.trafficBalance = {platform_gateway_key: Balance(balance = balance, frozenBalance = RMB(0))}
-                return
-
-            if withdraw > RMB(0) and sim == RMB(0) and ad == RMB(0) and device == RMB(0):
-                agent.withdrawBalance = {custom_gateway_key: Balance(balance = balance, frozenBalance = RMB(0))}
-                return
-
-            if device > RMB(0) and sim == RMB(0) and withdraw == RMB(0) and ad == RMB(0):
-                agent.deviceBalance = {custom_gateway_key: Balance(balance = balance, frozenBalance = RMB(0))}
-                return
-
-            agent.withdrawBalance = {custom_gateway_key: Balance(balance = balance, frozenBalance = RMB(0))}
-            return
-        except Exception, e:
-            print 'exception = %s. id = %s' % (str(e), str(agent.id))
-
-    agents = [agent for agent in Agent.objects.all()]
-
-    for agent in agents:
-        reactor_app(agent)
-        reactor_balance(agent)
-        reactor_pay_openid(agent)
-        agent.save()
-
-
-def rename_dealer_withdraw_record():
-    WithdrawRecord.get_collection().update({}, {'$set': {'role': ROLE.dealer, 'withdrawGatewayKey': ''},
-                                                '$unset': {'finishedTime': None},
-                                                '$rename': {"dealerName": "name", "dealerBalance": "balance",
-                                                            "userTel": "phone"}}, upsert = False, multi = True)
-
-
-def fill_agent_withdraw_reord():
-    records = [record for record in AgentWithdrawRecord.objects.all()]
-    for record in records:
-        fund_map = {
-            'amount': RMB(record.amount).mongo_amount,
-            'serviceFee': RMB(record.amount).mongo_amount,
-            'actualPay': RMB(record.actualPay).mongo_amount
-        }
-
-        agent = Agent.objects(id = str(record.ownerId)).first()
-        if not agent:
-            print 'agent is not exist. id = %s' % (str(agent.id))
-            continue
-
-        withdraw_gateway = WechatPaymentGateway(agent.wechat_agent_pay_app)
-
-        if record.payType not in [WITHDRAW_PAY_TYPE.WECHAT, WITHDRAW_PAY_TYPE.BANK]:
-            print 'pay type is invalid. id = %s' % (str(agent.id))
-            continue
-
-        pay_entity = BankCard(
-            cardNo = record.accountCode,
-            holderName = record.cardUserName,
-            bankName = record.parentBankName,
-            branchName = record.subBankName
-        )
-
-        while True:
-            try:
-                WithdrawRecord.create(agent,
-                                      withdraw_gateway,
-                                      pay_entity,
-                                      AGENT_INCOME_TYPE.DEALER_WITHDRAW_FEE,
-                                      record.payType,
-                                      fund_map,
-                                      False,
-                                      False,
-                                      **{
-                                          'balance': record.agentBalance,
-                                          'withdrawFeeRatio': Ratio(Const.PLATFORM_DEFAULT_WITHDRAW_FEE_RATIO),
-                                          # 'order': record.order,
-                                          'ownerId': record.ownerId,
-                                          'name': record.agentName,
-                                          'phone': record.phone,
-                                          'partition': [],
-                                          'status': record.status,
-                                          'postTime': record.postTime
-                                      })
-                break
-            except mongoengine.errors.NotUniqueError:
-                print 'unique error'
-            except Exception, e:
-                print 'create agent withdraw record exception = %s; agentId = %s' % (e, str(agent.id))
-
-
-def fill_dealer_withdraw_record():
-    records = WithdrawRecord.objects.filter(role = ROLE.dealer)
-
-    for record in records:  # type: WithdrawRecord
-        if not record.ownerId:
-            print 'has no dealer id. record = %s' % str(record.id)
-            dealer = None  # type: Dealer
-        else:
-            dealer = Dealer.objects(id = str(record.ownerId)).first()  # type: Dealer
-            if not dealer:
-                print 'dealer is none. id = %s' % record.ownerId
-            else:
-                try:
-                    app = dealer_withdraw_device_app(dealer)
-                    if app:
-                        record.withdrawGatewayKey = WechatPaymentGateway(app).key
-                except Exception, e:
-                    print 'dealer not belong to agent. dealerId = %s' % str(dealer.id)
-
-        record.incomeType = DEALER_INCOME_TYPE.DEVICE_INCOME
-        record.finishedTime = record.postTime
-
-        extras = {}
-
-        merchantId = getattr(record, 'merchantId', None)
-
-        # 没有payType的时候, 记录merchantId; 有payType, accountCode记录银行卡卡号或者微信openid
-        payType = getattr(record, 'payType', '')
-        if not payType:
-            if merchantId:
-                payType = WITHDRAW_PAY_TYPE.BANK
-
-                extras['withdrawBankCard'] = ObjectId(merchantId)
-
-                bank_card = Merchant.objects(id = str(merchantId)).first()  # type: Merchant
-                if not bank_card:
-                    print 'has not no account code. record = %s' % str(record.id)
-                else:
-                    if not record.accountCode:
-                        record.accountCode = bank_card.accountCode
-
-                    if not record.cardUserName:
-                        if dealer:
-                            record.cardUserName = dealer.nickname
-
-                    if not record.cardUserName:
-                        record.cardUserName = bank_card.merchantName
-
-                    if not record.parentBankName:
-                        record.parentBankName = bank_card.parentBankName
-
-                    if not record.subBankName:
-                        record.subBankName = bank_card.subBankName
-            else:
-                payType = WITHDRAW_PAY_TYPE.WECHAT
-
-                if not record.accountCode:
-                    if dealer:
-                        record.accountCode = getattr(dealer, 'payOpenId', '')
-
-                if not record.cardUserName:
-                    if dealer:
-                        record.cardUserName = dealer.nickname
-                    else:
-                        record.cardUserName = u'我'
-
-                if not record.parentBankName:
-                    record.parentBankName = u'微信'
-
-                if not record.subBankName:
-                    record.subBankName = u'微信企业付款'
-
-            record.payType = payType
-        else:
-            payType = getattr(record, 'payType', '')
-            if payType != WITHDRAW_PAY_TYPE.WECHAT:
-                if not record.accountCode:
-                    print 'has not no account code. record = %s' % str(record.id)
-                else:
-                    bank_card = Merchant.objects(accountCode = record.accountCode).first()  # type: Merchant
-                    if not bank_card:
-                        print 'bank card is null. bank = %s; record = %s' % (str(record.accountCode), str(record.id))
-                    else:
-                        extras['withdrawBankCard'] = ObjectId(str(bank_card.id))
-                        if not record.cardUserName:
-                            record.cardUserName = bank_card.merchantName
-
-                        if not record.parentBankName:
-                            record.parentBankName = bank_card.parentBankName
-
-                        if not record.subBankName:
-                            record.subBankName = bank_card.subBankName
-
-        if not record.name or not record.phone:
-            if dealer:
-                record.name = dealer.nickname
-                record.phone = dealer.username
-
-        old_withdrawFee = int(getattr(record, 'withdrawRatio', 0))
-        if old_withdrawFee != 0:
-            new_withdrawFeeRatio = Ratio(old_withdrawFee)
-        else:
-            if dealer:
-                new_withdrawFeeRatio = Ratio(dealer.withdrawFeeRatio)
-            else:
-                new_withdrawFeeRatio = Ratio(Const.PLATFORM_DEFAULT_WITHDRAW_FEE_RATIO)
-
-        # 计算提现收益分配
-        if new_withdrawFeeRatio > Ratio(Const.PLATFORM_DEFAULT_WITHDRAW_FEE_RATIO):
-            if dealer:
-                agent_fee_ratio = (new_withdrawFeeRatio - Ratio(Const.PLATFORM_DEFAULT_WITHDRAW_FEE_RATIO))
-                earned = record.amount * (agent_fee_ratio / Const.WITHDRAW_FEE_UNIT)
-                partition = [
-                    {'role': 'agent', 'id': dealer.agentId, 'ratio': agent_fee_ratio.mongo_amount,
-                     'earned': earned.mongo_amount}
-                ]
-
-                record.partition = partition
-
-        if record.payType == WITHDRAW_PAY_TYPE.WECHAT:
-            if record.status == WithdrawStatus.FAILED:
-                record.refunded = True
-                record.status = WithdrawStatus.CLOSED
-            elif record.status == WithdrawStatus.CLOSED and not record.refunded:
-                record.refunded = True
-        else:
-            pass
-
-        record.extras = extras
-        record.save()
-
-def fill_dealer():
-    try:
-        print 'unset role...'
-        Dealer.get_collection().update_many({}, {'$unset': {'role': ''}}, upsert = False)
-
-        print 'fill dealers...'
-
-        dealers = Dealer.objects.all()
-        for dealer in dealers:  # type: Dealer
-            try:
-                origin_balance = getattr(dealer, 'balance', RMB('0.00'))  # type: RMB
-                app = dealer_withdraw_device_app(dealer)
-                if not app:
-                    print 'no app. id = %s' % str(dealer.id)
-                    continue
-
-                key = WechatPaymentGateway(app).key
-                dealer.deviceBalance = {
-                    key: Balance(balance = origin_balance, frozenBalance = RMB('0.00'))
-                }
-                dealer.adBalance = {
-                    key: Balance(balance = RMB('0.00'), frozenBalance = RMB('0.00'))
-                }
-
-                payOpenId = getattr(dealer, 'payOpenId', '')
-                payAppId = getattr(dealer, 'payAppId', '')
-                if payOpenId and payAppId:
-                    dealer.set_bound_pay_openid(payAppId, openId = payOpenId)
-
-                inHouseAppId = getattr(dealer, 'inHouseAppId', '')
-                inHouseOpenId = getattr(dealer, 'inHouseOpenId', '')
-                if inHouseAppId and inHouseOpenId:
-                    dealer.set_bound_pay_openid(inHouseAppId, openId = inHouseOpenId)
-
-                dealer.save()
-            except Exception, e:
-                print 'exception = %s; dealer id = %s' % (str(e), str(dealer.id))
-
-        return dealers
-    except Exception, e:
-        print 'fill_dealer exception = %s' % str(e)
-
-def check_dealer():
-    dealers = Dealer.objects.all()
-    for dealer in dealers:  # type: Dealer
-        old_balance = RMB(getattr(dealer, 'balance', '0.00'))
-        new_total_balance = dealer.total_balance
-        new_device_balance = dealer.sub_balance(DEALER_INCOME_TYPE.DEVICE_INCOME)
-
-        assert old_balance <= new_total_balance, 'total balace error. id = %s' % (str(dealer.id))
-        assert old_balance <= new_device_balance, 'device balace error. id = %s' % (str(dealer.id))
-
-        new_gateway_keys = dealer.deviceBalance.keys()
-        assert len(new_gateway_keys) < 2, 'len gateway key errror. id = %s' % (str(dealer.id))
-
-        if new_total_balance == RMB(0):
-            assert len(new_gateway_keys) == 0, 'len gateway key errror2. id = %s' % (str(dealer.id))
-        else:
-            assert len(new_gateway_keys) == 1, 'len gateway key errror2. id = %s' % (str(dealer.id))
-
-        if len(new_gateway_keys) == 1:
-            app = get_dealer_pay_wechat_app(dealer)
-            old_gateway_key = WechatPaymentGateway(app).key
-            assert old_gateway_key == new_gateway_keys[0], 'len gateway key errror3. id = %s' % (str(dealer.id))
-
-        payOpenId = getattr(dealer, 'payOpenId', '')
-        payAppId = getattr(dealer, 'payAppId', '')
-
-        for appid, bound_info in dealer.payOpenIdMap.iteritems():
-            assert appid, 'pay open id error 1. id = %s' % (str(dealer.id))
-            assert bound_info, 'pay open id error 2. id = %s' % (str(dealer.id))
-            assert bound_info.openId, 'pay open id error 3. id = %s' % (str(dealer.id))
-
-        if payOpenId and payAppId:
-            assert payAppId in dealer.payOpenIdMap, 'pay open id error 4. id = %s' % (str(dealer.id))
-            assert payOpenId == dealer.payOpenIdMap[payAppId].openId, 'pay open id error 4. id = %s' % (str(dealer.id))
-
-        inHouseAppId = getattr(dealer, 'inHouseAppId', '')
-        inHouseOpenId = getattr(dealer, 'inHouseOpenId', '')
-        if inHouseAppId and inHouseOpenId:
-            assert inHouseAppId in dealer.payOpenIdMap, 'pay open id error 5. id = %s' % (str(dealer.id))
-            assert inHouseOpenId == dealer.payOpenIdMap[inHouseAppId].openId, 'pay open id error 6. id = %s' % (str(dealer.id))
-
-
-def check_agent():
-    agents = Agent.objects.all()
-    for agent in agents:  # type: Agent
-        old_balance = RMB(getattr(agent, 'balance', '0.00'))
-        new_total_balance = agent.total_balance
-
-        assert old_balance == new_total_balance, 'total balace error. id = %s' % (str(dealer.id))
-
-
-def fill_dealer_withdraw_record_2():
-    records = [record for record in WithdrawRecord.objects.filter(__raw__ = {'payAgentId': {'$exists': False}})]
-
-    for record in records:  # type: WithdrawRecord
-        if not record.ownerId:
-            print 'has no dealer id. record = %s' % str(record.id)
-            dealer = None  # type: Dealer
-        else:
-            dealer = Dealer.objects(id = str(record.ownerId)).first()  # type: Dealer
-            if not dealer:
-                print 'dealer is none. id = %s' % record.ownerId
-            else:
-                try:
-                    app = dealer_withdraw_device_app(dealer)
-                    if app:
-                        record.payAgentId = app.occupantId
-                        record.save()
-                except Exception, e:
-                    print 'dealer not belong to agent. dealerId = %s' % str(dealer.id)
-
-
-try:
-    # print 'fill_agent ...'
-    # fill_agent()
-    #
-    # print 'fill_dealer ...'
-    # fill_dealer()
-    #
-    # print 'do_error ...'
-    # do_error()
-    #
-    # print 'rename_dealer_withdraw_record ...'
-    # rename_dealer_withdraw_record()
-    #
-    # print 'fill_dealer_withdraw_record ...'
-    # fill_dealer_withdraw_record()
-    #
-    # print 'fill_agent_withdraw_reord ...'
-    # fill_agent_withdraw_reord()
-
-    fill_dealer_withdraw_record_2()
-
-    print 'success over'
-except Exception, e:
-    print 'exception = %s' % str(e)

+ 0 - 16
script/upgrade/update_bank.py

@@ -21,19 +21,3 @@ from script.base import init_env, get_logger
 logger = get_logger(__name__)
 
 init_env(interactive = False)
-from apps.web.dealer.models import Merchant
-from apps.web.common.models import Banks
-
-for item in Merchant.objects.all():
-    if not item.accountCode:
-        continue
-
-    bank_card = Banks.get_bank_info(item.accountCode)
-    if bank_card:
-        print bank_card['cardNo'], bank_card['bankCode'], item.parentBankName.encode('gb2312'), bank_card[
-            'bankName'].encode('gb2312'), bank_card['cardType'].encode('gb2312')
-
-        item.parentBankName = bank_card['bankName']
-        item.save()
-    else:
-        print item.accountCode, None, item.parentBankName.encode('gb2312')

+ 0 - 9
script/upgrade/update_bank_with_patterns.py

@@ -21,7 +21,6 @@ from script.base import init_env, get_logger
 logger = get_logger(__name__)
 
 init_env(interactive = False)
-from apps.web.dealer.models import Merchant
 from apps.web.common.models import Banks
 
 #
@@ -31,11 +30,3 @@ from apps.web.common.models import Banks
 #                  bankCode = item['bankCode'],
 #                  patterns = item['patterns'])
 #     bank.save()
-
-for item in Merchant.objects.all():
-    bank_card = Banks.get_bank_info(item.accountCode)
-    if bank_card:
-        print bank_card['cardNo'], bank_card['bankCode'], item.parentBankName.encode('gb2312'), bank_card[
-            'bankName'].encode('gb2312'), bank_card['cardType'].encode('gb2312')
-    else:
-        print item.accountCode, None, item.parentBankName.encode('gb2312')

+ 0 - 60
script/utils/upgrade_wechatminipay_app.py

@@ -1,60 +0,0 @@
-# -*- coding: utf-8 -*-
-# !/usr/bin/env python
-
-import datetime
-import os
-import sys
-
-import bson
-
-PROJECT_ROOT = os.path.join(os.path.abspath(os.path.split(os.path.realpath(__file__))[0] + "/.."), '..')
-sys.path.insert(0, PROJECT_ROOT)
-
-from script.base import init_env, get_logger
-
-logger = get_logger(__name__)
-
-init_env(interactive = True)
-
-sslcert_path = 'F:/downloads/WXCertUtil/cert/apiclient_cert.pem'
-sslkey_path = 'F:/downloads/WXCertUtil/cert/apiclient_key.pem'
-
-from apps.web.agent.models import Agent
-from apps.web.core.models import WechatMiniApp
-
-
-def is_valid_string(str):
-    try:
-        bson._make_c_string(str)
-        return True
-    except Exception as e:
-        return False
-
-
-agent = Agent.objects(id = '6417d4456f29257125ebf705').first()  # type: Agent
-
-app = agent.wechatMiniApp  # type: WechatMiniApp
-if os.path.isfile(sslcert_path):
-    with open(sslcert_path) as f:
-        content = str(f.read())
-        if is_valid_string(content):
-            print content
-            app.sslCert = content
-        else:
-            print('ssl cert is not valid.')
-
-else:
-    print('ssl cert path is not exist.')
-
-if os.path.isfile(sslkey_path):
-    with open(sslkey_path) as f:
-        content = str(f.read())
-        if is_valid_string(content):
-            print content
-            app.sslKey = content
-        else:
-            print('ssl key is not valid.')
-else:
-    print('ssl key path is not exist.')
-
-agent.save()

+ 0 - 61
script/wx_mrechant.py

@@ -1,61 +0,0 @@
-# coding=utf-8
-import json
-
-import os
-import requests
-
-from base import init_env
-
-init_env(True)
-
-from apps.web.merchant.models import MerchantSourceInfo
-from apps.web.merchant.utils import JDMerchant
-from apps.web.core.exceptions import MerchantError
-
-def get_mchid(ownerId):
-    record = MerchantSourceInfo.get_source_record(ownerId)
-
-    agentNo = record.agentNo
-    merchantNo = record.merchantNo
-    productCode = "401"
-    sign = JDMerchant.sign(agentNo, merchantNo, productCode)
-
-    entity = {
-        "agentNo": agentNo,
-        "merchantNo": merchantNo,
-        "productCode": productCode,
-        "sign": sign
-    }
-
-    entitySecData = JDMerchant.encrypt(entity)
-    data = {
-        "agentNo": agentNo,
-        "entity": entitySecData
-    }
-
-    url = os.path.join(JDMerchant.BASE_URL, "merchant/status/queryMerchantWXNo").replace("\\", "/")
-    response = requests.post(url=url, data=data)
-    result = response.json()
-    if result.get("code") != "0000":
-        raise MerchantError(result.get("message", ""))
-
-    hlbSubNoResultJson = result.get("data", dict()).get("hlbWxSubNoResultInfo")
-
-    try:
-        subResult = json.loads(hlbSubNoResultJson)
-    except Exception:
-        raise MerchantError(u"微信备案查询失败")
-
-    status = subResult.get("status")
-    orderNo = subResult.get("orderNo")
-    if status == "FAIL":
-        raise MerchantError(u"微信备案失败")
-    if status == "DOING":
-        raise MerchantError(u"微信备案受理中")
-
-    try:
-        wx_mch_id = subResult.get("threePartnerNoData")[0].get("threePartnerNo")
-    except Exception:
-        raise MerchantError(u"微信备案查询失败")
-
-    return orderNo

+ 0 - 17
static/administrator/js/config.router.js

@@ -145,23 +145,6 @@ angular.module('app')
                                 }]
                         }
                     })
-                    .state('app.user.merchant', {
-                        url: '/merchant',
-                        templateUrl: getTemplateUrl('tpl/merchantHistory.html'),
-                        resolve: {
-                            deps: ['$ocLazyLoad', 'uiLoad',
-                                function ($ocLazyLoad, uiLoad) {
-                                    return uiLoad.load([]).then(function () {
-                                        return $ocLazyLoad.load(['ui.select']).then(
-                                            function () {
-                                                return $ocLazyLoad.load(['js/controllers/merchantHistory.js']);
-                                            }
-                                        );
-                                    });
-
-                                }]
-                        }
-                    })
 
                     //设备管理
                     .state('app.dev', {

+ 0 - 60
static/administrator/js/controllers/dealerManage.js

@@ -79,21 +79,6 @@ app.controller('dealerManageCtrl', ['$scope', "$state", '$stateParams', '$http',
         {value: "free", label: "自由选择"},
     ];
 
-    $scope.enum.merchantStatus = [
-        {value: 0, label: "尚未申请"},
-        {value: 1, label: "商户入驻成功,产品开通中"},
-        {value: 2, label: "开通失败"},
-        {value: 3, label: "商户产品开通完成,准备提交微信审核"},
-        {value: 4, label: "开通成功"},
-        {value: 5, label: "微信实名审核中"},
-        {value: 6, label: "微信实名审核待用户确认"},
-        {value: 7, label: "微信实名确认已完成"},
-    ];
-    $scope.enum.merchantType = [
-        {value: 'N', label: "个人商户"},
-        {value: 'E', label: "企业商户"},
-    ];
-
     $scope.findEnum = function (list, value) {
         return list.find((item) => item.value === value)
     }
@@ -193,11 +178,6 @@ app.controller('dealerManageCtrl', ['$scope', "$state", '$stateParams', '$http',
                     ' </div>',
 
             },
-            {
-                field: 'merchantInfo',
-                displayName: '商户信息',
-                cellTemplate: '<div class="temp-row text-info" style="cursor: pointer;" ng-click="grid.appScope.showMerchantInfo(row.entity)" >商户详情</div>'
-            },
             {field: 'username', displayName: '用户名'},
             {
                 field: 'createdTime',
@@ -624,46 +604,6 @@ app.controller('dealerManageCtrl', ['$scope', "$state", '$stateParams', '$http',
         $("#detailInfoPanel").modal("hide");
     };
 
-    //展示详情
-    $scope.showMerchantInfo = function (entity) {
-        $("#merchantInfoPanel").modal("show");
-        $http.get('/superadmin/getMerchantInfo', {
-            params: {id: entity.id}
-        }).then(function (res) {
-            $scope.dialogData = res.data.payload;
-        }).catch(function (data) {
-            toaster.pop("error", "提示", "获取数据失败");
-        });
-    }
-    // 关闭显示
-    $scope.closeMerchantInfo = function () {
-        $("#merchantInfoPanel").modal("hide");
-    };
-
-    // 刷新经销商微信状态
-    $scope.refreshMerchantInfo = function (_id) {
-        $http.get('/superadmin/refreshMerchantInfo', {
-            params: {id: _id}
-        }).then(function (res) {
-            toaster.pop("info", "提示", "成功,请重新查看");
-        }).catch(function (data) {
-            toaster.pop("error", "提示", "失败");
-        });
-        $("#merchantInfoPanel").modal("hide");
-    };
-
-    // 刷新经销商微信状态
-    $scope.wechatReplay = function (_id) {
-        $http.get('/superadmin/wechatReplay', {
-            params: {id: _id}
-        }).then(function (res) {
-            toaster.pop("info", "提示", "成功");
-        }).catch(function (data) {
-            toaster.pop("error", "提示", "失败");
-        });
-        $("#merchantInfoPanel").modal("hide");
-    };
-
     // 必须先声明,否则ui-select无法双绑
     $scope.dialogData = {};
 

+ 0 - 98
static/administrator/js/controllers/merchantHistory.js

@@ -1,98 +0,0 @@
-app.controller('merchantHistoryCtrl', ['$scope', "$state", '$stateParams', '$http', '$timeout', 'uiGridConstants', 'i18nService', 'toaster', 'md5', function ($scope, $state, $stateParams, $http, $timeout, uiGridConstants, i18nService, toaster, MD5) {
-    i18nService.setCurrentLang("zh-cn");
-
-    $scope.gridOptions = {
-        data: 'myData',
-        showGridFooter: true, //是否显示grid footer
-        paginationPageSizes: [50, 200, 500, 1000, 2000], //每页显示个数可选项
-        paginationCurrentPage: 1, //当前页码
-        paginationPageSize: 50, //每页显示个数
-        totalItems: 0,// 总数量
-        useExternalPagination: true,//是否使用分页按钮
-        columnDefs: [],
-
-        onRegisterApi: function (gridApi) {
-            $scope.gridApi = gridApi;
-            gridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
-                if ($scope.setPagingData) {
-                    $scope.getPagedDataAsync(newPage, pageSize);
-                }
-            });
-        }
-    };
-
-    //查询条件
-    var condition = $scope.condition = {
-        id: "",
-        merchantId: "",
-        searchKey: "",
-    };
-
-    //事件
-    $scope.event = {
-        statusChange: function (key, item) {
-            condition[key].value = item.value;
-            condition[key].label = item.label;
-            this.search()
-        },
-
-        search: function () {
-            $scope.getPagedDataAsync(1, $scope.gridOptions.paginationPageSize);
-        }
-    };
-
-    function setColumnDefs() {
-        $scope.gridOptions.columnDefs = [
-            {field: 'action', displayName: '执行动作',},
-            {field: 'dateTimeAdded', displayName: '执行时间'},
-            {field: 'description', displayName: '描述',},
-            {field: 'id', displayName: 'ID',},
-            {field: 'merchantId', displayName: '商户ID',},
-        ];
-
-        var fields = $scope.gridOptions.columnDefs;
-        for (var index in fields) {
-            var item = fields[index];
-            if (item && item['minWidth'] == null) {
-                item['minWidth'] = 120;
-            }
-        }
-    }
-
-    $scope.setPagingData = function (data, curPage, pageSize) {
-        var pagedData = data.data.dataList;
-        $scope.myData = pagedData;
-        $scope.gridOptions.totalItems = data.data.total;
-    };
-
-    $scope.getPagedDataAsync = function (curPage, pageSize) {
-        if ($scope.gridOptionsLoading) {
-            return;
-        }
-        var params = {
-            pageSize: pageSize,
-            pageIndex: curPage,
-            ...condition
-        };
-
-        $scope.gridOptionsLoading = true;
-        $http.get('/superadmin/getMerchantLog', {
-            params: params
-        }).then(function (data) {
-            data = data.data
-            $scope.gridOptionsLoading = false;
-            $scope.setPagingData(data, curPage, pageSize);
-        }).catch(function (data) {
-            toaster.pop("error", "提示", "获取数据列表失败");
-        });
-    };
-
-    function initDataGrid() {
-        //首次加载表格
-        $scope.getPagedDataAsync($scope.gridOptions.paginationCurrentPage, $scope.gridOptions.paginationPageSize);
-    }
-
-    setColumnDefs();
-    initDataGrid();
-
-}]);

+ 0 - 5
static/administrator/tpl/blocks/nav.html

@@ -67,11 +67,6 @@
                     <span>客服</span>
                 </a>
             </li>
-            <li ui-sref-active="active">
-                <a ui-sref="app.user.merchant">
-                    <span>商户申请记录</span>
-                </a>
-            </li>
         </ul>
     </li>
 

+ 0 - 267
static/administrator/tpl/dealerManage.html

@@ -139,272 +139,6 @@
                 <div class="grid-mask" ng-if="gridOptionsLoading"><span>正在加载,请稍候...</span></div>
             </div>
         </div>
-
-        <div id="merchantInfoPanel" class="form-horizontal form-validation modal fade" role="dialog"
-             style="height: 800px">
-            <div class="panel panel-default">
-                <div class="panel-heading">
-                    <strong>{{infoDetail.title}}</strong>
-                </div>
-
-
-                <div class="panel-body">
-
-                    <div class="form-group">
-                        <label class="col-sm-3 control-label">商户类型</label>
-                        <div class="col-sm-6">
-                            <input type="text" value="{{findEnum(enum.merchantType,dialogData.merchantType).label}}"
-                                   class="form-control">
-                        </div>
-                    </div>
-
-                    <div class="form-group">
-                        <label class="col-sm-3 control-label">商户状态</label>
-                        <div class="col-sm-6">
-                            <input type="text" value="{{findEnum(enum.merchantStatus, dialogData.status).label}}"
-                                   class="form-control">
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <label class="col-sm-3 control-label">申请描述</label>
-                        <div class="col-sm-6">
-                            <input type="text" ng-model="dialogData.errorMsg"
-                                   class="form-control">
-                        </div>
-                    </div>
-
-                    <div class="form-group">
-                        <label class="col-sm-3 control-label">商户账号</label>
-                        <div class="col-sm-6"><input type="text" ng-model="dialogData.regEmail" class="form-control">
-                        </div>
-                    </div>
-
-                    <div class="form-group">
-                        <label class="col-sm-3 control-label">京东商户号</label>
-                        <div class="col-sm-6"><input type="text" ng-model="dialogData.merchantNo" class="form-control">
-                        </div>
-                    </div>
-
-                    <div class="form-group">
-                        <label class="col-sm-3 control-label">微信子商编</label>
-                        <div class="col-sm-6"><input type="text" ng-model="dialogData.subMerchantId"
-                                                     class="form-control">
-                        </div>
-                    </div>
-
-                    <div class="form-group">
-                        <label class="col-sm-3 control-label">微信申请单号</label>
-                        <div class="col-sm-6"><input type="text" ng-model="dialogData.applymentId" class="form-control">
-                        </div>
-                    </div>
-
-                    <div class="form-group">
-                        <label class="col-sm-3 control-label">提交时间</label>
-                        <div class="col-sm-6"><input type="text" ng-model="dialogData.createdTime" class="form-control">
-                        </div>
-                    </div>
-
-                    <div class="form-group">
-                        <label class="col-sm-3 control-label">状态更新时间</label>
-                        <div class="col-sm-6"><input type="text" ng-model="dialogData.updateTime" class="form-control">
-                        </div>
-                    </div>
-
-                    <div class="form-group">
-                        <label class="col-sm-3 control-label">法人证件</label>
-                        <div class="col-sm-9">
-                            <a href="{{dialogData.certificate.legalInfo.urlA}}" target="_blank">
-                                <img ng-src="{{dialogData.certificate.legalInfo.urlA}}"
-                                     style="width: 160px;height: 160px;object-fit: cover">
-                            </a>
-                            <a href="{{dialogData.certificate.legalInfo.urlA}}" target="_blank">
-                                <img ng-src="{{dialogData.certificate.legalInfo.urlB}}"
-                                     style="width: 160px;height: 160px;object-fit: cover">
-                            </a>
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <label class="col-sm-3 control-label">法人姓名</label>
-                        <div class="col-sm-6">
-                            <input type="text" ng-model="dialogData.certificate.legalInfo.name" class="form-control">
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <label class="col-sm-3 control-label">地址信息</label>
-                        <div class="col-sm-6">
-                            <input type="text" ng-value="dialogData.certificate.legalInfo.province.name
-                            + ' ' + dialogData.certificate.legalInfo.city.name
-                            + ' ' + dialogData.certificate.legalInfo.area.name
-                            + ' ' + dialogData.certificate.legalInfo.addr" class="form-control">
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <label class="col-sm-3 control-label">有效期</label>
-                        <div class="col-sm-6">
-                            <input type="text"
-                                   ng-value="dialogData.certificate.legalInfo.startTime + '至' +dialogData.certificate.legalInfo.endTime"
-                                   class="form-control">
-                        </div>
-                    </div>
-
-                    <div class="form-group" ng-if="dialogData.certificate.contactInfo">
-                        <label class="col-sm-3 control-label">联系人证件</label>
-                        <div class="col-sm-9">
-                            <a href="{{dialogData.certificate.contactInfo.urlA}}" target="_blank">
-                                <img ng-src="{{dialogData.certificate.contactInfo.urlA}}"
-                                     style="width: 160px;height: 160px;object-fit: cover">
-                            </a>
-                            <a href="{{dialogData.certificate.contactInfo.urlA}}" target="_blank">
-                                <img ng-src="{{dialogData.certificate.contactInfo.urlB}}"
-                                     style="width: 160px;height: 160px;object-fit: cover">
-                            </a>
-                        </div>
-                    </div>
-                    <div class="form-group" ng-if="dialogData.certificate.contactInfo">
-                        <label class="col-sm-3 control-label">联系人姓名</label>
-                        <div class="col-sm-6">
-                            <input type="text" ng-model="dialogData.certificate.contactInfo.name" class="form-control">
-                        </div>
-                    </div>
-                    <div class="form-group" ng-if="dialogData.certificate.contactInfo">
-                        <label class="col-sm-3 control-label">地址信息</label>
-                        <div class="col-sm-6">
-                            <input type="text" ng-model="dialogData.certificate.contactInfo.province.name
-                            + ' ' + dialogData.certificate.contactInfo.city.name
-                            + ' ' + dialogData.certificate.contactInfo.area.name
-                            + ' ' + dialogData.certificate.contactInfo.addr" class="form-control">
-                        </div>
-                    </div>
-                    <div class="form-group" ng-if="dialogData.certificate.contactInfo">
-                        <label class="col-sm-3 control-label">有效期</label>
-                        <div class="col-sm-6">
-                            <input type="text"
-                                   ng-model="dialogData.certificate.contactInfo.startTime + '至' +dialogData.certificate.contactInfo.endTime"
-                                   class="form-control">
-                        </div>
-                    </div>
-
-                    <div class="form-group" ng-if="dialogData.certificate.subjectInfo">
-                        <label class="col-sm-3 control-label">营业执照信息</label>
-                        <div class="col-sm-9">
-                            <a href="{{dialogData.certificate.subjectInfo.businessLicenceInfo.busLicenseUrl}}"
-                               target="_blank">
-                                <img ng-src="{{dialogData.certificate.subjectInfo.businessLicenceInfo.busLicenseUrl}}"
-                                     style="width: 160px;height: 160px;object-fit: cover">
-                            </a>
-                        </div>
-                    </div>
-                    <div class="form-group" ng-if="dialogData.certificate.subjectInfo">
-                        <label class="col-sm-3 control-label">公司名称</label>
-                        <div class="col-sm-6">
-                            <input type="text" ng-model="dialogData.certificate.subjectInfo.businessLicenceInfo.busName"
-                                   class="form-control">
-                        </div>
-                    </div>
-                    <div class="form-group" ng-if="dialogData.certificate.subjectInfo">
-                        <label class="col-sm-3 control-label">统一社会信用码</label>
-                        <div class="col-sm-6">
-                            <input type="text" ng-model="dialogData.certificate.subjectInfo.businessLicenceInfo.busCode"
-                                   class="form-control">
-                        </div>
-                    </div>
-                    <div class="form-group" ng-if="dialogData.certificate.subjectInfo">
-                        <label class="col-sm-3 control-label">地址信息</label>
-                        <div class="col-sm-6">
-                            <input type="text" ng-value="dialogData.certificate.subjectInfo.businessLicenceInfo.province.name
-                            + ' ' + dialogData.certificate.subjectInfo.businessLicenceInfo.city.name
-                            + ' ' + dialogData.certificate.subjectInfo.businessLicenceInfo.area.name
-                            + ' ' + dialogData.certificate.subjectInfo.businessLicenceInfo.addr" class="form-control">
-                        </div>
-                    </div>
-                    <div class="form-group" ng-if="dialogData.certificate.subjectInfo">
-                        <label class="col-sm-3 control-label">有效期</label>
-                        <div class="col-sm-6">
-                            <input type="text"
-                                   ng-value="dialogData.certificate.subjectInfo.businessLicenceInfo.startTime + '至' +dialogData.certificate.subjectInfo.businessLicenceInfo.endTime"
-                                   class="form-control">
-                        </div>
-                    </div>
-
-                    <div class="form-group">
-                        <label class="col-sm-3 control-label">银行卡</label>
-                        <div class="col-sm-9">
-                            <a href="{{dialogData.settle.bankCardImg}}" target="_blank">
-                                <img ng-src="{{dialogData.settle.bankCardImg}}"
-                                     style="width: 160px;height: 160px;object-fit: cover">
-                            </a>
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <label class="col-sm-3 control-label">卡号</label>
-                        <div class="col-sm-6">
-                            <input type="text" ng-model="dialogData.settle.bankCardCode" class="form-control">
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <label class="col-sm-3 control-label">银行</label>
-                        <div class="col-sm-6">
-                            <input type="text" ng-model="dialogData.settle.bankName" class="form-control">
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <label class="col-sm-3 control-label">支行</label>
-                        <div class="col-sm-6">
-                            <input type="text"
-                                   ng-value="dialogData.settle.bankCardSubName + '  ' + dialogData.settle.bankCardSubCode"
-                                   class="form-control">
-                        </div>
-                    </div>
-
-                    <div class="form-group">
-                        <label class="col-sm-3 control-label">门店照</label>
-                        <div class="col-sm-9">
-                            <a href="{{dialogData.business.storeAUrl}}" target="_blank">
-                                <img ng-src="{{dialogData.business.storeAUrl}}"
-                                     style="width: 160px;height: 160px;object-fit: cover">
-                            </a>
-                            <a href="{{dialogData.business.storeBUrl}}" target="_blank">
-                                <img ng-src="{{dialogData.business.storeBUrl}}"
-                                     style="width: 160px;height: 160px;object-fit: cover">
-                            </a>
-                            <a href="{{dialogData.business.storeCUrl}}" target="_blank">
-                                <img ng-src="{{dialogData.business.storeCUrl}}"
-                                     style="width: 160px;height: 160px;object-fit: cover">
-                            </a>
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <label class="col-sm-3 control-label">商户简称</label>
-                        <div class="col-sm-6">
-                            <input type="text" ng-model="dialogData.business.storeShotName" class="form-control">
-                        </div>
-                    </div>
-                    <div class="form-group">
-                        <label class="col-sm-3 control-label">地址信息</label>
-                        <div class="col-sm-6">
-                            <input type="text" ng-value="dialogData.business.province.name
-                            + ' ' + dialogData.business.city.name
-                            + ' ' + dialogData.business.area.name
-                            + ' ' + dialogData.business.addr" class="form-control">
-                        </div>
-                    </div>
-                </div>
-            </div>
-            <footer class="panel-footer text-center bg-light lter">
-                <button type="button" class="btn btn-info margin-5" ng-click="closeMerchantInfo()"
-                        style="margin-left: 8px"><i
-                        class="fa fa-close"></i> 关闭
-                </button>
-                <button type="button" class="btn btn-info margin-5" ng-click="refreshMerchantInfo(dialogData.id)"
-                        style="margin-left: 8px"><i
-                        class="fa fa-close"></i> 刷新(对该商户重新拉取一次状态)
-                </button>
-                <button type="button" class="btn btn-info margin-5" ng-click="wechatReplay(dialogData.id)"
-                        style="margin-left: 8px"><i
-                        class="fa fa-close"></i> 重新提交微信(微信二维码过期)
-                </button>
-            </footer>
-        </div>
     </div>
 
     <div id="detailInfoPanel" class="form-horizontal form-validation modal fade" role="dialog"
@@ -663,7 +397,6 @@
             </div>
 
             <div class="panel-body">
-
                 <div class="form-group">
                     <label class="col-sm-3 control-label">状态:</label>
                     <div class="col-sm-9">

+ 0 - 43
static/administrator/tpl/merchantHistory.html

@@ -1,43 +0,0 @@
-<div ng-controller="merchantHistoryCtrl">
-    <div class="bg-light lter b-b wrapper-md">
-        <h1 class="m-n font-thin h3">商户申请记录</h1>
-    </div>
-
-    <div class="wrapper-md">
-        <div class="panel panel-default">
-
-            <div class="row wrapper">
-                <div class="col-sm-3">
-
-                </div>
-
-                <div class="col-sm-9 form-inline text-right">
-                    <div class="input-group">
-                        <input type="text" class="form-control" ng-model="condition.id"
-                               placeholder="ID">
-                    </div>
-                    <div class="input-group">
-                        <input type="text" class="form-control" ng-model="condition.merchantId"
-                               placeholder="商户ID">
-                    </div>
-                    <div class="input-group">
-                        <input type="text" class=" form-control" ng-model="condition.searchKey"
-                               ng-keydown="$event.keyCode==13&&event.search()"
-                               placeholder="搜索">
-                        <span class="input-group-btn">
-                         <div class="btn  btn-default" ng-click="event.search()"><i class="fa fa-search"></i> 搜索</div>
-                        </span>
-                    </div>
-                </div>
-            </div>
-
-            <div class="table-responsive">
-                <div ui-grid="gridOptions" style="min-height:620px"
-                     ng-style="{'min-height':620}" ui-grid-pagination
-                     ui-grid-selection></div>
-                <div class="grid-mask" ng-if="gridOptionsLoading"><span>正在加载,请稍候...</span></div>
-            </div>
-        </div>
-
-    </div>
-</div>

+ 0 - 65
static/agents/customerParam.html

@@ -164,25 +164,6 @@
     </div>
 </div>
 
-<div class="edit-back merProfitShareDialog mui-hidden">
-    <div class="edit-content">
-        <div class="edit-box">
-            <div class="mui-input-row">
-                <label class="tips-event">商户分成比例</label>
-                <div class="mui-pull-right edit-row">
-                    <input id="merProfitShareRatio" maxlength="3" min="0" type="number" value="" placeholder=""
-                           onkeypress="return myNumberic(event,2);">
-                    <span>%</span>
-                </div>
-            </div>
-        </div>
-        <div class="mui-popup-buttons">
-            <span class="mui-popup-button">取消</span>
-            <span class="mui-popup-button mui-popup-button-bold">确认</span>
-        </div>
-    </div>
-</div>
-
 <div class="edit-back limitDevNumDialog mui-hidden">
     <div class="edit-content">
         <div class="edit-box">
@@ -403,52 +384,6 @@
             }
             return false;
         });
-
-        // 商户的分成比例设置
-        $('.merProfitShareDialog .mui-popup-buttons span').tap(function () {
-            if ($(this).index() === 0) {
-                //点击取消
-                $('.merProfitShareDialog').addClass('mui-hidden');
-            } else {
-                //点击保存
-                var value = $('#merProfitShareRatio').val();
-
-                if (value < 0) {
-                    mui.toast("最小为0%");
-                    return;
-                }
-
-                if (value > 100) {
-                    mui.toast("最大为100%");
-                    return;
-                }
-
-                var data = {"id": id, "agentMerProfitShare": value};
-
-                var url = "/agent/setDealerAgentMerProfitShare";
-                sendRequest(url, "POST", JSON.stringify(data), function (res) {
-                    if (res.result == 1) {
-                        mui.toast("设置成功");
-                        $('.merProfitShareDialog').addClass('mui-hidden');
-                        $("#agentMerProfitShareShow").text(value + "%");
-                    } else if (res.result === 50002) {
-                        mui.confirm(
-                            "您尚未绑定商户号,无法进行商户经营比例分成,是否立即去绑定商户",
-                            "提示",
-                            ["不用了", "去绑定"],
-                            function (e){
-                                if (e.index===1) {
-                                    goPage("/agent/index.html?#/merchant")
-                                }
-                            }
-                        )
-                    } else {
-                        mui.toast(res.description);
-                    }
-                });
-            }
-            return false;
-        });
     });
 
     // 限制设备数量

+ 0 - 36
static/app/index.html

@@ -223,31 +223,6 @@
                     </div>
                 </a>
 
-                <a class="mui-col-xs-6 mui-col-sm-6 row-cell" href="/dealer/index.html#/merchant"
-                   key="merchant" id="merchant">
-                    <div class="mui-row">
-                        <p class="mui-col-xs-3 mui-col-sm-3 mui-text-center">
-                            <i class="iconfont icon-jingdong c-red" style="font-size: 28px"></i>
-                        </p>
-                        <p class="mui-col-xs-9 mui-col-sm-9">
-                            绑定银行卡<span class="mui-ellipsis merchantStatusText">开通商户</span>
-                        </p>
-                    </div>
-                </a>
-
-
-                <a class="mui-col-xs-6 mui-col-sm-6 row-cell" href="javascript:goJoin();"
-                   key="zhenguduo" id="zhenguduo">
-                    <div class="mui-row">
-                        <p class="mui-col-xs-3 mui-col-sm-3 mui-text-center">
-                            <i class="iconfont icon-jiameng c-red"></i>
-                        </p>
-                        <p class="mui-col-xs-9 mui-col-sm-9">
-                            寻找加盟<span class="mui-ellipsis">合伙运营设备</span>
-                        </p>
-                    </div>
-                </a>
-
                 <a class="mui-col-xs-6 mui-col-sm-6 row-cell" href="/dealer/index.html#/batteryManager/list"
                    key="batteryManager" id="batteryManager">
                     <div class="mui-row">
@@ -391,12 +366,6 @@
 
     showTestInfo();//测试系统检测
 
-    var merchantStatusMap = {
-        0: {name: '未开通商户', style: 'c-gray'},
-        1: {name: '已开通', style: 'c-green'},
-        2: {name: '审核中', style: 'c-blue'},
-    }
-
     /**
     * @param item {Object}
     * @param item.id {string}
@@ -462,11 +431,6 @@
                     $("#total").html(info.onlineCount + info.offlineCount);
                     $("#online").html(info.onlineCount);
 
-                    if (info.merchantStatus !== null) {
-                        var merchantStatusItem = merchantStatusMap[info.merchantStatus] || {}
-                        $('.merchantStatusText').addClass(merchantStatusItem.style).text(merchantStatusItem.name)
-                    }
-
                     //展示用户反馈红点
                     if (info.feedback) {
                         $(".feedbackIconTip").removeClass("mui-hidden").text(info.feedback);

+ 0 - 1
static/app/js/xyf.common.js

@@ -198,7 +198,6 @@ var defaultPermission = {
         'user_feedback': true,
         'support_alarm': false,
         'user_identify': false,
-        'merchant': false,
         'zhenguduo': false,
         'batteryManager': false,
         'templateManager': false,

+ 1 - 31
static/app/location-edit.html

@@ -131,16 +131,11 @@
 <script>
     // 某些厂商必须要填写 乡镇 ,由于目前我们只有3级地区联动,所以需要手动填写
     var needCountry = false;
-    var merchant = false;
-    getFeatureList("dealer", {list: ['needCountry', 'merchant']}, function (payload) {
+    getFeatureList("dealer", {list: ['needCountry']}, function (payload) {
         if (payload.needCountry) {
             $('#needCountry').removeClass('mui-hidden')
         }
 
-        if (payload.merchant) {
-            merchant = payload.merchant
-        }
-
         initGroupInfo()
     });
 
@@ -271,7 +266,6 @@
                                 id: item.id,
                                 percent: item.percent,
                                 self: item.self,
-                                merchantStatus: item.merchantStatus,
                                 editDisabled: item.editDisabled
                             }
 
@@ -333,12 +327,6 @@
                     setMyPercent();
                 }
             });
-        }).on("click", ".p-goBindBankCard", function (event) {
-            var partnerId = $(this).closest('.mui-table-view-cell').attr('pId')
-            var merchantStatus = $(this).closest('.mui-table-view-cell').attr('merchantStatus')
-            if (merchantStatus == 0 || merchantStatus == 2) {
-                location.href = '/dealer/index.html#/merchant/partnerBank?partnerId=' + partnerId
-            }
         });
     };
 
@@ -489,14 +477,6 @@
         setMyPercent();//刷新我的比例
     });
 
-    var merchantStatusMap = {
-        0: "未绑定商户,去绑定",
-        1: "绑定审核中",
-        2: "绑定失败,去修改",
-        3: "绑定成功",
-        4: "绑定成功"
-    }
-
     function addPartner(option) {
         var name = option.name;
         var tel = option.tel;
@@ -504,7 +484,6 @@
         var percent = option.percent;
         var self = option.self;
         var editDisabled = option.editDisabled;
-        var merchantStatus = option.merchantStatus;
         var dom = $('<div class="mui-table-view-cell" >' +
             '<p class="font-b-16"> ' +
             '<span class="p-name-show"></span><span class="is-self c-success"></span> ' +
@@ -513,7 +492,6 @@
             '<p class="p-operation clearfix">' +
             '<span class="p-tel-show"></span>' +
             '<span class="font-b-16-6 mui-pull-right edit-row" permission="manage-show">' +
-            '<em class="p-goBindBankCard"><i class="iconfont icon-bank-card"></i><span>绑定商户</span></em>' +
             '<em class="p-edit"><i class="iconfont icon-edit"></i><span>编辑</span></em>' +
             '<em class="p-delete"><i class="iconfont icon-delete"></i><span>删除</span></em>' +
             '</span></p></div>');
@@ -525,19 +503,11 @@
         dom.find(".p-percent-show ").text(percent + "%");
         dom.attr("data-id", tel);
         dom.attr("pId", id);
-        dom.attr("merchantStatus", merchantStatus);
 
         if (editDisabled) {
             dom.find('.edit-row').remove()
         }
 
-        if (!merchant) {
-            // 没有特性则移除
-            dom.find('.p-goBindBankCard').remove()
-        } else {
-            dom.find('.p-goBindBankCard span').text(merchantStatusMap[merchantStatus])
-        }
-
         $(".my-percent").after(dom);
     }
 

+ 0 - 22
static/app/wallet/wallet.html

@@ -43,11 +43,6 @@
 
 <main class="margin-t-b-10">
     <ul class="mui-table-view navigate-after account-bd">
-        <li class="mui-table-view-cell">
-            <a class="mui-navigate-right" href="/dealer/index.html#/merchant/settle">
-                <i class="iconfont icon-formfill c-green"></i>结算记录
-            </a>
-        </li>
         <li class="mui-table-view-cell">
             <a class="mui-navigate-right" href="wallet-transactions.html">
                 <i class="iconfont icon-formfill c-blue"></i>提现记录
@@ -101,7 +96,6 @@
     }
 
     var walletData = null
-    var merchantTip = false
     //获取账号余额相关信息
     var urlBalance = "/dealer/walletData?random=" + Math.random() * 1000;
     sendRequest({
@@ -111,7 +105,6 @@
         success: function (res) {
             if (res.result == 1) {
                 var payload = walletData = res.payload;
-                merchantTip = payload.merchantTip;
                 if (payload.device) {
                     renderBalance("device", "bg-primary", "设备营收余额")
                 }
@@ -128,24 +121,9 @@
                 mui.toast(res.description);
             }
         }
-
     })
 
     $("body").on('tap', '.wallet-hd', function (e) {
-        var item = merchantTip
-        if (merchantTip && merchantTip.force) {
-            mui.confirm(item.content, item.title, ["去处理", "我知道了"], function (e) {
-                if (e.index === 0) {
-                    // 避免ios的弹窗不关闭
-                    setTimeout(function () {
-                        location.href = item.link
-                    }, 1)
-                } else {
-                }
-            });
-            return
-        }
-
         var sourceType = $(this).attr('sourceType')
         var sourceId = $(this).attr('sourceId')
 

+ 0 - 1
static/mock/dealer/groupInfo

@@ -16,7 +16,6 @@
     "partner": [
       {
         "name": "商户测试号",
-        "merchantStatus":0,
         "tel": 15012341234,
         "id": 1,
         "percent": 10

+ 0 - 9
taskmanager/config_test.py

@@ -512,15 +512,6 @@ CELERYBEAT_SCHEDULE = {
         }
     },
                        
-    'query_merchant_status': {
-        'task': 'tasks.query_merchant_status',
-        'schedule': crontab(minute=0, hour=3),
-        'options': {
-            'queue': MY_CELERY_QUEUE,
-            'routing_key': MY_CELERY_ROUTING_KEY
-        }
-    },
-
     'dealer_auto_charge_sim_card':{
         'task': 'tasks.dealer_auto_charge_sim_card',
         'schedule': crontab(day_of_month = '15', minute = 0, hour = 10),

+ 0 - 2
taskmanager/mediator.py

@@ -54,7 +54,6 @@ from taskmanager.tasks import (
     manager_export_consume_order_excel_from_db,
     manager_export_dealer_info_excel_from_db,
     export_aggregate_dealer_income,
-    query_merchant_status,
     device_offline_notify,
     batch_set_device_params,
     set_device_params,
@@ -67,7 +66,6 @@ from taskmanager.tasks import (
     notify_insurance_order_cancel,
     push_shanghai_platform_heatbeat,
     export_modify_customer_balance_record_excel_from_db,
-    pull_consume_order_timeout
 )
 
 

+ 0 - 4
taskmanager/tasks.py

@@ -19,7 +19,6 @@ from apps.web.user.tasks import (
     notify_insurance_order_cancel,
     notify_insurance_order_subscribe,
     pull_refund_order,
-    pull_consume_order_timeout
 )
 
 from apps.web.dealer.tasks import (report_feedback_to_dealer_via_wechat,
@@ -72,7 +71,6 @@ from apps.web.device.tasks import remove_serviceProgress_periodically, set_devic
     send_to_xf_falut, send_to_xf_fault_handle, deduct_rent_order, gen_daily_rent_order, sync_device_time_for_tcpcar, make_rpt_into_db, report_to_zhejiang_fight
 
 from apps.dispatch.tasks import send_topic_command
-from apps.web.merchant.tasks import query_merchant_status
 
 # noinspection PyUnresolvedReferences
 from apps.web.superadmin.tasks import (import_simcard_excel_to_db, export_simcard_excel_from_db, sum_customer, export_device_excel_from_db, handle_customer_complaints_yesterday)
@@ -88,11 +86,9 @@ poll_user_recharge_record = celery_task(poll_user_recharge_record)
 test_sync = celery_task(test_sync)
 report_to_user_low_power = celery_task(report_to_user_low_power)
 notify_virtual_card_expired = celery_task(notify_virtual_card_expired)
-query_merchant_status = celery_task(query_merchant_status)
 notify_insurance_order_subscribe = celery_task(notify_insurance_order_subscribe)
 notify_insurance_order_cancel = celery_task(notify_insurance_order_cancel)
 pull_refund_order = celery_task(pull_refund_order)
-pull_consume_order_timeout = celery_task(pull_consume_order_timeout)
 
 # : to dealer
 report_feedback_to_dealer_via_wechat = celery_task(report_feedback_to_dealer_via_wechat)

+ 0 - 2
testcase/unit/common.py

@@ -51,7 +51,6 @@ CONSUME_RECORD_ID = '5b8fc2027cc0282f04be33d9'
 PAY_AFTER_AD_ID = '5c2d71f5cdc57a223cf8aa15'
 BANNER_AD_ID = '5cadacaacdc57a1d6c3e55de'
 
-# BankCard
 MERCHANT_ID = '59a6ab388732d6169b33cde3'
 BANK_ACCOUNT_CODE = '6217561400008706928'
 
@@ -220,7 +219,6 @@ AGENT_NO_CUSTOMIZED_FIXTURE = {
     'customizedWechatCashflowAllowable': False,
     'customizedUserGzhAllowable': False,
     'customizedDealerGzhAllowable': False,
-    'customizedWechatMiniAllowable': False
 }
 
 DEFAULT_AGENT_FIXTURE = {

+ 2 - 41
testcase/unit/conftest.py

@@ -17,11 +17,11 @@ from apps.web.agent.models import Agent
 from apps.web.common.models import WithdrawRecord, Banks
 from apps.web.common.transaction import WithdrawStatus
 from apps.web.core import ROLE
-from apps.web.core.models import WechatAuthApp, WechatPayApp, AliApp, WechatManagerApp, BankCard, WechatMiniApp, \
+from apps.web.core.models import WechatAuthApp, WechatPayApp, AliApp, WechatManagerApp,  \
     WechatUserManagerApp
 from apps.web.core.payment.wechat import WechatPaymentGateway
 from apps.web.dealer.define import DEALER_INCOME_TYPE
-from apps.web.dealer.models import Dealer, OnSale, OnSaleRecord, Merchant
+from apps.web.dealer.models import Dealer, OnSale, OnSaleRecord
 from apps.web.device.models import Device, Group, DeviceType
 from apps.web.management.models import Manager
 from apps.web.superadmin.models import SuperManager
@@ -148,18 +148,6 @@ def default_wechat_auth_app():
     yield WechatAuthApp(appid = DEFAULT_WECHAT_CONFIG.appid, secret = DEFAULT_WECHAT_CONFIG.secret)
 
 
-@pytest.fixture(scope = 'session', autouse = True)
-def default_wechat_mini_app():
-    yield WechatMiniApp(
-        appid = DEFAULT_WECHAT_CONFIG.appid,
-        secret = DEFAULT_WECHAT_CONFIG.secret,
-        mchid = DEFAULT_WECHAT_CONFIG.mchid,
-        apikey = DEFAULT_WECHAT_CONFIG.apikey,
-        sslCert = DEFAULT_WECHAT_CONFIG.sslCert,
-        sslKey = DEFAULT_WECHAT_CONFIG.sslKey,
-        manual_withdraw = DEFAULT_WECHAT_CONFIG.manual_withdraw)
-
-
 @pytest.fixture(scope = 'session', autouse = True)
 def default_wechat_payment_app():
     WechatPayApp.objects(appid = DEFAULT_WECHAT_CONFIG.appid, mchid = DEFAULT_WECHAT_CONFIG.mchid).delete()
@@ -210,7 +198,6 @@ def default_agent(default_wechat_auth_app, default_wechat_managerial_app, defaul
 
     agent = Agent(**DEFAULT_AGENT_FIXTURE)  # type: Agent
     agent.payAppWechat = default_wechat_payment_app
-    agent.wechatMiniApp = default_wechat_mini_app
     agent.wechatLoginAuthApp = default_wechat_auth_app
     agent.wechatUserManagerialApp = default_wechat_user_managerial_app
     agent.wechatDealerManagerialApp = default_wechat_managerial_app
@@ -277,31 +264,6 @@ def device_type():
     _ = DeviceType(**DEVICE_TYPE_FIXTURE).save()
     yield _
 
-
-@pytest.fixture(scope = 'session', autouse = True)
-def bankcard():
-    # type: (*Any)->Merchant
-    """
-    a Dealer object
-    :return:
-    """
-    BankCard.objects(id = MERCHANT_ID).delete()
-    _ = BankCard(**BANK_CARD_FIXTURE).save()
-    yield _
-
-
-@pytest.fixture(scope = 'session', autouse = True)
-def merchant():
-    # type: ()->Merchant
-    """
-    a Dealer object
-    :return:
-    """
-    Merchant.objects(id = MERCHANT_ID).delete()
-    _ = Merchant(**MERCHANT_FIXTURE).save()
-    yield _
-
-
 @pytest.fixture(scope = 'function')
 def source_key():
     # type: ()->str
@@ -396,7 +358,6 @@ def agent_no_customized(bankcard):
     Agent.objects(id = AGENT_ID).delete()
 
     agent = Agent(**AGENT_NO_CUSTOMIZED_FIXTURE)  # type: Agent
-    agent.bankcards = [bankcard.id]
     agent.save()
 
     yield agent

+ 3 - 20
testcase/unit/test_agent.py

@@ -1,27 +1,12 @@
 # -*- coding: utf-8 -*-
 # !/usr/bin/env python
 
-from django.conf import settings
 from hypothesis import given, strategies as st
-from pytest_mock import MockFixture
-from typing import Union
 
-from apilib.monetary import RMB, Permillage
+from apilib.monetary import RMB
 from apilib.utils_datetime import generate_timestamp_ex
 from apps.web.agent.define import AGENT_INCOME_TYPE
-from apps.web.agent.models import Agent, AgentIncomeReport
-from apps.web.agent.withdraw import AgentWithdrawService
-from apps.web.common.models import WithdrawRecord, WithdrawRefundRecord
-from apps.web.common.transaction import WithdrawStatus, WITHDRAW_PAY_TYPE
-from apps.web.constant import Const
-from apps.web.core import ROLE
-from apps.web.core.models import BankCard
-from apps.web.dealer.define import DEALER_INCOME_TYPE
-from apps.web.dealer.models import Dealer
-from apps.web.dealer.withdraw import DealerWithdrawService
-from common import url_fn, DisposableModel, BANK_ACCOUNT_CODE, MERCHANT_ID
-from conftest import RequestTestClient
-from responses import WECHAT_WITHDRAW_SUCCEEDED, WECHAT_WITHDRAW_ERROR, BANK_WITHDRAW_SUCCEEDED, BANK_WITHDRAW_ERROR
+from apps.web.agent.models import Agent
 
 
 ###
@@ -587,9 +572,7 @@ def test_agent_clear_freeze_balance(agent_no_customized, source_key, income_type
 #     # type: (MockFixture, Agent, str, str, RequestTestClient, int)->None
 #
 #     if manual_type == 1:
-#         bank_card = BankCard.objects(id = MERCHANT_ID).first()
-#         bank_card.accountType = BankCard.AccountType.PUBLIC
-#         bank_card.save()
+#         pass
 #     else:
 #         wechat_payment_app = get_wechat_app_from_gateway_key(source_key)  # type: WechatPayApp
 #         wechat_payment_app.manual_withdraw = True

+ 6 - 12
testcase/unit/test_dealer.py

@@ -1,11 +1,11 @@
 # -*- coding: utf-8 -*-
 # !/usr/bin/env python
+import simplejson as json
 from django.conf import settings
 from django.core.urlresolvers import reverse
 from hypothesis import given, strategies as st
 from pytest_mock import MockFixture
 from typing import Dict, Union
-import simplejson as json
 
 from apilib.monetary import RMB
 from apilib.utils_datetime import generate_timestamp_ex
@@ -13,15 +13,14 @@ from apps.web.agent.define import AGENT_INCOME_TYPE
 from apps.web.agent.models import Agent
 from apps.web.common.models import WithdrawRecord
 from apps.web.common.transaction import WITHDRAW_PAY_TYPE, WithdrawStatus
-from apps.web.core.models import BankCard
 from apps.web.core.payment.wechat import WechatWithdrawGateway
 from apps.web.dealer.define import DEALER_INCOME_TYPE
-from apps.web.dealer.models import Dealer, Merchant
+from apps.web.dealer.models import Dealer
 from apps.web.dealer.urls import urlpatterns
+from library.wechatbase.exceptions import WeChatPayException, WechatNetworkException
 from testcase.unit.base import RequestTestClient
-from testcase.unit.common import url_fn, BANK_ACCOUNT_CODE, MERCHANT_ID
+from testcase.unit.common import url_fn, BANK_ACCOUNT_CODE
 from testcase.unit.responses import WECHAT_WITHDRAW_ERROR, BANK_WITHDRAW_SUCCEEDED, BANK_WITHDRAW_ERROR
-from library.wechatbase.exceptions import WeChatPayException, WechatNetworkException
 
 ViewName = str
 Url = str
@@ -815,13 +814,8 @@ def test_dealer_withdraw_with_bank_manual(mocker, dealer, agent, income_type, de
 
     agent.payAppWechat.occupant = agent
 
-    if manual_type == 1:
-        merchant = Merchant.objects(id = MERCHANT_ID).first()
-        merchant.accountType = BankCard.AccountType.PUBLIC
-        merchant.save()
-    else:
-        agent.payAppWechat.manual_withdraw = True
-        agent.payAppWechat.save()
+    agent.payAppWechat.manual_withdraw = True
+    agent.payAppWechat.save()
 
     gateway = WechatWithdrawGateway(agent.payAppWechat)
 

+ 0 - 2
urls.py

@@ -17,8 +17,6 @@ urlpatterns = patterns('',
                        url(r'^agent/', include('apps.web.agent.urls')),
                        url(r'^dealer/', include('apps.web.dealer.urls')),
                        url(r'^dealer/', include('apps.web.dealer.urls2')),
-                       url(r'^merchant/', include('apps.web.merchant.urls')),
-                       url(r'^miniuser/', include('apps.web.miniuser.urls')),
                        url(r'^user/', include('apps.web.user.urls')),
                        url(r'^user/', include('apps.web.user.urls2')),