jinze.py 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. import datetime
  4. import logging
  5. from decimal import Decimal
  6. from mongoengine import DoesNotExist
  7. from apilib.monetary import RMB
  8. from apps.web.device.models import Device, Group
  9. from apps.web.eventer.base import WorkEvent
  10. from apps.web.eventer import EventBuilder
  11. from apps.web.user.models import ServiceProgress, UserVirtualCard, VCardConsumeRecord, 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. event_data = self.deviceAdapter.analyze_event_data(device_event['data'])
  17. if event_data is None:
  18. return None
  19. if 'duration' in device_event:
  20. event_data.update({'duration': device_event['duration']})
  21. if event_data['mode'] in ['05', '06', '90', '91', '92', '93', '94']:
  22. return JinzeWorkEvent(self.deviceAdapter, event_data)
  23. class JinzeWorkEvent(WorkEvent):
  24. def do(self, **args):
  25. devNo = self.device['devNo']
  26. logger.info('jinze charging event detected, devNo=%s,curInfo=%s' % (devNo, self.event_data))
  27. try:
  28. lineInfo = Device.update_port_control_cache(devNo, self.event_data)
  29. group = Group.get_group(self.device['groupId'])
  30. if (not lineInfo.has_key('coins')) or (not lineInfo.has_key('needTime')):
  31. return
  32. if 'duration' in self.event_data and self.event_data['duration'] > 0:
  33. usedTime = round(self.event_data['duration'] / 60.0, 2)
  34. else:
  35. return
  36. vCardId = lineInfo.get('vCardId', None)
  37. money = RMB(lineInfo['coins'])
  38. price = lineInfo.get('price', 0.0)
  39. needTime = lineInfo['needTime']
  40. leftTime = needTime - usedTime if needTime > usedTime else 0
  41. backCoins, backPrice = 0.0, 0.0
  42. backCoins = RMB(money.amount * Decimal(leftTime) / Decimal(needTime))
  43. if backCoins > money:
  44. backCoins = money
  45. if vCardId is None: # 扫码的方式
  46. openId = lineInfo['openId']
  47. is_auto_refund = self.device.is_auto_refund
  48. try:
  49. consumeDict = {'chargeIndex': lineInfo['port'], 'reason': lineInfo['statusDesc'],
  50. 'elec': lineInfo['inputElec'], 'needTime': u'扫码订购%s分钟' % needTime,
  51. 'duration': usedTime}
  52. if not is_auto_refund:
  53. ServiceProgress.update_progress_and_consume_rcd(
  54. self.device['ownerId'],
  55. {'open_id': openId, 'device_imei': self.device['devNo'],
  56. 'port': lineInfo['port'], 'isFinished': False}, consumeDict
  57. )
  58. service_notify = u'自助充电\r\n套餐时间:{reverseTime}\r\n' \
  59. u'设备编号:{logicalCode}\r\n充电端口:{port}\r\n设备地址:{address}\r\n' \
  60. u'充电状态:{status}'.format(
  61. reverseTime = needTime,
  62. logicalCode = self.device['logicalCode'], port = self.event_data['port'],
  63. address = group['address'],
  64. status = self.event_data['statusDesc']
  65. )
  66. else:
  67. # 扫码退钱, 退到个人账号
  68. refund_money(self.device, backCoins, lineInfo['openId'])
  69. consumeDict.update({'refundedMoney': str(backCoins)})
  70. ServiceProgress.update_progress_and_consume_rcd(
  71. self.device['ownerId'],
  72. {
  73. 'open_id': openId, 'device_imei': self.device['devNo'],
  74. 'port': lineInfo['port'], 'isFinished': False
  75. }, consumeDict)
  76. service_notify = u'自助充电\r\n' \
  77. u'设备编号:{logicalCode}\r\n' \
  78. u'充电端口:{port}\r\n' \
  79. u'预付金额:{money}币\r\n' \
  80. u'退款金额:{back}币\r\n' \
  81. u'订购时间:{reverseTime}\r\n' \
  82. u'剩余时间:{leftTime}\r\n' \
  83. u'设备地址:{address}\r\n' \
  84. u'充电状态:{status}'.format(
  85. logicalCode = self.device['logicalCode'], port = self.event_data['port'],
  86. money = money, back = backCoins,
  87. reverseTime = needTime, leftTime = leftTime,
  88. address = group['address'],
  89. status = self.event_data['statusDesc'])
  90. finally:
  91. user = MyUser.objects(openId = openId, groupId = self.device['groupId']).first()
  92. title = u'充电结束,感谢您的使用!'
  93. if is_auto_refund and backCoins > 0:
  94. title = u'充电结束,感谢您的使用!退款金额已经返还到您的账号,请注意查收。'
  95. self.notify_user(
  96. user.managerialOpenId,
  97. 'service_complete',
  98. **{
  99. 'title': title,
  100. 'service': service_notify,
  101. 'finishTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
  102. 'remark': u'谢谢您的支持'
  103. })
  104. elif vCardId is not None: # 使用的是虚拟卡
  105. try:
  106. # 通知充电完成
  107. try:
  108. vCard = UserVirtualCard.objects.get(id = vCardId)
  109. except DoesNotExist, e:
  110. logger.info('can not find the vCard id = %s' % vCardId)
  111. return
  112. self.notify_user(
  113. self.get_managerialOpenId_by_openId(lineInfo['openId']),
  114. 'service_complete',
  115. **{
  116. 'title': u'充电结束,感谢您的使用!' if leftTime <= 0 else u'充电结束,感谢您的使用!退款金额会返还到您的虚拟卡,请注意查收。',
  117. 'service': u'自助充电\r\n'
  118. u'设备编号:{logicalCode}\r\n'
  119. u'充电端口:{port}\r\n'
  120. u'订购时间:{reverseTime}\r\n'
  121. u'剩余时间:{leftTime}\r\n'
  122. u'设备地址:{address}\r\n'
  123. u'充电状态:{status}'.format(
  124. logicalCode = self.device['logicalCode'],
  125. port = self.event_data['port'],
  126. reverseTime = needTime,
  127. leftTime = leftTime,
  128. address = group['address'],
  129. status = self.event_data['statusDesc']
  130. ),
  131. 'finishTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
  132. 'remark': u'谢谢您的支持'
  133. })
  134. consumeDict = {
  135. 'chargeIndex': lineInfo['port'],
  136. 'reason': lineInfo['reason'],
  137. 'elec': lineInfo['inputElec'], 'needTime': needTime,
  138. 'duration': usedTime
  139. }
  140. ServiceProgress.update_progress_and_consume_rcd(
  141. self.device['ownerId'],
  142. {
  143. 'open_id': lineInfo['openId'], 'device_imei': self.device['devNo'],
  144. 'port': lineInfo['port'], 'isFinished': False
  145. }, consumeDict
  146. )
  147. consumeRcdId = lineInfo.get('consumeRcdId', None)
  148. if consumeRcdId is None:
  149. logger.info('can not find consume rcd id')
  150. return
  151. try:
  152. vCardConsumeRcd = VCardConsumeRecord.objects.get(id = consumeRcdId)
  153. except DoesNotExist, e:
  154. logger.info('can not find the consume rcd id = %s' % consumeRcdId)
  155. return
  156. vCard.refund_quota(vCardConsumeRcd, usedTime, lineInfo['inputElec'], backCoins.mongo_amount)
  157. finally:
  158. pass
  159. except Exception, e:
  160. logger.exception('deal with jingneng devNo=%s event e=%s' % (devNo, e))
  161. finally:
  162. Device.clear_port_control_cache(devNo, str(self.event_data['port']))