# -*- coding: UTF-8 -*-
from __future__ import division
import datetime
import math
import traceback

import tablib
from django.db.models import Sum
from celery import shared_task
from api.tool.log_tool import logging_exception
from gm_types.doctor import BUDAN_LURU_STATUS, BUDAN_LURU_TYPE
from gm_types.gaia import ORDER_STATUS, REFUND_STATUS, MERCHANT_LEVEL_NEW
from themis.models import Team
from api.models import Order, BuDanLuRu, ConversationUserStatus, MerchantRelevance, Conversation, RefundOrder
from hera.management.commands.utils import get_mail
from hippo.models import Doctor, Merchant, MerchantPvStat, TrafficStat, MerchantLevelRecord
from hippo.models.user_list import UserList
from hippo.tool.merchant_tool import update_merchant_doctor_relation
from maidan.models import MaidanOrder
from helios.rpc.internal.default_invoker import create_default_invoker
from django.conf import settings
import redis
from dateutil.relativedelta import relativedelta

@shared_task
def update_merchant_by_doctor(doctor_ids):
    for doctor in Doctor.objects.filter(id__in=doctor_ids):
        update_merchant_doctor_relation(doctor)

@shared_task
def update_merchant_level(end_time=None, month=6.0):
    def get_level(score):
        if score < 1:
            return 0
        elif score < 50:
            return 1
        elif score < 100:
            return 2
        elif score < 300:
            return 3
        elif score < 500:
            return 4
        elif score < 1000:
            return 5
        elif score < 1500:
            return 6
        elif score >= 1500:
            return 7
    now = datetime.datetime.now()
    if not end_time:
        end_time = datetime.datetime(now.year, now.month, 1, 0, 0, 0)
    else:
        now = datetime.datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S')
        end_time = datetime.datetime(now.year, now.month, 1, 0, 0, 0)
    created_time = datetime.datetime(now.year, now.month, now.day, 0, 0, 0)
    merchants = Merchant.objects.only('id')
    dt = tablib.Dataset()
    dt.headers = [
        'merchant_id', u'更新结果'
    ]
    # 获取所有医生的id
    if end_time.month > month:
        start_time = datetime.datetime(end_time.year, end_time.month - int(month), 1, 0, 0,
                                       0)
    else:
        start_time = datetime.datetime(end_time.year - 1, end_time.month - int(month) + 12, 1, 0,
                                         0, 0)
    if start_time >= datetime.datetime(2020, 3, 1, 0, 0, 0):
        merchant_doctor_ids = {}
        for i in merchants:
            doctor_ids = list(i.merchant_doctors.all().values_list('doctor_id', flat=True))
            merchant_doctor_ids[str(i.id)] = doctor_ids
        # 按照商户的维度获取广告消耗
        # 初始化rpc对像
        invoker = create_default_invoker(debug=settings.DEBUG)
        ad_data = dict()
        for i in range(6):
            end_date = end_time - relativedelta(months=i)
            print(end_date)
            start_date = end_time - relativedelta(months=i + 1)
            rpc_client = invoker['artemis/account/accountflow/new_sum'](doctor_ids=merchant_doctor_ids,
                                                                        start_time=start_date.strftime(
                                                                            "%Y-%m-%d %H:%M:%S"),
                                                                        end_time=end_date.strftime("%Y-%m-%d %H:%M:%S"))
            res = rpc_client.unwrap()
            ad_data[i] = res
        # 计算商户得分,更新当前数据，写入历史记录表
        for obj in merchants:
            print(obj.id)
            try:
                advertise_consume_amount = ad_data.get(0, {}).get(str(obj.id), 0.0) * 0.3 + ad_data.get(1, {}).get(
                    str(obj.id), 0.0) * 0.2 + \
                                           ad_data.get(2, {}).get(str(obj.id), 0.0) * 0.2 + ad_data.get(3, {}).get(
                    str(obj.id), 0.0) * 0.15 + \
                                           ad_data.get(4, {}).get(str(obj.id), 0.0) * 0.1 + ad_data.get(5, {}).get(
                    str(obj.id), 0.0) * 0.05
                gmv_list = []
                pv_list = []
                for i in range(6):
                    end_date = end_time - relativedelta(months=i)
                    start_date = end_time - relativedelta(months=i + 1)
                    tmp = get_gmv_pv(start_date, end_date, obj)
                    gmv_list.append(tmp.get("gmv", 0))
                    pv_list.append(tmp.get("pv", 0))

                verify_gmv_amount = gmv_list[0] * 0.3 + gmv_list[1] * 0.2 + gmv_list[2] * 0.2 + \
                                    gmv_list[3] * 0.15 + gmv_list[4] * 0.1 + gmv_list[5] * 0.05
                pv_num = pv_list[0] * 0.3 + pv_list[1] * 0.2 + pv_list[2] * 0.2 + \
                         pv_list[3] * 0.15 + pv_list[4] * 0.1 + pv_list[5] * 0.05

                verify_pv_amount = verify_gmv_amount / pv_num if pv_num else 0.0
                merchant_score = math.ceil(
                    (verify_gmv_amount * 0.8 + advertise_consume_amount * 0.2) * 0.00232558139534884)
                per_pv_income = float(verify_gmv_amount / 10 + advertise_consume_amount) / pv_num if pv_num else 0.0
                merchant_level = get_v2_level(merchant_score, per_pv_income)
                refund_proportion = get_refund_proportion(start_time, end_time, obj)
                item = {"verify_gmv_amount": verify_gmv_amount}
                item.update(merchant_score=merchant_score, merchant_level=merchant_level,
                            verify_pv_amount=verify_pv_amount,
                            advertise_consume_amount=advertise_consume_amount, refund_proportion=refund_proportion)
                for k, v in item.items():
                    setattr(obj, k, v)
                obj.save()
                item.update(created_time=created_time)
                # 判断当前月份是不是存在分级记录
                l_time = datetime.datetime(created_time.year, created_time.month, 1, 0, 0, 0)
                if created_time.month == 12:
                    r_time = datetime.datetime(created_time.year + 1, 1, 1, 0, 0, 0)
                else:
                    r_time = datetime.datetime(created_time.year, created_time.month + 1, 1, 0, 0, 0)
                record_obj = MerchantLevelRecord.objects.filter(merchant_id=obj.id, created_time__gte=l_time,
                                                                created_time__lt=r_time).first()
                if record_obj:
                    for k, v in item.items():
                        setattr(record_obj, k, v)
                    record_obj.save()
                else:
                    item.update(merchant_id=obj.id)
                    MerchantLevelRecord.objects.create(**item)
                dt.append((str(obj.id), u'success'))
            except:
                dt.append((str(obj.id), u'fail'))
                logging_exception()
        get_mail(u'商户评级更新-1.xls', u'失败记录', u'zhangyanzhao@igengmei.com', dt.xls).send()

    elif start_time >= datetime.datetime(2020, 2, 1, 0, 0, 0) or start_time >= datetime.datetime(2020, 1, 1, 0, 0, 0) or end_time == datetime.datetime(2020, 3, 1, 0, 0, 0):
        invoker = create_default_invoker(debug=settings.DEBUG)

        if start_time >= datetime.datetime(2020, 2, 1, 0, 0, 0):
            #2020年2月份gmv总值和广告消耗总值
            result_1, merchant_doctor_ids = get_merchant_gmv(start_time, '2020-03-01 00:00:00', 1, merchants)
            rpc_client = invoker['artemis/account/accountflow/new_sum'](doctor_ids=merchant_doctor_ids,
                                                                        start_time=start_time.strftime("%Y-%m-%d %H:%M:%S"),
                                                                        end_time='2020-03-01 00:00:00')
            res_1 = rpc_client.unwrap()
            #计算3-7月 gmv总值和广告消耗总值
            result_2, merchant_doctor_ids = get_merchant_gmv('2020-03-01 00:00:00', end_time, 1, merchants)
            rpc_client = invoker['artemis/account/accountflow/new_sum'](doctor_ids=merchant_doctor_ids,
                                                                        start_time='2020-03-01 00:00:00',
                                                                        end_time=end_time.strftime("%Y-%m-%d %H:%M:%S"))
            res_2 = rpc_client.unwrap()
        elif start_time >= datetime.datetime(2020, 1, 1, 0, 0, 0):
            #2020年1、2月份gmv总值和广告消耗总值
            result_1, merchant_doctor_ids = get_merchant_gmv(start_time, '2020-03-01 00:00:00', 1, merchants)
            rpc_client = invoker['artemis/account/accountflow/new_sum'](doctor_ids=merchant_doctor_ids,
                                                                        start_time=start_time.strftime("%Y-%m-%d %H:%M:%S"),
                                                                        end_time='2020-03-01 00:00:00')
            res_1 = rpc_client.unwrap()
            #计算3-6月 gmv总值和广告消耗总值
            result_2, merchant_doctor_ids = get_merchant_gmv('2020-03-01 00:00:00', end_time, 1, merchants)
            rpc_client = invoker['artemis/account/accountflow/new_sum'](doctor_ids=merchant_doctor_ids,
                                                                        start_time='2020-03-01 00:00:00',
                                                                        end_time=end_time.strftime("%Y-%m-%d %H:%M:%S"))
            res_2 = rpc_client.unwrap()
        else:
            # 2020年1、2月份gmv总值和广告消耗总值
            result_1, merchant_doctor_ids = get_merchant_gmv('2020-01-01 00:00:00', end_time, 1, merchants)
            rpc_client = invoker['artemis/account/accountflow/new_sum'](doctor_ids=merchant_doctor_ids,
                                                                        start_time='2020-01-01 00:00:00',
                                                                        end_time=end_time.strftime("%Y-%m-%d %H:%M:%S"))
            res_1 = rpc_client.unwrap()
            # 2019年9-12月份gmv总值和广告消耗总值
            result_2, merchant_doctor_ids = get_merchant_gmv(start_time, '2020-01-01 00:00:00', 1, merchants)
            rpc_client = invoker['artemis/account/accountflow/new_sum'](doctor_ids=merchant_doctor_ids,
                                                                        start_time=start_time.strftime("%Y-%m-%d %H:%M:%S"),
                                                                        end_time='2020-01-01 00:00:00')
            res_2 = rpc_client.unwrap()
        for obj in merchants:
            print(obj.id)
            try:
                item = {}
                item_1, item_2 = result_1[obj.id], result_2[obj.id]
                #退款率
                pv_num = item_1.pop('pv_num') + item_2.pop('pv_num')
                orders_num = item_1.pop('orders_num') + item_2.pop('orders_num')
                refunds_num = item_1.pop('refunds_num') + item_2.pop('refunds_num')
                refund_proportion = refunds_num / (orders_num * 1.0) if orders_num else 0.0
                #评分计算
                advertise_consume_amount = (res_1.get(str(obj.id), 0.0) * 2 + res_2.get(str(obj.id), 0.0)) / month
                verify_gmv_amount = ((item_1.get("verify_gmv_amount", 0.0) * 2 + item_2.get("verify_gmv_amount", 0.0))) / month
                merchant_score = math.ceil(
                    (verify_gmv_amount * 0.8 + advertise_consume_amount * 0.2) * 0.00232558139534884)
                #等级
                merchant_level = get_level(merchant_score)
                #广告消耗均值
                advertise_consume_amount = (res_1.get(str(obj.id), 0.0) + res_2.get(str(obj.id), 0.0)) / month
                #单pv验证金额
                verify_gmv_amount = (item_1.get("verify_gmv_amount", 0.0) + item_2.get("verify_gmv_amount", 0.0))
                verify_pv_amount = verify_gmv_amount / pv_num if pv_num else 0.0
                #验证gmv均值
                verify_gmv_amount = verify_gmv_amount / month
                item.update(merchant_score=merchant_score, merchant_level=merchant_level, verify_pv_amount=verify_pv_amount,
                            advertise_consume_amount=advertise_consume_amount, verify_gmv_amount=verify_gmv_amount, refund_proportion=refund_proportion)
                for k, v in item.items():
                    setattr(obj, k, v)
                obj.save()
                item.update(created_time=created_time)
                #判断当前月份是不是存在分级记录
                l_time = datetime.datetime(created_time.year, created_time.month, 1, 0, 0, 0)
                if created_time.month == 12:
                    r_time = datetime.datetime(created_time.year + 1, 1, 1, 0, 0, 0)
                else:
                    r_time = datetime.datetime(created_time.year, created_time.month + 1, 1, 0, 0, 0)
                record_obj = MerchantLevelRecord.objects.filter(merchant_id=obj.id, created_time__gte=l_time, created_time__lt=r_time).first()
                if record_obj:
                    for k, v in item.items():
                        setattr(record_obj, k, v)
                    record_obj.save()
                else:
                    item.update(merchant_id=obj.id)
                    MerchantLevelRecord.objects.create(**item)
                dt.append((str(obj.id), u'success'))
            except:
                dt.append((str(obj.id), u'fail'))
                logging_exception()
        get_mail(u'商户评级更新-2.xls', u'失败记录', u'songzhenqi@igengmei.com', dt.xls).send()

    elif start_time < datetime.datetime(2020, 1, 1, 0, 0, 0) and end_time > datetime.datetime(2020, 3, 1, 0, 0, 0):
        #分三部分计算：2020.1.1之前的，2020.1.1 - 2020.3.1 ，2020.3.1之后的
        invoker = create_default_invoker(debug=settings.DEBUG)
        #2020年1，2月份gmv总值和广告消耗总值
        result_1, merchant_doctor_ids = get_merchant_gmv('2020-01-01 00:00:00', '2020-03-01 00:00:00', 1, merchants)
        rpc_client = invoker['artemis/account/accountflow/new_sum'](doctor_ids=merchant_doctor_ids,
                                                                    start_time='2020-01-01 00:00:00',
                                                                    end_time='2020-03-01 00:00:00')
        res_1 = rpc_client.unwrap()
        #2020年1月份之前的gmv总值和广告消耗总值
        result_2, merchant_doctor_ids = get_merchant_gmv(start_time, '2020-01-01 00:00:00', 1, merchants)
        rpc_client = invoker['artemis/account/accountflow/new_sum'](doctor_ids=merchant_doctor_ids,
                                                                    start_time=start_time.strftime("%Y-%m-%d %H:%M:%S"),
                                                                    end_time='2020-01-01 00:00:00')
        res_2 = rpc_client.unwrap()
        #2020年3月份之后的gmv总值和广告消耗总值
        result_3, merchant_doctor_ids = get_merchant_gmv('2020-03-01 00:00:00', end_time, 1, merchants)
        rpc_client = invoker['artemis/account/accountflow/new_sum'](doctor_ids=merchant_doctor_ids,
                                                                    start_time='2020-03-01 00:00:00',
                                                                    end_time=end_time.strftime("%Y-%m-%d %H:%M:%S"))
        res_3 = rpc_client.unwrap()
        for obj in merchants:
            print(obj.id)
            try:
                item = {}
                item_1, item_2, item_3 = result_1[obj.id], result_2[obj.id], result_3[obj.id]
                #评分
                advertise_consume_amount = (res_1.get(str(obj.id), 0.0) * 2 + res_2.get(str(obj.id), 0.0) + res_3.get(
                    str(obj.id), 0.0)) / month
                verify_gmv_amount = (item_1.get("verify_gmv_amount", 0.0) * 2 + item_2.get("verify_gmv_amount", 0.0) + item_3.get("verify_gmv_amount", 0.0)) / month
                merchant_score = math.ceil(
                    (verify_gmv_amount * 0.8 + advertise_consume_amount * 0.2) * 0.00232558139534884)
                #等级
                merchant_level = get_level(merchant_score)
                #广告消耗均值
                advertise_consume_amount = (res_1.get(str(obj.id), 0.0) + res_2.get(str(obj.id), 0.0) + res_3.get(str(obj.id), 0.0)) / month
                #退款率
                pv_num = item_1.pop('pv_num') + item_2.pop('pv_num') + item_3.pop('pv_num')
                orders_num = item_1.pop('orders_num') + item_2.pop('orders_num') + item_3.pop('orders_num')
                refunds_num = item_1.pop('refunds_num') + item_2.pop('refunds_num') + item_3.pop('refunds_num')
                refund_proportion = refunds_num / (orders_num * 1.0) if orders_num else 0.0
                #单pv验证金额
                verify_gmv_amount = item_1.get("verify_gmv_amount", 0.0) + item_2.get("verify_gmv_amount", 0.0) + item_3.get("verify_gmv_amount", 0.0)
                verify_pv_amount = verify_gmv_amount / pv_num if pv_num else 0.0
                #验证gmv均值
                verify_gmv_amount = verify_gmv_amount / month

                item.update(merchant_score=merchant_score, merchant_level=merchant_level, verify_pv_amount=verify_pv_amount,
                            advertise_consume_amount=advertise_consume_amount, verify_gmv_amount=verify_gmv_amount, refund_proportion=refund_proportion)
                for k, v in item.items():
                    setattr(obj, k, v)
                obj.save()
                item.update(created_time=created_time)
                # 判断当前月份是不是存在分级记录
                l_time = datetime.datetime(created_time.year, created_time.month, 1, 0, 0, 0)
                if created_time.month == 12:
                    r_time = datetime.datetime(created_time.year + 1, 1, 1, 0, 0, 0)
                else:
                    r_time = datetime.datetime(created_time.year, created_time.month + 1, 1, 0, 0, 0)
                record_obj = MerchantLevelRecord.objects.filter(merchant_id=obj.id, created_time__gte=l_time,
                                                                created_time__lt=r_time).first()
                if record_obj:
                    for k, v in item.items():
                        setattr(record_obj, k, v)
                    record_obj.save()
                else:
                    item.update(merchant_id=obj.id)
                    MerchantLevelRecord.objects.create(**item)
                dt.append((str(obj.id), u'success'))
            except:
                dt.append((str(obj.id), u'fail'))
                logging_exception()
        get_mail(u'商户评级更新-3.xls', u'失败记录', u'songzhenqi@igengmei.com', dt.xls).send()


