# -*- coding: utf-8 -*- # !/usr/bin/env python import logging from mongoengine import DoesNotExist from apilib.monetary import RMB from apilib.utils_sys import memcache_lock from apps.web.constant import Const from apps.web.core.networking import MessageSender 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 from apps.web.helpers import device_lock_key from apps.web.user.models import ServiceProgress, Card, CardRechargeOrder, CardConsumeRecord logger = logging.getLogger(__name__) class builder(EventBuilder): def __getEvent__(self, device_event): return DepartmentShowerEvent(self.deviceAdapter, device_event) class DepartmentShowerEvent(WorkEvent): def update_card_dealer_and_type(self, cardNo, cardType = 'ID'): dealer = Dealer.objects.get(id = self.device['ownerId']) try: card = Card.objects.get(cardNo = cardNo, agentId = dealer.agentId) # 如果卡的经销商换了,不允许使用 if card.dealerId and str(dealer.id) != card.dealerId: return None card.dealerId = self.device['ownerId'] card.devNo = self.device['devNo'] card.cardType = cardType return card.save() except DoesNotExist: card = Card( cardNo = cardNo, cardType = cardType, dealerId = str(dealer.id), agentId = str(dealer.agentId), ) try: return card.save() except Exception as e: logger.error('can not save card info,cardNo=%s' % cardNo) logger.exception(e) except Exception as e: logger.exception(e) return None def do(self, **args): devNo = self.device['devNo'] logger.info('department shower event detected, devNo=%s,msg=%s' % (devNo, self.event_data)) # 用户放上了ID卡,到服务器上来同步卡的余额 if self.event_data['cmd'] == 301: # 更新一次绑定关系 # 检查用户是否换设备刷卡 card = self.update_card_dealer_and_type(self.event_data['cardNo'], 'ID') if card is None: balance = 0 elif card.frozen: balance = 0 else: 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) balance = result['balance'] MessageSender.async_send(device = self.device, cmd = 301, payload = { 'cardNo': self.event_data['cardNo'], 'IMEI': self.device['devNo'], 'balance': int(balance * 100) }) # 余额是0,设备不会工作,直接返回 if RMB(balance) <= RMB(0): logger.info('this card balance is 0,cardId=%s' % (card.id)) return # 更新设备的状态,并发通知消息给用户 Device.update_dev_control_cache(self.device['devNo'], {'status': Const.DEV_WORK_STATUS_WORKING}) # 登记下正在服务的信息 ServiceProgress.register_card_service(self.device, -1, card) # 发消息给卡主 group = Group.get_group(self.device['groupId']) desc = u'正在刷卡使用,开始计费,卡号:%s,卡名称:%s,地址信息:%s %s' % ( card.cardNo, card.cardName, group['groupName'], group['address']) self.notify_balance_has_consume_for_card(card, 0.00, desc) elif self.event_data['cmd'] == 307: with memcache_lock(key = device_lock_key(self.device['devNo']), value = self.event_data['dsid'], expire = 360) as acquired: if acquired: devObj = Device.objects.get(devNo = devNo) minuteFee = devObj.otherConf.get('minuteFee', 10) replyAccountDict = {} for cardNo, cardValue in self.event_data['accounts'].items(): card = self.update_card_dealer_and_type(cardNo, 'ID') # 检查该消费单是否核销了 count = CardConsumeRecord.objects.filter(devNo = self.device['devNo'], sid = self.event_data['dsid']).count() # 如果有,就说明单已经核销了 if count > 0: balance = card.balance else: balance = card.balance - RMB(cardValue['arrearage'] / 100.0) replyAccountDict.update({cardNo: int(balance * 100)}) if count > 0: continue # 减掉余额 self.consume_money_for_card(card, RMB(cardValue['arrearage'] / 100.0)) # 记录数据 spendTime = round(cardValue['arrearage'] / minuteFee, 2) self.record_consume_for_card(card, RMB(cardValue['arrearage'] / 100.0), u'花费时间:%s' % spendTime, {'spendTime': cardValue, 'spendMoney': cardValue['arrearage'] / 100.0}, sid = self.event_data['dsid']) try: devInfo = MessageSender.send(self.device, 307, {'IMEI': self.device['devNo'], 'accounts': replyAccountDict, 'dsid': self.event_data['dsid']}) except Exception, e: logger.info('send 307 error=%s' % e) return