# coding=utf-8 import datetime import logging import simplejson as json from mongoengine import DoesNotExist from typing import TYPE_CHECKING from apilib.monetary import Percent from apps.web.constant import Const from apps.web.core import ROLE from apps.web.core.exceptions import InvalidFileSize, InvalidFileName from apps.web.core.file import AliOssFileUploader from apps.web.core.utils import JsonOkResponse, NoCommissionErrorResponse, JsonErrorResponse from apps.web.dealer.models2 import Partner, GroupShare from apps.web.dealer.proxy import DealerGroupStats from apps.web.dealer.utils2 import get_stats, LedgerStatsCalculator from apps.web.device.models import Group from apps.web.utils import permission_required if TYPE_CHECKING: from apps.web.dealer.models import Dealer from apps.web.device.models import GroupDict logger = logging.getLogger(__name__) @permission_required(ROLE.dealer, ROLE.subaccount) def getGroups(request): dealer = request.user.myBoss # type: Dealer groups = Group.get_groups_of_dealer(str(dealer.id)) result = list() for _group in groups: # type: GroupDict _data = { "groupId": str(_group.id), "groupName": _group.groupName, "partnerCount": len(_group.partners) } result.append(_data) return JsonOkResponse(payload={"groups": result}) @permission_required(ROLE.dealer, ROLE.subaccount) def getPartners(request): """ 获取全部的合伙人 """ dealer = request.user.myBoss # type: Dealer pageIndex = request.GET.get("pageIndex", 1) pageSize = request.GET.get("pageSize", 10) result = Partner.get_partners(dealer, int(pageIndex), int(pageSize)) payload = { "dataList": result } return JsonOkResponse(payload=payload) @permission_required(ROLE.dealer, ROLE.subaccount) def addPartner(request): """ 新增合伙人 """ dealer = request.user.myBoss data = json.loads(request.body or "{}") nickname = data.get("name") username = data.get("phone") try: partner = dealer.__class__.objects.get(agentId=dealer.agentId, username=username, nickname=nickname) except DoesNotExist: return NoCommissionErrorResponse(description=u"添加失败,{}【{}】账号不存在,请先注册为合伙人账号".format(username, nickname)) try: Partner.add_relation(dealer, partner) except ValueError as ve: return NoCommissionErrorResponse(description=ve.message) return JsonOkResponse() @permission_required(ROLE.dealer, ROLE.subaccount) def deletePartner(request): """ 删除合伙人 """ dealer = request.user.myBoss data = json.loads(request.body or "{}") partnerId = data.get("partnerId") try: partner = dealer.__class__.objects.get(agentId=dealer.agentId, id=partnerId) except DoesNotExist: return NoCommissionErrorResponse(description=u"删除失败") try: Partner.delete_relation(dealer, partner) except ValueError as ve: return NoCommissionErrorResponse(description=ve.message) return JsonOkResponse() @permission_required(ROLE.dealer, ROLE.subaccount) def getPartnerGroups(request): """ 获取合伙人的所有地址组的信息 """ data = json.loads(request.body or "{}") _id = request.GET.get("id") try: partner = Partner.get_partner(_id) # type: Partner if not partner: raise DoesNotExist("合伙关系不存在") except DoesNotExist: return NoCommissionErrorResponse(description=u"获取合伙人场地失败") groups = partner.get_partner_groups() return JsonOkResponse(payload={"groups": groups}) @permission_required(ROLE.dealer, ROLE.subaccount) def getGroupPartners(request): """ 获取组内的合伙人 """ groupId = request.GET.get("groupId") group = Group.get_group(groupId) # type: GroupDict if group.ownerId != str(request.user.bossId): return NoCommissionErrorResponse(description=u"获取失败") partners = [] for _item in group.partners: _partner = Partner.get_partner_by_dealer(str(request.user.bossId), _item["id"]) # type: Partner if not _partner: return NoCommissionErrorResponse(description=u"地址合伙人配置错误,请联系平台方处理(10000)") _share = _partner.get_share_group(groupId) # type: GroupShare if not _share: return NoCommissionErrorResponse(description=u"地址合伙人配置错误,请联系平台方处理(10001)") _p_dealer = request.user.myBoss.__class__.get_dealer(_partner.partnerId) # type: Dealer _data = { "partnerId": str(_p_dealer.id), "name": _p_dealer.nickname, "phone": _p_dealer.username, "isActive": _share.isActive, "ratio": _share.ratio, "payElecFee": _share.payElecFee, "contracts": _share.contracts } partners.append(_data) return JsonOkResponse(payload={"partners": partners}) @permission_required(ROLE.dealer, ROLE.subaccount) def updateGroupPartner(request): dealer = request.user.myBoss data = json.loads(request.body or "{}") groupId = data.get("groupId") partnerId = data.get("partnerId") ratio = data.get("ratio") payElecFee = data.get("payElecFee") isActive = data.get("isActive") contracts = data.get("contracts") partner = Partner.get_partner_by_dealer(str(dealer.id), partnerId) if not partner: return NoCommissionErrorResponse(u"合伙人变更失败(10001)") groupShare = partner.get_share_group(groupId) group = Group.get_group(groupId) # 新增的处理 try: if not groupShare: partner.add_group_share(group, ratio, payElecFee, isActive, contracts) # 更新的处理 else: partner.update_group_share(group, ratio, payElecFee, isActive, contracts) except ValueError as ve: return NoCommissionErrorResponse(description=ve.message) return JsonOkResponse() @permission_required(ROLE.dealer, ROLE.subaccount) def removeGroupPartner(request): """ 移除合伙人 """ dealer = request.user.myBoss data = json.loads(request.body or "{}") groupId = data.get("groupId") partnerId = data.get("partnerId") group = Group.get_group(groupId) # type: GroupDict if group.ownerId != str(dealer.id): return JsonErrorResponse(description=u"移除合伙人失败(10001)") partner = Partner.get_partner_by_dealer(str(dealer.id), partnerId) # type: Partner if not partner: return JsonErrorResponse(description=u"移除合伙人失败(10002)") if partner.dealerId != str(dealer.id): return JsonErrorResponse(description=u"移除合伙人失败(10003)") partner.remove_group_share(group) return JsonOkResponse() @permission_required(ROLE.dealer, ROLE.subaccount) def uploadContract(request): image = request.FILES.get("file") fileSuffix = image.name.split(".")[1] if fileSuffix not in ["jpg", "jpeg", "png"]: return NoCommissionErrorResponse(description=u"图片类型错误,请上传指的的图片类型(jpg,jpeg,png)。") # 上传保存图片 uploader = AliOssFileUploader(inputFile=image, uploadType="contract") try: outputUrl = uploader.upload() except InvalidFileSize as e: return JsonErrorResponse(description=e.message) except InvalidFileName as e: return JsonErrorResponse(description=e.message) payload = { "url": outputUrl } return JsonOkResponse(payload=payload) @permission_required(ROLE.dealer, ROLE.subaccount) def getLedgerExpected(request): """ 获取经销商的分润预估收益 """ dealer = request.user.myBoss # 获取所有的分成地址信息 groupIds = Group.get_group_ids_of_dealer(str(dealer.id)) partnerGroupIds = Group.get_group_ids_of_partner(str(dealer.id)) groupIds.extend(partnerGroupIds) # 获取今天的统计信息 并模拟出分润金额 now = datetime.datetime.now() date = now.strftime(Const.DATE_FMT) stats = get_stats(date=date, groupIds=groupIds) statsValue = LedgerStatsCalculator(stats, dealer).calculate() return JsonOkResponse(payload=statsValue.as_dict()) @permission_required(ROLE.dealer, ROLE.subaccount) def getLedgers(request): """ 获取经销商的分润 实际已经发生的 """ dealer = request.user.myBoss start = request.GET.get("startTime") end = request.GET.get("endTime") groupId = request.GET.get("groupId") if not start: start = datetime.date.today()-datetime.timedelta(days=1) else: start = datetime.datetime.strptime(start, "%Y-%m-%d").date() if not end: end = datetime.date.today()-datetime.timedelta(days=1) else: end = datetime.datetime.strptime(end, "%Y-%m-%d").date() if start > end: return JsonErrorResponse(description=u"查询日期错误") dateInterval = (end - start).days + 1 if dateInterval > 7: return JsonErrorResponse(description=u"单次查询记录最多7日") dates = [] for _day in range(dateInterval): dates.append(start.strftime("%Y-%m-%d")) start += datetime.timedelta(days=1) if not groupId: groupIds = Group.get_group_ids_of_dealer(str(dealer.id)) partnerGroupIds = Group.get_group_ids_of_partner(str(dealer.id)) groupIds.extend(partnerGroupIds) else: groupIds = [groupId] dataList = list() for _date in dates[::-1]: _stats = get_stats(date=_date, groupIds=groupIds) _statsValue = LedgerStatsCalculator(_stats, dealer).calculate() _data = {"date": _date} _data.update(_statsValue.as_dict()) dataList.append(_data) return JsonOkResponse(payload={"dataList": dataList})