zhongchuangCar.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. import logging
  4. import datetime
  5. from apilib.monetary import VirtualCoin
  6. from apilib.utils_sys import memcache_lock
  7. from apps.web.constant import DEALER_CONSUMPTION_AGG_KIND
  8. from apps.web.device.models import Group, Device
  9. from apps.web.eventer import EventBuilder
  10. from apps.web.eventer.base import WorkEvent
  11. from apps.web.user.models import ServiceProgress, MyUser
  12. from apps.web.user.transaction_deprecated import refund_money
  13. logger = logging.getLogger(__name__)
  14. class builder(EventBuilder):
  15. def __getEvent__(self, device_event):
  16. if device_event['cmd'] == 100:
  17. event_data = self.deviceAdapter.analyze_event_data(device_event['data'])
  18. return ZhongchuangCarWorkEventer(self.deviceAdapter, event_data)
  19. class ZhongchuangCarWorkEventer(WorkEvent):
  20. def do(self, **args):
  21. devNo = self.device["devNo"]
  22. logger.info("ZhongChuang car event detected, devNo=%s, info=%s" % (devNo, self.event_data))
  23. # 首先更新端口状态
  24. Device.update_dev_control_cache(devNo, self.event_data)
  25. # 4-14 zjl 协议沟通 当上传空闲状态(0 or 1)或者是充满状态(4) 均退款
  26. for port in ("1", "2"):
  27. # 需要退款的
  28. if self.event_data.has_key(port) and self.event_data[port]['orgStatus'] in [0, 1, 4]:
  29. with memcache_lock(key = '%s-%s-finished' % (devNo, port), value = '1', expire = 120) as acquired:
  30. if acquired:
  31. devCache = Device.get_dev_control_cache(self.device["devNo"])
  32. portCache = devCache.get(port)
  33. self.do_finish(port, portCache)
  34. try:
  35. self.deviceAdapter.reply_left_balance(port)
  36. except Exception, e:
  37. logger.info('remove left balance zero failed = %s' % e)
  38. # 正在充电
  39. elif self.event_data.has_key(port) and self.event_data[port]['orgStatus'] in [3]:
  40. logger.info("device charging...")
  41. # 故障的
  42. elif self.event_data.has_key(port) and self.event_data[port]['orgStatus'] in [5, 7, 8]:
  43. # TODO zjl 故障记录
  44. logger.info("device fault, reason is {}".format(self.event_data.get("desc", "未知错误!")))
  45. # 枪把连接的
  46. elif self.event_data.has_key(port) and self.event_data[port]['orgStatus'] in [2]:
  47. logger.info("device connected!")
  48. # 未知命令
  49. else:
  50. logger.error("unknown port <{}> or unKnown orgStatus <{}>, so event doesn't work!".format(
  51. port, self.event_data.get(port, dict()).get('orgStatus', "null")))
  52. def do_finish(self, port, portInfo):
  53. """
  54. 网络支付 结束事件处理, 现金返还原路 金币退还金币 现金退还现金
  55. :return:
  56. """
  57. devNo = self.device["devNo"]
  58. devCache = Device.get_dev_control_cache(devNo)
  59. portCache = devCache.get(str(port), {})
  60. if "coins" not in portCache:
  61. logger.info("no coins info!")
  62. return
  63. openId = portCache.get("openId")
  64. price = portCache['price'] if portCache.has_key('price') else portInfo["coins"]
  65. coins = portInfo["coins"]
  66. balance = portInfo['balance']
  67. rechargeRcdId = portCache.get("rechargeRcdId")
  68. vCardId = portCache.get("vCardId")
  69. if not openId:
  70. logger.info("ZhongChuang net pay finish with no openId! {}".format(devNo))
  71. return
  72. nowTime = datetime.datetime.now()
  73. consumeDict = {
  74. "elec": portInfo["elec"],
  75. "duration": portInfo["duration"],
  76. "coin": str(VirtualCoin(coins)),
  77. "balance": str(balance),
  78. "reason": portInfo["desc"],
  79. "finishedTime": datetime.datetime.strftime(nowTime, "%Y-%m-%d %H:%M:%S")
  80. }
  81. user = MyUser.objects.filter(openId = openId, groupId = self.device["groupId"]).first()
  82. group = Group.get_group(self.device["groupId"])
  83. logger.info("zhongchuang net pay finish and start to notify user! {}".format(devNo))
  84. self.notify_user(
  85. managerialOpenId = user.managerialOpenId if user else "",
  86. templateName = "service_complete",
  87. title = u"\\n\\n结束原因:\\t\\t{reason}\\n\\n设备编号:\\t\\t{logicalCode}\\n\\n服务地址:\\t\\t{group}\\n\\n使用时长:\\t\\t{duration}分钟\\n\\n付款金额:\\t\\t{coin}".format(
  88. reason = portInfo["desc"],
  89. logicalCode = self.device["logicalCode"],
  90. group = group.get("address", ""),
  91. duration = portInfo["duration"],
  92. coin = u"%s金币" % coins
  93. ),
  94. service = u"汽车桩充电服务",
  95. finishTime = datetime.datetime.strftime(nowTime, "%Y-%m-%d %H:%M:%S"),
  96. remark = u'谢谢您的支持'
  97. )
  98. consumeDict.update({DEALER_CONSUMPTION_AGG_KIND.COIN: VirtualCoin(coins).mongo_amount})
  99. if VirtualCoin(balance) > VirtualCoin(0):
  100. refundMoney = VirtualCoin(balance)
  101. consumeDict.update({
  102. DEALER_CONSUMPTION_AGG_KIND.REFUNDED_COINS: refundMoney.mongo_amount,
  103. DEALER_CONSUMPTION_AGG_KIND.COIN: (VirtualCoin(coins) - refundMoney).mongo_amount
  104. })
  105. refund_money(self.device, refundMoney, openId)
  106. self.notify_user(user.managerialOpenId if user else '', 'refund_coins', **{
  107. 'title': u"金币退款",
  108. 'backCount': u'金币:%s' % refundMoney,
  109. 'finishTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  110. })
  111. ServiceProgress.update_progress_and_consume_rcd(
  112. self.device["ownerId"],
  113. {
  114. "open_id": openId,
  115. "device_imei": devNo,
  116. "port": int(port),
  117. "isFinished": False
  118. },
  119. consumeDict
  120. )
  121. Device.clear_port_control_cache(devNo, str(port))