123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import logging
- from mongoengine import DoesNotExist
- from apilib.monetary import RMB, VirtualCoin
- from apilib.utils_datetime import to_datetime
- from apps.web.constant import Const, DEALER_CONSUMPTION_AGG_KIND
- from apps.web.device.models import Device
- from apps.web.eventer.base import WorkEvent
- from apps.web.eventer import EventBuilder
- from apps.web.south_intf.platform import notify_event_to_north
- from apps.web.user.models import ServiceProgress, UserVirtualCard, VCardConsumeRecord, Card, MyUser
- logger = logging.getLogger(__name__)
- class builder(EventBuilder):
- def __getEvent__(self, device_event):
- event_data = self.deviceAdapter.analyze_event_data(device_event['data'])
- if not event_data or 'cmdCode' not in event_data:
- return None
- if 'duration' in device_event:
- event_data.update({'duration': device_event['duration']})
- if event_data['cmdCode'] in ['86']:
- return ChargingHaiNiaoDoubleWorkEvent(self.deviceAdapter, event_data)
- class ChargingHaiNiaoDoubleWorkEvent(WorkEvent):
- def support_playback(self):
- return self.event_data['cmdCode'] == '86'
- def do(self, **args):
- devNo = self.device['devNo']
- logger.info('hainiaoDouble charging event detected, devNo=%s, curInfo=%s' % (devNo, self.event_data))
- if self.event_data['cmdCode'] == '86':
- port = self.event_data['port']
- reason = self.event_data['reason']
- if reason == '':
- return
- try:
- lineInfo = Device.clear_port_control_cache(self.device['devNo'], str(port))
- recvTime = to_datetime(self.recvTime)
- # 为-1的时候就是没有
- deviceDuration = self.event_data.get('duration', -1)
- if lineInfo is not None and 'startTime' in lineInfo:
- startTime = to_datetime(lineInfo['startTime'])
- if startTime > recvTime:
- serverDuration = 0
- else:
- serverDuration = int(round(((recvTime - startTime).total_seconds() / 60.0)))
- # 为-1的时候就是没有
- else:
- serverDuration = -1
- if deviceDuration > 0:
- usedTime = deviceDuration
- else:
- usedTime = serverDuration
- leftPrice = RMB(self.event_data['leftPrice'])
- leftTime = self.event_data['leftTime']
- leftTimeStr = str(leftTime)
- actualNeedTime = usedTime + leftTime
- group = self.device.group
- consumeDict = {'reason': reason, 'leftTime': leftTimeStr,
- 'chargeIndex': port, 'duration': usedTime}
- # 如果是刷卡的,直接更新消费记录,然后发送通知消息,不支持退费
- if lineInfo.has_key('cardNo'):
- card = Card.objects(cardNo = lineInfo['cardNo'], agentId = self.dealer.agentId).first()
- consumeDict.update({'balance': lineInfo['balance']})
- ServiceProgress.update_progress_and_consume_rcd(self.device['ownerId'],
- {'open_id': lineInfo['openId'], 'port': int(port),
- 'device_imei': self.device['devNo'],
- 'isFinished': False}, consumeDict)
- elif lineInfo.has_key('consumeRcdId'):
- backCoins = leftPrice
- vCardId = ''
- try:
- vCardId = lineInfo['vCardId']
- vCard = UserVirtualCard.objects.get(id = vCardId)
- except DoesNotExist, e:
- logger.info('can not find the vCard id = %s' % vCardId)
- return
- ServiceProgress.update_progress_and_consume_rcd(self.device['ownerId'],
- {'open_id': lineInfo['openId'], 'port': int(port),
- 'device_imei': self.device['devNo'],
- '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)
- return
- vCard.refund_quota(vCardConsumeRcd, usedTime, 0.0, backCoins.mongo_amount)
- else:
- user = MyUser.objects(openId = lineInfo.get('openId', ''), groupId = self.device['groupId']).first()
- if not user:
- logger.warning('no user, devNo=%s' % devNo)
- return
- # 通知服务结束
- self.notify_user(user.managerialOpenId if user else '', 'service_complete',
- **{
- 'title': u'%s' % reason,
- 'service': u'充电服务(设备编号:%s, 端口:%s,地址:%s)' % (
- self.device['logicalCode'], port, group['address']),
- 'finishTime': recvTime.strftime('%Y-%m-%d %H:%M:%S'),
- 'remark': u'谢谢您的支持'
- })
- # 如果需要退款,计算退款数据.
- if not self.device.is_auto_refund:
- ServiceProgress.update_progress_and_consume_rcd(self.device['ownerId'],
- {'open_id': lineInfo['openId'],
- 'port': int(port),
- 'device_imei': self.device['devNo'],
- 'isFinished': False}, consumeDict)
- return
- needPrice = RMB(lineInfo['needPrice'])
- minConsumptionLimit = self.device.my_obj.otherConf.get('minConsumptionLimit', 0)
- tempMoneyNum = float(needPrice) - float(minConsumptionLimit)
- if tempMoneyNum < 0:
- tempMoneyNum = 0
- backCoins = leftPrice
- if backCoins > needPrice:
- backCoins = needPrice
- if float(backCoins) >= tempMoneyNum:
- backCoins = RMB(tempMoneyNum)
- # 直接退现金
- if RMB(0) < backCoins <= needPrice:
- self.refund_net_pay(user, lineInfo, backCoins, VirtualCoin(0), consumeDict, True)
- refund = RMB(consumeDict.get(DEALER_CONSUMPTION_AGG_KIND.REFUNDED_CASH, '0.00'))
- if refund > RMB(0):
- self.notify_user(user.managerialOpenId if user else '', 'refund_coins', **{
- 'title': reason,
- 'backCount': u'%s元' % refund,
- 'finishTime': recvTime.strftime('%Y-%m-%d %H:%M:%S')
- })
- ServiceProgress.update_progress_and_consume_rcd(self.device['ownerId'],
- {'open_id': lineInfo['openId'], 'port': int(port),
- 'device_imei': self.device['devNo'],
- 'isFinished': False}, consumeDict)
- finally:
- notify_event_to_north(self.dealer, self.device, level = Const.EVENT_NORMAL, desc = reason)
|