# coding=utf-8 import datetime import logging import random import time import simplejson as json import typing from bson import ObjectId from mongoengine import DoesNotExist, ValidationError from apilib.monetary import RMB, VirtualCoin, Ratio from apilib.utils_sys import memcache_lock from apps.web.agent.models import Agent from apps.web.common.models import TempValues from apps.web.constant import FAULT_CODE, FAULT_LEVEL, Const, DEALER_CONSUMPTION_AGG_KIND, USER_RECHARGE_TYPE from apps.web.core.device_define.changyuan import CYCardMixin from apps.web.core.payment import WithdrawGateway from apps.web.dealer.models import Dealer from apps.web.device.models import Group, Device from apps.web.eventer import EventBuilder from apps.web.eventer.base import WorkEvent, FaultEvent from apps.web.report.ledger import Ledger from apps.web.user.models import CardRechargeOrder, Card, RechargeRecord, CardRechargeRecord, ServiceProgress, \ ConsumeRecord, CardConsumeRecord, MyUser from apps.web.user.models import RefundMoneyRecord from apps.web.user.transaction_deprecated import refund_money, refund_cash if typing.TYPE_CHECKING: from apps.web.device.models import GroupDict logger = logging.getLogger(__name__) class builder(EventBuilder): def __getEvent__(self, device_event): eventData = self.deviceAdapter.analyze_event_data(device_event.get("data")) if device_event.get('daid'): eventData['daid'] = device_event.get('daid') if eventData is None or "cmdCode" not in eventData: return None if eventData["cmdCode"] == "D7": return ChangYuanFaultEventer(self.deviceAdapter, eventData) else: return ChangYuanWorkEventer(self.deviceAdapter, eventData) class ChangYuanFaultEventer(FaultEvent): def do(self, **args): self.event_data.update({ "faultName": u"设备火灾预警", "faultCode": FAULT_CODE.FIRE_ALARM, "level": FAULT_LEVEL.CRITICAL, "desc": u"主板上报设备火警" }) warningData = { "warningStatus": 2, "warningDesc": "设备温度超限警告", "warningTime": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") } # 整机告警 Device.update_dev_warning_cache(self.device.devNo, {"0": warningData}) super(ChangYuanFaultEventer, self).do(**args) class ChangYuanWorkEventer(WorkEvent, CYCardMixin): def do(self, **args): cmdCode = self.event_data.get("cmdCode") cacheKey = "{}-{}-event".format(self.device.devNo, cmdCode) with memcache_lock(key = cacheKey, value = '1', expire = 300) as acquired: if acquired: if cmdCode == "F3": self._do_recharge_card_result() elif cmdCode == "F4": self._do_recharge_card() elif cmdCode == "D8": self._do_report_device_status() elif cmdCode == "D9": self._do_start_charge() elif cmdCode == "DA": self._do_finish() elif cmdCode == "DF": self._do_card_refund() else: logger.warning( "cyp_event is doing!, dev is <{}>, cmd is <{}>, data is <{}>".format(self.device.devNo, cmdCode, self.event_data)) def _do_card_refund(self): beforeRefund = self.event_data.get("beforeRefund") refund = self.event_data.get("refund") afterRefund = self.event_data.get("afterRefund") cardNo = str(self.event_data.get("cardNo")) if VirtualCoin(beforeRefund) + VirtualCoin(refund) != VirtualCoin(afterRefund): logger.info("bad refund event, beforeRefund is {}, refund is {} afterRefund is {}".format( beforeRefund, refund, afterRefund )) return card = self.update_card_dealer_and_type(cardNo, cardType = "IC") if not card: logger.info("cyp_ No cardNo cardNo is {}".format(cardNo)) return if VirtualCoin(card.balance) != VirtualCoin(beforeRefund): logger.info( "beforeRefund isn't equal card balance, cardNo is {}, beforeRefund is {}, card balance is {}".format( cardNo, beforeRefund, card.balance )) return self.refund_money_for_card(RMB(refund), str(card.id)) self.notify_user( card.managerialOpenId, 'refund_coins', **{ 'title': u"充电桩返费", 'backCount': u'%s' % refund, 'finishTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') } ) def _do_over_ack_clear_port(self, daid, port, overServiceProgress = False): res = self.deviceAdapter._ack_finished_massage(daid) if res['rst'] == 0: if overServiceProgress: sp = ServiceProgress.objects.filter(device_imei = self.device.devNo, port = port, isFinished = False).first() if sp: sp.update(isFinished = True, finished_time = time.time(), expireAt = datetime.datetime.now()) Device.clear_port_control_cache(self.device["devNo"], port) logger.info('cyp_do_over_ack_clear_port() is over !!') def _do_update_ConsumeRecord_CardConsumeRecord_service_progress(self, portCache, updateMoney): portCache["payCount"] = portCache.get('payCount') + 1 portCache["allPayMoney"] = updateMoney portCache["coins"] = updateMoney orderNo = portCache.get('orderNo') cardOrderNo = portCache.get("cardOrderNo") try: order = ConsumeRecord.objects.get(orderNo = orderNo) # type: ConsumeRecord card_order = CardConsumeRecord.objects.get(orderNo = cardOrderNo) service_pogress = ServiceProgress.objects( __raw__ = {'device_imei': order.devNo, 'consumeOrder.orderNo': orderNo}).first() order.coin = updateMoney order.money = updateMoney card_order.money = updateMoney service_pogress.consumeOrder['money'] = updateMoney service_pogress.consumeOrder['coin'] = updateMoney order.save() card_order.save() service_pogress.save() except Exception as e: logger.debug('cyp_%s' % e) finally: pass def _do_recharge_card(self): """ 同步卡的请求 :return: """ cardNo = self.event_data.get("cardNo") cardBalance = self.event_data.get("cardBalance") cardType = self.event_data.get("cardType") card = self.update_card_dealer_and_type(cardNo) if not card: logger.error("not card exist, can not async card balance <{}>".format(cardNo)) return # 更新卡的余额 以设备侧的为准 if RMB(cardBalance) != card.balance: logger.info('Card<{}> balance<{}> needs to be sync !!!'.format(cardNo, card.balance)) card.balance = RMB(cardBalance) card = card.save() # orderNos 表示充值的订单 cardOrderNos 表示卡充值的订单 money, coins, orderNos, cardOrderNos = CardRechargeOrder.get_to_do_list(str(card.id)) # 一旦卡被冻结 立即下发 创建一张为 负数的金额订单 将卡的余额清空 if card.frozen: group = Group.get_group(card.groupId) CardRechargeOrder.new_one( openId = card.openId, cardId = str(card.id), cardNo = card.cardNo, money = RMB(0), coins = VirtualCoin(0) - VirtualCoin(coins) - VirtualCoin(card.balance), group = group, rechargeId = ObjectId(), rechargeType = u"sendCoin" ) money, coins, orderNos, cardOrderNos = CardRechargeOrder.get_to_do_list(str(card.id)) # 没有需要同步的订单的情况下 直接退出 if not orderNos: logger.info('Not card recharge record!, card is <{}>'.format(cardNo)) # self._do_offline_recharge_by_dealer(cardNo, card, cardType) return orderNos = [str(item) for item in orderNos] sid = str(random.randint(0, 0xFFFF)) TempValues.set('%s-%s' % (self.device.devNo, sid), value = json.dumps(orderNos)) TempValues.set('%s-%s-%s' % (self.device.devNo, sid, cardNo), value = json.dumps(cardOrderNos)) TempValues.set('%s-%s' % (self.device.devNo, cardNo), value = str(sid)) # 计算总的需要同步的金额 asyncMoney = RMB(cardBalance) + RMB(coins) logger.info('ready to recharge card, card is <{}>, money is <{}>'.format(cardNo, coins)) # 已经下发金额后,先将订单的状态改为结束。如果主板上报失败,再将订单状态迁移回来否则就不再变化订单状态了 try: CardRechargeOrder.update_card_order_has_finished(str(card.id)) except Exception as e: logger.debug('%s' % e) else: self.deviceAdapter._async_card_balance(cardType, cardNo, asyncMoney) def _do_recharge_card_result(self): """ 确认卡的同步结果 :return: """ asyncStatus = self.event_data.get("asyncStatus") answerSid = self.event_data.get("sid") cardBalance = self.event_data.get("cardBalance") cardNo = self.event_data.get("cardNo") card = self.update_card_dealer_and_type(cardNo) if not card: logger.error("not found card, event is <{}>".format(self.event_data)) return sid = TempValues.get('{}-{}'.format(self.device.devNo, cardNo)) if sid != answerSid: logger.error('answer sid is not equal sid <{}>-<{}>'.format(sid, answerSid)) return # 根据sid 以及卡号 查询出此次充值的所有的订单 orderNos = TempValues.get('{}-{}'.format(self.device.devNo, sid)) cardOrderNos = TempValues.get('{}-{}-{}'.format(self.device.devNo, sid, cardNo)) # 明确接收到了主板同步失败的情况下 直接退出 不在转换充值订单的问题 防止出错 if not asyncStatus: logger.error("card async not success! event data is <{}>".format(self.event_data)) return # 下面的都不会更改订单的状态 最多走售后 money, coins = RMB(0), VirtualCoin(0) # 校验金额是否是相等的 orderNos = [ObjectId(item) for item in orderNos] rds = RechargeRecord.objects.filter(ownerId = card.dealerId, id__in = orderNos) for item in rds: money += item.money coins += item.coins # 这个地方就是异常值处理了 if VirtualCoin(coins + card.balance) != VirtualCoin(cardBalance): logger.error('card pre balance not equal now balance! event is <{}>'.format(self.event_data)) return # 依次更改卡充值的订单 并创建充值订单 cardOrders = CardRechargeOrder.objects.filter(orderNo__in = cardOrderNos) for _order in cardOrders: # type: CardRechargeOrder _order.update_after_recharge_ic_card( device = self.device, sendMoney = RMB(_order.coins), preBalance = card.balance ) preBalance = card.balance card.balance = card.balance + _order.coins # 创建充值记录 CardRechargeRecord.add_record( card = card, group = Group.get_group(_order.groupId), order = _order, device = self.device ) # 保存 card.save() # 完成之后将TempValue 的key value 清空 TempValues.remove('%s-%s' % (self.device['devNo'], sid)) TempValues.remove('%s-%s' % (self.device['devNo'], cardNo)) TempValues.remove("%s-%s-%s" % (self.device["devNo"], sid, cardNo)) def _do_report_device_status(self): """ 同步设备状态 :return: """ portInfo = self.event_data.get("portInfo") voltage = self.event_data.get("voltage") temperature = self.event_data.get("temperature") # 首先依据上报的状态获取已使用未使用端口数量 allPorts, usedPorts, usePorts = self.deviceAdapter.get_port_static_info(portInfo) # 端口信息更新 devCache = Device.get_dev_control_cache(self.device.devNo) or dict() for portStr, value in devCache.items(): if not portStr.isdigit() or not isinstance(value, dict): continue # 更新每个端口的信息 tempPortInfo = portInfo.get(portStr, dict()) value.update(tempPortInfo) devCache[portStr] = value devCache["voltage"] = voltage devCache["temperature"] = temperature devCache["allPorts"] = allPorts devCache["usedPorts"] = usedPorts devCache["usePorts"] = usePorts Device.update_dev_control_cache(self.device.devNo, devCache) def _do_start_charge(self): """ 充电开始指令, 主要是更新各种缓存等等, 对于扫码的启动基本在adapter缓存已经处理完成,主要需要处理的是刷卡的启动 根据 需求方要求 刷卡的可以做合单处理 :return: """ logger.info( 'cyp_do_start_charge() is run!! event_data:{}'.format(json.dumps(self.event_data, ensure_ascii = False))) portStr = self.event_data.get("portStr") cardBalance = self.event_data.get("cardBalance") allPayMoney = self.event_data.get("allPayMoney") payMoney = self.event_data.get("payMoney") cardNo = str(self.event_data.get("cardNo")) if cardNo == '00000000': return card = self.update_card_dealer_and_type(cardNo) if not self.check_card_can_use(card): logger.info( "[ChangYuanWorkEventer _do_start_charge] check card not can use devNo = {}".format(self.device.devNo)) self.notify_invalid_card_to_dealer(cardNo, card) return self.deviceAdapter.stop_charging_port(portStr) # 判断卡是否存在 如果不存在 直接更新缓存信息即可 if not card: Device.update_dev_control_cache(self.device.devNo, {portStr: self.event_data}) return devCache = Device.get_dev_control_cache(self.device.devNo) portCache = devCache.get(portStr) or dict() # 离线卡 以设备上报过来的数据为准 self.update_card_balance(card, RMB(cardBalance)) if portCache.get("status", Const.DEV_WORK_STATUS_IDLE) != Const.DEV_WORK_STATUS_IDLE: # TODO 续充时候的处理 logger.info('cyp_do_card_start_charge again!!') self._do_update_ConsumeRecord_CardConsumeRecord_service_progress(portCache, allPayMoney) # 不是续充,第一次刷卡 else: logger.info('cyp_do_card_start_charge the once!!') # 记录ID卡的消费 attachParas = { "chargeIndex": portStr } servicedInfo = { 'cardNo': cardNo, 'chargeIndex': portStr } orderNo, cardOrderNo = self.record_consume_for_card(card, RMB(payMoney), servicedInfo = servicedInfo, attachParas = attachParas) # 记录缓存信息 可以在个人中心以及经销商的端口管理显示 portCache = { "cardNo": cardNo, "openId": card.openId, "allPayMoney": allPayMoney, "lastPayMoney": payMoney, "payCount": 1, "coins": allPayMoney, "status": Const.DEV_WORK_STATUS_WORKING, "startTime": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "orderNo": orderNo, "cardOrderNo": cardOrderNo, "consumeType": "card", "cardBalance": cardBalance } ServiceProgress.register_card_service( self.device, int(portStr), card, { "orderNo": orderNo, "money": RMB(allPayMoney).mongo_amount, "coin": RMB(allPayMoney).mongo_amount, "cardOrderNo": cardOrderNo } ) # 更新端口缓存 Device.update_dev_control_cache(self.device.devNo, {portStr: portCache}) # 通知消费 self.notify_balance_has_consume_for_card(card, payMoney) def _do_finish(self): """ 充电结束的指令 :return: """ # if self.event_data.get('reasonCode') == u'E8': # #远程手工停止 # logger.info('cyp_Remote shut-off !! event_data:{}'.format(json.dumps(self.event_data,ensure_ascii=False))) cardNo = str(self.event_data.get("cardNo")) if cardNo == "00000000": self._do_netpay_finish() else: self._do_card_finish() def _do_card_finish(self): logger.info( 'cyp_do_card_finish() is run !! event_data:{}'.format(json.dumps(self.event_data, ensure_ascii = False))) cardNo = str(self.event_data.get("cardNo")) leftBalance = self.event_data.get('leftBalance') usedtime = self.event_data.get('usedTime') usedElec = self.event_data.get("usedElec") desc = self.event_data.get('desc') port = self.event_data['portStr'] daid = self.event_data['daid'] card = self.update_card_dealer_and_type(cardNo, cardType = "IC") if not card: logger.debug("cyp_server no find card!!!") self._do_over_ack_clear_port(daid, port, overServiceProgress = True) return dev_control_cache = Device.get_dev_control_cache(self.device.devNo) try: port_cache = dev_control_cache[port] if not port_cache or port_cache == {'status': 0}: raise except Exception: logger.debug('cyp_the device no cache!!! dev_control_cache:{}'.format( json.dumps(dev_control_cache, ensure_ascii = False))) self._do_over_ack_clear_port(daid, port, overServiceProgress = True) return # port_cache ={'status': 1, 'openId': u'o-VzzwAfpdglJY38Kj7yMvVWlIgw', 'cardNo': u'828CA649', 'price': 5.0, 'coins': 5.0, 'cardOrderNo': '1600314329724498', 'startTime': '2020-09-17 11:45:29', 'orderNo': '1600314329469873'} if cardNo != port_cache.get('cardNo'): # 该端口开始时候记录的卡号与结束上报的时候的卡号不相同,可能缓存纪录有问题,基本不可能!! logger.info('cyp_the device no cardNo cache,do ack,clear port cache!!! port_cache:{}'.format( json.dumps(port_cache, ensure_ascii = False))) self._do_over_ack_clear_port(daid, port, overServiceProgress = True) return servicedInfo = { "port": port, "elec": usedElec, "usedTime": usedtime, "reason": desc, "finishedTime": datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%M:%S") } servicedInfo.update(port_cache) servicedInfo["leftBalance"] = leftBalance servicedInfo['spendMoney'] = str(RMB(servicedInfo["allPayMoney"]) - RMB(leftBalance)) logger.info('cyp_servicedInfo:{}'.format(json.dumps(servicedInfo, ensure_ascii = False))) # card.balance = card.balance + RMB(leftBalance) # # try: # # card.save() # except Exception as e: # logger.debug('cyp_update_card_balance ie error %s' % e) try: group = Group.get_group(self.device["groupId"]) self.notify_user( managerialOpenId = card.managerialOpenId, 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}\\n\\n待返费:\\t\\t{refund}".format( reason = u"充电结束", logicalCode = self.device["logicalCode"], group = group.get("address", ""), duration = usedtime, coin = u"%s" % servicedInfo['allPayMoney'], refund = u"%s 请将卡片贴近充电桩进行返费" % leftBalance ), service = u"本次充电结束,请将充电卡放在桩的刷卡区域返费,保持静止5秒以上,直到听到 返费成功 语音后,再把卡移开!", finishTime = datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%M:%S"), remark = u'谢谢您的支持' ) finally: newServicedInfo = { "cardNo": servicedInfo["cardNo"], "reason": servicedInfo["reason"], "port": servicedInfo["port"], "elec": servicedInfo["elec"], "finishedTime": servicedInfo["finishedTime"], "coin": servicedInfo["coins"] } ServiceProgress.update_progress_and_consume_rcd( self.device["ownerId"], { "device_imei": self.device["devNo"], "cardId": str(card.id), "port": int(port), "isFinished": False, "consumeOrder.orderNo": servicedInfo.get('orderNo'), }, newServicedInfo ) self._do_over_ack_clear_port(daid, port) logger.info('cyp_do_card_finish() is over!!') def _do_netpay_finish(self): logger.info('cyp_do_netpay_finish() is run !! event_data:{}'.format( json.dumps(self.event_data, ensure_ascii = False))) cardNo = str(self.event_data.get("cardNo")) leftBalance = self.event_data.get('leftBalance') usedtime = self.event_data.get('usedTime') usedElec = self.event_data.get("usedElec") desc = self.event_data.get('desc') port = self.event_data['portStr'] daid = self.event_data['daid'] dev_control_cache = Device.get_dev_control_cache(self.device.devNo) try: port_cache = dev_control_cache[port] if not port_cache or port_cache == {'status': 0}: raise except Exception: logger.info('cyp_the device no port_cache,do ack,clear port cache!!! dev_control_cache:{}'.format( dev_control_cache)) self._do_over_ack_clear_port(daid, port, overServiceProgress = True) return try: servicedInfo = { "port": port, "elec": usedElec, "usedTime": usedtime, "reason": desc, "finishedTime": datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%M:%S") } servicedInfo.update(port_cache) servicedInfo["leftBalance"] = leftBalance payType = servicedInfo['payType'] openId = servicedInfo['openId'] coins = servicedInfo['coins'] price = servicedInfo['allPayMoney'] vCardId = servicedInfo.get('vCardId') rechargeRcdId = servicedInfo.get('rechargeRcdId') # 尝试进行分账 rechargeRecord = self.do_ledger(rechargeRcdId) # 如果没有openId则为经销商远程上分 if not openId and cardNo == '00000000': logger.info('cyp_Remote activation by dealer') return if payType == 'coin': servicedInfo['spendCoin'] = str(VirtualCoin(servicedInfo['coins']) - VirtualCoin(leftBalance)) elif payType == 'cash': servicedInfo['spendMoney'] = str(RMB(servicedInfo['coins']) - RMB(leftBalance)) logger.info('cyp_servicedInfo:{}'.format(json.dumps(servicedInfo, ensure_ascii = False))) group = Group.get_group(self.device["groupId"]) user = MyUser.objects.filter(openId = openId, groupId = self.device["groupId"]).first() logger.info("cyp_ChangYuanPower net pay finish and start to notify user! {}".format(self.device["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 = u"充电结束", logicalCode = self.device["logicalCode"], group = group.get("address", ""), duration = usedtime, coin = u"%s金币" % coins if payType == 'coin' else u"%s元" % price ), service = u"自助充电服务", finishTime = datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%M:%S"), remark = u'谢谢您的支持') if RMB(leftBalance) > RMB(0): if payType == "cash": if not self.device.is_auto_refund: return refundMoney = RMB(rechargeRecord.money) * Ratio(float(leftBalance) / float(coins)) refund_order = refund_cash( rechargeRecord, refundMoney, VirtualCoin(0), user = user, minus_total_consume = VirtualCoin(rechargeRecord.coins)) # type: RefundMoneyRecord if refund_order: logger.info("refund cash apply success!") servicedInfo.update({DEALER_CONSUMPTION_AGG_KIND.REFUNDED_CASH: refundMoney.mongo_amount}) self.notify_user(user.managerialOpenId if user else '', 'refund_coins', **{ 'title': u"退款(退款金额将于1-5个工作日内返还)", 'backCount': u'%s 元' % refundMoney, 'finishTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') }) # 金币支付并且 设备金币退款的开关打开 elif payType == "coin": if not self.device.is_auto_refund: return refundMoney = VirtualCoin(leftBalance) servicedInfo.update({DEALER_CONSUMPTION_AGG_KIND.REFUNDED_COINS: refundMoney.mongo_amount}) refund_money(self.device, refundMoney, openId) # 虚拟卡支付的情况 else: logger.info("pay type need not to refund!") newServicedInfo = { "reason": servicedInfo["reason"], "port": servicedInfo["port"], "coin": servicedInfo["coins"], "elec": servicedInfo["elec"], } if DEALER_CONSUMPTION_AGG_KIND.REFUNDED_COINS in servicedInfo: refunded_coins = servicedInfo[DEALER_CONSUMPTION_AGG_KIND.REFUNDED_COINS] newServicedInfo.update( { DEALER_CONSUMPTION_AGG_KIND.SPEND_MONEY: (VirtualCoin(coins) - refunded_coins).mongo_amount, DEALER_CONSUMPTION_AGG_KIND.REFUNDED_COINS: refunded_coins }) elif DEALER_CONSUMPTION_AGG_KIND.REFUNDED_CASH in servicedInfo: refunded_cash = servicedInfo[DEALER_CONSUMPTION_AGG_KIND.REFUNDED_CASH] newServicedInfo.update( { DEALER_CONSUMPTION_AGG_KIND.REFUNDED_CASH: refunded_cash }) ServiceProgress.update_progress_and_consume_rcd( self.device["ownerId"], { "open_id": openId, "device_imei": self.device["devNo"], "port": int(port), "isFinished": False, "consumeOrder.orderNo": servicedInfo.get('orderNo'), }, newServicedInfo ) logger.info('cyp_do_netpay_finish() is over !!') finally: self._do_over_ack_clear_port(daid, port) def update_card_dealer_and_type(self, cardNo, cardType = 'IC', isHaveBalance = True, balance = None): """ 更新卡的状态 重写目的 如果卡不存在 立即下发停止充电指令 而不是新建一张卡 :param cardNo: :param cardType: :param isHaveBalance: :param balance: :return: """ dealer = Dealer.objects.get(id = self.device["ownerId"]) agent = Agent.objects.get(id = dealer.agentId) if not agent: logger.error('agent is not found, agentId=%s' % dealer.agentId) return try: card = Card.objects.get(cardNo = cardNo, agentId = dealer.agentId) # 如果卡没有被绑定,这个时候检查下绑定关系。如果卡已经被某个经销商认领了,就不要刷新,不要动了 if card.cardType and card.dealerId and card.devNo and (card.dealerId == self.device['ownerId']): return card card.dealerId = self.device['ownerId'] card.devNo = self.device['devNo'] card.cardType = cardType card.devTypeCode = self.device['devType']['code'] card.isHaveBalance = isHaveBalance return card.save() except DoesNotExist: return except Exception as e: logger.exception(e) return def notify_invalid_card_to_dealer(self, cardNo, card): logger.info('Illegal card <{}>, charging is about to stop'.format(cardNo)) group = Group.get_group(self.device['groupId']) self.notify_dealer( 'device_fault', title = u'注意!注意!您当前的设备已被非法卡使用!', device = u'组号::%s, 二维码编号:%s' % (self.device['groupNumber'], self.device['logicalCode']), location = u'组名称:%s, 地址:%s' % (group['groupName'], group['address']), fault = u'在%s编号为%s的设备被非法卡卡启动,启动卡号为:%s 卡联系人 %s 卡联系电话 %s' % ( group['address'], self.device['logicalCode'], card.cardNo if card else '', card.phone if card else '', card.cardName if card else ''), notifyTime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') )