# coding=utf-8 import typing from apilib.monetary import RMB from apps.web.report.ledger import LedgerConsumeOrder from collections import namedtuple from apps.web.dealer.proxy import DealerGroupStats if typing.TYPE_CHECKING: from apps.web.dealer.models import Dealer, DealerDict class Stats(namedtuple("Stats", ["amount", "bestowAmount", "profit", "elecFee", "orderCount", "elecCount", "duration"])): def as_dict(self): return self._asdict() class LedgerStatsCalculator(object): """ 分润统计计算器 """ def __init__(self, orders, dealer): # type:(list, Dealer) -> None self._orders = orders self._dealer = dealer def calculate(self): # type:() -> Stats amount = RMB(0) bestowAmount = RMB(0) profit = RMB(0) elecFee = RMB(0) orderCount = 0 elecCount = 0.0 duration = 0 for _order in self._orders: # type: DealerGroupStats amount += _order.amount bestowAmount += _order.bestowAmount orderCount += _order.orderCount elecCount += _order.elecCount duration += _order.duration elecFee += _order.group.elecFee * _order.elecCount if _order.is_ledgered: partition = _order.ledger.partition else: partition = LedgerConsumeOrder(_order).get_partition_map() profit += self._get_profit_by_partition(partition) return Stats( amount=amount, bestowAmount=bestowAmount, profit=profit, elecFee=elecFee, orderCount=orderCount, elecCount=elecCount, duration=duration ) def _get_profit_by_partition(self, partition): # type: (list) -> RMB """ [ { "role" : "partner", "share" : NumberDecimal("20"), "id" : "62188d6f1bab8edffc4d88af", "elecFee" : NumberDecimal("2.00"), "money" : NumberDecimal("-0.40") }, { "role" : "owner", "share" : NumberDecimal("80"), "id" : "62188a891bab8edffc4d88ad", "money" : NumberDecimal("-1.60") } ] """ for _item in partition: if _item["id"] == str(self._dealer.id): item = _item break else: item = None if not item: return RMB(0) return RMB(item.get("money", RMB(0))) + RMB(item.get("elecFee", RMB(0))) def get_stats(date, groupIds): """ 获取统计记录 """ return DealerGroupStats.objects.filter( date=date, groupId__in=groupIds )