# 最新计算商家等级方法
def get_v2_level(score,per_pv_income):
    if score <= 0:
        return 0
    elif score < 50:
        if per_pv_income >= 0.3:
            return 1
        else:
            return 0
    elif score < 100:
        if per_pv_income >= 1.5:
            return 2
        else:
            return 1
    elif score < 300:
        if per_pv_income >= 1.8:
            return 3
        else:
            return 2
    elif score < 500:
        if per_pv_income >= 3:
            return 4
        else:
            return 3
    elif score < 1000:
        if per_pv_income >= 4:
            return 5
        else:
            return 4
    elif score < 1500:
        if per_pv_income >= 5:
            return 6
        else:
            return 5
    elif score >= 1500:
        if per_pv_income >= 8:
            return 7
        else:
            return 6


def get_gmv_pv(start_time, end_time, merchant_obj):
    doctor_ids = list(merchant_obj.merchant_doctors.all().values_list('doctor_id', flat=True))
    #     # 计算订单，买单，补单GMV
    #     # ORDER_STATUS.USED 是"2"
    orders = Order.objects.filter(service__doctor_id__in=doctor_ids, validate_time__gte=start_time,
                                  validate_time__lt=end_time, status=ORDER_STATUS.USED)
    res_dict = orders.aggregate(sum=Sum("discount"))
    order_sum = res_dict.get("sum") if res_dict.get("sum") else 0.00

    # 买单
    res_dict = MaidanOrder.objects.filter(doctor_id__in=doctor_ids, payment_time__gte=start_time,
                                          payment_time__lt=end_time,
                                          status=ORDER_STATUS.PAID).aggregate(
        sum=Sum("discount_cent"))
    maidan_sum = res_dict.get("sum") / 100.0 if res_dict.get("sum") else 0.00
    # 补单录入
    res_dict = BuDanLuRu.objects.filter(doctor_id__in=doctor_ids, created_time__gte=start_time,
                                        created_time__lt=end_time, status=BUDAN_LURU_STATUS.ENTERED,
                                        type=BUDAN_LURU_TYPE.COMMON).aggregate(sum=Sum("amount"))
    budanluru_sum = res_dict.get("sum") if res_dict.get("sum") else 0.00
    verify_gmv_amount = (order_sum + maidan_sum + budanluru_sum)*10
    time_ls = []
    for j in [start_time, end_time]:
        if isinstance(j, str):
            time_ls.append(j.split(' ')[0])
        else:
            time_ls.append('%d-%02d-%02d' % (j.year, j.month, j.day))
    traffic_stat_objs = TrafficStat.objects.filter(doctor_id__in=doctor_ids, date__gte=time_ls[0],
                                                   date__lt=time_ls[1]).values('date').annotate(
        service_pv_num=Sum('service_pv_num'), home_pv_num=Sum('home_pv_num'))
    pv_num = 0.0
    for stat in traffic_stat_objs:
        # 页面浏览量
        pv_num += (stat['service_pv_num'] + stat['home_pv_num'])
    return {"gmv":verify_gmv_amount,"pv":pv_num}


