123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import json
- import logging
- import datetime
- import time
- from mongoengine import DoesNotExist
- from apilib.monetary import RMB, VirtualCoin
- from apilib.utils_string import make_title_from_dict
- from apilib.utils_sys import memcache_lock
- from apps.web.constant import Const, ErrorCode, DEALER_CONSUMPTION_AGG_KIND
- 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.eventer.weifuleCommon import WeiFuLeStatusEvent, WeiFuLeCommonEvent
- from apps.web.user.models import ServiceProgress, UserVirtualCard, VCardConsumeRecord, \
- ConsumeRecord, Card, CardConsumeRecord, CardRechargeOrder, MyUser, CardRechargeRecord, RechargeRecord
- logger = logging.getLogger(__name__)
- created_order_32 = 32
- exec_order_33 = 33
- finished_order_34 = 34
- id_card_request_35 = 35
- card_recharge_order_36 = 36
- status_change_event_44 = 44
- ic_consume_event_48 = 48 # ic卡花钱的时候,会上报此事件
- part_sn_event = 49 # 组件上报相关信息
- card_is_normal = 1
- card_not_in_db = 2
- card_is_forzen = 3
- card_has_not_order = 4 # IC卡适用
- card_less_balance = 5 # ID卡适用
- card_type_is_ic = 6 # IC卡不允许当做ID卡使用
- no_load_code = 7
- 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 event_data['fun_code'] in [created_order_32, exec_order_33, finished_order_34, id_card_request_35,
- card_recharge_order_36]:
- return ChargingSocketWorkEvent(self.deviceAdapter, event_data)
- if event_data['fun_code'] in [status_change_event_44]:
- return WeiFuLeStatusEvent(self.deviceAdapter, device_event)
- class ChargingSocketWorkEvent(WorkEvent, WeiFuLeCommonEvent):
- def analyse_need_from_package(self, order):
- needKind, needValue, unit = 'needElec', 0, u'度'
- if order['chrmt'] == 'TIME':
- needKind = 'needTime'
- needValue = order['amount_time'] / 60
- unit = u'分钟'
- else:
- needValue = order['amount_elec'] / 1000000.0
- return needKind, needValue, unit
- def create_progress_for_socket_order(self, consumeRcd, order):
- try:
- port = int(order['port'])
- progress = ServiceProgress.objects.filter(device_imei=self.device.devNo, port=port).first()
- if not progress:
- progress = ServiceProgress(device_imei=self.device.devNo, port=port)
- progress.start_time = order['create_time']
- progress.finished_time = order['create_time'] + order.get('amount_time', 60 * 60 * 12)
- progress.isFinished = False
- else:
- if order['id'] in progress.consumes:
- return
- if progress.isFinished == False:
- progress.finished_time = progress.finished_time + order.get('amount_time', 60 * 60 * 12)
- else:
- progress.consumes = []
- progress.start_time = order['create_time']
- progress.finished_time = order['create_time'] + order.get('amount_time', 60 * 60 * 12)
- progress.isFinished = False
- progress.open_id = consumeRcd.openId
- progress.consumes.append(order['id'])
- progress.status = 'running'
- progress.save()
- except Exception as e:
- logger.exception(e)
- def do(self, **args):
- devNo = self.device['devNo']
- funCode = self.event_data.get('fun_code')
- order = self.event_data.get('order', {})
- logger.info('weifule charging event detected, devNo=%s' % (devNo,))
- with memcache_lock(key = '%s-%s-%s-finished' % (devNo, order.get('id'), funCode), value = '1',
- expire = 120) as acquired:
- if acquired:
- self._do_ack_order(order)
- try:
- if funCode == created_order_32:
- self._do_created_order_32(order)
- elif funCode == exec_order_33:
- self._do_exec_order_33(order)
- elif funCode == finished_order_34 and order['order_type'] != 'card_charge':
- self._do_finished_order_34(order)
- elif funCode == finished_order_34 and order['order_type'] == 'card_charge':
- self.update_card_recharge_for_success_event(order['id'], RMB(order['balance'] / 100.0))
- elif funCode == id_card_request_35:
- self.response_id_card()
- elif funCode == card_recharge_order_36: # 如果是卡充值,直接回复订单
- self.deal_with_ic_charge_event()
- except Exception:
- import traceback
- logger.warn(traceback.format_exc())
- logger.info('deal order is finished < funCode: {} order: {} >'.format(funCode, order.get('id')))
- else:
- logger.info('weifule charging event is doing !!!, devNo=%s' % (devNo,))
- def update_balance_for_IC_card(self, card, balance):
- card.balance = balance
- try:
- card.save()
- except Exception, e:
- pass
- def __translate_reason(self, cause, chrmt):
- if cause == 1:
- if chrmt == 'TIME':
- return u'订购时间已经用完。'
- else:
- return u'订购电量已经用完。'
- elif cause == 2:
- return u'用户远程停止。'
- elif cause == 3:
- return u'管理员操作停止。'
- elif cause == 4:
- return u'经销商远程停止。'
- elif cause == 5:
- return u'用户拔掉充电器,或者插座脱落。'
- elif cause == 6:
- return u'端口功率过载,系统为了安全,关闭此充电端口。'
- elif cause == 7:
- return u'整机电压过载,系统为了安全,关闭所有充电端口。'
- elif cause == 8:
- return u'端口电流过载,系统为了安全,关闭此充电端口。'
- elif cause == 9:
- return u'整机功率超限,系统为了安全,关闭所有充电端口。'
- elif cause == 10:
- return u'检测到温度超限,系统为了安全,关闭所有充电端口。'
- elif cause == 11:
- return u'充满自停'
- elif cause == 20:
- return u'端口功率过小。可能是电池已经充满,也可能是所接负载功率太小'
- return u'充电结束。'
- def record_consume_for_card(self, card, money, orderNo):
- group = Group.get_group(self.device['groupId'])
- address = group['address']
- group_number = self.device['groupNumber']
- now = datetime.datetime.now()
- new_record = {
- 'orderNo': orderNo,
- 'time': now.strftime('%Y-%m-%d %H:%M:%S'),
- 'dateTimeAdded': now,
- 'openId': card.openId,
- 'ownerId': self.device['ownerId'],
- 'coin': money.mongo_amount,
- 'money': money.mongo_amount,
- 'devNo': self.device['devNo'],
- 'logicalCode': self.device['logicalCode'],
- 'groupId': self.device['groupId'],
- 'address': address,
- 'groupNumber': group_number,
- 'groupName': group['groupName'],
- 'devTypeCode': self.device.devTypeCode,
- 'devTypeName': self.device.devTypeName,
- 'isNormal': True,
- 'status': ConsumeRecord.Status.RUNNING,
- 'remarks': u'刷卡消费',
- 'errorDesc': '',
- 'sequanceNo': '',
- 'desc': '',
- 'attachParas': {},
- 'servicedInfo': {}
- }
- ConsumeRecord.get_collection().insert_one(new_record)
- # 刷卡消费也记录一条数据
- new_card_record = {
- 'orderNo': orderNo,
- 'openId': card.openId,
- 'cardId': str(card.id),
- 'money': money.mongo_amount,
- 'balance': card.balance.mongo_amount,
- 'devNo': self.device['devNo'],
- 'devType': self.device['devType']['name'],
- 'logicalCode': self.device['logicalCode'],
- 'groupId': self.device['groupId'],
- 'address': address,
- 'groupNumber': group_number,
- 'groupName': group['groupName'],
- 'result': 'success',
- 'remarks': u'刷卡消费',
- 'sequanceNo': '',
- 'dateTimeAdded': datetime.datetime.now(),
- 'desc': '',
- 'servicedInfo': {},
- 'linkedConsumeRcdOrderNo': str(new_record['orderNo'])
- }
- CardConsumeRecord.get_collection().insert(new_card_record)
- return new_record['orderNo'], new_card_record['orderNo']
- def _do_ack_order(self, order):
- funCode = self.event_data['fun_code']
- if funCode in [created_order_32, finished_order_34]:
- try:
- self.deviceAdapter.ack_event(order['id'], funCode)
- except Exception, e:
- logger.info('ack event devNo=%s err=%s' % (self.device.devNo, e))
- pass
- def _do_created_order_32(self, order):
- if order['order_type'] == 'apps_start': # 扫码
- self.pay_apps_start_by_32(order)
- consumeRcd = ConsumeRecord.objects.filter(orderNo=order['id']).first()
- if consumeRcd is None:
- return
- self.create_progress_for_socket_order(consumeRcd, order)
- elif order['order_type'] == 'card_start':
- cardNo = order['card_no']
- # 登记下卡相关信息
- if order['card_type'] == 'IC':
- card = self.update_card_dealer_and_type(cardNo, 'IC')
- if card:
- self.update_balance_for_IC_card(card, RMB(order['balance'] / 100.0))
- else:
- return
- # 如果卡冻结了,马上把端口关闭
- if card.frozen:
- logger.info('this card=%s is frozen,so shut down the port which opened by the card' % cardNo)
- self.deviceAdapter.stop_charging_port(order['port'])
- else:
- card = self.update_card_dealer_and_type(cardNo, 'ID')
- if not card:
- logger.info('no find card=<{}>'.format(cardNo))
- return
- balance = card.balance - RMB(order['amount'] / 100.0)
- card.balance = balance
- # 卡的显示余额同步下
- card.showBalance = balance
- card.save()
- fee = RMB(order['amount'] / 100.0)
- # 记录卡消费记录以及消费记录
- orderNo, cardOrderNo = self.record_consume_for_card(card, fee, order['id'])
- consumeRcd = ConsumeRecord.objects.filter(orderNo=orderNo).first()
- self.create_progress_for_socket_order(consumeRcd, order)
- # 通知用户,已经扣费
- title = make_title_from_dict([
- {u'设备地址': u'{}'.format(self.device.group.address)},
- {u'设备编号': u'{}'.format(self.device['logicalCode'])},
- {u'实体卡': u'{}--No:{}'.format(card.cardName or card.nickName, card.cardNo)},
- {u'本次消费': u'{} 元'.format(fee)},
- {u'卡余额': u'{} 元'.format(RMB(order['balance'] / 100.0))},
- ])
- start_time_stamp = order.get('create_time')
- start_time = datetime.datetime.fromtimestamp(start_time_stamp)
-
- self.notify_user(
- card.managerialOpenId,
- 'dev_start',
- **{
- 'title': title,
- 'things': u'刷卡消费',
- 'remark': u'感谢您的支持!',
- 'time': start_time.strftime(Const.DATETIME_FMT)
- }
- )
- # 缓存切换
- ctrInfo = Device.get_dev_control_cache(self.device.devNo)
- lineInfo = ctrInfo.get(str(order['port']), {})
- if not lineInfo or lineInfo.get('status') == Const.DEV_WORK_STATUS_IDLE:
- lineInfo = {
- 'port': str(order['port']),
- 'status': Const.DEV_WORK_STATUS_WORKING,
- 'order_type': 'card_start',
- 'startTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
- 'orderNo': orderNo,
- }
- Device.update_port_control_cache(self.device.devNo, lineInfo)
- else:
- pass
- def _do_exec_order_33(self, order):
- now = datetime.datetime.fromtimestamp(order['exec_time'])
- consumeRcd = ConsumeRecord.objects.filter(orderNo=order['id']).first()
- if not consumeRcd:
- logger.info('no this order <{}> '.format(order['id']))
- return
- consumeRcd.startTime = now
- consumeRcd.save()
- ctrInfo = Device.get_dev_control_cache(self.device.devNo)
- lineInfo = ctrInfo.get(str(order['port']), {})
- if lineInfo.get('status') == Const.DEV_WORK_STATUS_WORKING and lineInfo.get('orderNo') == order['id']:
- lineInfo.update({'chrmt': order['chrmt']})
- if 'card_no' in order:
- lineInfo.update({'cardType': order.get('card_type'),'cardNo': order.get('card_no')})
- Device.update_port_control_cache(self.device.devNo, lineInfo)
- logger.info('now to exec order <{}>'.format(lineInfo.get('orderNo')))
- return
- consumeRcd = ConsumeRecord.objects.filter(orderNo=order['id']).first()
- lineInfo = {
- 'port': str(order['port']),
- 'status': Const.DEV_WORK_STATUS_WORKING,
- 'order_type': order['order_type'],
- 'startTime': now.strftime('%Y-%m-%d %H:%M:%S'),
- 'orderNo': consumeRcd.orderNo,
- 'chrmt': order['chrmt']
- }
- if 'card_no' in order:
- lineInfo.update({'cardType': order.get('card_type'), 'cardNo': order.get('card_no')})
- Device.update_port_control_cache(self.device.devNo, lineInfo)
- logger.info('now to exec next order <{}>'.format(lineInfo.get('orderNo')))
- def _do_finished_order_34(self, order):
- # 如果是离线卡的余额回收,修改下余额,然后直接返回即可
- if order['order_type'] == 'card_refund':
- return self.update_card_dealer_and_type(cardNo=order['card_no'], cardType='IC', balance=RMB(order['balance'] / 100.0))
-
- consumeRcd = ConsumeRecord.objects.filter(orderNo=order['id'], status__ne='finished').first() # type: ConsumeRecord
- if not consumeRcd:
- logger.info('Repeat processing!! orderNo<{}>'.format(order['id']))
- return
- progress = ServiceProgress.objects.filter(device_imei=self.device.devNo, port=int(order['port']), consumes__contains=order['id']).first()
- if progress is None:
- pass
- else:
- progress.consumes.remove(order['id'])
- if len(progress.consumes) > 0: # 还有其他的单未处理完成
- progress.save()
- else:
- progress.status = 'finished' # 此时为本次服务的最后一单
- progress.isFinished = True
- progress.save()
- try:
- order['reason'] = self.__translate_reason(order['cause'], order['chrmt'])
- group = Group.get_group(self.device['groupId'])
- consumeDict = {
- 'reason': order['reason'],
- 'chargeIndex': order['port'],
- 'duration': round(order['time'] / 60.0, 1),
- 'elec': round(order['elec'] / 1000000.0, 2)
- }
- notifyDict = {
- 'service': u'充电服务完成',
- 'finishTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
- 'remark': u'谢谢您的支持'
- }
- refundDict = {
- 'finishTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
- }
- refundProtection = self.device['otherConf'].get('refundProtection', 5)
-
- package = consumeRcd.package
- if package.get('name') == '充满自停' and package.get('coins') == 0 and package.get('price') == 0: # 后付费
-
- usedFee = VirtualCoin(order['money'] * 0.01)
- usedTime = order['time'] / 60
- cause = int(order.get(u'cause', 0))
- if cause == no_load_code or usedTime <= refundProtection:
- usedFee = VirtualCoin(0)
-
- consumeDict.update({
- DEALER_CONSUMPTION_AGG_KIND.SPEND_MONEY: usedFee.mongo_amount
- })
-
- user = MyUser.objects(openId=consumeRcd.openId, groupId=self.device['groupId']).first()
- if not user:
- return
- try:
- user.pay(usedFee)
- consumeRcd.update(coin=usedFee.mongo_amount, status='finished')
- except Exception:
- pass
- notifyDict.update(
- {'title': make_title_from_dict([
- {u'设备编号': self.device['logicalCode']},
- {u'端口': order['port']},
- {u'地址': group['address']},
- {u'结束原因': order['reason']},
- {u'充电时间': u'%s分钟' % round(usedTime, 1)},
- {u'本次服务费用': u'%s币' % usedFee},
- ])})
-
- # 通知服务结束
- notifyOpenId = user.managerialOpenId if user else ''
- self.notify_user(notifyOpenId, 'service_complete', **notifyDict)
- consumeRcd.update_service_info(consumeDict)
- consumeRcd.update(status='finished', finishedTime=datetime.datetime.now(),
- servicedInfo__source=json.dumps(order))
- logger.info('orderNo<{}> finished!!'.format(consumeRcd.orderNo))
- return
- else:
- coins = consumeRcd.coin
- backCoins = RMB(0)
- if order['chrmt'] == 'TIME': # 按照时间计费
- needTime = round(order['amount_time'] / 60.0, 1)
- usedTime = round(order['time'] / 60.0, 1)
- leftTime = round(order['left_time'] / 60 if order['left_time'] > 0 else 0, 1)
- leftTimeStr = leftTime
- actualNeedTime = round(usedTime + leftTime, 1)
-
- consumeDict.update({
- 'needTime': needTime,
- 'leftTime': leftTimeStr,
- 'actualNeedTime': u'动态功率计算为%s分钟' % actualNeedTime,
- })
- notifyDict.update({'title': make_title_from_dict([
- {u'设备编号': self.device['logicalCode']},
- {u'端口': order['port']},
- {u'地址': group['address']},
- {u'结束原因': order['reason']},
- {u'订购时间': u'%s分钟' % needTime},
- {u'应充时间': u'%s分钟' % actualNeedTime},
- {u'充电时间': u'%s分钟' % usedTime},
- {u'剩余时间': u'%s分钟' % leftTimeStr}
- ])})
-
- refundTitleDictList = [
- {u'设备编号': self.device['logicalCode']},
- {u'端口': order['port']},
- {u'付款': u'%s元' % coins},
- {u'预定时间': u'%s分钟' % needTime},
- {u'应充时间': u'%s分钟' % actualNeedTime},
- {u'充电时间': u'%s分钟' % usedTime},
- {u'剩余时间': u'%s分钟' % leftTimeStr},
- ]
-
- else:
- needElec = round(order['amount_elec'] / 1000000.0, 2)
- usedTime = round(order['time'] / 60.0, 1)
- usedElec = round(order['elec'] / 1000000.0, 2)
- leftElec = round(needElec - usedElec if needElec > usedElec else 0.0, 2)
- consumeDict.update({
- 'needElec': needElec,
- 'leftElec': leftElec,
- })
-
- notifyDict.update({'title': make_title_from_dict([
- {u'设备编号': self.device['logicalCode']},
- {u'端口': order['port']},
- {u'结束原因': order['reason']},
- {u'充电时间': u'%s分钟' % usedTime},
- {u'订购电量': u'%s度' % needElec},
- {u'消耗电量': u'%s度' % usedElec},
- {u'剩余电量': u'%s度' % leftElec},
- ])})
-
- refundTitleDictList = [
- {u'设备编号': self.device['logicalCode']},
- {u'端口': order['port']},
- {u'结束原因': order['reason']},
- {u'充电时间': u'%s分钟' % usedTime},
- {u'订购电量': u'%s度' % needElec},
- {u'消耗电量': u'%s度' % usedElec},
- {u'剩余电量': u'%s度' % leftElec},
- ]
-
- if usedTime <= refundProtection:
- backCoins = coins
- else:
- if self.device.is_auto_refund:
- backCoins = coins * (float(order['left_money']) / float(order['amount']))
-
- refundDict.update({
- 'title': make_title_from_dict(refundTitleDictList),
- 'backCount': u'金币:%s' % backCoins
- })
- logger.info(
- 'REFUND STATUS orderNo=<{}>, refundSwitch={}, refundProtectionTime=<{}>, backCoins=<{}>'.format(
- consumeRcd.orderNo, self.device.is_auto_refund, refundProtection, backCoins.mongo_amount
- ))
-
- if u'虚拟卡' in consumeRcd.remarks:
- # 退额度
- try:
- vRcd = VCardConsumeRecord.objects.get(orderNo=order['id'])
- vCard = UserVirtualCard.objects.get(id=vRcd.cardId)
- except DoesNotExist, e:
- logger.info('can not find the vCard id = %s' % vRcd.cardId)
- return
- # 通知服务结束
- notifyOpenId = self.get_managerialOpenId_by_openId(vRcd.openId) if vCard else ''
- self.notify_user(notifyOpenId, 'service_complete', **notifyDict)
- # 不需要退款,直接返回,不通知
- if self.device.is_auto_refund and backCoins > RMB(0):
- if order['chrmt'] == 'TIME':
- vCard.refund_quota(vRcd, usedTime, 0.0, backCoins.mongo_amount)
- else:
- vCard.refund_quota(vRcd, 0.0, usedElec, backCoins.mongo_amount)
- # 刷卡的方式
- elif order['order_type'] == 'card_start' and order['card_no']:
- dealer = Dealer.get_dealer(ownerId=self.device['ownerId'])
- card = Card.objects.filter(agentId=dealer['agentId'], cardNo=order['card_no']).first()
- if card is None: # 离线卡没有绑定或者在线卡被解绑了
- return
- # 先通知
- notifyOpenId = card.managerialOpenId if card else ''
- self.notify_user(notifyOpenId, 'service_complete', **notifyDict)
- # 不需要退款,直接返回.在线卡需要退费,离线卡只登记使用记录就OK
- if backCoins > RMB(0) and card.cardType == 'ID' and backCoins > RMB(0):
- card = self.refund_money_for_card(RMB(backCoins), card.id)
- card.showBalance = card.balance
- card.save()
- consumeDict.update({'refundedMoney': str(backCoins)})
- self.notify_user(notifyOpenId, 'refund_coins', **refundDict)
- else: # 扫码的
- user = MyUser.objects(openId=consumeRcd.openId, groupId=self.device['groupId']).first()
- if not user:
- return
- # 通知服务结束
- notifyOpenId = user.managerialOpenId if user else ''
- self.notify_user(notifyOpenId, 'service_complete', **notifyDict)
- # 如果需要退款,计算退款数据.
- if backCoins > RMB(0):
- refundCash = 'refundRMB_device_event' in self.device.owner.features
- rechargeRcdId = consumeRcd.recharge_record_id
- if rechargeRcdId:
- rechargeRcd = RechargeRecord.objects.filter(id=rechargeRcdId, isQuickPay=True).first()
- else:
- rechargeRcd = None
-
- if refundCash is True and rechargeRcd is not None: # 退现金特征 + 有充值订单
- refundRMB = rechargeRcd.money * (backCoins.amount / coins.amount)
- self.refund_net_pay(user, {'rechargeRcdId': rechargeRcdId, 'openId': user.openId},
- refundRMB, VirtualCoin(0), consumeDict, True)
-
- refundDict.update({'backCount': u'金额:%s' % refundRMB})
- self.notify_user(notifyOpenId, 'refund_coins', **refundDict)
-
- else:
- self.refund_net_pay(user, {'openId': user.openId}, RMB(0), backCoins, consumeDict,
- False)
-
- self.notify_user(notifyOpenId, 'refund_coins', **refundDict)
- consumeRcd.update_service_info(consumeDict)
- consumeRcd.update(status='finished', finishedTime=datetime.datetime.now(),servicedInfo__source=json.dumps(order))
-
- except Exception as e:
- logger.exception('some exception happed,devNo=%s,e=%s' % (self.device.devNo, e))
- finally:
- ctrInfo = Device.get_dev_control_cache(self.device.devNo)
- lineInfo = ctrInfo.get(str(order['port']), {})
- # 如果缓存中要结束的端口是本单的 就清空缓存 否则不处理
- if order['id'] == lineInfo.get('orderNo'):
- Device.clear_port_control_cache(self.device.devNo, order['port'])
- # 这里采用更新端口 不操作缓存
- self.deviceAdapter.get_port_status_from_dev()
- def deal_with_ic_charge_event(self):
- cardNo = self.event_data['card_no']
- card = self.update_card_dealer_and_type(cardNo, 'IC')
- if not card:
- return self.deviceAdapter.response_card_charge_result(self.event_data['card_no'], card_not_in_db)
- elif card.frozen:
- return self.deviceAdapter.response_card_charge_result(self.event_data['card_no'], card_is_forzen)
- preBalance = card.balance
- rechargeOrder = CardRechargeOrder.get_last_to_do_one(str(card.id))
- if rechargeOrder:
- self.recharge_ic_card(card=card,
- preBalance=preBalance,
- rechargeType='append',
- order=rechargeOrder,
- need_verify=False)
- else:
- return self.deviceAdapter.response_card_charge_result(self.event_data['card_no'], card_has_not_order)
- def recharge_ic_card(self, card, preBalance, rechargeType, order, need_verify=True):
- # type:(Card, RMB, str, CardRechargeOrder, bool)->bool
- """
- # rechargeType有两种,一种是用直接覆写overwrite的方式,一种是append追加钱的方式。
- # 不同的的设备,充值的方式还不一样.注意:money是实际用户付的钱,coins是给用户充值的钱,比如付10块(money),充15(coins)。
- :param card:
- :param preBalance:
- :param rechargeType:
- :param order:
- :return:
- """
- if not order or order.coins == RMB(0):
- return False
- status = Card.get_card_status(str(card.id))
- if status == 'busy':
- return False
- Card.set_card_status(str(card.id), 'busy')
- try:
- # IC卡需要下发到设备,设备写卡,把余额打入卡中
- if rechargeType == 'overwrite':
- sendMoney = preBalance + order.coins
- else:
- sendMoney = order.coins
- # 先判断order最近一次充值是否OK. 满足三个条件才认为上次充值成功:
- # 1、操作时间已经超过三天
- # 2、操作结果是串口超时, 即result == 1
- # 3、当前余额大于最后一次充值操作的充值前余额
- if need_verify and len(order.operationLog) > 0:
- log = order.operationLog[-1]
- result = log['result']
- time_delta = (datetime.datetime.now() - log['time']).total_seconds()
- last_pre_balance = RMB(log['preBalance'])
- if (result == ErrorCode.DEVICE_CONN_FAIL or result == ErrorCode.BOARD_UART_TIMEOUT) \
- and (time_delta > 3 * 24 * 3600 or preBalance > last_pre_balance):
- logger.debug('{} recharge verify result is finished.'.format(repr(card)))
- order.update_after_recharge_ic_card(device=self.device,
- sendMoney=sendMoney,
- preBalance=preBalance,
- result=ErrorCode.SUCCESS,
- description=u'充值校验结束')
- CardRechargeRecord.add_record(
- card=card,
- group=Group.get_group(order.groupId),
- order=order,
- device=self.device)
- return False
- try:
- operation_result, balance = self.deviceAdapter.recharge_card(card.cardNo, sendMoney,
- orderNo=str(order.id))
- order.update_after_recharge_ic_card(device=self.device,
- sendMoney=sendMoney,
- preBalance=preBalance,
- syncBalance=balance,
- result=operation_result['result'],
- description=operation_result['description'])
- if operation_result['result'] != ErrorCode.SUCCESS:
- return False
- if not balance:
- balance = preBalance + order.coins
- CardRechargeRecord.add_record(
- card=card,
- group=Group.get_group(order.groupId),
- order=order,
- device=self.device)
- # 刷新卡里面的余额
- card.balance = balance
- card.lastMaxBalance = balance
- card.save()
- return True
- except Exception as e:
- order.update_after_recharge_ic_card(device=self.device,
- sendMoney=sendMoney,
- preBalance=preBalance,
- syncBalance=balance,
- result=ErrorCode.EXCEPTION,
- description=e.message)
- return False
- except Exception as e:
- logger.exception(e)
- return False
- finally:
- Card.set_card_status(str(card.id), 'idle')
- def response_id_card(self):
- cardNo = self.event_data['card_no']
- Card.record_dev_card_no(self.device['devNo'], cardNo)
- card = Card.objects.filter(cardNo=cardNo, agentId=self.device.owner.agentId).first()
-
- # 如果没有卡,直接返回
- if card is None:
- return self.deviceAdapter.response_card_balance(cardNo=cardNo, balance=0, result=card_not_in_db, amount=0)
-
- if card.cardType == '':
- card.update(cardType='ID')
- elif card.cardType != 'ID': # 如果以前是离线卡,只能用于离线卡,需要提醒用户
- return self.deviceAdapter.response_card_balance(cardNo=cardNo, balance=0, result=card_type_is_ic, amount=0)
-
- if card.frozen:
- return self.deviceAdapter.response_card_balance(cardNo=cardNo, balance=0, result=card_is_forzen, amount=0)
- card_recharge_order = CardRechargeOrder.get_last_to_do_one(str(card.id))
- if card_recharge_order:
- result = self.recharge_id_card(card=card,
- rechargeType='append',
- order=card_recharge_order)
- card.reload()
- oper = self.event_data.get('reduce')
- fee = RMB(self.device['otherConf'].get('id_card_oncefee', 1))
- if oper:
- if card.balance >= fee:
- result = card_is_normal
- balance = card.balance - fee
- # balance = card.showBalance * 100
- else:
- result = card_less_balance
- # balance = card.showBalance * 100
- balance = card.balance
- self.deviceAdapter.response_card_balance(cardNo, fee, balance, result) # 返回的cardNo为16进制
- else:
- self.deviceAdapter.response_card_balance(cardNo, fee, card.balance, card_is_normal)
|