upgrade_reactor_withdraw.py 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. """
  4. 将重复的用户按组归并
  5. """
  6. import datetime
  7. import os
  8. import sys
  9. import mongoengine
  10. from bson import ObjectId
  11. from mongoengine import StringField, ReferenceField, IntField, DateTimeField, BooleanField, EmbeddedDocument
  12. from typing import Union
  13. PROJECT_ROOT = os.path.join(os.path.abspath(os.path.split(os.path.realpath(__file__))[0] + "/.."), '..')
  14. sys.path.insert(0, PROJECT_ROOT)
  15. import os
  16. os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'configs.production')
  17. from script.base import init_env
  18. init_env(interactive = False)
  19. from apps.web.agent.define import AGENT_INCOME_TYPE
  20. from apps.web.core.db import MonetaryField, Searchable
  21. from apps.web.common.models import WithdrawRecord, Balance
  22. from apps.web.constant import Const
  23. from apps.web.core import ROLE
  24. from apps.web.common.transaction import WithdrawStatus, WITHDRAW_PAY_TYPE
  25. from apps.web.agent.models import Agent
  26. from apps.web.core.models import WechatPayApp, AliApp, BankCard
  27. from apilib.monetary import Ratio, RMB
  28. from apps.web.dealer.define import DEALER_INCOME_TYPE
  29. from apps.web.dealer.models import Dealer, Merchant
  30. from apps.web.core.payment.wechat import WechatPaymentGateway
  31. class WechatAppOld(EmbeddedDocument):
  32. meta = {
  33. 'abstract': True
  34. }
  35. @property
  36. def occupant(self):
  37. return getattr(self, '__occupant__', None)
  38. @occupant.setter
  39. def occupant(self, occupant):
  40. setattr(self, '__occupant__', occupant)
  41. class AliAppOld(WechatAppOld):
  42. meta = {'abstract': True}
  43. @property
  44. def alipay_enable(self):
  45. return getattr(self, '__alipay_enable__')
  46. @alipay_enable.setter
  47. def aplipay_eable(self, alipay_enable):
  48. setattr(self, '__alipay_enable__', alipay_enable)
  49. class _WechatMiniApp(WechatAppOld):
  50. appid = StringField(verbose_name = 'appid', null = False)
  51. secret = StringField(verbose_name = "secretId", null = False, max_length = 32)
  52. mchid = StringField(verbose_name = 'mchid', null = False)
  53. apikey = StringField(verbose_name = 'apikey', null = False)
  54. sslcert_path = StringField(verbose_name = '证书pem格式', null = False)
  55. sslkey_path = StringField(verbose_name = '证书密钥pem格式', null = False)
  56. manual_withdraw = BooleanField(verbose_name = u'是否手动提现', default = False)
  57. def __repr__(self):
  58. return '<WechatMiniPaymentApp appid=%s, mchid=%s>' % (self.appid, self.mchid)
  59. def to_dict(self):
  60. return {
  61. 'appid': self.appid,
  62. 'secret': self.secret,
  63. 'mchid': self.mchid,
  64. 'apikey': self.apikey,
  65. 'sslcert_path': self.sslcert_path,
  66. 'sslkey_path': self.sslkey_path,
  67. 'manual_withdraw': self.manual_withdraw
  68. }
  69. @property
  70. def valid(self):
  71. return self.appid and self.secret and self.mchid and self.sslkey_path and self.sslcert_path and self.apikey
  72. @staticmethod
  73. def get_null_app():
  74. return _WechatMiniApp(appid = '', secret = '', mchid = '', apikey = '', sslcert_path = '', sslkey_path = '')
  75. def __eq__(self, other):
  76. # type: (Union[WechatPayApp, _WechatPaymentApp, _WechatMiniApp])->bool
  77. if not isinstance(other, WechatPayApp) \
  78. and not isinstance(other, _WechatPaymentApp) \
  79. and isinstance(other, _WechatMiniApp):
  80. return False
  81. if other.appid != self.appid:
  82. return False
  83. if other.mchid != self.mchid:
  84. return False
  85. if other.secret != self.secret:
  86. return False
  87. if other.apikey != self.apikey:
  88. return False
  89. if other.sslcert_path != self.sslcert_path:
  90. return False
  91. if other.sslkey_path != self.sslkey_path:
  92. return False
  93. return True
  94. class _WechatPaymentApp(WechatAppOld):
  95. appid = StringField(verbose_name = 'appid', null = False)
  96. secret = StringField(verbose_name = "secretId", null = False, max_length = 32)
  97. mchid = StringField(verbose_name = 'mchid', null = False)
  98. apikey = StringField(verbose_name = 'apikey', null = False)
  99. sslcert_path = StringField(verbose_name = '证书pem格式', null = False)
  100. sslkey_path = StringField(verbose_name = '证书密钥pem格式', null = False)
  101. rootca_path = StringField(verbose_name = 'CA证书')
  102. manual_withdraw = BooleanField(verbose_name = u'是否手动提现', default = False)
  103. def __repr__(self):
  104. return '<WechatPaymentApp appid=%s>' % (self.appid,)
  105. def to_dict(self):
  106. def encrypt(url): return '******' if url else ''
  107. return {
  108. 'appid': self.appid,
  109. 'secret': self.secret,
  110. 'mchid': self.mchid,
  111. 'apikey': self.apikey,
  112. 'sslcert_path': self.sslcert_path,
  113. 'sslkey_path': self.sslkey_path,
  114. 'rootca_path': self.rootca_path,
  115. }
  116. @property
  117. def valid(self):
  118. return self.appid and self.secret and self.mchid and self.sslkey_path and self.sslcert_path and self.apikey
  119. @staticmethod
  120. def get_null_app():
  121. return _WechatPaymentApp(appid = '', secret = '', mchid = '',
  122. apikey = '',
  123. sslcert_path = '', sslkey_path = '',
  124. rootca_path = '', manual_withdraw = False)
  125. def __eq__(self, other):
  126. # type: (Union[WechatPayApp, _WechatPaymentApp, _WechatMiniApp])->bool
  127. if not isinstance(other, WechatPayApp) \
  128. and not isinstance(other, _WechatPaymentApp) \
  129. and isinstance(other, _WechatMiniApp):
  130. return False
  131. if other.appid != self.appid:
  132. return False
  133. if other.mchid != self.mchid:
  134. return False
  135. if other.secret != self.secret:
  136. return False
  137. if other.apikey != self.apikey:
  138. return False
  139. if other.sslcert_path != self.sslcert_path:
  140. return False
  141. if other.sslkey_path != self.sslkey_path:
  142. return False
  143. return True
  144. class _AliPaymentApp(AliAppOld):
  145. appid = StringField(verbose_name = '支付宝appid', default = '')
  146. public_key_path = StringField(verbose_name = '支付宝账户公钥', default = '')
  147. alipayPublicKeyContent = StringField(verbose_name = '支付宝公钥文本')
  148. appPublicKeyContent = StringField(verbose_name = '应用公钥文本')
  149. app_private_key_path = StringField(verbose_name = '支付宝应用私钥', default = '')
  150. shadow = BooleanField(verbose_name = u'是否沙箱版本支付宝', default = False)
  151. def __repr__(self):
  152. return '<AliPaymentApp appid=%s>' % (self.appid,)
  153. def to_dict(self):
  154. return {
  155. 'appid': self.appid,
  156. 'public_key_path': self.public_key_path,
  157. 'hasAlipayAppKeyPair': bool(self.app_private_key_path is not ''),
  158. 'alipayPublicKeyContent': self.alipayPublicKeyContent,
  159. 'appPublicKeyContent': self.appPublicKeyContent,
  160. 'app_private_key_path': self.app_private_key_path,
  161. 'debug': self.shadow
  162. }
  163. @staticmethod
  164. def get_null_app():
  165. return _AliPaymentApp(appid = '', public_key_path = '', app_private_key_path = '', shadow = False)
  166. @property
  167. def valid(self):
  168. return self.appid and self.public_key_path and self.app_private_key_path
  169. @property
  170. def alipay_enable(self):
  171. return getattr(self, '__alipay_enable__')
  172. @alipay_enable.setter
  173. def aplipay_eable(self, alipay_enable):
  174. setattr(self, '__alipay_enable__', alipay_enable)
  175. def __eq__(self, other):
  176. # type: (Union[_AliPaymentApp, AliApp])->bool
  177. if not isinstance(other, _AliPaymentApp) and not isinstance(other, AliApp):
  178. return False
  179. if other.appid != self.appid:
  180. return False
  181. if other.app_private_key_path != self.app_private_key_path:
  182. return False
  183. if other.public_key_path != self.public_key_path:
  184. return False
  185. return True
  186. class AgentWithdrawRecord(Searchable):
  187. """
  188. status:
  189. 0 <==> '已提交申请'
  190. 1 <==> '提现成功'
  191. 2 <==> '处理中'
  192. 3 <==> '提现失败'
  193. """
  194. ownerId = StringField(verbose_name = "代理商id")
  195. phone = StringField(verbose_name = "持卡人电话", default = "")
  196. payType = StringField(verbose_name = "支付方式", default = "")
  197. agentName = StringField(verbose_name = "代理商姓名", default = "")
  198. cardUserName = StringField(verbose_name = "持卡人姓名", default = "")
  199. agentBalance = MonetaryField(verbose_name = "代理商当前余额", default = RMB('0.00'))
  200. accountCode = StringField(verbose_name = "提现银行卡号", default = "")
  201. order = StringField(verbose_name = "订单号", default = "")
  202. amount = MonetaryField(verbose_name = "提现金额", default = RMB('0.00'))
  203. serviceFee = MonetaryField(verbose_name = "服务费", default = RMB('0.00'))
  204. actualPay = MonetaryField(verbose_name = "实际金额", default = RMB('0.00'))
  205. withdrawBankCard = ReferenceField(BankCard)
  206. status = IntField(verbose_name = "状态", default = WithdrawStatus.SUBMITTED)
  207. remarks = StringField(verbose_name = "备注", default = "")
  208. postTime = DateTimeField(verbose_name = "请求时间", default = datetime.datetime.now)
  209. finishedTime = StringField(verbose_name = "完成时间", default = "")
  210. parentBankName = StringField(verbose_name = "银行名称", default = "")
  211. subBankName = StringField(verbose_name = "银行支行名称", default = "")
  212. meta = {
  213. 'indexes': ['ownerId'],
  214. 'collection': 'AgentWithdrawRecord',
  215. 'db_alias': 'default'
  216. }
  217. def do_error():
  218. WithdrawRecord._meta.update({'auto_create_index': False})
  219. for record in WithdrawRecord.objects.filter(order = None): # type: WithdrawRecord
  220. record.order = WithdrawRecord.make_no(ROLE.dealer, record.ownerId)
  221. record.withdrawGatewayKey = ''
  222. record.save()
  223. duplicate_records = WithdrawRecord.get_collection().aggregate([
  224. {'$group': {
  225. '_id': {'firstField': "$order"},
  226. 'uniqueIds': {'$addToSet': "$_id"},
  227. 'count': {'$sum': 1}
  228. }},
  229. {'$match': {
  230. 'count': {'$gt': 1}
  231. }}
  232. ], allowDiskUse = True)
  233. for duplicate_record in duplicate_records:
  234. if duplicate_record['count'] >= 2:
  235. print "duplicate ids = %s" % str(duplicate_record['uniqueIds'])
  236. WithdrawRecord.get_collection().remove(
  237. {'_id': {'$in': duplicate_record['uniqueIds'][0:duplicate_record['count'] - 1]}})
  238. WithdrawRecord._meta.update({'auto_create_index': True})
  239. def fill_agent():
  240. def reactor_app(agent):
  241. __modified = False
  242. if agent.customizedWechatCashflowAllowable:
  243. wechat_app = getattr(agent, 'wechatPayApp', None)
  244. if not wechat_app:
  245. print 'configure error for no wechat. agent = {agentId}'.format(agentId = str(agent.id))
  246. else:
  247. wechat_app = _WechatPaymentApp(**dict(wechat_app)) # type: _WechatPaymentApp
  248. if not wechat_app.valid:
  249. print 'configure error for invalid wechat. agent = {agentId}'.format(agentId = str(agent.id))
  250. else:
  251. db_app = WechatPayApp.objects(appid = wechat_app.appid,
  252. mchid = wechat_app.mchid).first() # type: WechatPayApp
  253. if not db_app:
  254. pay_app = WechatPayApp(**wechat_app.to_dict()).save() # type: WechatPayApp
  255. agent.payAppWechat = pay_app
  256. __modified = True
  257. elif wechat_app == db_app:
  258. agent.payAppWechat = db_app
  259. __modified = True
  260. else:
  261. print 'configure error for wechat not equal db. appid = {appid}, mchid = {mchid}'.format(
  262. appid = wechat_app.appid,
  263. mchid = wechat_app.mchid)
  264. else:
  265. # print 'not customize wechat app. id = %s' % str(agent.id)
  266. return
  267. if agent.customizedAlipayCashflowAllowable:
  268. ali_app = getattr(agent, 'aliPayApp', None)
  269. if not ali_app:
  270. print 'configure error for no ali. agent = {agentId}'.format(agentId = str(agent.id))
  271. else:
  272. ali_app = _AliPaymentApp(**dict(ali_app)) # type: _AliPaymentApp
  273. if not ali_app.valid:
  274. print 'configure error for invalid ali. agent = {agentId}'.format(agentId = str(agent.id))
  275. else:
  276. db_app = AliApp.objects(appid = ali_app.appid).first() # type: AliApp
  277. if not db_app:
  278. pay_app = AliApp(appid = ali_app.appid,
  279. public_key_path = ali_app.public_key_path,
  280. alipayPublicKeyContent = ali_app.alipayPublicKeyContent,
  281. appPublicKeyContent = ali_app.appPublicKeyContent,
  282. app_private_key_path = ali_app.app_private_key_path,
  283. shadow = ali_app.shadow).save() # type: AliApp
  284. agent.payAppAli = pay_app
  285. __modified = True
  286. elif ali_app == db_app:
  287. agent.payAppAli = db_app
  288. __modified = True
  289. else:
  290. print 'configure error for ali not equal db. ali appid = {appid}'.format(appid = ali_app.appid)
  291. def reactor_pay_openid(agent):
  292. payOpenId = getattr(agent, 'payOpenId', '')
  293. payAppId = getattr(agent, 'payAppId', '')
  294. if payAppId and payOpenId:
  295. agent.set_bound_pay_openid(payAppId, openId = payOpenId)
  296. def reactor_balance(agent):
  297. try:
  298. custom_gateway_key = WechatPaymentGateway(agent.wechat_agent_pay_app).key
  299. platform_gateway_key = WechatPaymentGateway(agent.platform_wechat_pay_app).key
  300. agent.adBalance = {platform_gateway_key: Balance(balance = RMB(0), frozenBalance = RMB(0))}
  301. agent.trafficBalance = {platform_gateway_key: Balance(balance = RMB(0), frozenBalance = RMB(0))}
  302. agent.deviceBalance = {custom_gateway_key: Balance(balance = RMB(0), frozenBalance = RMB(0))}
  303. agent.withdrawBalance = {custom_gateway_key: Balance(balance = RMB(0), frozenBalance = RMB(0))}
  304. balance = RMB(getattr(agent, 'balance', '0.00'))
  305. if balance <= RMB('0.00'):
  306. return
  307. ad = RMB(getattr(agent.incomeMap, 'ad', 0))
  308. sim = RMB(getattr(agent.incomeMap, 'dealer_card_fee', 0))
  309. withdraw = RMB(getattr(agent.incomeMap, 'dealer_withdraw_fee', 0))
  310. device = RMB(getattr(agent.incomeMap, 'dealer_device_fee', 0))
  311. if ad > RMB(0) and sim == RMB(0) and withdraw == RMB(0) and device == RMB(0):
  312. agent.adBalance = {platform_gateway_key: Balance(balance = balance, frozenBalance = RMB(0))}
  313. return
  314. if sim > RMB(0) and ad == RMB(0) and withdraw == RMB(0) and device == RMB(0):
  315. agent.trafficBalance = {platform_gateway_key: Balance(balance = balance, frozenBalance = RMB(0))}
  316. return
  317. if withdraw > RMB(0) and sim == RMB(0) and ad == RMB(0) and device == RMB(0):
  318. agent.withdrawBalance = {custom_gateway_key: Balance(balance = balance, frozenBalance = RMB(0))}
  319. return
  320. if device > RMB(0) and sim == RMB(0) and withdraw == RMB(0) and ad == RMB(0):
  321. agent.deviceBalance = {custom_gateway_key: Balance(balance = balance, frozenBalance = RMB(0))}
  322. return
  323. agent.withdrawBalance = {custom_gateway_key: Balance(balance = balance, frozenBalance = RMB(0))}
  324. return
  325. except Exception, e:
  326. print 'exception = %s. id = %s' % (str(e), str(agent.id))
  327. agents = [agent for agent in Agent.objects.all()]
  328. for agent in agents:
  329. reactor_app(agent)
  330. reactor_balance(agent)
  331. reactor_pay_openid(agent)
  332. agent.save()
  333. def rename_dealer_withdraw_record():
  334. WithdrawRecord.get_collection().update({}, {'$set': {'role': ROLE.dealer, 'withdrawGatewayKey': ''},
  335. '$unset': {'finishedTime': None},
  336. '$rename': {"dealerName": "name", "dealerBalance": "balance",
  337. "userTel": "phone"}}, upsert = False, multi = True)
  338. def fill_agent_withdraw_reord():
  339. records = [record for record in AgentWithdrawRecord.objects.all()]
  340. for record in records:
  341. fund_map = {
  342. 'amount': RMB(record.amount).mongo_amount,
  343. 'serviceFee': RMB(record.amount).mongo_amount,
  344. 'actualPay': RMB(record.actualPay).mongo_amount
  345. }
  346. agent = Agent.objects(id = str(record.ownerId)).first()
  347. if not agent:
  348. print 'agent is not exist. id = %s' % (str(agent.id))
  349. continue
  350. withdraw_gateway = WechatPaymentGateway(agent.wechat_agent_pay_app)
  351. if record.payType not in [WITHDRAW_PAY_TYPE.WECHAT, WITHDRAW_PAY_TYPE.BANK]:
  352. print 'pay type is invalid. id = %s' % (str(agent.id))
  353. continue
  354. pay_entity = BankCard(
  355. cardNo = record.accountCode,
  356. holderName = record.cardUserName,
  357. bankName = record.parentBankName,
  358. branchName = record.subBankName
  359. )
  360. while True:
  361. try:
  362. WithdrawRecord.create(agent,
  363. withdraw_gateway,
  364. pay_entity,
  365. AGENT_INCOME_TYPE.DEALER_WITHDRAW_FEE,
  366. record.payType,
  367. fund_map,
  368. False,
  369. False,
  370. **{
  371. 'balance': record.agentBalance,
  372. 'withdrawFeeRatio': Ratio(Const.PLATFORM_DEFAULT_WITHDRAW_FEE_RATIO),
  373. # 'order': record.order,
  374. 'ownerId': record.ownerId,
  375. 'name': record.agentName,
  376. 'phone': record.phone,
  377. 'partition': [],
  378. 'status': record.status,
  379. 'postTime': record.postTime
  380. })
  381. break
  382. except mongoengine.errors.NotUniqueError:
  383. print 'unique error'
  384. except Exception, e:
  385. print 'create agent withdraw record exception = %s; agentId = %s' % (e, str(agent.id))
  386. def fill_dealer_withdraw_record():
  387. records = WithdrawRecord.objects.filter(role = ROLE.dealer)
  388. for record in records: # type: WithdrawRecord
  389. if not record.ownerId:
  390. print 'has no dealer id. record = %s' % str(record.id)
  391. dealer = None # type: Dealer
  392. else:
  393. dealer = Dealer.objects(id = str(record.ownerId)).first() # type: Dealer
  394. if not dealer:
  395. print 'dealer is none. id = %s' % record.ownerId
  396. else:
  397. try:
  398. app = dealer_withdraw_device_app(dealer)
  399. if app:
  400. record.withdrawGatewayKey = WechatPaymentGateway(app).key
  401. except Exception, e:
  402. print 'dealer not belong to agent. dealerId = %s' % str(dealer.id)
  403. record.incomeType = DEALER_INCOME_TYPE.DEVICE_INCOME
  404. record.finishedTime = record.postTime
  405. extras = {}
  406. merchantId = getattr(record, 'merchantId', None)
  407. # 没有payType的时候, 记录merchantId; 有payType, accountCode记录银行卡卡号或者微信openid
  408. payType = getattr(record, 'payType', '')
  409. if not payType:
  410. if merchantId:
  411. payType = WITHDRAW_PAY_TYPE.BANK
  412. extras['withdrawBankCard'] = ObjectId(merchantId)
  413. bank_card = Merchant.objects(id = str(merchantId)).first() # type: Merchant
  414. if not bank_card:
  415. print 'has not no account code. record = %s' % str(record.id)
  416. else:
  417. if not record.accountCode:
  418. record.accountCode = bank_card.accountCode
  419. if not record.cardUserName:
  420. if dealer:
  421. record.cardUserName = dealer.nickname
  422. if not record.cardUserName:
  423. record.cardUserName = bank_card.merchantName
  424. if not record.parentBankName:
  425. record.parentBankName = bank_card.parentBankName
  426. if not record.subBankName:
  427. record.subBankName = bank_card.subBankName
  428. else:
  429. payType = WITHDRAW_PAY_TYPE.WECHAT
  430. if not record.accountCode:
  431. if dealer:
  432. record.accountCode = getattr(dealer, 'payOpenId', '')
  433. if not record.cardUserName:
  434. if dealer:
  435. record.cardUserName = dealer.nickname
  436. else:
  437. record.cardUserName = u'我'
  438. if not record.parentBankName:
  439. record.parentBankName = u'微信'
  440. if not record.subBankName:
  441. record.subBankName = u'微信企业付款'
  442. record.payType = payType
  443. else:
  444. payType = getattr(record, 'payType', '')
  445. if payType != WITHDRAW_PAY_TYPE.WECHAT:
  446. if not record.accountCode:
  447. print 'has not no account code. record = %s' % str(record.id)
  448. else:
  449. bank_card = Merchant.objects(accountCode = record.accountCode).first() # type: Merchant
  450. if not bank_card:
  451. print 'bank card is null. bank = %s; record = %s' % (str(record.accountCode), str(record.id))
  452. else:
  453. extras['withdrawBankCard'] = ObjectId(str(bank_card.id))
  454. if not record.cardUserName:
  455. record.cardUserName = bank_card.merchantName
  456. if not record.parentBankName:
  457. record.parentBankName = bank_card.parentBankName
  458. if not record.subBankName:
  459. record.subBankName = bank_card.subBankName
  460. if not record.name or not record.phone:
  461. if dealer:
  462. record.name = dealer.nickname
  463. record.phone = dealer.username
  464. old_withdrawFee = int(getattr(record, 'withdrawRatio', 0))
  465. if old_withdrawFee != 0:
  466. new_withdrawFeeRatio = Ratio(old_withdrawFee)
  467. else:
  468. if dealer:
  469. new_withdrawFeeRatio = Ratio(dealer.withdrawFeeRatio)
  470. else:
  471. new_withdrawFeeRatio = Ratio(Const.PLATFORM_DEFAULT_WITHDRAW_FEE_RATIO)
  472. # 计算提现收益分配
  473. if new_withdrawFeeRatio > Ratio(Const.PLATFORM_DEFAULT_WITHDRAW_FEE_RATIO):
  474. if dealer:
  475. agent_fee_ratio = (new_withdrawFeeRatio - Ratio(Const.PLATFORM_DEFAULT_WITHDRAW_FEE_RATIO))
  476. earned = record.amount * (agent_fee_ratio / Const.WITHDRAW_FEE_UNIT)
  477. partition = [
  478. {'role': 'agent', 'id': dealer.agentId, 'ratio': agent_fee_ratio.mongo_amount,
  479. 'earned': earned.mongo_amount}
  480. ]
  481. record.partition = partition
  482. if record.payType == WITHDRAW_PAY_TYPE.WECHAT:
  483. if record.status == WithdrawStatus.FAILED:
  484. record.refunded = True
  485. record.status = WithdrawStatus.CLOSED
  486. elif record.status == WithdrawStatus.CLOSED and not record.refunded:
  487. record.refunded = True
  488. else:
  489. pass
  490. record.extras = extras
  491. record.save()
  492. def fill_dealer():
  493. try:
  494. print 'unset role...'
  495. Dealer.get_collection().update_many({}, {'$unset': {'role': ''}}, upsert = False)
  496. print 'fill dealers...'
  497. dealers = Dealer.objects.all()
  498. for dealer in dealers: # type: Dealer
  499. try:
  500. origin_balance = getattr(dealer, 'balance', RMB('0.00')) # type: RMB
  501. app = dealer_withdraw_device_app(dealer)
  502. if not app:
  503. print 'no app. id = %s' % str(dealer.id)
  504. continue
  505. key = WechatPaymentGateway(app).key
  506. dealer.deviceBalance = {
  507. key: Balance(balance = origin_balance, frozenBalance = RMB('0.00'))
  508. }
  509. dealer.adBalance = {
  510. key: Balance(balance = RMB('0.00'), frozenBalance = RMB('0.00'))
  511. }
  512. payOpenId = getattr(dealer, 'payOpenId', '')
  513. payAppId = getattr(dealer, 'payAppId', '')
  514. if payOpenId and payAppId:
  515. dealer.set_bound_pay_openid(payAppId, openId = payOpenId)
  516. inHouseAppId = getattr(dealer, 'inHouseAppId', '')
  517. inHouseOpenId = getattr(dealer, 'inHouseOpenId', '')
  518. if inHouseAppId and inHouseOpenId:
  519. dealer.set_bound_pay_openid(inHouseAppId, openId = inHouseOpenId)
  520. dealer.save()
  521. except Exception, e:
  522. print 'exception = %s; dealer id = %s' % (str(e), str(dealer.id))
  523. return dealers
  524. except Exception, e:
  525. print 'fill_dealer exception = %s' % str(e)
  526. def check_dealer():
  527. dealers = Dealer.objects.all()
  528. for dealer in dealers: # type: Dealer
  529. old_balance = RMB(getattr(dealer, 'balance', '0.00'))
  530. new_total_balance = dealer.total_balance
  531. new_device_balance = dealer.sub_balance(DEALER_INCOME_TYPE.DEVICE_INCOME)
  532. assert old_balance <= new_total_balance, 'total balace error. id = %s' % (str(dealer.id))
  533. assert old_balance <= new_device_balance, 'device balace error. id = %s' % (str(dealer.id))
  534. new_gateway_keys = dealer.deviceBalance.keys()
  535. assert len(new_gateway_keys) < 2, 'len gateway key errror. id = %s' % (str(dealer.id))
  536. if new_total_balance == RMB(0):
  537. assert len(new_gateway_keys) == 0, 'len gateway key errror2. id = %s' % (str(dealer.id))
  538. else:
  539. assert len(new_gateway_keys) == 1, 'len gateway key errror2. id = %s' % (str(dealer.id))
  540. if len(new_gateway_keys) == 1:
  541. app = get_dealer_pay_wechat_app(dealer)
  542. old_gateway_key = WechatPaymentGateway(app).key
  543. assert old_gateway_key == new_gateway_keys[0], 'len gateway key errror3. id = %s' % (str(dealer.id))
  544. payOpenId = getattr(dealer, 'payOpenId', '')
  545. payAppId = getattr(dealer, 'payAppId', '')
  546. for appid, bound_info in dealer.payOpenIdMap.iteritems():
  547. assert appid, 'pay open id error 1. id = %s' % (str(dealer.id))
  548. assert bound_info, 'pay open id error 2. id = %s' % (str(dealer.id))
  549. assert bound_info.openId, 'pay open id error 3. id = %s' % (str(dealer.id))
  550. if payOpenId and payAppId:
  551. assert payAppId in dealer.payOpenIdMap, 'pay open id error 4. id = %s' % (str(dealer.id))
  552. assert payOpenId == dealer.payOpenIdMap[payAppId].openId, 'pay open id error 4. id = %s' % (str(dealer.id))
  553. inHouseAppId = getattr(dealer, 'inHouseAppId', '')
  554. inHouseOpenId = getattr(dealer, 'inHouseOpenId', '')
  555. if inHouseAppId and inHouseOpenId:
  556. assert inHouseAppId in dealer.payOpenIdMap, 'pay open id error 5. id = %s' % (str(dealer.id))
  557. assert inHouseOpenId == dealer.payOpenIdMap[inHouseAppId].openId, 'pay open id error 6. id = %s' % (str(dealer.id))
  558. def check_agent():
  559. agents = Agent.objects.all()
  560. for agent in agents: # type: Agent
  561. old_balance = RMB(getattr(agent, 'balance', '0.00'))
  562. new_total_balance = agent.total_balance
  563. assert old_balance == new_total_balance, 'total balace error. id = %s' % (str(dealer.id))
  564. def fill_dealer_withdraw_record_2():
  565. records = [record for record in WithdrawRecord.objects.filter(__raw__ = {'payAgentId': {'$exists': False}})]
  566. for record in records: # type: WithdrawRecord
  567. if not record.ownerId:
  568. print 'has no dealer id. record = %s' % str(record.id)
  569. dealer = None # type: Dealer
  570. else:
  571. dealer = Dealer.objects(id = str(record.ownerId)).first() # type: Dealer
  572. if not dealer:
  573. print 'dealer is none. id = %s' % record.ownerId
  574. else:
  575. try:
  576. app = dealer_withdraw_device_app(dealer)
  577. if app:
  578. record.payAgentId = app.occupantId
  579. record.save()
  580. except Exception, e:
  581. print 'dealer not belong to agent. dealerId = %s' % str(dealer.id)
  582. try:
  583. # print 'fill_agent ...'
  584. # fill_agent()
  585. #
  586. # print 'fill_dealer ...'
  587. # fill_dealer()
  588. #
  589. # print 'do_error ...'
  590. # do_error()
  591. #
  592. # print 'rename_dealer_withdraw_record ...'
  593. # rename_dealer_withdraw_record()
  594. #
  595. # print 'fill_dealer_withdraw_record ...'
  596. # fill_dealer_withdraw_record()
  597. #
  598. # print 'fill_agent_withdraw_reord ...'
  599. # fill_agent_withdraw_reord()
  600. fill_dealer_withdraw_record_2()
  601. print 'success over'
  602. except Exception, e:
  603. print 'exception = %s' % str(e)