def get_refund_proportion(start_time, end_time, merchant_obj):
    doctor_ids = list(merchant_obj.merchant_doctors.all().values_list('doctor_id', flat=True))
    pay_orders = Order.objects.filter(service__doctor_id__in=doctor_ids, pay_time__gte=start_time,
                                  pay_time__lt=end_time, status__in=[ORDER_STATUS.PAID, ORDER_STATUS.REFUNDED, ORDER_STATUS.USED, ORDER_STATUS.SETTLED, ORDER_STATUS.WAIT_REFUNDED]).only('id')
    pay_order_ids = list(pay_orders.values_list('id', flat=True))
    refund_orders = RefundOrder.objects.filter(order_id__in=pay_order_ids, created_at__gte=start_time, created_at__lt=end_time, status__in=[REFUND_STATUS.REFUNDED, REFUND_STATUS.DOCTOR_APPROVE])
    refunds_num = refund_orders.count()
    orders_num = pay_orders.count()
    refund_proportion = refunds_num / (orders_num * 1.0) if orders_num else 0.0
    return refund_proportion


def get_merchant_gmv(start_time, end_time, month, merchants):
    result = {}
    merchant_doctor_ids = {}
    for i in merchants:
        print(i.id)
        doctor_ids = list(i.merchant_doctors.all().values_list('doctor_id', flat=True))
        merchant_doctor_ids[str(i.id)] = doctor_ids
        # 计算订单，买单，补单GMV
        # 订单
        orders = Order.objects.filter(service__doctor_id__in=doctor_ids, validate_time__gte=start_time,
                                      validate_time__lt=end_time, status=ORDER_STATUS.USED)
        res_dict = orders.aggregate(sum=Sum("discount"))
        order_sum = res_dict.get("sum") if res_dict.get("sum") else 0.00

        # 买单
        res_dict = MaidanOrder.objects.filter(doctor_id__in=doctor_ids, payment_time__gte=start_time,
                                              payment_time__lt=end_time,
                                              status=ORDER_STATUS.PAID).aggregate(
            sum=Sum("discount_cent"))
        maidan_sum = res_dict.get("sum") / 100.0 if res_dict.get("sum") else 0.00
        # 补单录入
        res_dict = BuDanLuRu.objects.filter(doctor_id__in=doctor_ids, created_time__gte=start_time,
                                            created_time__lt=end_time, status=BUDAN_LURU_STATUS.ENTERED,
                                            type=BUDAN_LURU_TYPE.COMMON).aggregate(sum=Sum("amount"))
        budanluru_sum = res_dict.get("sum") if res_dict.get("sum") else 0.00

        # 单pv验证额
        #查询时间处理
        time_ls = []
        for j in [start_time, end_time]:
            if isinstance(j, str):
                time_ls.append(j.split(' ')[0])
            else:
                time_ls.append('%d-%02d-%02d' % (j.year, j.month, j.day))
        traffic_stat_objs = TrafficStat.objects.filter(doctor_id__in=doctor_ids, date__gte=time_ls[0],
                                                       date__lt=time_ls[1]).values('date').annotate(service_pv_num=Sum('service_pv_num'), home_pv_num=Sum('home_pv_num'))
        pv_num = 0.0
        from hippo.views.stats import gen_pv
        for stat in traffic_stat_objs:
            # 页面浏览量
            pv_num += gen_pv(stat['service_pv_num'], stat['home_pv_num'])
        verify_gmv_amount = (order_sum + maidan_sum + budanluru_sum) * 10 / (month * 1.0)
        #已付款单数，对应的退款单数计算
        pay_orders = Order.objects.filter(service__doctor_id__in=doctor_ids, pay_time__gte=start_time,
                                      pay_time__lt=end_time, status__in=[ORDER_STATUS.PAID, ORDER_STATUS.REFUNDED, ORDER_STATUS.USED, ORDER_STATUS.SETTLED, ORDER_STATUS.WAIT_REFUNDED]).only('id')
        pay_order_ids = list(pay_orders.values_list('id', flat=True))
        refund_orders = RefundOrder.objects.filter(order_id__in=pay_order_ids, created_at__gte=start_time, created_at__lt=end_time, status__in=[REFUND_STATUS.REFUNDED, REFUND_STATUS.DOCTOR_APPROVE])
        result[i.id] = {"pv_num": pv_num, "verify_gmv_amount": verify_gmv_amount,
                        "orders_num": pay_orders.count(), 'refunds_num': refund_orders.count()}

    return result, merchant_doctor_ids

