# -*- coding: utf-8 -*- # !/usr/bin/env python import datetime import logging from decimal import Decimal from mongoengine import DoesNotExist from apilib.monetary import RMB from apps.web.device.models import Device, Group from apps.web.eventer.base import WorkEvent from apps.web.eventer import EventBuilder from apps.web.user.models import ServiceProgress, UserVirtualCard, VCardConsumeRecord, MyUser 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: return None if 'duration' in device_event: event_data.update({'duration': device_event['duration']}) if event_data['mode'] in ['05', '06', '90', '91', '92', '93', '94']: return JinzeWorkEvent(self.deviceAdapter, event_data) class JinzeWorkEvent(WorkEvent): def do(self, **args): devNo = self.device['devNo'] logger.info('jinze charging event detected, devNo=%s,curInfo=%s' % (devNo, self.event_data)) try: lineInfo = Device.update_port_control_cache(devNo, self.event_data) group = Group.get_group(self.device['groupId']) if (not lineInfo.has_key('coins')) or (not lineInfo.has_key('needTime')): return if 'duration' in self.event_data and self.event_data['duration'] > 0: usedTime = round(self.event_data['duration'] / 60.0, 2) else: return vCardId = lineInfo.get('vCardId', None) money = RMB(lineInfo['coins']) price = lineInfo.get('price', 0.0) needTime = lineInfo['needTime'] leftTime = needTime - usedTime if needTime > usedTime else 0 backCoins, backPrice = 0.0, 0.0 backCoins = RMB(money.amount * Decimal(leftTime) / Decimal(needTime)) if backCoins > money: backCoins = money if vCardId is None: # 扫码的方式 openId = lineInfo['openId'] is_auto_refund = self.device.is_auto_refund try: consumeDict = {'chargeIndex': lineInfo['port'], 'reason': lineInfo['statusDesc'], 'elec': lineInfo['inputElec'], 'needTime': u'扫码订购%s分钟' % needTime, 'duration': usedTime} if not is_auto_refund: ServiceProgress.update_progress_and_consume_rcd( self.device['ownerId'], {'open_id': openId, 'device_imei': self.device['devNo'], 'port': lineInfo['port'], 'isFinished': False}, consumeDict ) service_notify = u'自助充电\r\n套餐时间:{reverseTime}\r\n' \ u'设备编号:{logicalCode}\r\n充电端口:{port}\r\n设备地址:{address}\r\n' \ u'充电状态:{status}'.format( reverseTime = needTime, logicalCode = self.device['logicalCode'], port = self.event_data['port'], address = group['address'], status = self.event_data['statusDesc'] ) else: # 扫码退钱, 退到个人账号 refund_money(self.device, backCoins, lineInfo['openId']) consumeDict.update({'refundedMoney': str(backCoins)}) ServiceProgress.update_progress_and_consume_rcd( self.device['ownerId'], { 'open_id': openId, 'device_imei': self.device['devNo'], 'port': lineInfo['port'], 'isFinished': False }, consumeDict) service_notify = u'自助充电\r\n' \ u'设备编号:{logicalCode}\r\n' \ u'充电端口:{port}\r\n' \ u'预付金额:{money}币\r\n' \ u'退款金额:{back}币\r\n' \ u'订购时间:{reverseTime}\r\n' \ u'剩余时间:{leftTime}\r\n' \ u'设备地址:{address}\r\n' \ u'充电状态:{status}'.format( logicalCode = self.device['logicalCode'], port = self.event_data['port'], money = money, back = backCoins, reverseTime = needTime, leftTime = leftTime, address = group['address'], status = self.event_data['statusDesc']) finally: user = MyUser.objects(openId = openId, groupId = self.device['groupId']).first() title = u'充电结束,感谢您的使用!' if is_auto_refund and backCoins > 0: title = u'充电结束,感谢您的使用!退款金额已经返还到您的账号,请注意查收。' self.notify_user( user.managerialOpenId, 'service_complete', **{ 'title': title, 'service': service_notify, 'finishTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), 'remark': u'谢谢您的支持' }) elif vCardId is not None: # 使用的是虚拟卡 try: # 通知充电完成 try: vCard = UserVirtualCard.objects.get(id = vCardId) except DoesNotExist, e: logger.info('can not find the vCard id = %s' % vCardId) return self.notify_user( self.get_managerialOpenId_by_openId(lineInfo['openId']), 'service_complete', **{ 'title': u'充电结束,感谢您的使用!' if leftTime <= 0 else u'充电结束,感谢您的使用!退款金额会返还到您的虚拟卡,请注意查收。', 'service': u'自助充电\r\n' u'设备编号:{logicalCode}\r\n' u'充电端口:{port}\r\n' u'订购时间:{reverseTime}\r\n' u'剩余时间:{leftTime}\r\n' u'设备地址:{address}\r\n' u'充电状态:{status}'.format( logicalCode = self.device['logicalCode'], port = self.event_data['port'], reverseTime = needTime, leftTime = leftTime, address = group['address'], status = self.event_data['statusDesc'] ), 'finishTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), 'remark': u'谢谢您的支持' }) consumeDict = { 'chargeIndex': lineInfo['port'], 'reason': lineInfo['reason'], 'elec': lineInfo['inputElec'], 'needTime': needTime, 'duration': usedTime } ServiceProgress.update_progress_and_consume_rcd( self.device['ownerId'], { 'open_id': lineInfo['openId'], 'device_imei': self.device['devNo'], 'port': lineInfo['port'], '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, lineInfo['inputElec'], backCoins.mongo_amount) finally: pass except Exception, e: logger.exception('deal with jingneng devNo=%s event e=%s' % (devNo, e)) finally: Device.clear_port_control_cache(devNo, str(self.event_data['port']))