dianchuan_CarCharging.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. import datetime
  4. import logging
  5. from apilib.monetary import RMB, 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.helpers import device_lock_key
  12. from apps.web.user.models import ServiceProgress, MyUser, ConsumeRecord
  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 or 'cmdCode' not in event_data:
  18. return None
  19. if event_data['cmdCode'] in ['30', '36', '34', '79']:
  20. return DianchuanCarChargingWorkEvent(self.deviceAdapter, event_data)
  21. return None
  22. class DianchuanCarChargingWorkEvent(WorkEvent):
  23. def do(self, **args):
  24. devNo = self.device['devNo']
  25. logger.info('dian chuan car charging event detected, devNo=%s,curInfo=%s' % (devNo, self.event_data))
  26. if self.event_data['cmdCode'] == '79':
  27. self.do_login()
  28. if self.event_data['cmdCode'] == '30':
  29. self.do_check_prot()
  30. elif self.event_data['cmdCode'] == '36':
  31. self.do_finish()
  32. def do_login(self):
  33. """
  34. 处理登录请求
  35. """
  36. self.device.deviceAdapter._qr_code_devNo_issue()
  37. def do_finish(self):
  38. sequanceNo = self.event_data['seqNo']
  39. self.device.deviceAdapter._response_finished(sequanceNo)
  40. with memcache_lock(key=device_lock_key(sequanceNo), value=sequanceNo, expire=360) as acquired:
  41. if not acquired:
  42. return
  43. portStr = str(self.event_data["port"])
  44. order = ConsumeRecord.objects.filter(devNo=self.device.devNo, sequanceNo=sequanceNo).first() # type: ConsumeRecord
  45. if not order:
  46. logger.warning('order<no={}> is not exists.'.format(sequanceNo))
  47. self.device.deviceAdapter._response_finished(sequanceNo)
  48. consumeDict = {
  49. 'chargeIndex': self.event_data['port'],
  50. 'total_spend_elec': self.event_data['total_spend_elec'],
  51. 'total_spend_money': self.event_data['total_spend_money'],
  52. 'duration': self.event_data['eDuration'],
  53. }
  54. user = MyUser.objects.get(
  55. openId=order.openId, groupId=order.groupId)
  56. ctrInfo = Device.get_dev_control_cache(self.device.devNo)
  57. lineInfo = ctrInfo.get(portStr, {})
  58. payCoins = VirtualCoin(lineInfo["coins"])
  59. spendCoins = VirtualCoin(self.event_data["total_spend_money"])
  60. refundCoins = payCoins - spendCoins
  61. refundedMoney = RMB(0)
  62. group = Group.get_group(self.device['groupId'])
  63. serviceChargeOn = self.device.bill_as_service_feature.on
  64. if serviceChargeOn:
  65. serviceCharge = self.device.bill_as_service_feature.service_charge
  66. totalElec = float(self.event_data['total_spend_elec'])
  67. totalServiceFee = VirtualCoin(totalElec * float(serviceCharge))
  68. refundCoins = payCoins - spendCoins - totalServiceFee
  69. logger.info(
  70. "[Dian Chuan Car Charge device <{}> refund money is <{}>]".format(self.device.devNo, refundedMoney))
  71. try:
  72. is_cash = False
  73. consumeDict.update({DEALER_CONSUMPTION_AGG_KIND.COIN: VirtualCoin(payCoins).mongo_amount})
  74. if refundedMoney > RMB(0) or refundCoins > VirtualCoin(0):
  75. consumeDict.update(
  76. {DEALER_CONSUMPTION_AGG_KIND.COIN: (VirtualCoin(payCoins) - refundCoins).mongo_amount})
  77. self.refund_net_pay(user, lineInfo, refundedMoney, refundCoins, consumeDict, is_cash)
  78. ServiceProgress.update_progress_and_consume_rcd(
  79. self.device.ownerId,
  80. {
  81. 'open_id': lineInfo['openId'],
  82. 'port': int(portStr),
  83. 'device_imei': self.device.devNo,
  84. 'isFinished': False
  85. },
  86. consumeDict)
  87. finally:
  88. extra = []
  89. if serviceChargeOn:
  90. extra.append({u'电费金额': '{}(元)'.format(spendCoins)})
  91. extra.append({u'服务费金额': '{}(元)'.format(totalServiceFee)})
  92. extra.append({u'消费电量': '{}(度)'.format(totalElec)})
  93. if DEALER_CONSUMPTION_AGG_KIND.REFUNDED_CASH in consumeDict:
  94. real_refund = RMB(consumeDict[DEALER_CONSUMPTION_AGG_KIND.REFUNDED_CASH])
  95. if real_refund > RMB(0):
  96. extra.append({u'消费金额': '{}(元)'.format(RMB(0) - real_refund)})
  97. extra.append({u'退款金额': '{}(元)'.format(real_refund)})
  98. else:
  99. extra.append({u'消费金额': '{}(元)'.format(0)})
  100. elif DEALER_CONSUMPTION_AGG_KIND.REFUNDED_COINS in consumeDict:
  101. real_refund = VirtualCoin(consumeDict[DEALER_CONSUMPTION_AGG_KIND.REFUNDED_COINS])
  102. if real_refund > VirtualCoin(0):
  103. extra.append({u'消费金额': '{}(金币)'.format(VirtualCoin(payCoins) - real_refund)})
  104. extra.append({u'退款金额': '{}(金币)'.format(real_refund)})
  105. else:
  106. extra.append({u'消费金额': '{}(金币)'.format(VirtualCoin(payCoins))})
  107. else:
  108. extra.append({u'消费金额': '{}(金币)'.format(VirtualCoin(payCoins))})
  109. self.notify_user_service_complete(
  110. service_name='充电',
  111. openid=order.user.managerialOpenId,
  112. port=portStr,
  113. address=group['address'],
  114. reason=self.event_data['reason'],
  115. finished_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
  116. extra=extra)
  117. ServiceProgress.update_progress_and_consume_rcd(
  118. self.device['ownerId'],
  119. {
  120. 'open_id': order.openId,
  121. 'device_imei': self.device['devNo'],
  122. 'port': self.event_data['port'],
  123. 'isFinished': False
  124. },
  125. consumeDict
  126. )
  127. Device.clear_port_control_cache(self.device.devNo, portStr)
  128. def do_check_port(self):
  129. data = self.event_data
  130. print (data)