# encoding=utf-8
from __future__ import unicode_literals
import datetime
import json
import math
from django.conf import settings
from django.db import transaction
from django.db import IntegrityError
from django.db.models import Max, Min, Q
from gm_types.doctor import HOSPITAL_MEDICAL_TYPE
from gm_types.gaia import SERVICE_REVIEW_STATUS, SERVICE_REVIEW_TYPE, TREATMENT_MEANS_CHOICES, \
    CommodityCategoryProperty, TAG_TYPE
from gm_types.gaia import SERVICE_SELL_TYPE, OPERTOR_REVIEW_TYPE, DOCTOR_USE_COUPON_TYPE

from agile.models import TagMapOldTag
from api.models import ServiceRegister, ServiceRegisterAttr, ServiceRegisterItem, ServiceTag, Tag, \
    ServiceRegisterItemKey, ServiceReviewRecord, ServiceItemKey, TagAttr, AttrOptions, ItemWiki, TagWiki, Special, \
    SpecialSeckillService, SpecialItem, ServiceVideo, ServiceRegisterVideo, SKUExamine, Coupon, MerchantRelevance, \
    Merchant, AuditAttrOptions, CommodityCategoryRelation, CommodityCategory, CommodityCategoryPropertyRelation, TagV3, \
    ServiceNewTag, ServiceRegisterTag
from api.models import ServiceRegisterAttrOption, Service, ServiceAttr, ServiceAttrOption, ServiceItem, \
    CouponSKURestrict
from api.models.types import SERVICEREGISTER_STATUS, SERVICE_TYPE, PAYMENT_TYPE, DOCTOR_TYPE, SERVICE_FLAG
from hera.queries.serviceregister import ReviewRecordDQ
from hera.queries.serviceregisteroffline import ServiceRegisterOfflineDQ
from hera.decorator import lock_serviceregister
from rpc.decorators import bind_context
from rpc.exceptions import (RPCPermissionDeniedException, RPCIntegrityError,
                            RPCNotFoundException)
from rpc.tool.dict_mixin import to_dict
from rpc.tool.error_code import gen, CODES
from rpc.tool.log_tool import info_logger, exception_logger
from api.tool.user_tool import get_portrait_by_user, get_user_from_context
from ..datatables import ServiceRegisterDT
from ..helpers import send_email
from ..models import UserPerm
from ..utils import check_business, check_operate, operate_business
from api.tasks.doctor_rank_task import delete_service_rank
from api.tasks.service_task import refresh_service_cache_info
from api.manager.service_info_manager import get_sku_id_to_sku_name_info, get_register_sku_id_to_sku_name_info

uri_pre = 'hera/serviceregister'
default_ordering = 10000


@bind_context(uri_pre + '/data')
def serviceregister_data(ctx, serviceregister_id, options=None):
    try:
        serviceregister = ServiceRegister.objects.get(id=serviceregister_id)
    except:
        raise RPCNotFoundException
    if options is None:
        options = {
            'fields': None,
            'excludes': None,
            'expands': None,
        }
    data = to_dict(serviceregister, **options)
    data['short_description'] = serviceregister.service.short_description
    data['image_header'] = serviceregister.service.image_header
    data['tip'] = serviceregister.service.tip
    data['tags'] = serviceregister.service.tags.last().id \
        if serviceregister.service and serviceregister.service.tags.all() else ''
    data['detail_description'] = serviceregister.service.detail_description
    items = []
    for item in serviceregister.service.items.all():
        item_data = to_dict(item)
        item_data['attrs'] = item.items_name
        items.append(item_data)
    data['items'] = items
    data['attrs'] = [attr.name for attr in serviceregister.service.attrs.all()]
    return data


@bind_context(uri_pre + '/edit')
def serviceregister_edit(ctx, serviceregister_id=None, serviceregister_info=None):
    if serviceregister_info is None:
        return None

    serviceregister_info['doctor_id'] = serviceregister_info.pop('doctor') or None
    serviceregister_info['start_time'] = serviceregister_info.pop('start_time') or None
    serviceregister_info['end_time'] = serviceregister_info.pop('end_time') or None
    serviceregister_info['status'] = serviceregister_info.pop('status') or None
    if serviceregister_info['status'] not in [SERVICEREGISTER_STATUS.DRAFT, SERVICEREGISTER_STATUS.STAY,
                                              SERVICEREGISTER_STATUS.WAIT_AUDIT, SERVICEREGISTER_STATUS.REJECT]:
        return {
            'status': False,
            'message': u'原状态不正确 请刷新页面重试'
        }
    if serviceregister_id is None:
        try:
            serviceregister = ServiceRegister.objects.create(**serviceregister_info)
            # 创建时将当前用户设为创建人
            serviceregister.user = get_user_from_context(ctx)
            serviceregister.save()
        except IntegrityError:
            raise RPCIntegrityError
    else:
        try:
            serviceregister = ServiceRegister.objects.get(id=serviceregister_id)
        except:
            info_logger.info(__import__('traceback').format_exc())
            raise RPCNotFoundException
        if serviceregister_info['status'] == SERVICEREGISTER_STATUS.WAIT_AUDIT:
            serviceregister.submit_time = datetime.datetime.now()
        for k, v in serviceregister_info.iteritems():
            setattr(serviceregister, k, v)
        serviceregister.save()
    return {
        'status': True,
        'message': u'保存成功'
    }