@shared_task
def user_list_data_write():
    #获取所有商户
    merchants = Merchant.objects.all()
    """
    获取单个商户所对应的所有用户,下单同时产生私信，私信用户包含下单、支付和验证的用户
    通过私信维度筛选用户，后再更新订单信息
    """
    for merchant in merchants:
        try:
            print(merchant.id)
            """
            #获取当前商户下的所有doctor_id,
            doctor_list_ids=[(u'zhangweixin',)]
            """
            doctor_ids = []
            doctor_list_ids = merchant.merchant_doctors.all().values_list('doctor_id')
            for item in doctor_list_ids:
                doctor_ids.append(item[0])
            """
            通过医生的doctor_id获取其对应的doctor_user_id
            在conversationuserstatus表中通过医生的用户id获取本商户的所有私信
            """
            doctor_list_user_ids = Doctor.objects.filter(id__in=doctor_ids).values_list('user_id')
            doctor_user_ids = []
            for item in doctor_list_user_ids:
                doctor_user_ids.append(item[0])
            conversationuserstatus_list = ConversationUserStatus.objects.filter(user_id__in=doctor_user_ids).order_by('conversation__created_time')

            """
            通过商户的私信或对应的会话，通过会话获取会话对应的另一个user_id
            并将用户写入user_list
            """
            for conversationuserstatus in conversationuserstatus_list:
                doctor_user_id = conversationuserstatus.user_id
                user_list = conversationuserstatus.conversation.user_status_set.values_list('user_id')
                for item in user_list:
                    if doctor_user_id != item[0]:
                        user_id = item[0]
                        break
                defaults = {'conversation_id': conversationuserstatus.conversation_id, 'doctor_user_id': doctor_user_id,
                            'conversation_created_time': conversationuserstatus.conversation.created_time}
                kwargs = {'merchant_id': merchant.id, 'user_id': user_id}
                user_obj, _ = UserList.objects.update_or_create(defaults=defaults, **kwargs)
                """
                在MerchantPvStat表中获取用户最近浏览的记录
                """
                time_now = datetime.datetime.today()
                start_time = time_now - datetime.timedelta(days=30)
                browse_obj = MerchantPvStat.objects.filter(user_id=user_id, merchant_id=merchant.id, browsing_time__gte=start_time).order_by('browsing_time').last()
                if browse_obj:
                    user_obj.browse_id = browse_obj.id
                    user_obj.browse_time = browse_obj.browsing_time
                """
                更新用户的订单相关信息
                支付订单
                认证订单
                """
                pay_order = Order.objects.filter(user_id=user_obj.user_id, service__doctor_id__in=doctor_ids, status=ORDER_STATUS.PAID).order_by('pay_time').last()
                if pay_order:
                    user_obj.order_pay_id = pay_order.id
                    user_obj.order_pay_time = pay_order.pay_time
                validated_orders = Order.objects.filter(user_id=user_obj.user_id, service__doctor_id__in=doctor_ids, validated=True).order_by('validate_time')
                if validated_orders:
                    res = validated_orders.aggregate(sum=Sum("real_payment"))
                    user_obj.amount = res.get("sum") if res.get("sum") else 0.00
                    user_obj.order_validated_time = validated_orders.last().validate_time
                    user_obj.order_validated_id = validated_orders.last().id
                user_obj.modify_time = datetime.datetime.today()
                user_obj.save()
        except:
            try:
                info = str(traceback.format_exc())
                sub = '用户列表数据写入错误统计.txt'
                body = '用户列表数据写入错误统计'
                to_user_email = 'songzhenqi@igengmei.com'
                message = info + str(merchant.id)
                get_mail(sub, body, to_user_email, message).send()
                continue
            except:
                continue




