# -*- coding: utf-8 -*- #!/usr/bin/env python from typing import List, Dict, TYPE_CHECKING from bson.objectid import ObjectId from bson.decimal128 import Decimal128 from apilib.monetary import RMB, Ratio, sum_rmb, sum_ratio from apilib.utils import recursive_repr from apps.web.constant import PARTITION_ROLE if TYPE_CHECKING: from apps.web.device.models import GroupDict class SubIncomePartition(object): def __init__(self, object_id, role, share, money): # type: (ObjectId, str, Ratio, RMB)->None assert isinstance(object_id, ObjectId) assert isinstance(share, Ratio) assert isinstance(money, RMB) assert role in PARTITION_ROLE.choices() self.object_id = object_id # type: ObjectId self.role = role # type: str self.share = share # type: Ratio self.money = money # type: RMB def __repr__(self): return '' % (self.role, self.object_id, self.share, self.money) class GroupIncomePartition(object): def __init__(self, money, agent, owner, partner): # type: (RMB, List[SubIncomePartition], List[SubIncomePartition], List[SubIncomePartition])->None assert isinstance(money, RMB) def check_component(component): # type:(list)->None assert isinstance(component, list), '{0!r} has to be a list'.format(component) if not component: return else: assert all( isinstance(c, SubIncomePartition) for c in component ),\ '{0!r} has to be a list of SubIncomePartition'.format(component) check_component(agent) check_component(owner) check_component(partner) self.money = money # type: List[SubIncomePartition] self.agent = agent # type: List[SubIncomePartition] self.owner = owner # type: List[SubIncomePartition] self.partner = partner assert sum_ratio(_.share for _ in self.whole) == Ratio(100) assert sum_rmb(_.money for _ in self.whole) == money @property def dealer(self): return self.owner + self.partner @property def whole(self): return self.agent + self.dealer @recursive_repr() def __repr__(self): return '{name}(sum={money})(owner={owner}, partner={partner}, agent={agent})'.format( name=self.__class__.__name__, money=self.money, owner=self.owner, partner=self.partner, agent=self.agent ) def dealer_money_map(self): # type: ()->Dict[str, Decimal128] return { str(dealer.object_id): dealer.money.mongo_amount for dealer in self.dealer } def dealer_ids(self): # type: ()->List[ObjectId] return [ _.object_id for _ in self.dealer ] @classmethod def from_ledger(cls, agentId, ownerId, agentProfitShare, group, money): # type: (str, str, float, GroupDict, RMB)->GroupIncomePartition agent_partition = [] owner_partition = [] partner_partition = [] # partners = group.partners() # type:List[dict] # for partner in partners: # share = Ratio() # partner_partition.append( # SubIncomePartition(role='partner', object_id=ObjectId(partner['id']), ))