@bind_context(uri_pre + '/audit_pass')
def audit_pass(ctx, serviceregister_id):
    try:
        serviceregister = ServiceRegister.objects.get(id=serviceregister_id)
    except ServiceRegister.DoesNotExist:
        raise RPCNotFoundException
    if serviceregister.status not in [SERVICEREGISTER_STATUS.WAIT_AUDIT, SERVICEREGISTER_STATUS.SPECIAL_APPROVAL]:
        return {
            'status': False,
            'message': u'原状态不正确 请刷新页面重试'
        }

    if serviceregister.service:
        service = serviceregister.service
        action = 'modify'
    else:
        service = Service()
        action = 'create'

    serviceregister.audit_time = datetime.datetime.now()
    serviceregister.approver = get_user_from_context(ctx)
    if serviceregister.doctor and serviceregister.doctor.hospital.city:
        service.name = "【{}@{}】{}".format(
            serviceregister.doctor.hospital.city,
            serviceregister.doctor.name,
            serviceregister.name,
        )
    else:
        service.name = serviceregister.name

    if serviceregister.extra_charge:
        service.special_remind = "【额外费用】\n" + serviceregister.extra_charge
    else:
        service.special_remind = "【】"
    service.short_description = serviceregister.name
    service.reservation = serviceregister.reservation
    service.refund_anytime = serviceregister.refund_anytime
    service.is_stage = serviceregister.is_stage
    service.compensation_in_advance = serviceregister.compensation_in_advance
    service.show_location = serviceregister.show_location
    service.user_safe = serviceregister.user_safe
    if serviceregister.start_time:
        service.start_time = serviceregister.start_time
    else:
        service.start_time = datetime.datetime.now()
    if serviceregister.delay:
        service.end_time = (service.start_time + datetime.timedelta(
            days=int(serviceregister.delay))).strftime(
            '%Y-%m-%d %X')
    if serviceregister.end_time:
        service.end_time = serviceregister.end_time
    item = serviceregister.items.filter(is_online=True).last()
    if not item:
        raise RPCNotFoundException
    service.total_num = serviceregister.total_num
    service.ceiling_price = serviceregister.items.filter(is_online=True).aggregate(
        pre=Max('gengmei_price')).get('pre')
    service.single_user_buy_limit = serviceregister.single_user_buy_limit
    service.valid_duration = serviceregister.valid_duration
    service.fake_sold_num = serviceregister.fake_sold_num
    service.doctor = serviceregister.doctor
    service.exchange_points_ceiling = 0
    if serviceregister.items.all().count() >= 2:
        service.is_multiattribute = True
    else:
        service.is_multiattribute = False
    service.gengmei_price = serviceregister.items.filter(is_online=True).aggregate(
        pre=Min('gengmei_price')).get('pre')
    service.cash_back_rate = item.cash_back_rate
    service.discount = int(item.gengmei_price * item.discount * 0.01)
    if item.pre_payment_price_int:
        pre_payment_price = item.pre_payment_price_int
    else:
        pre_payment_price = int(item.pre_payment_price * 0.01 * item.gengmei_price)
    service.pre_payment_price = pre_payment_price
    service.total_price = service.pre_payment_price
    service.original_price = item.original_price
    if action == 'create':
        service.ordering = default_ordering
    service.sell_num_limit = service.real_stock
    service.payment_type = PAYMENT_TYPE.PREPAYMENT
    if serviceregister.doctor.doctor_type == DOCTOR_TYPE.DOCTOR:
        service.service_flag = SERVICE_FLAG.DOCTOR
    else:
        service.service_flag = SERVICE_FLAG.HOSPITAL
        if serviceregister.doctor.hospital:
            service.hospital = serviceregister.doctor.hospital
    service.share_get_cashback = False
    service.is_operation = serviceregister.is_operation
    service.save()

    if action == 'create':
        serviceregister.service = service
        serviceregister.save()

    items_keys = {}
    old_attrs = []
    old_options = []
    for attr in service.attrs.all():
        old_attrs.append(attr.id)
        for option in attr.options.all():
            old_options.append(option.id)
    new_attrs = []
    new_options = []
    for attr in serviceregister.attrs.all().filter(checked=True):
        new_attr, _ = ServiceAttr.objects.get_or_create(name=attr.name, service=service)
        new_attrs.append(new_attr.id)
        for option in attr.options.all().filter(checked=True):
            new_option, _ = ServiceAttrOption.objects.get_or_create(name=option.name, service_attr=new_attr)
            items_keys[option.id] = new_option.id
            new_options.append(new_option.id)
    ServiceAttrOption.objects.filter(id__in=(set(old_options) - set(new_options))).delete()
    ServiceAttr.objects.filter(id__in=(set(old_attrs) - set(new_attrs))).delete()
    new_items = []
    old_items = [item.id for item in service.items.all()]
    for item in serviceregister.items.filter(is_online=True):
        keys_data = item.key.split('-')
        keys = [int(key) for key in keys_data]
        if len(keys) > 1:
            if not (items_keys.get(keys[0], None) and items_keys.get(keys[1], None)):
                continue
            if items_keys[keys[0]] < items_keys[keys[1]]:
                key = '{}-{}'.format(items_keys[keys[0]], items_keys[keys[1]])
            else:
                key = '{}-{}'.format(items_keys[keys[1]], items_keys[keys[0]])
        else:
            if not items_keys.get(keys[0], None):
                continue
            key = items_keys[keys[0]]
        item_data = to_dict(item)
        item_data.pop('seckill_price')
        item_data.pop('service_register')
        item_data.pop('is_online')
        item_data.pop('id')
        item_data.pop('key')
        item_data['service_id'] = service.id
        item_data['discount'] = item_data['gengmei_price'] * item_data['discount'] * 0.01
        if item_data['pre_payment_price_int']:
            pre_payment_price = item_data['pre_payment_price_int']
        else:
            pre_payment_price = item_data['gengmei_price'] * item_data['pre_payment_price'] * 0.01
        item_data.pop('pre_payment_price_int')
        item_data['pre_payment_price'] = pre_payment_price
        sis = ServiceItem.objects.filter(parent_id=0, key=key, service=service)
        if sis.exists():
            serviceitem = sis.first()
        else:
            serviceitem = ServiceItem.objects.create(key=key, service=service)
        for k, v in item_data.iteritems():
            setattr(serviceitem, k, v)
        serviceitem.save()
        new_items.append(serviceitem.id)
    ServiceItem.objects.filter(parent_id=0, id__in=(set(old_items) - set(new_items))).delete()
    service.save()
    serviceregister.service = service
    serviceregister.status = SERVICEREGISTER_STATUS.PASS
    serviceregister.save()
    return {
        'status': True,
        'message': u'保存成功'
    }


@bind_context(uri_pre + '/reject')
def audit_reject(ctx, serviceregister_id, reason_info):
    try:
        serviceregister = ServiceRegister.objects.get(id=serviceregister_id)
    except ServiceRegister.DoesNotExist:
        raise RPCNotFoundException
    if serviceregister.status not in [SERVICEREGISTER_STATUS.WAIT_AUDIT, SERVICEREGISTER_STATUS.SPECIAL_APPROVAL]:
        return {
            'status': False,
            'message': u'原状态不正确 请刷新页面重试'
        }
    serviceregister.status = SERVICEREGISTER_STATUS.REJECT
    reason = ''
    reason_info = json.loads(reason_info)
    if reason_info[0].strip():
        serviceregister.reason += reason_info[0].strip()
        reason += reason_info[0] + '\n'
    if reason_info[1].strip():
        serviceregister.reason1 += reason_info[1].strip()
        reason += reason_info[1] + '\n'
    if reason_info[2].strip():
        serviceregister.reason2 += reason_info[2].strip()
        reason += reason_info[2] + '\n'

    serviceregister.save()
    title = '您的{}上线申请被拒绝'.format(serviceregister.name)
    body = '您的{}上线申请被拒绝\n拒绝原因:{}'.format(serviceregister.name, reason)
    to_email_list = [serviceregister.user.email]
    send_email(to_email_list, title, body)
    return {
        'status': True,
        'message': u'驳回成功'
    }


@bind_context(uri_pre + '/change')
def audit_reject(ctx, serviceregister_id):
    try:
        serviceregister = ServiceRegister.objects.get(id=serviceregister_id)
    except ServiceRegister.DoesNotExist:
        raise RPCNotFoundException
    serviceregister.status = SERVICEREGISTER_STATUS.DRAFT
    if serviceregister.service:
        serviceregister.service.is_online = False
        serviceregister.service.save()
    serviceregister.save()
    return {
        'status': True,
        'message': u'申请修改成功',
        'id': serviceregister.id,
    }


@bind_context(uri_pre + '/special_approval')
def special_approval(ctx, serviceregister_id):
    try:
        serviceregister = ServiceRegister.objects.get(id=serviceregister_id)
    except ServiceRegister.DoesNotExist:
        raise RPCNotFoundException
    if serviceregister.status != SERVICEREGISTER_STATUS.WAIT_AUDIT:
        return {
            'status': False,
            'message': u'原状态不正确 请刷新页面重试'
        }
    serviceregister.status = SERVICEREGISTER_STATUS.SPECIAL_APPROVAL
    serviceregister.save()
    return {
        'status': True,
        'message': u'申请特批成功'
    }


@bind_context(uri_pre + '/datatable')
def serviceregister_datatable(ctx, req_data):
    dtobj = ServiceRegisterDT(ServiceRegister)
    return dtobj.process(req_data, ['name',
                                    'doctor__name',
                                    'doctor__hospital__name',
                                    'doctor__business_partener__username'])


@bind_context(uri_pre + '/get')
def serviceregister_detail(ctx, serviceregister_id, options=None):
    """get serviceregister detail by serviceregister_id

    """
    try:
        serviceregister = ServiceRegister.objects.get(id=serviceregister_id)
    except:
        raise RPCNotFoundException
    if options is None:
        options = {
            'fields': None,
            'excludes': None,
            'expands': None,
        }
    service_data = to_dict(serviceregister, **options)
    service_data['reasonadd'] = ''
    service_data['reason1add'] = ''
    service_data['reason2add'] = ''
    attrs = []
    for attr in serviceregister.attrs.all():
        attr_data = to_dict(attr)
        options_data = []
        for option in attr.options.all():
            options_data.append(to_dict(option))
        attr_data['options'] = options_data
        attrs.append(attr_data)
    service_data['attrs'] = attrs
    datas = []
    for item in serviceregister.items.filter(is_online=True):
        data = to_dict(item, **options)
        result = []
        for attr in item.key.split('-'):
            option = ServiceRegisterAttrOption.objects.get(pk=attr)
            result.append(option.name)
        data['name'] = '+'.join(result)
        datas.append(data)
    service_data['order_amount'] = serviceregister.service.sell_amount if serviceregister.service else 0
    service_data['sell_num_limit'] = serviceregister.service.sell_num_limit if serviceregister.service else 0
    service_data['items'] = datas
    service_data['type'] = SERVICE_TYPE.OPERATION
    return service_data