@shared_task
def message_sync(conversation, send_user, target_user):
    """
    :param conversation:
    :param id:
    :return:
    判断目标是不是医生
    不是：结束
    是：userlist更新或者其他操作
    """
    doctor = Doctor.objects.filter(user_id=target_user.id).first()
    if not doctor:
        return None
    """
    判断该用户是不是第一次和会话医生所属的商户第一次私信沟通
    """
    merchant = MerchantRelevance.objects.filter(doctor_id=doctor.id).first()
    if not merchant:
        return None
    doctor_list_ids = MerchantRelevance.objects.filter(merchant_id=merchant.merchant_id).values_list('doctor_id')
    doctor_ids = []
    for item in doctor_list_ids:
        doctor_ids.append(item[0])
    user_list_ids = Doctor.objects.filter(id__in=doctor_ids).values_list('user_id')
    user_ids = []
    for item in user_list_ids:
        user_ids.append(item[0])
    conversation_amount = 0
    for user_id in user_ids:
        hash_user_id = Conversation.gen_uid_hash([int(send_user.id), int(user_id)])
        count = Conversation.objects.filter(uid_hash=hash_user_id).count()
        conversation_amount += count
        if conversation_amount > 1:
            return '已存在用户'
    """
    该用户第一次与该商户下的医生私信会话
    将用户写入userlist,在ConversationUserStatus中找到此次会话的医生方
    """

    defaults = {'conversation_id': conversation.id, 'doctor_user_id': target_user.id,
                'conversation_created_time': conversation.created_time}
    kwargs = {'merchant_id': merchant.merchant_id, 'user_id': send_user.id}
    user_obj, _ = UserList.objects.update_or_create(defaults=defaults, **kwargs)
    """
    在MerchantPvStat表中获取用户最近浏览的记录
    """
    time_now = datetime.datetime.today()
    start_time = time_now - datetime.timedelta(days=30)
    browse_obj = MerchantPvStat.objects.filter(user_id=send_user.id, merchant_id=merchant.merchant_id, browsing_time__gte=start_time).order_by('browsing_time').last()
    if browse_obj:
        user_obj.browse_id = browse_obj.id
        user_obj.browse_time = browse_obj.browsing_time
    """
    更新用户的订单相关信息
    支付订单
    认证订单
    """
    pay_order = Order.objects.filter(user_id=user_obj.user_id, service__doctor_id__in=doctor_ids,
                                     status=ORDER_STATUS.PAID).order_by('pay_time').last()
    if pay_order:
        user_obj.order_pay_id = pay_order.id
        user_obj.order_pay_time = pay_order.pay_time
    validated_orders = Order.objects.filter(user_id=user_obj.user_id, service__doctor_id__in=doctor_ids,
                                            validated=True).order_by('validate_time')
    if validated_orders:
        user_obj.order_validated_id = validated_orders.last().id
        user_obj.order_validated_time = validated_orders.last().validate_time
        res = validated_orders.aggregate(sum=Sum("real_payment"))
        user_obj.amount = res.get("sum") if res.get("sum") else 0.00
    user_obj.modify_time = datetime.datetime.today()
    user_obj.save()



@shared_task
def userlist_update_pay_order_per_hour():
    """
    支付订单记录更新
    :return:
    """
    """
    通过pay_time更新用户最新支付订单
    """
    doctor_cache = redis.StrictRedis(**settings.REDIS['doctor'])
    end_time = datetime.datetime.today()
    expire_time = end_time + datetime.timedelta(hours=2)
    if not doctor_cache.setnx('userlist_update_pay_order_per_hour_lock', expire_time.strftime('%Y-%m-%d %H:%M:%S')):
        redis_expire_time_str = doctor_cache.get('userlist_update_pay_order_per_hour_lock')
        redis_expire_time = datetime.datetime.strptime(redis_expire_time_str, '%Y-%m-%d %H:%M:%S')
        if end_time > redis_expire_time:
            doctor_cache.set('userlist_update_pay_order_per_hour_lock', expire_time.strftime('%Y-%m-%d %H:%M:%S'))
        else:
            return None
    pay_order_start_time = doctor_cache.get('pay_order_start_time')
    if not pay_order_start_time:
        # if UserList.objects.all().exclude(order_pay_time=None).order_by('order_pay_time').first():
        #     pay_order_start_time = UserList.objects.all().exclude(order_pay_time=None).order_by('order_pay_time').first().order_pay_time
        # else:
        pay_order_start_time = datetime.datetime.strptime('2019-09-09 00:00:00', '%Y-%m-%d %H:%M:%S')
    pay_orders = Order.objects.filter(pay_time__gt=pay_order_start_time, pay_time__lte=end_time, status=ORDER_STATUS.PAID).order_by('pay_time')
    for pay_order in pay_orders:
        print(pay_order.id)
        if UserList.objects.filter(order_pay_id=pay_order.id):
            continue
        """
        判断当前订单归属：1、新用户的订单，2、已有用户的历史订单，3、已有用户的新订单
        """
        user_id = pay_order.user_id
        pay_time = pay_order.pay_time
        doctor_id = pay_order.service.doctor_id
        # doctor_user_id = Doctor.objects.get(id=doctor_id).user_id
        merchantrelevance = MerchantRelevance.objects.filter(doctor_id=doctor_id).first()
        if merchantrelevance:
            merchant_id = merchantrelevance.merchant_id
        else:
            continue
        obj = UserList.objects.filter(user_id=user_id, merchant_id=merchant_id).first()
        if obj:
            if not obj.order_pay_time or obj.order_pay_time < pay_time:
                obj.order_pay_time = pay_time
                obj.order_pay_id = pay_order.id
                # obj.doctor_user_id = doctor_user_id
                obj.save()
        else:
            defaults = {'order_pay_time':pay_time,'order_pay_id':pay_order.id,'modify_time':datetime.datetime.today()}
            kwargs = {'merchant_id': merchant_id, 'user_id': user_id}
            UserList.objects.update_or_create(defaults=defaults, **kwargs)
    doctor_cache.set('pay_order_start_time', end_time)
    doctor_cache.delete('userlist_update_pay_order_per_hour_lock')

