MProfitRatioCalc.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. from .MerchantCalc import MerchantCalc, mch_detail_paths, mch_paths
  2. from .algorithm import calc_mch_profit
  3. from .DataStream import EMchPosmap as pos_map
  4. from .DataStream import day_stamp
  5. import logging
  6. import time as time
  7. import logging
  8. import json
  9. logger = logging.getLogger('MProfitRatioCalc')
  10. def mixed_ratio(rclient):
  11. result = list()
  12. data = rclient.get('nc_refill-stat-merchant-mixed')
  13. if data is not None:
  14. mch_cfgs = json.loads(data)
  15. for mchid, val in mch_cfgs.items():
  16. mchid = int(mchid)
  17. period = int(val['period'])
  18. formula = val['profit_formula'].strip()
  19. result.append((mchid, period, formula))
  20. return result
  21. class MProfitRatioCalc(MerchantCalc):
  22. def _calc_handler(self, rclient):
  23. logger.debug('_calc_handler')
  24. mixed_ratios = mixed_ratio(rclient)
  25. reader = self._reader()
  26. gross = dict()
  27. detail = dict()
  28. types = dict()
  29. _fix = False
  30. for mchid, period, formula in mixed_ratios:
  31. logger.debug(f'mchid={mchid} period={period}')
  32. end_time = int(time.time())
  33. if period == 86401:
  34. cur_day = day_stamp(end_time)
  35. period = end_time - cur_day
  36. _fix = True
  37. logger.debug(f'mchid={mchid} period={period}')
  38. days, start_time, end_time = self.calc_time(reader, end_time - period, end_time)
  39. if len(days) == 0:
  40. continue
  41. stamp = days[0]
  42. tuple_pathes = reader.many_tuple_path(days, mchids={mchid})
  43. gen = mch_detail_paths(reader, tuple_pathes, days)
  44. start = start_time - stamp
  45. end = end_time - stamp
  46. types_detail = {}
  47. spec_amount = 0.0
  48. for _mchid, _card_type, _spec, _data in gen:
  49. submit_count, succ_count, fail_count, succ_ratio, profit = calc_mch_profit(_data, pos_map, start, end)
  50. if _card_type is None and _spec is None:
  51. if _fix == True and succ_count == 0:
  52. profit += 5
  53. spec_amount += 5
  54. profit_ratio = round(profit / (spec_amount + 0.0000001), 6)
  55. gross[_mchid] = [submit_count, succ_count, fail_count, succ_ratio, profit, profit_ratio]
  56. spec_amount = 0.0
  57. else:
  58. key = f"{_mchid}-{_card_type}-{_spec}"
  59. amount = succ_count * _spec
  60. spec_amount += amount
  61. profit_ratio = round(profit / (amount + 0.0000001), 6)
  62. detail[key] = [submit_count, succ_count, fail_count, succ_ratio, profit, profit_ratio]
  63. if _card_type not in types_detail:
  64. types_detail[_card_type] = []
  65. types_detail[_card_type].append((submit_count, succ_count, fail_count, succ_ratio, profit, profit_ratio, _spec))
  66. _mch_type_detail = self._calc_types_detail(mchid, types_detail)
  67. types.update(_mch_type_detail)
  68. result = {'gross': gross, 'detail': detail, 'types': types}
  69. logger.debug(f'profit_ratio={result}')
  70. if len(gross) != 0 or len(detail) != 0:
  71. rclient.set(f"nc_refill_merchant_profit_ratio", json.dumps(result))
  72. rclient.publish('refill', json.dumps({'type': 'mch_profit_ratio', 'value': 0}))
  73. return 5
  74. def _calc_types_detail(self, _mchid, types_detail):
  75. result = {}
  76. for _card_type, vals in types_detail.items():
  77. key = f'{_mchid}-{_card_type}'
  78. submit_count, succ_count, fail_count, succ_ratio, profit, profit_ratio = 0, 0, 0, 0.0, 0.0, 0.0
  79. spec_amount = 0
  80. for item in vals:
  81. _submit_count, _succ_count, _fail_count, _succ_ratio, _profit, _profit_ratio, _spec = item
  82. submit_count += _submit_count
  83. succ_count += _succ_count
  84. fail_count += _fail_count
  85. profit += _profit
  86. spec_amount += _spec * _succ_count
  87. succ_ratio = round(succ_count / (succ_count + fail_count + 0.0000001), 6)
  88. profit_ratio = round(profit / (spec_amount + 0.000001), 6)
  89. result[key] = [submit_count, succ_count, fail_count, succ_ratio, profit, profit_ratio]
  90. return result