# -*- coding: utf-8 -*- # !/usr/bin/env python import logging import datetime from apilib.monetary import VirtualCoin from apilib.utils_sys import memcache_lock from apps.web.constant import DEALER_CONSUMPTION_AGG_KIND from apps.web.device.models import Group, Device from apps.web.eventer import EventBuilder from apps.web.eventer.base import WorkEvent from apps.web.user.models import ServiceProgress, MyUser from apps.web.user.transaction_deprecated import refund_money logger = logging.getLogger(__name__) class builder(EventBuilder): def __getEvent__(self, device_event): if device_event['cmd'] == 100: event_data = self.deviceAdapter.analyze_event_data(device_event['data']) return ZhongchuangCarWorkEventer(self.deviceAdapter, event_data) class ZhongchuangCarWorkEventer(WorkEvent): def do(self, **args): devNo = self.device["devNo"] logger.info("ZhongChuang car event detected, devNo=%s, info=%s" % (devNo, self.event_data)) # 首先更新端口状态 Device.update_dev_control_cache(devNo, self.event_data) # 4-14 zjl 协议沟通 当上传空闲状态(0 or 1)或者是充满状态(4) 均退款 for port in ("1", "2"): # 需要退款的 if self.event_data.has_key(port) and self.event_data[port]['orgStatus'] in [0, 1, 4]: with memcache_lock(key = '%s-%s-finished' % (devNo, port), value = '1', expire = 120) as acquired: if acquired: devCache = Device.get_dev_control_cache(self.device["devNo"]) portCache = devCache.get(port) self.do_finish(port, portCache) try: self.deviceAdapter.reply_left_balance(port) except Exception, e: logger.info('remove left balance zero failed = %s' % e) # 正在充电 elif self.event_data.has_key(port) and self.event_data[port]['orgStatus'] in [3]: logger.info("device charging...") # 故障的 elif self.event_data.has_key(port) and self.event_data[port]['orgStatus'] in [5, 7, 8]: # TODO zjl 故障记录 logger.info("device fault, reason is {}".format(self.event_data.get("desc", "未知错误!"))) # 枪把连接的 elif self.event_data.has_key(port) and self.event_data[port]['orgStatus'] in [2]: logger.info("device connected!") # 未知命令 else: logger.error("unknown port <{}> or unKnown orgStatus <{}>, so event doesn't work!".format( port, self.event_data.get(port, dict()).get('orgStatus', "null"))) def do_finish(self, port, portInfo): """ 网络支付 结束事件处理, 现金返还原路 金币退还金币 现金退还现金 :return: """ devNo = self.device["devNo"] devCache = Device.get_dev_control_cache(devNo) portCache = devCache.get(str(port), {}) if "coins" not in portCache: logger.info("no coins info!") return openId = portCache.get("openId") price = portCache['price'] if portCache.has_key('price') else portInfo["coins"] coins = portInfo["coins"] balance = portInfo['balance'] rechargeRcdId = portCache.get("rechargeRcdId") vCardId = portCache.get("vCardId") if not openId: logger.info("ZhongChuang net pay finish with no openId! {}".format(devNo)) return nowTime = datetime.datetime.now() consumeDict = { "elec": portInfo["elec"], "duration": portInfo["duration"], "coin": str(VirtualCoin(coins)), "balance": str(balance), "reason": portInfo["desc"], "finishedTime": datetime.datetime.strftime(nowTime, "%Y-%m-%d %H:%M:%S") } user = MyUser.objects.filter(openId = openId, groupId = self.device["groupId"]).first() group = Group.get_group(self.device["groupId"]) logger.info("zhongchuang net pay finish and start to notify user! {}".format(devNo)) self.notify_user( managerialOpenId = user.managerialOpenId if user else "", templateName = "service_complete", title = u"\\n\\n结束原因:\\t\\t{reason}\\n\\n设备编号:\\t\\t{logicalCode}\\n\\n服务地址:\\t\\t{group}\\n\\n使用时长:\\t\\t{duration}分钟\\n\\n付款金额:\\t\\t{coin}".format( reason = portInfo["desc"], logicalCode = self.device["logicalCode"], group = group.get("address", ""), duration = portInfo["duration"], coin = u"%s金币" % coins ), service = u"汽车桩充电服务", finishTime = datetime.datetime.strftime(nowTime, "%Y-%m-%d %H:%M:%S"), remark = u'谢谢您的支持' ) consumeDict.update({DEALER_CONSUMPTION_AGG_KIND.COIN: VirtualCoin(coins).mongo_amount}) if VirtualCoin(balance) > VirtualCoin(0): refundMoney = VirtualCoin(balance) consumeDict.update({ DEALER_CONSUMPTION_AGG_KIND.REFUNDED_COINS: refundMoney.mongo_amount, DEALER_CONSUMPTION_AGG_KIND.COIN: (VirtualCoin(coins) - refundMoney).mongo_amount }) refund_money(self.device, refundMoney, openId) self.notify_user(user.managerialOpenId if user else '', 'refund_coins', **{ 'title': u"金币退款", 'backCount': u'金币:%s' % refundMoney, 'finishTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') }) ServiceProgress.update_progress_and_consume_rcd( self.device["ownerId"], { "open_id": openId, "device_imei": devNo, "port": int(port), "isFinished": False }, consumeDict ) Device.clear_port_control_cache(devNo, str(port))