@shared_task
def userlist_update_validate_order_per_hour():
    """
    通过validate_time更新用户最新验证订单
    """
    end_time = datetime.datetime.today()
    doctor_cache = redis.StrictRedis(**settings.REDIS['doctor'])
    expire_time = end_time + datetime.timedelta(hours=2)
    if not doctor_cache.setnx('userlist_update_validate_order_per_hour_lock', expire_time.strftime('%Y-%m-%d %H:%M:%S')):
        redis_expire_time_str = doctor_cache.get('userlist_update_validate_order_per_hour_lock')
        redis_expire_time = datetime.datetime.strptime(redis_expire_time_str, '%Y-%m-%d %H:%M:%S')
        if end_time > redis_expire_time:
            doctor_cache.set('userlist_update_validate_order_per_hour_lock', expire_time.strftime('%Y-%m-%d %H:%M:%S'))
        else:
            return None
    validate_order_start_time = doctor_cache.get('validate_order_start_time')
    if not validate_order_start_time:
        # if UserList.objects.all().exclude(order_validated_time=None).order_by('order_validated_time').first():
        #     validate_order_start_time = UserList.objects.all().exclude(order_validated_time=None).order_by('order_validated_time').first().order_validated_time
        # else:
        validate_order_start_time = datetime.datetime.strptime('2019-09-09 00:00:00', '%Y-%m-%d %H:%M:%S')
    validate_orders = Order.objects.filter(validate_time__gt=validate_order_start_time, validate_time__lte=end_time, validated=True).order_by('validate_time')
    for validate_order in validate_orders:
        print(validate_order.id)
        if UserList.objects.filter(order_validated_id=validate_order.id):
            continue
        """
        获取当前验证订单的用户id，商户id，验证时间，
        """
        user_id = validate_order.user_id
        validate_time = validate_order.validate_time
        doctor_id = validate_order.service.doctor_id
        merchantrelevance = MerchantRelevance.objects.filter(doctor_id=doctor_id).first()
        if merchantrelevance:
            merchant_id = merchantrelevance.merchant_id
        else:
            continue
        """
        判断当前验证订单归属：1、新用户的订单，2、已有用户的历史订单，3、已有用户的新订单
        """
        obj = UserList.objects.filter(user_id=user_id, merchant_id=merchant_id).first()
        if obj:
            if not obj.order_validated_time  or obj.order_validated_time < validate_time:
                obj.order_validated_time = validate_time
                obj.order_validated_id = validate_order.id
                obj.amount += validate_order.real_payment
                obj.save()
        else:

            defaults = {'order_validated_time':validate_time, 'order_validated_id':validate_order.id, 'modify_time':datetime.datetime.today()}
            kwargs = {'merchant_id': merchant_id, 'user_id': user_id}
            user_obj, _ = UserList.objects.update_or_create(defaults=defaults, **kwargs)
            """
            更新用户的验证金额
            """
            user_obj.amount = validate_order.real_payment
            user_obj.save()

    doctor_cache.set('validate_order_start_time', end_time)
    doctor_cache.delete('userlist_update_validate_order_per_hour_lock')

@shared_task
def userlist_update_conversation_per_hour():
    """
    通过conversation_id更新用户最新私信
    """
    doctor_cache = redis.StrictRedis(**settings.REDIS['doctor'])
    end_time = datetime.datetime.today()
    expire_time = end_time + datetime.timedelta(hours=2)
    if not doctor_cache.setnx('userlist_update_conversation_per_hour_lock', expire_time.strftime('%Y-%m-%d %H:%M:%S')):
        redis_expire_time_str = doctor_cache.get('userlist_update_conversation_per_hour_lock')
        redis_expire_time = datetime.datetime.strptime(redis_expire_time_str, '%Y-%m-%d %H:%M:%S')
        if end_time > redis_expire_time:
            doctor_cache.set('userlist_update_conversation_per_hour_lock', expire_time.strftime('%Y-%m-%d %H:%M:%S'))
        else:
            return None
    conversation_start_id = doctor_cache.get('conversation_start_id')
    if not conversation_start_id:
        # if UserList.objects.all().exclude(conversation_id=None).order_by('conversation_id').first():
        #     conversation_start_id = UserList.objects.all().exclude(conversation_id=None).order_by('conversation_id').first().conversation_id
        # else:
        #     conversation_start_id = 0
        conversation_start_time = datetime.datetime.strptime('2019-09-09 00:00:00', '%Y-%m-%d %H:%M:%S')
        conversations = Conversation.objects.filter(created_time__gte=conversation_start_time).order_by('id')
    else:
        conversations = Conversation.objects.filter(id__gt=conversation_start_id).order_by('id')

    for conversation in conversations:
        """
        通过订单所属的商户号和user_id在userlist表中匹配
        """
        print(conversation.id)
        if UserList.objects.filter(conversation_id=conversation.id):
            continue
        user_list = conversation.user_status_set.values_list('user_id')
        """
        分别获取医生和用户的user_id
        """
        doctor_user_id = user_id = None
        for item in user_list:
            if Doctor.objects.filter(user_id=item[0]):
                doctor_user_id = item[0]
            else:
                user_id = item[0]
        if not doctor_user_id or not user_id:
            continue
        doctor_id = Doctor.objects.get(user_id=doctor_user_id).id
        merchantrelevance = MerchantRelevance.objects.filter(doctor_id=doctor_id).first()
        if merchantrelevance:
            merchant_id = merchantrelevance.merchant_id
        else:
            continue
        """
        判断当前私信归属：1、新用户的私信，2、已有用户的旧私信，3、已有用户的新私信
        """
        obj = UserList.objects.filter(user_id=user_id, merchant_id=merchant_id).first()
        if obj:
            if obj.conversation_id < conversation.id:
                obj.conversation_id = conversation.id
                obj.conversation_created_time = conversation.created_time
                obj.doctor_user_id = doctor_user_id
                obj.save()
        else:
            defaults = {'doctor_user_id': doctor_user_id,'conversation_id':conversation.id,'conversation_created_time':conversation.created_time,'modify_time':datetime.datetime.today()}
            kwargs = {'merchant_id': merchant_id, 'user_id': user_id}
            UserList.objects.update_or_create(defaults=defaults, **kwargs)
    if conversations:
        doctor_cache.set('conversation_start_id', conversations.last().id)
    doctor_cache.delete('userlist_update_conversation_per_hour_lock')


