heshuichongdian.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. import logging
  4. from mongoengine import DoesNotExist
  5. from apilib.monetary import RMB, VirtualCoin
  6. from apilib.utils_datetime import to_datetime
  7. from apps.web.constant import DEALER_CONSUMPTION_AGG_KIND
  8. from apps.web.device.models import Device
  9. from apps.web.eventer.base import WorkEvent
  10. from apps.web.eventer import EventBuilder
  11. from apps.web.user.models import UserVirtualCard, ServiceProgress, MyUser
  12. logger = logging.getLogger(__name__)
  13. class builder(EventBuilder):
  14. def __getEvent__(self, device_event):
  15. event_data = self.deviceAdapter.analyze_event_data(device_event['data'])
  16. if event_data['cmdCode'] in ['FB', 'FD', '01', '02']:
  17. return HeshuiChongdianEvent(self.deviceAdapter, event_data)
  18. return None
  19. class HeshuiChongdianEvent(WorkEvent):
  20. def support_playback(self):
  21. return True
  22. def do(self, **args):
  23. devNo = self.device['devNo']
  24. logger.info('heshuichongdian event detected, devNo=%s' % (devNo,))
  25. try:
  26. port = self.event_data['port']
  27. cmdCode = self.event_data['cmdCode']
  28. if cmdCode == 'FD':
  29. leftTime = self.event_data['leftTime']
  30. else:
  31. leftTime = 0
  32. lineInfo = Device.clear_port_control_cache(self.device['devNo'], str(port))
  33. recvTime = to_datetime(self.recvTime)
  34. if not lineInfo or ('startTime' not in lineInfo):
  35. return
  36. if cmdCode in ['FB', 'FD']:
  37. usedTime = int(lineInfo['needTime'] / 60.0 - leftTime)
  38. else:
  39. usedTime = self.event_data['usedTime'] # 单位秒
  40. group = self.device.group
  41. if cmdCode == 'FB':
  42. reason = u'使用结束。'
  43. elif cmdCode == 'FD':
  44. reason = u'使用(结束/异常)。'
  45. else:
  46. reason = u'使用结束'
  47. consumeDict = {'reason': reason}
  48. if lineInfo.has_key('consumeRcdId'):
  49. # 退额度
  50. try:
  51. vCardId = lineInfo['vCardId']
  52. vCard = UserVirtualCard.objects.get(id = vCardId)
  53. except DoesNotExist, e:
  54. logger.info('can not find the vCard id = %s' % vCardId)
  55. return
  56. # 通知服务结束
  57. self.notify_user(self.get_managerialOpenId_by_openId(lineInfo['openId']) if vCard else '',
  58. 'service_complete',
  59. **{
  60. 'title': reason,
  61. 'service': u'设备编号:%s,地址:%s' % (self.device['logicalCode'], group['address']),
  62. 'finishTime': recvTime.strftime('%Y-%m-%d %H:%M:%S'),
  63. 'remark': u'谢谢您的支持'
  64. })
  65. ServiceProgress.update_progress_and_consume_rcd(self.device['ownerId'],
  66. {'open_id': lineInfo['openId'], 'port': port,
  67. 'device_imei': self.device['devNo'],
  68. 'isFinished': False}, consumeDict)
  69. else: # 非虚拟卡的方式
  70. user = MyUser.objects(openId = lineInfo['openId'], groupId = self.device['groupId']).first()
  71. # 通知服务结束
  72. self.notify_user(user.managerialOpenId if user else '', 'service_complete',
  73. **{
  74. 'title': reason,
  75. 'service': u'设备编号:%s,地址:%s' % (self.device['logicalCode'], group['address']),
  76. 'finishTime': recvTime.strftime('%Y-%m-%d %H:%M:%S'),
  77. 'remark': u'谢谢您的支持'
  78. })
  79. ServiceProgress.update_progress_and_consume_rcd(self.device['ownerId'],
  80. {'open_id': lineInfo['openId'], 'port': port,
  81. 'device_imei': self.device['devNo'],
  82. 'isFinished': False}, consumeDict)
  83. if cmdCode == 'FB': # 充电正常结束的不予退费
  84. return
  85. if not self.device.is_auto_refund: # 开关关闭,不予退费
  86. return
  87. coins = lineInfo['coins']
  88. if cmdCode == 'FD':
  89. needTime = lineInfo['needTime'] / 60.0
  90. if leftTime == -1:
  91. refundMoney = round((needTime - usedTime) / float(needTime) * float(coins), 2)
  92. else:
  93. refundMoney = round(float(leftTime) / float(needTime) * float(coins), 2)
  94. else:
  95. needTime = lineInfo['needTime']
  96. refundMoney = round((needTime - usedTime) / float(needTime) * float(coins), 2)
  97. if refundMoney > coins:
  98. refundMoney = coins
  99. consumeDict = {}
  100. self.refund_net_pay(user, lineInfo, RMB(refundMoney), VirtualCoin(0), consumeDict, True)
  101. refund = RMB(consumeDict.get(DEALER_CONSUMPTION_AGG_KIND.REFUNDED_CASH, '0.00'))
  102. if refund > RMB(0):
  103. self.notify_user(user.managerialOpenId if user else '', 'refund_coins', **{
  104. 'title': reason,
  105. 'backCount': u'%s元' % refund,
  106. 'finishTime': recvTime.strftime('%Y-%m-%d %H:%M:%S')
  107. })
  108. finally:
  109. pass