utils2.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. # coding=utf-8
  2. import typing
  3. from apilib.monetary import RMB
  4. from apps.web.report.ledger import LedgerConsumeOrder
  5. from collections import namedtuple
  6. from apps.web.dealer.proxy import DealerGroupStats
  7. if typing.TYPE_CHECKING:
  8. from apps.web.dealer.models import Dealer, DealerDict
  9. class Stats(namedtuple("Stats", ["amount", "bestowAmount", "profit", "elecFee", "orderCount", "elecCount", "duration"])):
  10. def as_dict(self):
  11. return self._asdict()
  12. class LedgerStatsCalculator(object):
  13. """
  14. 分润统计计算器
  15. """
  16. def __init__(self, orders, dealer): # type:(list, Dealer) -> None
  17. self._orders = orders
  18. self._dealer = dealer
  19. def calculate(self): # type:() -> Stats
  20. amount = RMB(0)
  21. bestowAmount = RMB(0)
  22. profit = RMB(0)
  23. elecFee = RMB(0)
  24. orderCount = 0
  25. elecCount = 0.0
  26. duration = 0
  27. for _order in self._orders: # type: DealerGroupStats
  28. amount += _order.amount
  29. bestowAmount += _order.bestowAmount
  30. orderCount += _order.orderCount
  31. elecCount += _order.elecCount
  32. duration += _order.duration
  33. elecFee += _order.group.elecFee * _order.elecCount
  34. if _order.is_ledgered:
  35. partition = _order.ledger.partition
  36. else:
  37. partition = LedgerConsumeOrder(_order).get_partition_map()
  38. profit += self._get_profit_by_partition(partition)
  39. return Stats(
  40. amount=amount,
  41. bestowAmount=bestowAmount,
  42. profit=profit,
  43. elecFee=elecFee,
  44. orderCount=orderCount,
  45. elecCount=elecCount,
  46. duration=duration
  47. )
  48. def _get_profit_by_partition(self, partition): # type: (list) -> RMB
  49. """
  50. [
  51. {
  52. "role" : "partner",
  53. "share" : NumberDecimal("20"),
  54. "id" : "62188d6f1bab8edffc4d88af",
  55. "elecFee" : NumberDecimal("2.00"),
  56. "money" : NumberDecimal("-0.40")
  57. },
  58. {
  59. "role" : "owner",
  60. "share" : NumberDecimal("80"),
  61. "id" : "62188a891bab8edffc4d88ad",
  62. "money" : NumberDecimal("-1.60")
  63. }
  64. ]
  65. """
  66. for _item in partition:
  67. if _item["id"] == str(self._dealer.id):
  68. item = _item
  69. break
  70. else:
  71. item = None
  72. if not item:
  73. return RMB(0)
  74. return RMB(item.get("money", RMB(0))) + RMB(item.get("elecFee", RMB(0)))
  75. def get_stats(date, groupIds):
  76. """
  77. 获取统计记录
  78. """
  79. return DealerGroupStats.objects.filter(
  80. date=date,
  81. groupId__in=groupIds
  82. )