@shared_task
def userlist_update_browse_per_hour():
    """
    通过browse_id更新用户30天内最新浏览记录
    """
    doctor_cache = redis.StrictRedis(**settings.REDIS['doctor'])
    end_time = datetime.datetime.today()
    expire_time = end_time + datetime.timedelta(hours=2)
    if not doctor_cache.setnx('userlist_update_browse_per_hour_lock', expire_time.strftime('%Y-%m-%d %H:%M:%S')):
        redis_expire_time_str = doctor_cache.get('userlist_update_browse_per_hour_lock')
        redis_expire_time = datetime.datetime.strptime(redis_expire_time_str, '%Y-%m-%d %H:%M:%S')
        if end_time > redis_expire_time:
            doctor_cache.set('userlist_update_browse_per_hour_lock', expire_time.strftime('%Y-%m-%d %H:%M:%S'))
        else:
            return None
    browse_start_id = doctor_cache.get('browse_start_id')
    if not browse_start_id:
        # if UserList.objects.all().exclude(browse_time=None).order_by('browse_id').first():
        #     browse_start_id = UserList.objects.all().exclude(browse_time=None).order_by('browse_id').first().browse_id
        # else:
        #     browse_start_id = 0
        browsing_start_time = datetime.datetime.strptime('2019-09-18 11:00:00', '%Y-%m-%d %H:%M:%S')
        browses = MerchantPvStat.objects.filter(browsing_time__gte=browsing_start_time).order_by('id')
    else:
        browses = MerchantPvStat.objects.filter(id__gt=browse_start_id).order_by('id')

    for browse in browses:
        """
        通过订单所属的merchant_id和user_id在userlist表中匹配
        """
        print(browse.id)
        # if UserList.objects.filter(browse_id=browse.id):
        #     continue
        user_id = browse.user_id
        merchant_id = browse.merchant_id
        """
        判断当前浏览记录归属：1、已有用户的历史浏览记录，2、已有用户的新浏览记录
        """
        obj = UserList.objects.filter(user_id=user_id,merchant_id=merchant_id).first()
        if obj:
            if obj.browse_id < browse.id:
                obj.browse_id = browse.id
                obj.browse_time = browse.browsing_time
                obj.save()
    """
    清除最新浏览记录在30天以前数据
    """
    end_time = datetime.datetime.today()-datetime.timedelta(days=30)
    users = UserList.objects.filter(browse_time__lt=end_time)
    if users:
        users.update(browse_id=None, browse_time=None, modify_time=datetime.datetime.today())
    if browses:
        doctor_cache.set('browse_start_id', browses.last().id)
    doctor_cache.delete('userlist_update_browse_per_hour_lock')


@shared_task
def account_merchant_charge(end_time=None):
    if not end_time:
        today = datetime.datetime.now()
        end_time = datetime.datetime(today.year, today.month, 1, 0, 0, 0)
    else:
        end_time = datetime.datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S')
        end_time = datetime.datetime(end_time.year, end_time.month, 1, 0, 0, 0)
    if end_time.month == 1:
        start_time = datetime.datetime(end_time.year - 1, 12, 1, 0, 0, 0)
    else:
        start_time = datetime.datetime(end_time.year, end_time.month - 1, 1, 0, 0, 0)

    dt_success = tablib.Dataset()
    dt_success.headers = (u'商户名称', u'医生id', u'BD组', u'BD', u'充值金额', u'佣金', u'本月商家等级')
    data = Merchant.objects.only('id').order_by('id')
    length = data.count()
    step = 1000
    j = 0
    while j <= length:
        doctor_ids = {}
        result = {}
        # 获取所有医生的id
        objs = data[j:(j + step)]
        for i in objs:
            key = i.id
            print(key)
            doctor_ids_set = list(i.merchant_doctors.all().values_list('doctor_id', flat=True))
            doctor_ids[str(key)] = doctor_ids_set
            # 计算订单，买单，补单
            # #订单
            orders = Order.objects.filter(service__doctor_id__in=doctor_ids_set, validate_time__gte=start_time,
                                          validate_time__lt=end_time, status=ORDER_STATUS.USED)
            res_dict = orders.aggregate(sum=Sum("discount"))
            order_sum = res_dict.get("sum") if res_dict.get("sum") else 0.00
            # 买单
            res_dict = MaidanOrder.objects.filter(doctor_id__in=doctor_ids_set, payment_time__gte=start_time,
                                                  payment_time__lt=end_time,
                                                  status=ORDER_STATUS.PAID).aggregate(
                sum=Sum("discount_cent"))
            maidan_sum = res_dict.get("sum") / 100 if res_dict.get("sum") else 0.00
            # 补单录入
            res_dict = BuDanLuRu.objects.filter(doctor_id__in=doctor_ids_set, created_time__gte=start_time,
                                                created_time__lt=end_time, status=BUDAN_LURU_STATUS.ENTERED,
                                                type=BUDAN_LURU_TYPE.COMMON).aggregate(sum=Sum("amount"))
            budanluru_sum = res_dict.get("sum") if res_dict.get("sum") else 0.00
            result[i.id] = order_sum + maidan_sum + budanluru_sum
        # 按医生的维度获取GMV以及广告消耗
        # 初始化rpc对像
        invoker = create_default_invoker(debug=settings.DEBUG)
        rpc_client = invoker['artemis/account/recharge/amount'](doctor_ids=doctor_ids, start_time=start_time.strftime('%Y-%m-%d %H:%M:%S'), end_time=end_time.strftime('%Y-%m-%d %H:%M:%S'))
        res = rpc_client.unwrap()
        # 计算商户得分
        for obj in objs:
            print(obj.id)
            try:
                user = obj.doctor.business_partener
                business = user.username if not user.last_name or '***' in user.last_name else user.last_name
            except:
                business = ''
            try:
                team_name = Team.objects.get(id=obj.doctor.business_group).name
            except:
                team_name = ''
            charge_amount = res.get(str(obj.id), 0.0)
            commission_amount = result.get(obj.id, 0.0)
            dt_success.append((obj.name, str(obj.doctor.user_id), team_name, business, charge_amount, commission_amount, MERCHANT_LEVEL_NEW.getDesc(obj.merchant_level)))
        j += step
    get_mail(u'商家充值信息.xls', u'商家充值信息', settings.MERCHANT_CHARGE, dt_success.xls).send()