@bind_context(uri_pre + '/createattr')
def serviceregister_attrcreate(ctx, serviceregister_id, name):
    try:
        serviceregister = ServiceRegister.objects.get(id=serviceregister_id)
    except:
        raise RPCNotFoundException
    attr = serviceregister.attrs.create(name=name)
    return to_dict(attr)


@bind_context(uri_pre + '/createoption')
def serviceregister_attrcreate(ctx, attr_id, name):
    try:
        serviceregisterattr = ServiceRegisterAttr.objects.get(id=attr_id)
    except:
        raise RPCNotFoundException
    option = serviceregisterattr.options.create(name=name)
    return to_dict(option)


@bind_context(uri_pre + '/getoption')
def serviceregister_getoption(ctx, attr_id):
    try:
        serviceregisterattr = ServiceRegisterAttr.objects.get(id=attr_id)
    except:
        raise RPCNotFoundException
    data = []
    for option in serviceregisterattr.options.all():
        data.append(to_dict(option))
    return data


@bind_context(uri_pre + '/items_update')
def serviceregister_items_update(ctx, serviceregister_id, items):
    try:
        serviceregister = ServiceRegister.objects.get(id=serviceregister_id)
    except:
        raise RPCNotFoundException
    serviceregister.items.all().update(is_online=False)
    attrs = []
    for item in items:
        try:
            temp = ServiceRegisterItem.objects.get(key=item['key'])
        except ServiceRegisterItem.DoesNotExist:
            temp = ServiceRegisterItem.objects.create(service_register_id=serviceregister.id)
        except:
            raise
        for k, v in item.iteritems():
            setattr(temp, k, v)
        temp.save()
        if isinstance(temp.key, int):
            attrs.append(temp.key)
        else:
            for attr in temp.key.split('-'):
                attrs.append(attr)
    new_attrs = list(set(attrs))
    serviceregister.attrs.all().update(checked=False)
    for attr in serviceregister.attrs.all():
        attr.options.all().update(checked=False)
    options = ServiceRegisterAttrOption.objects.filter(id__in=new_attrs)
    options.update(checked=True)
    for option in options:
        option.service_register_attr.checked = True
        option.service_register_attr.save()
    return 'data'


@bind_context(uri_pre + '/items_get')
def serviceregister_items_get(ctx, item_keys):
    data = {}
    for item_key in item_keys:
        try:
            item = ServiceRegisterItem.objects.get(key=item_key)
            item = to_dict(item)
        except:
            item = {
                'key': 0,
                'pre_payment_price': 20,
                'pre_payment_price_int': 0,
                'original_price': 0,
                'gengmei_price': 0,
                'discount': 10,
                'is_online': True
            }
        data[item_key] = item
    return data


@bind_context(uri_pre + '/savedata')
def serviceregister_edit(ctx, serviceregister_id=None, service_info=None, data=None):
    if service_info is None:
        return None

    tags = [service_info.pop('tags')] or None
    ordering = service_info.pop('ordering') or None
    if not service_info['is_online']:
        service_info.pop('is_online')

    try:
        serviceregister = ServiceRegister.objects.get(id=serviceregister_id)
    except:
        info_logger.info(__import__('traceback').format_exc())
        raise RPCNotFoundException
    service = serviceregister.service
    for k, v in service_info.iteritems():
        setattr(service, k, v)
    if tags:
        new_tags = set(Tag.objects.filter(id__in=tags))
        old_tags = set(service.tags.all())
        for tag_obj in (new_tags - old_tags):
            ServiceTag.objects.get_or_create(
                service_id=service.id,
                tag=tag_obj)
        ServiceTag.objects.filter(service_id=service.id,
                                  tag__in=(old_tags - new_tags)).delete()
    service.sell_num_limit = service.real_stock
    serviceregister.service_name = service_info['service_name']
    serviceregister.ordering = ordering
    if data['status'] == SERVICEREGISTER_STATUS.IS_ONLINE:
        serviceregister.online_time = datetime.datetime.now()
        serviceregister.status = data['status']
        service.is_online = True
        service.ordering = serviceregister.ordering
        if service_info['service_name']:
            service.name = service_info['service_name']
    if data['status'] == SERVICEREGISTER_STATUS.WAIT_ONLINE:
        serviceregister.edit_time = datetime.datetime.now()
        if serviceregister.status == SERVICEREGISTER_STATUS.PASS:
            serviceregister.status = data['status']
    service.save()
    serviceregister.save()
    return service.id


@bind_context(uri_pre + '/create')
def serviceregister_create(ctx):
    user = get_user_from_context(ctx)
    serviceregister, _ = ServiceRegister.objects.get_or_create(status=SERVICEREGISTER_STATUS.STAY, user=user)
    attrs = []
    for attr in serviceregister.attrs.all():
        attr_data = to_dict(attr)
        options_data = []
        for option in attr.options.all():
            options_data.append(to_dict(option))
        attr_data['options'] = options_data
        attrs.append(attr_data)
    serviceregister = to_dict(serviceregister)
    serviceregister['attrs'] = attrs
    serviceregister['reasonadd'] = u''
    serviceregister['reason1add'] = u''
    serviceregister['reason2add'] = u''
    return serviceregister


# @bind_context(uri_pre + '/items_edit')
# def items_edit(ctx, items):
#     info = []
#     share_get_cashback = False
#     points_deduction_percent = 0
#     for obj in items:
#         item = ServiceItem.objects.get(pk=obj['key'])
#         item.points_deduction_percent = obj['points_deduction_percent']
#         if str(obj['cash_back_rate']) != '0':
#             share_get_cashback = True
#         item.cash_back_rate = obj['cash_back_rate']
#         item.topic_cash_back_limit = obj['topic_cash_back_limit']
#         cash_back_rate = item.cash_back_rate
#         points_deduction_percent = item.points_deduction_percent
#         item.save()
#         info.append(obj['key'])
#     item.service.share_get_cashback = share_get_cashback
#     item.service.cash_back_rate = cash_back_rate
#     item.service.points_deduction_percent = points_deduction_percent
#     item.service.save()
#     return info


@bind_context(uri_pre + '/copy')
def serviceregister_copy(ctx, serviceregister_id):
    try:
        sr = ServiceRegister.objects.get(id=serviceregister_id)
    except ServiceRegister.DoesNotExist:
        raise RPCNotFoundException
    attrs = sr.attrs.all()
    items = sr.items.all()
    items_keys = {}
    sr.id = None
    sr.name += ' 副本'
    sr.approver = None
    sr.status = SERVICEREGISTER_STATUS.DRAFT
    sr.user = get_user_from_context(ctx)
    sr.service = None
    sr.audit_time = None
    sr.edit_time = None
    sr.online_time = None
    sr.save()
    for attr in attrs:
        options = attr.options.all()
        attr.id = None
        attr.service_register = sr
        attr.save()
        for option in options:
            old_id = option.id
            option.id = None
            option.service_register_attr = attr
            option.save()
            items_keys[old_id] = option.id

    for item in items:
        keys_data = item.key.split('-')
        keys = [int(key) for key in keys_data]
        if len(keys) > 1:
            if not items_keys.get(keys[0], None) and items_keys.get(keys[1], None):
                continue
            if items_keys[keys[0]] < items_keys[keys[1]]:
                key = '{}-{}'.format(items_keys[keys[0]], items_keys[keys[1]])
            else:
                key = '{}-{}'.format(items_keys[keys[1]], items_keys[keys[0]])
        else:
            if not items_keys.get(keys[0], None):
                continue
            key = items_keys[keys[0]]
        item.id = None
        item.key = key
        item.service_register = sr
        item.save()
    return {'id': sr.id}


@bind_context(uri_pre + '/review_list')
def review_query(ctx, options):
    if check_operate(ctx.session.user_id):
        business_ids = operate_business(ctx.session.user_id)
        init_q = Q(doctor__business_partener__id__in=business_ids)
    elif check_business(ctx.session.groups):
        # 判断是商务并且非商务leader
        user = ctx.session.user
        members = UserPerm.members(user)
        init_q = Q(doctor__business_partener__in=members)
    else:
        init_q = None
    dqobj = ReviewRecordDQ(init_q=init_q)
    return dqobj.process(**options)


