123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- # -*- coding: utf-8 -*-
- import datetime
- import logging
- from mongoengine import DoesNotExist, ValidationError
- from typing import TYPE_CHECKING
- from apps.web.constant import USER_RECHARGE_TYPE
- from apps.web.core.payment import WithdrawGateway
- from apps.web.device.models import Group
- from apps.web.report.ledger import Ledger
- from apps.web.user.models import Card, RechargeRecord
- if TYPE_CHECKING:
- from apps.web.device.models import DeviceDict
- logger = logging.getLogger(__name__)
- class CYConstant(object):
- FINISH_REASON_MAP = {
- '01': '充满电停止',
- '02': '超功率停止',
- '03': '时间用完停止',
- '04': '远程停止',
- '05': '预付卡的扣费金额用完',
- '06': '到达安全充电时间',
- '07': '正常结束充电',
- '09': '电量超限',
- '10': '设备充满停止充电'
- }
- NEED_REFUND = ["01", "04", "05", "06", "07", "10"]
- DEFAULT_DISCOUNT = "0"
- REFUND_PRODUCTION_TIME = 5
- MAX_TEMPERATURE = 70
- MIN_TEMPERATURE = -15
- class FunCode(object):
- # 发送设备事件
- GET_SETTING = "A0"
- SET_SETTING = "A1"
- GET_DEV_INFO = "A2"
- CLEAN_DEV_INFO = "A3"
- REFUND_RECORD = "A4"
- CHARGE_RECORD = "A5"
- CHECK_DEV_STATUS = "A6"
- WEIXIN_PAY_START = "A7"
- START_OR_STOP = "A9"
- CARD_RECHARGR = "AC"
- CARD_BALANCE = "AD"
- STOP_DEV = "AF"
- RESTART = "B0"
- class CmdCode(object):
- # 设备上报事件
- CARD_REFUND = "B3"
- STOP_DEV = "A8"
- DEV_CONNECTED = "AE"
- CARD_PAY_START = "B1"
- HEART_BEAT = "B2"
- class CYCardMixin(object):
- if TYPE_CHECKING:
- @property
- def device(self):
- # type:()->DeviceDict
- return DeviceDict()
- def notify_dealer(self, templateName, **kwargs):
- pass
- def check_card_can_use(self, card): # type:(Card) -> bool
- """
- 对于平台卡检验 的判定
- 返回结果是可用或者不可用
- 注意: 卡是否录入是以经销商录入为标准判定
- 规则是:
- 1.如果校验开关关闭 则都是可用的
- 2.如果校验开关打开 卡录入情况下可用 卡没有录入的情况下不可用
- """
- needBindCard = self.device.otherConf.get("needBindCard", True)
- if not needBindCard:
- return True
- # 剩下的是需要检验的情况
- # 1. 没有绑定
- if not card:
- return False
- # 2. 解除了绑定(经销商绑定的卡会通过检验 经销商绑定的卡是 匿名用户的openId)
- if not card.openId:
- return False
- # 3. 卡被冻结
- if card.frozen:
- return False
- # 4. 地址不通用的情况
- if not Group.is_currency_mode_group(card.groupId, self.device.groupId):
- return False
- return True
- def update_card_dealer_and_type(self, cardNo, cardType='IC', isHaveBalance=True, balance=None):
- """
- 从数据库找卡 主要功能是为没有卡类型的卡添加上卡的类型
- 昌原的卡比较特别 如果是数据库的卡 一定会有dealerId
- """
- from apps.web.agent.models import Agent
- dealer = self.device.owner
- agent = Agent.objects(id = dealer.agentId).first() # type: Agent
- if not agent:
- logger.error('agent is not found, agentId=%s' % dealer.agentId)
- return None
- try:
- card = Card.objects.get(cardNo=cardNo, agentId=str(agent.id))
- # 存在卡的类型 说明已经在数据库中了
- if card.cardType:
- return card
- card.devNo = card.devNo or self.device.devNo
- card.cardType = card.cardType or cardType
- card.isHaveBalance = isHaveBalance
- return card.save()
- except DoesNotExist:
- return None
- except Exception as e:
- logger.error("[CYCardMixin update_card_dealer_and_type] find card error = {}, dev = {}".format(e, self.device.devNo))
- return None
- def notify_invalid_card_to_dealer(self, cardNo, card):
- logger.info('[CYCardMixin notify_invalid_card_to_dealer] Illegal card <{}>, charging is about to stop'.format(cardNo))
- self.notify_dealer(
- 'device_fault',
- title=u'您当前的设备已被非法卡使用!',
- device=u'设备{}-{}'.format(self.device.logicalCode, self.device.groupNumber),
- location=u'地址{}-{}'.format(self.device.group.address, self.device.group.groupName),
- fault="启动卡号为:{} 卡联系人 {} 卡联系电话 {}".format(
- cardNo, card.nickName if card else "", card.phone if card else ""
- ),
- notifyTime=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
- )
- def do_ledger(self, rechargeRcdId):
- logger.info("[{} do_ledger] rechargeId = {}, devNo= {}".format(self.__class__.__name__, rechargeRcdId, self.device.devNo))
- if not rechargeRcdId:
- return
- record = RechargeRecord.objects(id = rechargeRcdId).first() # type: RechargeRecord
- if not record:
- logger.error("dev <{}> don't get a recharge record by id <{}>".format(self.device.devNo, rechargeRcdId))
- return
- if not record.is_success():
- logger.debug('{} state is {}.'.format(str(record), record.result))
- raise ValueError(u'订单不能为未支付状态')
- try:
- if record.is_ledgered:
- logger.debug('{} has been ledgered.'.format(str(record)))
- return record
- ledgerTime = None if (
- not WithdrawGateway.is_ledger(record.withdraw_source_key)) else datetime.datetime.now()
- ledger = Ledger(USER_RECHARGE_TYPE.RECHARGE, record, ledgerTime=ledgerTime)
- ledger.execute(stats=True)
- except DoesNotExist as de:
- logger.error("dev <{}> don't get a recharge record by id <{}>".format(self.device.devNo, rechargeRcdId))
- return
- except ValidationError as ve:
- logger.error("dev <{}> bad a recharge record id <{}>".format(self.device.devNo, rechargeRcdId))
- return
- except Exception as e:
- logger.exception(e)
- return
- # 执行分账成功的情况下 将充值订单返回
- return record
|