@shared_task
def merchant_level_info(begin_time=None, month=6):
    if not begin_time:
        today = datetime.datetime.now()
        if today.month > month:
            begin_time = datetime.datetime(today.year, today.month - month, 1, 0, 0)
        else:
            begin_time = datetime.datetime(today.year - 1, today.month - month + 12, 1, 0, 0)
    else:
        begin_time = datetime.datetime.strptime(begin_time, '%Y-%m-%d %H:%M:%S')
    dt_success = tablib.Dataset()
    start_time = begin_time
    discount_months = []
    advertise_discount_months = []
    k = 1
    discount_month = start_time.month
    for i in range(int(month)):
        if discount_month < 13:
            discount_months.append(u'抽成{}-{}'.format(start_time.year, discount_month))
            advertise_discount_months.append(u'广告消耗{}-{}'.format(start_time.year, discount_month))
            discount_month += 1
        else:
            discount_months.append(u'抽成{}-{}'.format(start_time.year + 1, k))
            advertise_discount_months.append(u'广告消耗{}-{}'.format(start_time.year + 1, k))
            discount_month += 1
            k += 1
    title = (u'商户名称', u'商户id' ,u'BD', u'BD组', u'{}月份佣金返点'.format(discount_months[-1][2:])) + tuple(discount_months) + tuple(advertise_discount_months) + (u'商家等级', )
    dt_success.headers = title
    merchants = Merchant.objects.only('id').order_by('-merchant_level')
    invoker = create_default_invoker(debug=settings.DEBUG)
    # 获取所有医生的id
    for merchant in merchants:
        key = merchant.id
        print(key)
        doctor_ids = list(merchant.merchant_doctors.all().values_list('doctor_id', flat=True))
        start_time = begin_time
        #按照月份循环查询，通过起始时间于结束时间选定单个月份
        discount_amount_ls = []
        for i in range(int(month)):
            if start_time.month < 12:
                end_time = datetime.datetime(start_time.year, start_time.month + 1, start_time.day, 0, 0, 0)
            else:
                end_time = datetime.datetime(start_time.year + 1, start_time.month - 11, start_time.day, 0, 0, 0)
            # 计算订单，买单，补单GMV
            #订单
            orders = Order.objects.filter(service__doctor_id__in=doctor_ids, validate_time__gte=start_time, validate_time__lt=end_time, status=ORDER_STATUS.USED)
            res_dict = orders.aggregate(sum=Sum("discount"))
            order_sum = res_dict.get("sum") if res_dict.get("sum") else 0.00
            # 买单
            res_dict = MaidanOrder.objects.filter(doctor_id__in=doctor_ids, payment_time__gte=start_time,
                                                  payment_time__lt=end_time,
                                                  status=ORDER_STATUS.PAID).aggregate(
                sum=Sum("discount_cent"))
            maidan_sum = res_dict.get("sum") / 100.0 if res_dict.get("sum") else 0.00
            # 补单录入
            res_dict = BuDanLuRu.objects.filter(doctor_id__in=doctor_ids, created_time__gte=start_time,
                                                created_time__lt=end_time, status=BUDAN_LURU_STATUS.ENTERED,
                                                type=BUDAN_LURU_TYPE.COMMON).aggregate(sum=Sum("amount"))
            budanluru_sum = res_dict.get("sum") if res_dict.get("sum") else 0.00
            total_amount = order_sum + maidan_sum + budanluru_sum
            discount_amount_ls.append(total_amount)
            start_time = end_time
        try:
            user = merchant.doctor.business_partener
            business = user.username if not user.last_name or '***' in user.last_name else user.last_name
        except:
            business = ''
        try:
            team_name = Team.objects.get(id=merchant.doctor.business_group).name
        except:
            team_name = ''
        #广告消耗分月汇总
        rpc_client = invoker['artemis/account/accountflow/month_sum'](doctor_ids=doctor_ids, start_time=begin_time.strftime("%Y-%m-%d %H:%M:%S"), month=month)
        res = rpc_client.unwrap()
        #返点计算。最后一个月抽成 * 返点比例（根据商家等级划分）
        last_month_discount = discount_amount_ls[-1]
        cashback = settings.MERCHANT_CASHBACK.get(merchant.merchant_level, 0) * last_month_discount
        row_data = (merchant.name, str(merchant.id), business, team_name, int(cashback)) + tuple(discount_amount_ls) + tuple(res) + (MERCHANT_LEVEL_NEW.getDesc(merchant.merchant_level), )
        dt_success.append(row_data)
    get_mail(u'商户抽成及广告消耗统计统计.xls', u'商户订单、买单、补单抽成以及广告消耗', settings.MERCHANT_LEVEL_INFO, dt_success.xls).send()


@shared_task
def merchant_level_discount_cashback(end_time=None):
    dt_success = tablib.Dataset()
    dt_success.headers = (u'商户id', u'返现金额', u'返现结果')
    if not end_time:
        today = datetime.datetime.now()
        end_time = datetime.datetime(today.year, today.month, 1, 0, 0, 0)
    else:
        end_time = datetime.datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S')
        end_time = datetime.datetime(end_time.year, end_time.month, 1, 0, 0, 0)
    if end_time.month == 1:
        start_time = datetime.datetime(end_time.year - 1, 12, 1, 0, 0, 0)
    else:
        start_time = datetime.datetime(end_time.year, end_time.month - 1, 1, 0, 0, 0)
    merchants = Merchant.objects.filter(merchant_level__gte=MERCHANT_LEVEL_NEW.V5).only('id')
    for merchant in merchants:
        print(merchant.id)
        # 获取所有医生的id
        doctor_ids = list(merchant.merchant_doctors.all().values_list('doctor_id', flat=True))
        # 计算订单，买单，补单
        # #订单
        orders = Order.objects.filter(service__doctor_id__in=doctor_ids, validate_time__gte=start_time,
                                      validate_time__lt=end_time, status=ORDER_STATUS.USED)
        res_dict = orders.aggregate(sum=Sum("discount"))
        order_sum = res_dict.get("sum") if res_dict.get("sum") else 0.00
        # 买单
        res_dict = MaidanOrder.objects.filter(doctor_id__in=doctor_ids, payment_time__gte=start_time,
                                              payment_time__lt=end_time,
                                              status=ORDER_STATUS.PAID).aggregate(
            sum=Sum("discount_cent"))
        maidan_sum = res_dict.get("sum") / 100.0 if res_dict.get("sum") else 0.00
        # 补单录入
        res_dict = BuDanLuRu.objects.filter(doctor_id__in=doctor_ids, created_time__gte=start_time,
                                            created_time__lt=end_time, status=BUDAN_LURU_STATUS.ENTERED,
                                            type=BUDAN_LURU_TYPE.COMMON).aggregate(sum=Sum("amount"))
        budanluru_sum = res_dict.get("sum") if res_dict.get("sum") else 0.00
        #计算返点金额
        discount_amount = order_sum + maidan_sum + budanluru_sum
        cashback_amount = settings.MERCHANT_CASHBACK.get(merchant.merchant_level, 0) * discount_amount
        # 初始化rpc对像
        invoker = create_default_invoker(debug=settings.DEBUG)
        cashback_month = end_time.strftime('%Y-%m-%d %H:%M:%S')
        rpc_client = invoker['artemis/account/merchant_cashback'](doctor_id=merchant.doctor_id, cashback_amount=int(cashback_amount), discount_amount=0, cashback_month=cashback_month, remark=u'佣金返点')
        res = rpc_client.unwrap()
        dt_success.append((str(merchant.id), str(int(cashback_amount)), res))
    get_mail(u'商家按级别自动返点.xls', u'商家返点', [u'songzhenqi@igengmei.com', u'weiyujie@igengmei.com'], dt_success.xls).send()