@bind_context(uri_pre + '/get_reviewdata')
def review_data(ctx, serviceregister_id):
    """
    获取待审核美购信息
    :param ctx:
    :param serviceregister_id: 美购注册ID
    """
    try:
        serviceregister = ServiceRegister.objects.get(pk=serviceregister_id)
        service_data = {}
        list_service = []
        special_data = []
        if serviceregister.review_status == SERVICE_REVIEW_STATUS.UNDER_REVIEW:
            serviceregister_data_res = get_serviceregister_detail(serviceregister)
            list_serviceregister = serviceregister_data_res.get('list_serviceregister', [])
            serviceregister_data = serviceregister_data_res.get('serviceregister_data', {})
            list_serviceregister_detail_info = serviceregister_data_res.get('list_serviceregister_detail_info', [])
            if serviceregister.service:
                service_data_res = get_service_detail(serviceregister.service)
                service_data = service_data_res.get('service_data', {})
                list_service = service_data_res.get('list_service', [])
                special_data = service_data_res.get('special_data', [])

            return {
                'serviceregister_data': serviceregister_data,
                'list_serviceregister': list_serviceregister,
                'service_data': service_data,
                'list_service': list_service,
                'special_data': special_data,
                'list_serviceregister_detail_info': list_serviceregister_detail_info,
                'service_lock': getattr(serviceregister.service, 'is_lock', False),
                'need_operator_check': True if serviceregister.operator_review_type == OPERTOR_REVIEW_TYPE.WATI_REVIEW else False,
            }
        else:
            gen(CODES.SERVICE_STATUS_ERROR)
    except:
        raise


