# coding=utf-8 from typing import TYPE_CHECKING, Optional from mongoengine import Document, StringField, BooleanField, EmbeddedDocumentListField, EmbeddedDocument, DoesNotExist, ListField from apilib.monetary import Percent from apps.web.core.db import PercentField from apps.web.device.models import Group from apps.web.dealer.utils import Dealer if TYPE_CHECKING: from apps.web.device.models import GroupDict class GroupShare(EmbeddedDocument): groupId = StringField(verbose_name=u"地址") isActive = BooleanField(verbose_name=u"是否参与分账", default=True) payElecFee = BooleanField(verbose_name=u"电费支付方", default=False) ratio = PercentField(verbose_name=u"分成百分比", max_value=Percent(100), min_value=Percent(0)) contracts = ListField(verbose_name=u"电子合同") def to_dict(self): return { "groupId": self.groupId, "ratio": self.ratio, "isActive": self.isActive, "payElecFee": self.payElecFee, "contracts": self.contracts or list() } @property def group(self): # type:() -> GroupDict return Group.get_group(self.groupId) def __eq__(self, groupId): """配合for in 使用""" return self.groupId == groupId class Partner(Document): """ 合伙人的关系表 查询表 """ dealerId = StringField(verbose_name=u"经销商ID", required=True) partnerId = StringField(verbose_name=u"合伙人ID[角色为经销商]", required=True) shareGroups = EmbeddedDocumentListField(verbose_name=u"地址分成的数据", document_type=GroupShare, default=list) isDelete = BooleanField(verbose_name=u"绑定关系", default=False) @property def dealer(self): return Dealer.get_dealer(self.dealerId) @property def partner(self): return Dealer.get_dealer(self.partnerId) @classmethod def get_partner(cls, _id): return cls.objects.filter(id=_id, isDelete=False).first() @classmethod def get_partner_by_dealer(cls, dealerId, partnerId): return cls.objects.filter(dealerId=dealerId, partnerId=partnerId, isDelete=False).first() @classmethod def get_partners(cls, dealer, pageIndex=1, pageSize=10): # type:(Dealer, int, int) -> list dCls, result = dealer.__class__, list() for _item in cls.objects.filter(dealerId=str(dealer.id), isDelete=False).skip((pageIndex-1)*pageSize).limit(pageSize): # type: Partner _partner = dCls.get_dealer(_item.partnerId) _temp = { "id": str(_item.id), "partnerId": str(_partner.id), "name": _partner.nickname, "phone": _partner.username, "groupCount": len(_item.shareGroups) } result.append(_temp) return result @classmethod def add_relation(cls, dealer, partner): # type:(Dealer, Dealer) -> Partner try: relation = cls.objects.get(dealerId=str(dealer.id), partnerId=str(partner.id)) except DoesNotExist: return cls(dealerId=str(dealer.id), partnerId=str(partner.id)).save() if relation.isDelete: relation.update(isDelete=False, shareGroups=[]) return relation.reload() raise ValueError(u"请勿重复添加合伙人") @classmethod def delete_relation(cls, dealer, partner): # type:(Dealer, Dealer) -> None try: relation = cls.objects.get(dealerId=str(dealer.id), partnerId=str(partner.id)) # type: Partner except DoesNotExist: raise ValueError(u"未找到合伙人,删除失败") if relation.isDelete: raise ValueError(u"未找到合伙人,删除失败") for _share in relation.shareGroups: # type: GroupShare _share.group.remove_partner(str(partner.id)) relation.update(shareGroups=[], isDelete=True) return def get_partner_groups(self): # type:() -> list result = list() for _share in self.shareGroups: # type: GroupShare _data = _share.to_dict() _group = _share.group _data.update({ "address": _group.address, "groupName": _group.groupName }) result.append(_data) return result def get_share_group(self, groupId): # type:(str) -> Optional[GroupShare, None] for _share in self.shareGroups: if _share.groupId != str(groupId): continue return _share else: return None def add_group_share(self, group, ratio, payElecFee, isActive, contracts): # type:(GroupDict, Percent, bool, bool, list) -> Partner """ 添加组 """ if str(group.id) in self.shareGroups: raise ValueError(u"重复添加") group.update_partner(self.partnerId, ratio, payElecFee, isActive) self.shareGroups.append(GroupShare( groupId=str(group.id), ratio=Percent(ratio), payElecFee=payElecFee, isActive=isActive, contracts=contracts )) return self.save() def update_group_share(self, group, ratio, payElecFee, isActive, contracts): """ 更新组内分成情况 """ share = self.get_share_group(str(group.id)) # type: GroupShare if not share: raise ValueError("当前场地合伙人未参与分成") group.update_partner(self.partnerId, ratio, payElecFee, isActive) share.ratio = ratio share.payElecFee = payElecFee share.isActive = isActive share.contracts = contracts return share._instance.save() def remove_group_share(self, group): """ 删除组 """ if str(group.id) not in self.shareGroups: raise ValueError(u"移除失败,未找到组内合伙人") group.remove_partner(self.partnerId) _share = self.get_share_group(group.groupId) self.shareGroups.remove(_share) return self.save()