123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import datetime
- import logging
- from mongoengine import DoesNotExist
- from apilib.monetary import RMB
- from apps.web.constant import Const
- from apps.web.device.models import Group, Device
- from apps.web.eventer.base import WorkEvent, FaultEvent
- from apps.web.eventer import EventBuilder
- from apps.web.south_intf.platform import notify_event_to_north
- from apps.web.user.models import ServiceProgress, MyUser, CardConsumeRecord, CardRechargeOrder, UserVirtualCard, \
- VCardConsumeRecord
- from apps.web.user.transaction_deprecated import refund_money
- logger = logging.getLogger(__name__)
- class builder(EventBuilder):
- def __getEvent__(self, device_event):
- event_data = self.deviceAdapter.analyze_event_data(device_event['data'])
- if event_data is None or 'cmdCode' not in event_data:
- return None
- if event_data['cmdCode'] in ['A8', 'B6', 'C8', 'C9']:
- return ChargingXUEYINGWorkEvent(self.deviceAdapter, event_data)
- if event_data['cmdCode'] == 'C4':
- if event_data['status'] == Const.DEV_WORK_STATUS_FAULT:
- return FaultEvent(self.deviceAdapter, event_data)
- else:
- return ChargingXUEYINGWorkEvent(self.deviceAdapter, event_data)
- class ChargingXUEYINGWorkEvent(WorkEvent):
- def do(self, **args):
- devNo = self.device['devNo']
- logger.info('xueying charging event detected, devNo=%s' % (devNo,))
- if self.event_data['cmdCode'] == 'B6': # 使用IC卡充电结束
- card = self.update_card_dealer_and_type(self.event_data['cardNo'], 'IC')
- sid = str(self.event_data['finishedTime']) + str(self.event_data['orderNo'])
- # 如果记录过,就表示处理过,不重复处理
- count = CardConsumeRecord.objects.filter(cardId = str(card.id), sid = sid).count()
- if count > 0:
- return
- self.update_card_balance(card, RMB(self.event_data['balance'] / 100.0))
- # 如果没有响应过,就需要记录下卡的消费数据
- self.record_consume_for_card(card, RMB(self.event_data['coins'] / 100.0), desc = '',
- servicedInfo = {'duration': self.event_data['duration'] / 60.0})
- elif self.event_data['cmdCode'] == 'A8': # 刷卡,或者网络卡的余额
- card = self.update_card_dealer_and_type(self.event_data['cardNo'], 'ID')
- card_recharge_order = CardRechargeOrder.get_last_to_do_one(str(card.id))
- result = self.recharge_id_card(card = card,
- rechargeType = 'append',
- order = card_recharge_order)
- card.reload()
- logger.info(
- 'cardNo=%s,openId=%s,result=%s,curinfo=%s' % (card.cardNo, card.openId, result, self.event_data))
- # 扣费
- if not card.openId:
- res = '02'
- balance = 0
- elif card.frozen:
- res = '04'
- balance = 0
- elif float(result['balance']) < self.event_data['coins'] / 100.0:
- res = '05'
- balance = 0
- else:
- res = '01'
- balance = int(result['balance'] * 100) - self.event_data['coins']
- self.deviceAdapter.reply_card_balance(res, self.event_data['orderNo'], balance)
- elif self.event_data['cmdCode'] == 'C8': # ID卡,充电结束,需要刷新数据
- card = self.update_card_dealer_and_type(self.event_data['cardNo'], 'ID')
- sid = str(self.event_data['finishedTime']) + str(self.event_data['orderNo'])
- # 如果记录过,就表示处理过,不重复处理
- count = CardConsumeRecord.objects.filter(cardId = str(card.id), sid = sid).count()
- if count > 0:
- return
- self.consume_money_for_card(card, RMB(self.event_data['coins'] / 100.0))
- # 如果没有响应过,就需要记录下卡的消费数据
- self.record_consume_for_card(card, RMB(self.event_data['coins'] / 100.0), desc = '',
- servicedInfo = {'duration': self.event_data['duration']})
- elif self.event_data['cmdCode'] == 'C9': # 扫码,充电结束,需要刷新数据
- try:
- port = str(self.event_data['port'])
- ctrInfo = Device.get_dev_control_cache(self.device['devNo'])
- lineInfo = ctrInfo.get(port, None)
- if lineInfo is None or (not lineInfo.has_key('openId')) or (lineInfo.has_key('dealing')):
- return
- ctrInfo[port]['dealing'] = True
- Device.update_dev_control_cache(devNo, ctrInfo)
- usedTime = self.event_data['duration']
- group = Group.get_group(self.device['groupId'])
- consumeDict = {'reason': u'充电结束', 'chargeIndex': port, 'duration': usedTime}
- group = Group.get_group(self.device['groupId'])
- user = MyUser.objects(openId = lineInfo['openId'], groupId = self.device['groupId']).first()
- # 如果不需要退款,更新完毕,直接结束.
- 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)
- self.notify_user(user.managerialOpenId if user else '', 'service_complete',
- **{
- 'title': u'充电结束。一共使用时间:%s分钟' % (usedTime),
- 'service': u'充电服务(设备编号:%s, 端口:%s,地址:%s)' % (
- self.device['logicalCode'], port, group['address']),
- 'finishTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
- 'remark': u'谢谢您的支持'
- })
- return
- backCoins = lineInfo['coins'] - self.event_data['coins'] / 100.0
- if backCoins < 0:
- backCoins = 0
- # 通知服务结束
- consumeDict.update({'refundedMoney': str(backCoins)})
- if lineInfo.has_key('consumeRcdId'): # 如果用的是虚拟卡,直接把配额返回到虚拟卡
- try:
- vCardId = lineInfo['vCardId']
- vCard = UserVirtualCard.objects.get(id = vCardId)
- except DoesNotExist, e:
- logger.info('can not find the vCard id = %s' % vCardId)
- return
- 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)
- else:
- refund_money(self.device, backCoins, lineInfo['openId'])
- ServiceProgress.update_progress_and_consume_rcd(self.device['ownerId'],
- {'open_id': lineInfo['openId'], 'port': int(port),
- 'device_imei': self.device['devNo'],
- 'isFinished': False}, consumeDict)
- if lineInfo.has_key('consumeRcdId'):
- self.notify_user(user.managerialOpenId if user else '', 'refund_coins', **{
- 'title': u'充电结束。您使用的是虚拟卡。预付%s元,订购充电时间%s分钟,使用了%s分钟,花费了%s元。给您退还成相应的虚拟卡额度,您下次可以接着使用哦' % (
- lineInfo['coins'], lineInfo['needTime'], usedTime, self.event_data['coins'] / 100.0),
- 'backCount': u'金币:%s' % backCoins,
- 'finishTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
- })
- else:
- self.notify_user(user.managerialOpenId if user else '', 'refund_coins', **{
- 'title': u'充电结束。您预付%s元,订购充电时间%s分钟,使用了%s分钟,花费了%s元。给您退还成相应的金币:%s元,您下次可以接着使用哦' % (
- lineInfo['coins'], lineInfo['needTime'], usedTime, self.event_data['coins'] / 100.0,
- backCoins),
- 'backCount': u'金币:%s' % backCoins,
- 'finishTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
- })
- finally:
- Device.clear_port_control_cache(devNo, str(port))
- notify_event_to_north(self.dealer, self.device, level = Const.EVENT_NORMAL, desc = u'充电结束')
- elif self.event_data['cmdCode'] == 'C4': # 直接更新端口以及设备状态
- port = str(self.event_data['port'])
- if port == 0:
- return
- ctrInfo = Device.get_dev_control_cache(self.device['devNo'])
- ctrInfo[port].update({'status': self.event_data['status']})
- Device.update_dev_control_cache(devNo, ctrInfo)
|