@bind_context(uri_pre + '/review_reject')
@transaction.atomic
def review_result(ctx, serviceregister_id, is_pass, is_operator_pass=False, reason=None):
    """
    审核申请
    :param ctx:
    :param reason: 拒绝原因
    :param serviceregister_id: 美购申请ID
    :param is_pass: 是否通过审核
    modify by oldman 2016-12-26 （sku一期优化）
    """
    ctx.logger.app(serviceregister_id=serviceregister_id, is_pass=is_pass)

    stock_num = 99999  # 经由产品确认目前删除库存的概念，不论什么时候审核结束库存都会修改为99999
    reviewrecord = ServiceReviewRecord.objects.filter(
        serviceregister__id=serviceregister_id).order_by('-created_time')[0]
    serviceregister = ServiceRegister.objects.select_for_update().get(pk=serviceregister_id)
    if getattr(serviceregister.service, 'is_lock', False):
        raise gen(CODES.SERVICE_STATUS_ERROR)
    if serviceregister.review_status != SERVICE_REVIEW_STATUS.UNDER_REVIEW:
        raise gen(CODES.OPERATION_NOT_SUPPORTED)
    if is_pass and is_operator_pass:
        old_count = Service.any_can_sell_items_has_stock(
            serviceregister.service_id) if serviceregister.service_id else False
        reviewrecord.now_review_status = SERVICE_REVIEW_STATUS.PASS
        serviceregister.review_status = SERVICE_REVIEW_STATUS.PASS
        serviceregister.operator_review_type = OPERTOR_REVIEW_TYPE.NO_REVIEW
        if serviceregister.service:
            # 更新ServiceTag表
            q = Q(service=serviceregister.service) & (~Q(tag__tag_type=TAG_TYPE.YUNYING))
            ServiceTag.objects.filter(q).delete()
            if serviceregister.upgrade:
                service_register_tags = ServiceRegisterTag.objects.filter(serviceregister_id=serviceregister.id)
                for service_register_tag in service_register_tags:
                    ServiceTag.objects.create(service_id=serviceregister.service.id,
                                              tag_id=service_register_tag.tag_id)
                serviceregister.service.upgrade = True
            else:
                ServiceTag.objects.create(service_id=serviceregister.service.id,
                                          tag_id=serviceregister.project_type.id)
            serviceregister.service.project_type = serviceregister.project_type
            serviceregister.service.short_description = serviceregister.short_description
            serviceregister.service.start_time = serviceregister.start_time
            serviceregister.service.end_time = serviceregister.end_time
            serviceregister.service.reservation = serviceregister.reservation
            # 2017-3-16 库存改为在ServiceRegisterItem中，此字段不再维护
            # serviceregister.service.total_num = (serviceregister.total_num + serviceregister.add_num)
            serviceregister.service.image_header = serviceregister.image_header
            serviceregister.service.is_online = True
            serviceregister.service.photo_details_doctor = serviceregister.photo_details
            serviceregister.service.sell_num_limit = serviceregister.service.real_stock
            # 美购改版 2017-03-31
            serviceregister.service.image_bigpic = serviceregister.image_bigpic
            serviceregister.service.update_supplement_images(serviceregister.get_supplement_images())
            serviceregister.service.update_supplement_images_order(serviceregister.get_supplement_images())
            serviceregister.service.have_extra_pay = serviceregister.have_extra_pay
            serviceregister.service.extra_pay_info = serviceregister.extra_pay_info
            serviceregister.service.service_type = serviceregister.service_type
            recommend_service_ids = [item.get('id') for item in serviceregister.get_recommend_services()]
            serviceregister.service.update_recommend_services(recommend_service_ids)
            serviceregister.service.merchant_id = serviceregister.merchant_id
            serviceregister.service.doctor_id = serviceregister.doctor_id
            serviceregister.service.name = serviceregister.name
            serviceregister.service.save()
            old_video = getattr(serviceregister.service, 'video', None)
            new_video = getattr(serviceregister, 'video', None)
            if old_video:
                if new_video:
                    old_video.video_url = new_video.video_url
                    old_video.video_pic = new_video.video_pic
                    old_video.persistentId = new_video.persistentId
                    old_video.persistent_status = new_video.persistent_status
                    old_video.water_url = new_video.water_url
                    old_video.save()
                else:
                    old_video.delete()
            else:
                if new_video:
                    ServiceVideo.objects.create(
                        service_id=serviceregister.service.id,
                        video_url=new_video.video_url,
                        video_pic=new_video.video_pic,
                        persistentId=new_video.persistentId,
                        persistent_status=new_video.persistent_status,
                        water_url=new_video.water_url
                    )
        else:
            service_flag = SERVICE_FLAG.DOCTOR if serviceregister.doctor.doctor_type == DOCTOR_TYPE.DOCTOR else \
                SERVICE_FLAG.HOSPITAL  # 美购标记
            is_operation = False  # 是否是手术类
            itemwiki = TagWiki.objects.filter(tag_id=serviceregister.project_type.id)
            wiki = None
            if len(itemwiki) > 0:
                is_operation = True if (
                        itemwiki[0].itemwiki and itemwiki[
                    0].itemwiki.treatment_means == TREATMENT_MEANS_CHOICES.OPERATE) else False
                wiki = itemwiki[0].itemwiki
            upgrade = False
            if serviceregister.upgrade:
                upgrade = True
            serviceregister.service = Service.objects.create(
                doctor=serviceregister.doctor,
                name=serviceregister.name,
                short_description=serviceregister.short_description,
                start_time=serviceregister.start_time,
                end_time=serviceregister.end_time,
                project_type=serviceregister.project_type,
                reservation=serviceregister.reservation,
                image_header=serviceregister.image_header,
                is_stage=serviceregister.is_stage,
                exchange_points_ceiling=0,
                is_online=False,
                service_flag=service_flag,
                service_type=serviceregister.service_type,
                is_operation=is_operation,
                wiki=wiki,
                photo_details_doctor=serviceregister.photo_details,
                valid_duration=180 if is_operation else 90,
                image_bigpic=serviceregister.image_bigpic,
                extra_pay_info=serviceregister.extra_pay_info,
                have_extra_pay=serviceregister.have_extra_pay,
                merchant_id=serviceregister.merchant_id,
                upgrade=upgrade,
            )
            video = getattr(serviceregister, 'video', None)
            if video:
                ServiceVideo.objects.create(
                    service_id=serviceregister.service.id,
                    video_url=video.video_url,
                    video_pic=video.video_pic,
                    persistentId=video.persistentId,
                    persistent_status=video.persistent_status,
                    water_url=video.water_url
                )
            if serviceregister.upgrade:
                service_register_tags = ServiceRegisterTag.objects.filter(serviceregister_id=serviceregister.id)
                for service_register_tag in service_register_tags:
                    ServiceTag.objects.create(service_id=serviceregister.service.id,
                                              tag_id=service_register_tag.tag_id)
            else:
                ServiceTag.objects.create(service_id=serviceregister.service.id,
                                          tag_id=serviceregister.project_type.id)
            serviceregister.service.update_supplement_images(serviceregister.get_supplement_images())
            serviceregister.service.update_supplement_images_order(serviceregister.get_supplement_images())
            recommend_service_ids = [item.get('id') for item in serviceregister.get_recommend_services()]
            serviceregister.service.update_recommend_services(recommend_service_ids)
            if not serviceregister.upload_button:  # 判断是否是多属性(在创建的时间判断的)
                serviceregister.service.is_multiattribute = True
        # 2017-3-16 库存改为在ServiceRegisterItem中，此字段不再维护
        # serviceregister.total_num += serviceregister.add_num  # 更新美购注册总数量和数量
        items = ServiceRegisterItem.objects.filter(service_register__id=serviceregister_id, is_delete=False,
                                                   is_online=True)

        ServiceItem.objects.filter(parent_id=0, service_id=serviceregister.service.id).update(
            is_delete=True)  # 原来所有的多属性置为软删除

        for item in items:
            if item.service_register.upgrade is True:
                upgrade = True
            else:
                upgrade = False
            if item.serviceitem:  # 修改多属性
                #  获取默认价格信息 modif by oldman 2016-12-26
                price_info = item.serviceitem.get_default_price_info()
                price_info_id = price_info.get('id')

                price_params = {
                    'price_id': price_info_id,
                    'discount': item.discount,
                    'pre_payment_price': item.pre_payment_price_int,
                    'original_price': item.original_price,
                    'cash_back_rate': item.cash_back_rate,
                    'cash_back_fee': math.ceil((item.cash_back_rate * item.gengmei_price) / 100.00),
                    'is_enable': True,
                }

                if price_info.get('gengmei_price') != item.gengmei_price:
                    price_params['self_support_discount'] = int(item.gengmei_price * 0.4)
                    price_params['gengmei_price'] = item.gengmei_price

                try:
                    item.serviceitem.update_price(**price_params)
                except Exception as e:
                    exception_logger.error('item-%s-%s' % (json.dumps(price_params), e.message))
                item.serviceitem.key = item.key
                item.total_num = item.serviceitem.total_num + item.stock_add_num
                item.serviceitem.is_delete = False
                item.serviceitem.serviceregisteritem_id = item.id
                item.serviceitem.service_id = serviceregister.service.id
                item.serviceitem.city_id = item.city_id
                item.serviceitem.sku_description = item.sku_description
                if upgrade is True:
                    item.serviceitem.property_id = item.property_id
                    item.serviceitem.image_header = item.image_header
                item.serviceitem.save()
                # 回填商品类目属性和商品属性关系
                com_categoryRelationObjs = CommodityCategoryRelation.objects.filter(commodity_register_id=item.id)
                for obj in com_categoryRelationObjs:
                    obj.commodity_id = item.serviceitem.id
                    obj.save()
                com_categoryPropertyObjs = CommodityCategoryPropertyRelation.objects.filter(
                    commodity_register_id=item.id)
                for obj in com_categoryPropertyObjs:
                    obj.commodity_id = item.serviceitem.id
                    obj.save()

                # 设置库存 sku_stock,因为相关实现使用了update，所以必须save item()之后再处理
                # 经过产品确认，每次审核成功之后都写死库存
                item.serviceitem.increase_stock(stock_num)
                # if item.stock_add_num > 0:
                    # item.serviceitem.increase_stock(item.stock_add_num)
                # elif item.stock_add_num < 0:
                    # item.serviceitem.decrease_stock((0 - item.stock_add_num))
                    # item.serviceitem.decrease_stock(stock_num)

                # 无申请id的活动价同步更新
                activity_ids = item.serviceitem.specialitem_set.filter(doctorseckillapply__isnull=True).values_list(
                    'special_id', flat=True)
                price_ids = item.serviceitem.serviceitemprice_set.filter(
                    selling_rule__activity_id__in=activity_ids).values_list('id', flat=True)
                for price_id in price_ids:
                    price_params['price_id'] = price_id
                    try:
                        item.serviceitem.update_price(**price_params)
                    except Exception as e:
                        exception_logger.error('price-%s-%s' % (json.dumps(price_params), e.message))

            else:  # 添加多属性
                if upgrade is True:
                    property_id = item.property_id
                    image_header = item.image_header
                else:
                    property_id = None
                    image_header = ''
                serviceitem = ServiceItem.objects.create(
                    service_id=serviceregister.service.id,
                    key=item.key,
                    is_delete=False,
                    city_id=item.city_id,
                    sku_description=item.sku_description,
                    property_id=property_id,
                    image_header=image_header,
                )
                serviceitem.total_num += item.stock_add_num
                serviceitem.save()
                # todo 设置库存 total_num sku_stock
                # 经过产品确认，每次审核成功之后都写死库
                serviceitem.increase_stock(stock_num)
                # if item.stock_add_num > 0:
                    # serviceitem.increase_stock(item.stock_add_num)
                # elif item.stock_add_num < 0:
                    # serviceitem.decrease_stock((0 - item.stock_add_num))
                    # serviceitem.decrease_stock(stock_num)
                serviceitem.create_price(
                    sale_limit=0,
                    is_default_price=True,
                    selling_rule_id=None,
                    discount=item.discount,
                    pre_payment_price=item.pre_payment_price_int,
                    original_price=item.original_price,
                    gengmei_price=item.gengmei_price,
                    cash_back_rate=item.cash_back_rate,
                    cash_back_fee=math.ceil((item.cash_back_rate * item.gengmei_price) / 100.00),
                    self_support_discount=int(item.gengmei_price * 0.4),
                    single_user_buy_limit=0
                )
                item.serviceitem = serviceitem

                # 回填商品类目属性和商品属性关系表的commodity = skuID
                com_categoryRelationObjs = CommodityCategoryRelation.objects.filter(commodity_register_id=item.id)
                for obj in com_categoryRelationObjs:
                    obj.commodity_id = serviceitem.id
                    obj.save()
                com_categoryPropertyObjs = CommodityCategoryPropertyRelation.objects.filter(
                    commodity_register_id=item.id)
                for obj in com_categoryPropertyObjs:
                    obj.commodity_id = serviceitem.id
                    obj.save()
                if not item.service_register.upgrade:
                    serviceregisterkeys = ServiceRegisterItemKey.objects.filter(serviceregisteritem__id=item.id)
                    for serviceregisterkey in serviceregisterkeys:
                        ServiceItemKey.objects.create(
                            serviceitem=serviceitem,
                            serviceattroption=serviceregisterkey.serviceregisterattroption
                        )

                # 全店通用或者医生通用券则创建相应的美券规则
                # 先看看当前医生有没有全店通用券
                whole_coupon_ids, doctor_coupons_ids = [], []
                mer = MerchantRelevance.objects.filter(doctor_id=serviceregister.service.doctor_id).first()
                if mer:
                    m = Merchant.objects.get(id=mer.merchant_id)
                    whole_coupon_ids = list(Coupon.objects.filter(
                        doctor_id=m.doctor_id,
                        doctor_coupon_use_type=DOCTOR_USE_COUPON_TYPE.FULL_PLATFORM_GENERAL
                    ).values_list('id', flat=True))
                # 再处理医生通用
                if serviceregister.service.doctor_id:
                    doctor_coupons_ids = list(Coupon.objects.filter(
                        doctor_id=serviceregister.service.doctor_id,
                        doctor_coupon_use_type=DOCTOR_USE_COUPON_TYPE.DOCTOR_GENERAL
                    ).values_list('id', flat=True))

                coupons = list(set(whole_coupon_ids) | set(doctor_coupons_ids))
                CouponSKURestrict.objects.bulk_create(
                    [CouponSKURestrict(coupon_id=coupon_id, sku_id=serviceitem.id) for coupon_id in coupons]
                )
            item.stock_add_num = 0
            item.save()
            # 修改项目名字
            if not item.service_register.upgrade:
                auditattroptions = AuditAttrOptions.objects.filter(serviceregisteritem=item, is_delete=False).first()
                if auditattroptions:
                    itemkey = ServiceRegisterItemKey.objects.get(serviceregisteritem=item)
                    itemkey.serviceregisterattroption.name = auditattroptions.name
                    itemkey.serviceregisterattroption.save()
                    auditattroptions.delete()

        new_count = Service.any_can_sell_items_has_stock(serviceregister.service_id)
        if not old_count and new_count:
            push_service_detail(serviceregister.service)
    elif is_operator_pass and not is_pass:  # 运营通过
        serviceregister.operator_review_type = OPERTOR_REVIEW_TYPE.REVIEW_PASS
    else:
        serviceregister.review_status = SERVICE_REVIEW_STATUS.TURN_DOWN
        serviceregister.operator_review_type = OPERTOR_REVIEW_TYPE.NO_REVIEW
        reviewrecord.now_review_status = SERVICE_REVIEW_STATUS.SPECIAL_APPROVAL_TURN_DOWN if \
            reviewrecord.review_type == SERVICE_REVIEW_TYPE.SPECIAL else SERVICE_REVIEW_STATUS.TURN_DOWN
        reviewrecord.reason = reason
    serviceregister.last_review_time = datetime.datetime.now()
    serviceregister.is_draft = False
    serviceregister.save()

    if serviceregister.service:
        serviceregister.service.save()
        refresh_service_cache_info.delay(service_ids=[serviceregister.service.id])

    reviewrecord.operator = get_user_from_context(ctx).person
    reviewrecord.audit_time = datetime.datetime.now()
    reviewrecord.save()
    # doctor 设置自营医生
    if serviceregister.service:
        serviceregister.service.smart_self_support()


