123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744 |
- # 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')
- )
|