@bind_context(uri_pre + '/offline_list')
def offline_query(ctx, options):
    if check_business(ctx.session.groups):
        # 判断是商务并且非商务leader
        user = ctx.session.user
        members = UserPerm.members(user)
        init_q = Q(doctor__business_partener__in=members)
    elif check_operate(ctx.session.user_id):
        business_ids = operate_business(ctx.session.user_id)
        init_q = Q(doctor__business_partener__id__in=business_ids)
    else:
        init_q = None
    dqobj = ServiceRegisterOfflineDQ(init_q=init_q)
    return dqobj.process(**options)


@bind_context(uri_pre + '/offline_detail')
def offline_detail(ctx, serviceregister_id):
    try:
        serviceregister = ServiceRegister.objects.get(pk=serviceregister_id)
        detail = get_service_detail(serviceregister.service)
        new_project = new_project_type(serviceregister=serviceregister)
        business_state = {'is_business': False}
        if 'business' in ctx.session.groups:
            business_state = {'is_business': True}
        detail['service_data'].update(business_state)
        detail['service_data'].update({"new_project_type": new_project})
        return detail
    except:
        raise


def get_serviceregister_detail(serviceregister):
    """
    获取美购注册的展示信息
    """
    serviceregister_data = {}
    list_serviceregister = []
    list_serviceregister_detail_info = [{'is_lowest': False}, ]  # 第一默认值是为了配合hera样式展示, 切勿删除
    project_type_change = ''
    if serviceregister.service:
        service = serviceregister.service
        if serviceregister.project_type != service.project_type:
            old_tag_type = TAG_TYPE.getDesc(service.project_type.tag_type,
                                            defaultValue='') if service.project_type else ''
            old_tag_name = service.project_type.name if service.project_type else ''
            old_tag = '{}-{}'.format(old_tag_type, old_tag_name)
            new_tag_type = TAG_TYPE.getDesc(serviceregister.project_type.tag_type,
                                            defaultValue='') if serviceregister.project_type else ''
            new_tag_name = serviceregister.project_type.name if serviceregister.project_type else ''
            new_tag = '{}-{}'.format(new_tag_type, new_tag_name)
            project_type_change = '由"{}"改为"{}"'.format(old_tag, new_tag)

    serviceregister_data['project_type_change'] = project_type_change
    serviceregister_data['doctor_name'] = serviceregister.doctor.name
    serviceregister_data['merchant'] = serviceregister.get_merchant().get('name',
                                                                          '') if serviceregister.get_merchant() else ''
    try:
        serviceregister_data['hospital_type'] = HOSPITAL_MEDICAL_TYPE.getDesc(
            serviceregister.doctor.hospital.hospital_extra.hospital_type)
    except:
        serviceregister_data['hospital_type'] = u''
    serviceregister_data['project_type'] = serviceregister.project_type.name if \
        serviceregister.project_type else u''
    serviceregister_data['new_project_type'] = new_project_type(serviceregister=serviceregister)
    serviceregister_data['hospital_name'] = serviceregister.doctor.hospital.name
    serviceregister_data['short_description'] = serviceregister.short_description
    serviceregister_data['start_time'] = datetime.datetime.strftime(serviceregister.start_time,
                                                                    '%Y-%m-%d %H:%M:%S')
    serviceregister_data['end_time'] = datetime.datetime.strftime(serviceregister.end_time,
                                                                  '%Y-%m-%d %H:%M:%S')
    serviceregister_data['reservation'] = serviceregister.reservation
    serviceregister_data['total_num'] = (serviceregister.total_num + serviceregister.add_num)
    serviceregister_data['image_header'] = serviceregister.image_header
    serviceregister_data['photo_details'] = serviceregister.photo_details
    try:
        serviceregister_data['business_partner'] = serviceregister.doctor.business_partener.username
    except:
        serviceregister_data['business_partner'] = u''
    serviceregister_items = ServiceRegisterItem.objects.filter(service_register__id=serviceregister.id,
                                                               is_online=True,
                                                               is_delete=False).order_by(
        'sort')
    # 美购改版 2017-03-31
    serviceregister_data['image_bigpic'] = serviceregister.image_bigpic
    serviceregister_data['supplement_images'] = serviceregister.get_supplement_images()
    serviceregister_data['have_extra_pay'] = serviceregister.have_extra_pay
    serviceregister_data['extra_pay_info'] = serviceregister.extra_pay_info
    serviceregister_data['recommend_services'] = serviceregister.get_recommend_services()
    serviceregister_data['video'] = serviceregister.get_video_info()
    serviceregister_data['service_type_desc'] = SERVICE_SELL_TYPE.getDesc(serviceregister.service_type)
    servicetag_names=""
    if serviceregister.upgrade:
        if serviceregister.tags.all():
            tag_names=[tag.name for tag in serviceregister.tags.all()]
            servicetag_names="/".join(tag_names)
    else:
        servicetag_names=serviceregister.project_type.name if serviceregister.project_type else u''
    serviceregister_data["servicetag_names"]=servicetag_names
    serviceregister_data["upgrade"]=serviceregister.upgrade

    if len(serviceregister_items) > 0:
        list_serviceregister_header = []
        list_serviceregister_header.append('skuID')
        # 非标准美购
        # list_sttrs = ServiceRegisterItemKey.objects.filter(
        #     serviceregisteritem__id=serviceregister_items[0].id)

        # 标准美购
        # if list_sttrs[0].serviceregisterattroption.tag_attr.id != settings.DEFAULT_TAG_ATTR_ID:
        #     list_sttrs = list_sttrs.order_by('serviceregisterattroption__tag_attr_id')
        #     for item_attrs in list_sttrs:
        #         list_serviceregister_header.append(item_attrs.serviceregisterattroption.tag_attr.name)
        # 非标准美购
        # else:
        #     list_serviceregister_header.append('SKU名称')
        list_serviceregister_header.append('SKU名称')
        list_serviceregister_header.append(u'SKU头图')
        list_serviceregister_header.append(u'更美价')
        list_serviceregister_header.append(u'市场价')
        list_serviceregister_header.append(u'是否特殊分销')
        list_serviceregister_header.append(u'预付款')
        list_serviceregister_header.append(u'预付款比例')
        list_serviceregister_header.append(u'抽成')
        list_serviceregister_header.append(u'抽成比例')
        list_serviceregister_header.append(u'库存')
        # list_serviceregister_header.append(u'商品类目')
        # list_serviceregister_header.append(u'部位属性')
        # list_serviceregister_header.append(u'仪器属性')
        # list_serviceregister_header.append(u'材料属性')
        # list_serviceregister_header.append(u'剂量规格属性')
        # list_serviceregister_header.append(u'项目说明')
        register_service_item_property_ids = [item.property_id for item in serviceregister_items if item.property_id]
        service_item_id_to_sku_name_info = dict()
        if register_service_item_property_ids:
            service_item_id_to_sku_name_info = get_register_sku_id_to_sku_name_info(register_service_item_property_ids)
        list_serviceregister.append(list_serviceregister_header)
        for item in serviceregister_items:
            serviceregister_detail = []
            is_in_skuexamine_list = False  # 判断是否存在sku改价审核列表中
            serviceregister_detail.append(item.serviceitem.id if item.serviceitem else '')
            serviceregister_item_keys = ServiceRegisterItemKey.objects. \
                filter(serviceregisteritem__id=item.id).order_by('serviceregisterattroption__tag_attr__id')
            # 标准美购
            if item.serviceitem:
                current_gengmei_price = item.serviceitem.get_current_price_info().get('gengmei_price')
                skuexamine_info = list(
                    SKUExamine.objects.filter(
                        serviceitem_id=item.serviceitem.id,
                        skuexaminelist__start_time__lte=datetime.datetime.now(),
                        skuexaminelist__end_time__gte=datetime.datetime.now()
                    ).values('skuexaminelist__title', 'skuexaminelist')
                )
                is_in_skuexamine_list = bool(skuexamine_info)
            else:
                current_gengmei_price = 2 << 31
                skuexamine_info = {}

            if not item.service_register.upgrade:
                auditattroptions = AuditAttrOptions.objects.filter(serviceregisteritem=item, is_delete=False).first()
                if auditattroptions:
                    serviceregister_detail.append(auditattroptions.name)
                else:
                    for pro in serviceregister_item_keys:
                        serviceregister_detail.append(pro.serviceregisterattroption.name)
            else:
                audit_attroptionsz_name = item.service_register.name
                if item.property_id:
                    audit_attroptionsz_name = service_item_id_to_sku_name_info.get(str(item.property_id), {}).get('tob_sku_name', '')
                serviceregister_detail.append(audit_attroptionsz_name)

            city_name = item.city.name if item.city else ''
            serviceregister_detail.append('<a href="{}" target="_blank"><img width="50px" height="50px" src="{}" onerror="this.style.display=\'none\'"/></a>'.format(item.image_header,item.image_header))
            serviceregister_detail.append(item.gengmei_price)
            serviceregister_detail.append(item.original_price)
            serviceregister_detail.append(
                '是' if serviceregister.service_type == SERVICE_SELL_TYPE.FENGXIANGGOU else '否')
            serviceregister_detail.append(item.pre_payment_price_int)
            serviceregister_detail.append(
                u'{0}%'.format(int(item.pre_payment_price_int / (item.gengmei_price * 1.00) * 100)))
            serviceregister_detail.append(item.discount)
            serviceregister_detail.append(u'{0}%'.format(int(item.discount / (item.gengmei_price * 1.00) * 100)))
            if item.serviceitem:
                old_stock = item.serviceitem.sku_stock
            else:
                old_stock = 0
            # 更改后的库存
            serviceregister_detail.append(old_stock + item.stock_add_num)

            # commodityCategoryRelationItem = CommodityCategoryRelation.objects.filter(commodity_id=item.serviceitem.id).first() if item.serviceitem else CommodityCategoryRelation.objects.filter(commodity_register_id=item.id).first()
            # category_id = commodityCategoryRelationItem.category_id if commodityCategoryRelationItem else ''
            # comdityCategoryItem = CommodityCategory.objects.filter(id=category_id).first() if category_id else ''
            # serviceregister_detail.append(comdityCategoryItem.name if comdityCategoryItem else '')

            # positon_property = ''
            # instrument_property = ''
            # materials_property = ''
            # measure_property = ''
            # relItems = CommodityCategoryPropertyRelation.objects.filter(commodity_id=item.serviceitem.id) if item.serviceitem else CommodityCategoryPropertyRelation.objects.filter(commodity_register_id=item.id)
            # for it in relItems:
            #     if it.property_type == CommodityCategoryProperty.POSITON:
            #         positon_property = it.property_name
            #     if it.property_type == CommodityCategoryProperty.INSTRUMENT:
            #         instrument_property = it.property_name
            #     if it.property_type == CommodityCategoryProperty.MATERIALS:
            #         materials_property = it.property_name
            #     if it.property_type == CommodityCategoryProperty.MEASURE:
            #         measure_property = it.property_name
            # serviceregister_detail.append(positon_property)
            # serviceregister_detail.append(instrument_property)
            # serviceregister_detail.append(materials_property)
            # serviceregister_detail.append(measure_property)
            # serviceregister_detail.append(item.sku_description)
            list_serviceregister.append(serviceregister_detail)
            detail_info = {
                'current_gengmei_price': current_gengmei_price,
                'belongs_to': skuexamine_info,
                'is_lowest': item.gengmei_price != current_gengmei_price and is_in_skuexamine_list
            }
            list_serviceregister_detail_info.append(detail_info)
    return {
        'serviceregister_data': serviceregister_data,
        'list_serviceregister': list_serviceregister,
        'list_serviceregister_detail_info': list_serviceregister_detail_info,
    }


def get_service_detail(service):
    """
    获取美购展示信息
    modify by oldman 2016-12-26 sku一期
    """

    service_data = {}
    list_service = []
    service_data['doctor_name'] = service.doctor.name
    service_data['name'] = service.name
    service_data['project_type'] = service.project_type.name if \
        service.project_type else u''
    service_data['hospital_name'] = service.doctor.hospital.name
    service_data['short_description'] = service.short_description
    service_data['start_time'] = datetime.datetime.strftime(service.start_time,
                                                            '%Y-%m-%d %H:%M:%S')
    service_data['end_time'] = datetime.datetime.strftime(service.end_time, '%Y-%m-%d %H:%M:%S') if \
        service.end_time else None
    service_data['business_partner'] = service.doctor.business_partener.username
    service_data['reservation'] = service.reservation
    service_data['total_num'] = service.total_num
    service_data['image_header'] = service.image_header
    service_data['photo_details'] = service.photo_details_doctor if \
        service.photo_details_doctor else service.photo_details_operate
    service_data['is_lock'] = service.is_lock
    service_items = ServiceItem.objects.filter(parent_id=0, service__id=service.id, is_delete=False).order_by('sort')
    list_special = []
    # 美购改版 2017-03-31
    service_data['image_bigpic'] = service.image_bigpic
    service_data['supplement_images'] = service.get_supplement_images()
    service_data['have_extra_pay'] = service.have_extra_pay
    service_data['extra_pay_info'] = service.extra_pay_info
    service_data['recommend_services'] = service.get_recommend_services()
    service_data['video'] = service.get_video_info()
    service_data['merchant'] = service.get_merchant().get('name', '') if service.get_merchant() else ''
    service_data['service_type_desc'] = SERVICE_SELL_TYPE.getDesc(service.service_type)
    servicetag_names=""
    if service.upgrade:
        if service.tags.all():
            tag_names=[tag.name for tag in service.tags.all()]
            servicetag_names="/".join(tag_names)
    else:
        servicetag_names=service.project_type.name if service.project_type else u''
    service_data["servicetag_names"]=servicetag_names
    service_data["upgrade"]=service.upgrade


    if len(service_items) > 0:
        list_service_header = []
        list_service_header.append('skuID')
        list_sttrs_service = ServiceItemKey.objects.filter(serviceitem__id=service_items[0].id)
        # 标准美购
        # if list_sttrs_service[0].serviceattroption.tag_attr != settings.DEFAULT_TAG_ATTR_ID:
        #     list_sttrs_service = list_sttrs_service.order_by('serviceattroption__tag_attr_id')
        #     for item_attrs_service in list_sttrs_service:
        #         list_service_header.append(item_attrs_service.serviceattroption.tag_attr.name)
        # # 非标准美购
        # else:
        #   list_service_header.append('项目名称')
        list_service_header.append(u'SKU名称')
        list_service_header.append(u'SKU头图')
        list_service_header.append(u'更美价')
        list_service_header.append(u'市场价')
        list_service_header.append(u'是否特殊分销')
        list_service_header.append(u'预付款')
        list_service_header.append(u'预付款比例')
        list_service_header.append(u'抽成')
        list_service_header.append(u'抽成比例')
        list_service_header.append(u'库存')
        # list_service_header.append(u'商品类目')
        # list_service_header.append(u'部位属性')
        # list_service_header.append(u'仪器属性')
        # list_service_header.append(u'材料属性')
        # list_service_header.append(u'剂量规格属性')
        # list_service_header.append(u'项目说明')
        list_service.append(list_service_header)
        all_service_item_id = [item.id for item in service_items]
        service_item_id_to_sku_name_info = get_sku_id_to_sku_name_info(all_service_item_id, False)
        for item_service in service_items:
            service_detail = []
            service_detail.append(item_service.id)

            # service_items_keys = ServiceItemKey.objects.filter(
            #     serviceitem__id=item_service.id).order_by('serviceattroption__tag_attr__id')
            if item_service.service.upgrade:
                service_attroption_name = service_item_id_to_sku_name_info[str(item_service.id)].get('name', '')
                if not service_attroption_name:
                    service_attroption_name = item_service.service.name
                service_detail.append(service_attroption_name)
            else:
                service_items_keys = ServiceItemKey.objects.filter(
                    serviceitem__id=item_service.id).order_by('serviceattroption__tag_attr__id')
                for pro_service in service_items_keys:
                    service_detail.append(pro_service.serviceattroption.name)

            # todo 获取serviceitem的默认价格(新版sku)
            price_info = item_service.get_default_price_info()
            gengmei_price = price_info.get('gengmei_price', 0)
            original_price = price_info.get('original_price', 0)
            pre_payment_price = price_info.get('pre_payment_price', 0)
            discount = price_info.get('discount', 0)
            city_name = item_service.city.name if item_service.city else ''
            service_detail.append('<a href="{}" target="_blank"><img width="50px" height="50px" src="{}" onerror="this.style.display=\'none\'"/></a>'.format(item_service.image_header,item_service.image_header))
            service_detail.append(gengmei_price)
            service_detail.append(original_price)
            service_detail.append('是' if service.service_type == SERVICE_SELL_TYPE.FENGXIANGGOU else '否')
            service_detail.append(pre_payment_price)
            service_detail.append(
                u'{0}%'.format(int(pre_payment_price / (gengmei_price * 1.00) * 100)))
            service_detail.append(discount)
            service_detail.append(u'{0}%'.format
                                  (int(discount / (gengmei_price * 1.00) * 100)))
            service_detail.append(item_service.sku_stock)

            # commodityCategoryRelationItem = CommodityCategoryRelation.objects.filter(commodity_id=item_service.id).first()
            # category_id = commodityCategoryRelationItem.category_id if commodityCategoryRelationItem else ''
            # comdityCategoryItem = CommodityCategory.objects.filter(id=category_id).first() if category_id else ''
            # service_detail.append(comdityCategoryItem.name if comdityCategoryItem else '')

            # positon_property = ''
            # instrument_property = ''
            # materials_property = ''
            # measure_property = ''
            # relItems = CommodityCategoryPropertyRelation.objects.filter(commodity_id=item_service.id)
            # for it in relItems:
            #     if it.property_type == CommodityCategoryProperty.POSITON:
            #         positon_property = it.property_name
            #     if it.property_type == CommodityCategoryProperty.INSTRUMENT:
            #         instrument_property = it.property_name
            #     if it.property_type == CommodityCategoryProperty.MATERIALS:
            #         materials_property = it.property_name
            #     if it.property_type == CommodityCategoryProperty.MEASURE:
            #         measure_property = it.property_name
            # service_detail.append(positon_property)
            # service_detail.append(instrument_property)
            # service_detail.append(materials_property)
            # service_detail.append(measure_property)
            #
            # service_detail.append(item_service.sku_description)
            list_service.append(service_detail)
        list_special.extend(service_item_in_special(service_items=service_items))

    return {
        'service_data': service_data,
        'list_service': list_service,
        'special_data': list_special,
    }


@transaction.atomic
@bind_context(uri_pre + '/offline_result')
def offline_result(ctx, serviceregister_id, is_pass, reason=None):
    """
    下线申请的审核
    """
    ctx.logger.app(serviceregister_id=serviceregister_id, is_pass=is_pass)

    serviceregister = ServiceRegister.objects.get(id=serviceregister_id)
    review_record = ServiceReviewRecord.objects.filter(serviceregister_id=serviceregister_id).last()
    if serviceregister.review_status != SERVICE_REVIEW_STATUS.UNDER_OFFLINE:
        raise gen(CODES.OPERATION_NOT_SUPPORTED)
    if is_pass:
        serviceregister.service.is_online = False
        serviceregister.service.offline_reason = ''
        review_record.now_review_status = SERVICE_REVIEW_STATUS.PASS
        serviceregister.review_status = SERVICE_REVIEW_STATUS.PASS
    else:
        serviceregister.review_status = SERVICE_REVIEW_STATUS.TURN_DOWN
        review_record.now_review_status = SERVICE_REVIEW_STATUS.TURN_DOWN
        review_record.reason = reason
    serviceregister.is_draft = False
    serviceregister.last_review_time = datetime.datetime.now()
    serviceregister.save()
    serviceregister.service.save()
    if is_pass:
        delete_service_rank.delay(service_id=serviceregister.service.id)
        refresh_service_cache_info.delay(service_ids=[serviceregister.service.id])
    review_record.operator = get_user_from_context(ctx).person
    review_record.audit_time = datetime.datetime.now()
    review_record.save()
    # doctor 设置自营医生
    serviceregister.service.smart_self_support()


def push_service_detail(service):
    """
    发送开团提醒通知  先写死了....
    """
    try:
        extra = {'msgType': 9, 'type': 1, 'is_activity_push': False, 'service_id': service.id,
                 'pushUrl': 'gengmei://service?service_id={id}'.format(id=service.id)}
        platform = ['android', 'iPhone']
        from rpc.context import create_fake_context
        ctx = create_fake_context()
        title = u'上架啦!'
        ctx.gaia_local['api/event/service/start_sale'](platform=platform,
                                                       service_id=service.id,
                                                       extra=extra,
                                                       alert=service.name,
                                                       title=title
                                                       ).unwrap()
    except Exception as e:
        info_logger.info(__import__('traceback').format_exc())


def service_item_in_special(service_items):
    """
    判断这个serviceitem是否参加了未来的秒杀
    """
    dict_seckill = []
    specialsekills = SpecialItem.objects.filter(special__end_time__gte=datetime.datetime.now(),
                                                serviceitem__in=service_items)
    for specialsekill in specialsekills:
        dict_seckill.append({
            "specialname": specialsekill.special.title if specialsekill.special else '',
            "itemname": '+'.join(specialsekill.serviceitem.items_name),
            "special_id": specialsekill.special.id if specialsekill.special else ''
        })
    return dict_seckill


def new_project_type(serviceregister=None, tag_id=None, service_id=None):
    # 后台hera新增新标签项目类型 = 根据老标签查找新标签 + service_id的新标签
    if service_id:
        tag_map_old_ids = [tag_map.tag_id for tag_map in TagMapOldTag.objects.filter(old_tag_id__in=tag_id)]
        check_new_tags = [i.name for i in TagV3.objects.filter(id__in=tag_map_old_ids)]
        new_tag_ids = [i.tag_id for i in ServiceNewTag.objects.filter(service_id=service_id)]
        return new_tag_ids + tag_map_old_ids, ",".join(check_new_tags)
    else:
        project_type = []
        tag_map_old_tags = [tag_map.tag_id for tag_map in
                            TagMapOldTag.objects.filter(old_tag_id=serviceregister.project_type_id)]
        new_tag_ids = [i.tag_id for i in ServiceNewTag.objects.filter(service_id=serviceregister.service_id)]
        # 筛选出新标签是三级标签的，并且更新到数据库
        new_tags = TagV3.objects.filter(id__in=list(new_tag_ids + tag_map_old_tags))
        new_tag_name_id_dic = {}
        for new_tag in new_tags:
            project_type.append(new_tag.name)
            new_tag_name_id_dic[new_tag.name] = new_tag.tag_type
        return "/".join(list(set(project_type)))
