import json
import logging

from prm_core.models import *
from django.core.exceptions import ObjectDoesNotExist
from prm_core.serializers import *
from rest_framework.views import APIView, Response
from django.http import Http404
from prm_core.permission import *
from prm_core.solr import search_and_filter_objects
from prm_core.matter import get_matter_value_by_key
from haystack.query import SearchQuerySet, SQ
from prm_core.decorators import *
from Prime.settings import SOLR_DJANGO_CT
from haystack.query import SearchQuerySet, SQ
from haystack.utils.app_loading import haystack_get_model
from prm_core.number_generate import generate_number
from prm_core.numbers import get_client_number

logger = logging.getLogger('django.request')
# Client
#
# 创建客户和更新客户这两个接口涉及到图片附件的上传,前端需要用formdata传数据。
# formdata传数据会导致对象被转为字符串的问题,所以获取到的对象都需要做json.loads的处理。
#
class ClientView(APIView):
    """
    Client 客户
    get：获取客户列表：返回基础字段信息。
    ?start=0&size=100&order_by=-date&&s_keywords=APAC&s_type=all
    post：创建客户：
    delete：删除客户：如果存在关联案件，不允许删除。（2017-12-21：案件model未定，目前直接删除）
    """

    @set_latest_filters('client')
    def get(self, request):
        user = request.user
        if not check_action_permission(request.user, 'entity', 'public'):
            return Response({'status': '0', 'error_message': 'No permission.'})
        # LL 06282018 去除matter_name字段搜索
        SEARCH_FIELDS = ['name', 'english_name', 'multi_joint_children_name', 'multi_joint_children_english_name']
        ORDER_FIELDS = {'number': 'number', 'name': 'name', 'industry_name': 'sort_industry_company',
                      'tel': 'sort_tel_mobile', '-number': '-number', '-name': '-name',
                      '-industry_name': '-sort_industry_company', '-tel': '-sort_tel_mobile'}

        start = request.GET.get('start', 0)
        size = request.GET.get('size', 20)
        # 默认number排序;
        order_by = request.GET.get('order_by', '-number')
        if order_by:
            order_by = ORDER_FIELDS.get(order_by, '-number')
        s_type = request.GET.get("s_type")
        s_keywords = request.GET.get("s_keywords")

        # 筛选条件
        f_entity_type = request.GET.get('f_entity_type', None)
        f_matter_id = request.GET.get('f_matter_id', None)
        fq = {}
        sq = {}
        data = {}
        object_type = 'entity'
        # 过滤
        f_recently = request.GET.get('f_recently', None)
        # 过滤潜在客户:无客户号
        or_fq = {}
        # TODO: is_potential
        # or_fq['is_potential'] = None
        fq['is_opposite'] = False

        # # 最近查看
        if f_recently == '1':
            fq['obj_id__in'] = user.recent_items.get('client', None)
            if not fq['obj_id__in']:
                return Response({'status': '0', 'error_message': 'No Recently viewed data.'})
        elif f_matter_id:  # 根据案件id获取客户id
            matter = Matter.objects.filter(id=int(f_matter_id)).first()
            if matter:
                sq['obj_id__in'] = [client['id'] for client in get_matter_value_by_key(matter, 'matter_client')]
        elif f_entity_type:  # 先查出所有案件，再根据所有案件的客户字段找出所有客户的id，再进行过滤。
            fq['entity_type'] = f_entity_type
            # del or_fq['is_potential']

        # client_ids = SearchQuerySet().models(
        #     haystack_get_model('prm_core', SOLR_DJANGO_CT['matter'])).values_list('multi_client_id')
        # c_ids = []
        # for ids in client_ids:
        #     if isinstance(ids[0], list):
        #         c_ids.extend(ids[0])
        #     elif isinstance(ids[0], str):
        #         c_ids.append(ids[0])
        # fq['obj_id__in'] = set(c_ids)

        # 搜索
        if s_type and s_keywords:
            if s_type == 'all':
                _fields = SEARCH_FIELDS
            else:
                _fields = [s_type]
            for f in _fields:
                if f == 'matter_name':
                    search_queryset = SearchQuerySet().models(Matter).filter(name__contains=s_keywords).values_list(
                        'multi_client_id')
                    client_ids = []
                    for multi_client_id in search_queryset:
                        try:
                            client_ids.extend(multi_client_id[0])
                        except:
                            # should get a log.
                            pass
                    sq['obj_id__in'] = list(set(client_ids))

                sq[f + '__contains'] = s_keywords
                srs = search_and_filter_objects(object_type, int(start), int(size), 'OR', order_by, None, None, '2',
                                                {f + '__contains': s_keywords}, fq)
                data[f + '_hits'] = srs['hits']

        s2 = search_and_filter_objects(object_type, int(start), int(size), 'OR', order_by, None, None, '2', sq, fq, None, or_fq)
        # 添加母公司
        for _entity in s2['data']:
            parent_ids = _entity.pop('parents', [])
            _entity['parents'] = Entity.objects.filter(id__in=parent_ids).values('id', 'name', 'english_name')
        data['hits'] = s2['hits']
        data['list'] = s2['data']
        data['size'] = s2['size']
        
        # 返回每条数据的权限
        # ids = map(lambda x: int(x['obj_id']), data['list'])
        # auths = object_authority(user, 'entity', ids)
        # for item in data['list']:
        #     for auth in auths:
        #         if int(item['obj_id']) == auth['entity_id']:
        #             item['authority'] = auth['access']
        #             break

        return Response({'status': '1', 'data': data})

    # create Client
    def post(self, request):
        # 权限验证
        user = request.user
        if not check_action_permission(user, 'entity', 'add'):
            data = {"status": "0", "message": "No Permission."}
            return Response(data)

        name = request.data.get("name")
        # 检查名字是否重复
        # 如果重复则直接返回该对象id
        _entity = Entity.objects.filter(name=name).first()
        if _entity:
            return Response({"status": "1", "message": "...", "data": {"client": {"id": _entity.id}}})
        del _entity

        picture = request.FILES.get('picture')
        english_name = request.data.get("english_name")
        entity_type = request.data.get("entity_type")
        company = request.data.get("company")
        industry = request.data.get("industry")
        tel = request.data.get("tel")
        mobile = request.data.get("mobile")
        fax = request.data.get("fax")
        email = request.data.get("email")
        address = request.data.get("address")
        client_members = request.data.get("client_members")
        parents = request.data.get("parents")
        child = request.data.get("child")
        website = request.data.get("website")
        tax_id = request.data.get("tax_id")
        registered_company = request.data.get("registered_company")
        bank_account = request.data.get("bank_account")
        bank_name = request.data.get("bank_name")
        registered_company_address = request.data.get("registered_company_address")
        billing_period = request.data.get("billing_period")
        contacts = request.data.get('contacts')
        competitors = request.data.get('competitors')
        billing_tel = request.data.get('billing_tel')
        number = request.data.get('number', None)

        new_entity = Entity()
        new_entity.name = name
        new_entity.english_name = english_name
        new_entity.entity_type = entity_type
        new_entity.company = company
        new_entity.is_active = True
        if industry:
            industry = int(industry)
            industry_obj = Industry.objects.filter(id=industry).first()
            new_entity.industry = industry_obj

        new_entity.tel = tel
        new_entity.mobile = mobile
        new_entity.fax = fax
        new_entity.email = email
        new_entity.address = address
        new_entity.website = website
        new_entity.tax_id = tax_id                                             # 税号
        new_entity.registered_company = registered_company                     # 注册公司名称
        new_entity.registered_company_address = registered_company_address     # 公司注册地址
        new_entity.bank_account = bank_account          # 银行账户
        new_entity.bank_name = bank_name                # 开户行名称
        new_entity.billing_period = billing_period      # 账单周期
        new_entity.billing_tel = billing_tel

        if number is None:
            number = get_client_number()['number']
        if len(Entity.objects.filter(number=number)) > 0:
            return Response({'status': '0', 'error_message': 'client number is used'})
        new_entity.number = number

        # 客户图片保存
        if picture:
            attachment = Attachment()
            attachment.name = name + '-photo'
            attachment.type_of = '2'
            attachment.file = picture
            attachment.save()
            new_entity.picture = attachment

        # 保存新建client对象
        new_entity.save()

        EntityAccess.objects.create(entity=new_entity, access='4', leavel='v') #默认是view

        # 添加联系人
        if contacts:
            contacts = json.loads(contacts)
            contacts_entities = Contact.objects.filter(id__in=contacts)
            for contact in contacts_entities:
                contact.client = new_entity
                contact.save()

        # 添加账单联系人
        # if billing_contact:
        #     billing_contact = json.loads(billing_contact)
        #     billing_contacts = Contact.objects.filter(id__in=billing_contact)
        #     for billing_contact in billing_contacts:
        #         new_entity.billing_contact = billing_contact
        #         new_entity.save()

        # 如果是联合客户，添加关联
        if client_members:
            client_members = json.loads(client_members)
            client_members_objs = Entity.objects.filter(id__in=client_members)
            for client_members_obj in client_members_objs:
                new_entity.joint_parent.add(client_members_obj)

        # 关联客户子公司
        if child:
            child = json.loads(child)
            child_entities = Entity.objects.filter(id__in=child)
            for child_entity in child_entities:
                child_entity.parents.add(new_entity)

        # 添加母公司
        if parents:
            parents = json.loads(parents)
            parents_entities = Entity.objects.filter(id__in=parents)
            for parents_entity in parents_entities:
                new_entity.parents.add(parents_entity)

        if competitors:
            competitors = json.loads(competitors)
            for competitor in competitors:
                new_entity.competitors.add(competitor)

        client = EntityDetailSerializer(new_entity).data
        data = {"client": client}
        data = {"status": "1", "message": "...", "data": data}
        # 添加索引
        new_entity.save()
        return Response(data)


class ClientDetail(APIView):
    """
    Client 客户
    get：获取客户详细信息
    put：1.验证是否具有更新权限。2.更新客户详细信息。
    """

    def get_object(self, pk):
        try:
            return Entity.objects.get(pk=pk)
        except ObjectDoesNotExist:
            raise Http404

    # get Client detail
    @set_recent_items('client', 20)
    def get(self, request, pk):
        entity = self.get_object(pk)
        serializer = EntityDetailSerializer(entity)
        return Response(serializer.data)

    # put Client detail
    def put(self, request, pk):
        # 权限验证
        user = request.user
        if not check_action_permission(user, 'entity', 'change'):
            data = {"status": "0", "error_message": "No Permission."}
            return Response(data)

        name = request.data.get("name")
        picture = request.FILES.get('picture')
        english_name = request.data.get("english_name")
        entity_type = request.data.get("entity_type")
        company = request.data.get("company")
        industry = request.data.get("industry")
        tel = request.data.get("tel")
        mobile = request.data.get("mobile")
        fax = request.data.get("fax")
        email = request.data.get("email")
        address = request.data.get("address")
        client_members = request.data.get("client_members")
        parents = request.data.get("parents")
        child = request.data.get("child")
        website = request.data.get("website")
        tax_id = request.data.get("tax_id")
        registered_company = request.data.get("registered_company")
        bank_account = request.data.get("bank_account")
        bank_name = request.data.get("bank_name")
        registered_company_address = request.data.get("registered_company_address")
        billing_period = request.data.get("billing_period")
        contacts = request.data.get("contacts")
        competitors = request.data.get("competitors")
        number = request.data.get("number", None)
        billing_tel = request.data.get("billing_tel")
        # assert 1 == 2
        entity = self.get_object(pk)
        entity.name = name
        entity.english_name = english_name
        entity.entity_type = entity_type
        entity.company = company
        if industry is not None:
            industry = int(industry)
            industry_obj = Industry.objects.filter(id=industry).first()
            entity.industry = industry_obj
        else:
            entity.industry = None
        entity.tel = tel
        entity.mobile = mobile
        entity.fax = fax
        entity.email = email
        entity.address = address
        entity.website = website
        entity.tax_id = tax_id  # 税号
        entity.registered_company = registered_company  # 注册公司名称
        entity.registered_company_address = registered_company_address  # 公司注册地址
        entity.bank_account = bank_account  # 银行账户
        entity.bank_name = bank_name  # 开户行名称
        entity.billing_period = billing_period  # 账单周期
        entity.billing_tel = billing_tel
        if number:
            entity.number = number

        # # 账单联系人
        # if billing_contact is not None:
        #     billing_contact = json.loads(billing_contact)
        #     billing_contact_obj = Contact.objects.filter(id__in=billing_contact).first()
        #     if billing_contact_obj:
        #         entity.billing_contact = billing_contact_obj
        #     else:
        #         entity.billing_contact = None

        # 客户图片保存(删除操作)
        if picture is not None:
            attachment = Attachment()
            attachment.name = name + '-photo'
            attachment.type_of = '2'
            attachment.file = picture
            attachment.save()
            entity.picture = attachment

        # 更新联系人
        if contacts is not None:
            contacts = json.loads(contacts)
            # 初始化 客户-联系人关系
            original_contacts = Contact.objects.filter(client=entity)
            for original_contact in original_contacts:
                original_contact.client = None
                original_contact.save()
            # 更新 客户-联系人关系
            contacts_entities = Contact.objects.filter(id__in=contacts)
            for contact in contacts_entities:
                contact.client = entity
                contact.save()

        # 如果是联合客户，添加关联
        if client_members is not None:
            client_members = json.loads(client_members)
            original_members = entity.joint_parent.all()
            for original_member in original_members:
                entity.joint_parent.remove(original_member)
            for client_member in client_members:
                entity.joint_parent.add(client_member)

        # 关联客户子公司
        if child is not None:
            child = json.loads(child)
            original_children = entity.children.all()
            for original_child in original_children:
                entity.children.remove(original_child)
            for i in child:
                entity.children.add(i)

        # 添加母公司
        if parents is not None:
            parents = json.loads(parents)
            original_parents = entity.parents.all()
            for original_parent in original_parents:
                entity.parents.remove(original_parent)
            for parent in parents:
                entity.parents.add(parent)

        if competitors is not None:
            competitors = json.loads(competitors)
            original_competitors = entity.competitors.all()
            for original_competitor in original_competitors:
                entity.competitors.remove(original_competitor)
            for competitor in competitors:
                entity.competitors.add(competitor)
        # save
        entity.save()
        client = EntityDetailSerializer(entity).data
        data = {"client": client}
        data = {"status": "1", "message": "...", "data": data}
        return Response(data)


class ClientBatchOperation(APIView):
    # delete Client detail

    def _get_clients_from_matter(self, client_id):
        # 模板相关信息,确定当前字段ID(field_id)
        TEMPLATE_ID = '1'
        TEMPLATE_KEY = 'matter_client'
        TEMPLATE_MODEL = '1'

        try:
            field_id = TemplateField.objects.get(template_id=TEMPLATE_ID, key=TEMPLATE_KEY)
        except:
            logger.error('Get TemplateField Fail.')
            raise Http404
        tmp_values = TemplateFieldValue.objects.filter(model=TEMPLATE_MODEL, field_id=field_id).values('value')
        _flag = False
        for i in tmp_values:
            # 如果存在某个案件中则raise, 不能被删除
            client_ids = i.get('value', '').split(',')
            if str(client_id) in client_ids:
                _flag = True
                _matter_name = ''
                break
        return _flag

    def post(self, request):
        user = request.user
        if not check_action_permission(user, "entity", "delete"):

            data = {"status": "0", "error_message": "No Permission."}
            return Response(data)

        ids = request.data.get("ids")
        for i in ids:
            _flag = self._get_clients_from_matter(i)
            if _flag:
                return Response({"status": "0", "error_message": "Fail, the client has already related Matter."})

        try:
            Entity.objects.filter(id__in=ids).delete()
        except Exception as e:
            logger.exception('Client Delete Fail.')
            return Response({"status": "0", "error_message": "Fail."})
        return Response({"status": "1", "message": "Client Delete"})

    # 批量更新
    def put(self, request):
        user = request.user

        if not check_action_permission(user, 'entity', 'change'):
            data = {"status": "0", "error_message": "No Permission."}
            return Response(data)

        clients = request.data.get('clients')
        for client in clients:
            id = client['id']
            client_obj = Entity.objects.filter(id=id).first()
            if client_obj:
                client_obj.company = client.get('company')
                if client.get('industry'):
                    client_obj.industry = Industry.objects.filter(id=client.get('industry')).first()
                # 默认修改座机tel,有座机和两个电话都没的情况都更新到座机tel
                if not client_obj.tel and not client_obj.mobile:
                    client_obj.tel = client.get('tel')
                elif client_obj.tel:
                    client_obj.tel = client.get('tel')
                else:
                    client_obj.mobile = client.get('tel')
            client_obj.save()
        return Response({"status": "1", "message": "Client(s) Update!"})


class ClientQuickBuild(APIView):
    """
    快速新建接口
    """
    def post(self, request):
        # 权限验证
        user = request.user
        if not check_action_permission(user, 'entity', 'add'):
            data = {"status": "0", "message": "No Permission."}
            return Response(data)

        name = request.data.get("name")
        english_name = request.data.get("english_name")
        # 检查名字是否重复
        # 如果重复则直接返回该对象id
        _entity = Entity.objects.filter(name=name).first()
        if _entity:
            return Response({"status": "1", "message": "...", "data": {"client": {"id": _entity.id}}})
        del _entity

        _entity = Entity()
        _entity.name = name
        _entity.english_name = english_name
        _entity.is_opposite = False
        _entity.is_potential = True
        _entity.save()

        client = EntityDetailSerializer(_entity).data
        data = {"status": "1", "message": "...", "data": {"client": client}}
        return Response(data)

132afe4cd8d2bd746883e23258fee1d7987ac184
<mask token>


class ClientDetail(APIView):
    <mask token>
    <mask token>
    <mask token>
    <mask token>


class ClientBatchOperation(APIView):

    def _get_clients_from_matter(self, client_id):
        TEMPLATE_ID = '1'
        TEMPLATE_KEY = 'matter_client'
        TEMPLATE_MODEL = '1'
        try:
            field_id = TemplateField.objects.get(template_id=TEMPLATE_ID,
                key=TEMPLATE_KEY)
        except:
            logger.error('Get TemplateField Fail.')
            raise Http404
        tmp_values = TemplateFieldValue.objects.filter(model=TEMPLATE_MODEL,
            field_id=field_id).values('value')
        _flag = False
        for i in tmp_values:
            client_ids = i.get('value', '').split(',')
            if str(client_id) in client_ids:
                _flag = True
                _matter_name = ''
                break
        return _flag

    def post(self, request):
        user = request.user
        if not check_action_permission(user, 'entity', 'delete'):
            data = {'status': '0', 'error_message': 'No Permission.'}
            return Response(data)
        ids = request.data.get('ids')
        for i in ids:
            _flag = self._get_clients_from_matter(i)
            if _flag:
                return Response({'status': '0', 'error_message':
                    'Fail, the client has already related Matter.'})
        try:
            Entity.objects.filter(id__in=ids).delete()
        except Exception as e:
            logger.exception('Client Delete Fail.')
            return Response({'status': '0', 'error_message': 'Fail.'})
        return Response({'status': '1', 'message': 'Client Delete'})

    def put(self, request):
        user = request.user
        if not check_action_permission(user, 'entity', 'change'):
            data = {'status': '0', 'error_message': 'No Permission.'}
            return Response(data)
        clients = request.data.get('clients')
        for client in clients:
            id = client['id']
            client_obj = Entity.objects.filter(id=id).first()
            if client_obj:
                client_obj.company = client.get('company')
                if client.get('industry'):
                    client_obj.industry = Industry.objects.filter(id=client
                        .get('industry')).first()
                if not client_obj.tel and not client_obj.mobile:
                    client_obj.tel = client.get('tel')
                elif client_obj.tel:
                    client_obj.tel = client.get('tel')
                else:
                    client_obj.mobile = client.get('tel')
            client_obj.save()
        return Response({'status': '1', 'message': 'Client(s) Update!'})


class ClientQuickBuild(APIView):
    """
    快速新建接口
    """

    def post(self, request):
        user = request.user
        if not check_action_permission(user, 'entity', 'add'):
            data = {'status': '0', 'message': 'No Permission.'}
            return Response(data)
        name = request.data.get('name')
        english_name = request.data.get('english_name')
        _entity = Entity.objects.filter(name=name).first()
        if _entity:
            return Response({'status': '1', 'message': '...', 'data': {
                'client': {'id': _entity.id}}})
        del _entity
        _entity = Entity()
        _entity.name = name
        _entity.english_name = english_name
        _entity.is_opposite = False
        _entity.is_potential = True
        _entity.save()
        client = EntityDetailSerializer(_entity).data
        data = {'status': '1', 'message': '...', 'data': {'client': client}}
        return Response(data)

<mask token>


class ClientDetail(APIView):
    """
    Client 客户
    get：获取客户详细信息
    put：1.验证是否具有更新权限。2.更新客户详细信息。
    """

    def get_object(self, pk):
        try:
            return Entity.objects.get(pk=pk)
        except ObjectDoesNotExist:
            raise Http404

    @set_recent_items('client', 20)
    def get(self, request, pk):
        entity = self.get_object(pk)
        serializer = EntityDetailSerializer(entity)
        return Response(serializer.data)

    def put(self, request, pk):
        user = request.user
        if not check_action_permission(user, 'entity', 'change'):
            data = {'status': '0', 'error_message': 'No Permission.'}
            return Response(data)
        name = request.data.get('name')
        picture = request.FILES.get('picture')
        english_name = request.data.get('english_name')
        entity_type = request.data.get('entity_type')
        company = request.data.get('company')
        industry = request.data.get('industry')
        tel = request.data.get('tel')
        mobile = request.data.get('mobile')
        fax = request.data.get('fax')
        email = request.data.get('email')
        address = request.data.get('address')
        client_members = request.data.get('client_members')
        parents = request.data.get('parents')
        child = request.data.get('child')
        website = request.data.get('website')
        tax_id = request.data.get('tax_id')
        registered_company = request.data.get('registered_company')
        bank_account = request.data.get('bank_account')
        bank_name = request.data.get('bank_name')
        registered_company_address = request.data.get(
            'registered_company_address')
        billing_period = request.data.get('billing_period')
        contacts = request.data.get('contacts')
        competitors = request.data.get('competitors')
        number = request.data.get('number', None)
        billing_tel = request.data.get('billing_tel')
        entity = self.get_object(pk)
        entity.name = name
        entity.english_name = english_name
        entity.entity_type = entity_type
        entity.company = company
        if industry is not None:
            industry = int(industry)
            industry_obj = Industry.objects.filter(id=industry).first()
            entity.industry = industry_obj
        else:
            entity.industry = None
        entity.tel = tel
        entity.mobile = mobile
        entity.fax = fax
        entity.email = email
        entity.address = address
        entity.website = website
        entity.tax_id = tax_id
        entity.registered_company = registered_company
        entity.registered_company_address = registered_company_address
        entity.bank_account = bank_account
        entity.bank_name = bank_name
        entity.billing_period = billing_period
        entity.billing_tel = billing_tel
        if number:
            entity.number = number
        if picture is not None:
            attachment = Attachment()
            attachment.name = name + '-photo'
            attachment.type_of = '2'
            attachment.file = picture
            attachment.save()
            entity.picture = attachment
        if contacts is not None:
            contacts = json.loads(contacts)
            original_contacts = Contact.objects.filter(client=entity)
            for original_contact in original_contacts:
                original_contact.client = None
                original_contact.save()
            contacts_entities = Contact.objects.filter(id__in=contacts)
            for contact in contacts_entities:
                contact.client = entity
                contact.save()
        if client_members is not None:
            client_members = json.loads(client_members)
            original_members = entity.joint_parent.all()
            for original_member in original_members:
                entity.joint_parent.remove(original_member)
            for client_member in client_members:
                entity.joint_parent.add(client_member)
        if child is not None:
            child = json.loads(child)
            original_children = entity.children.all()
            for original_child in original_children:
                entity.children.remove(original_child)
            for i in child:
                entity.children.add(i)
        if parents is not None:
            parents = json.loads(parents)
            original_parents = entity.parents.all()
            for original_parent in original_parents:
                entity.parents.remove(original_parent)
            for parent in parents:
                entity.parents.add(parent)
        if competitors is not None:
            competitors = json.loads(competitors)
            original_competitors = entity.competitors.all()
            for original_competitor in original_competitors:
                entity.competitors.remove(original_competitor)
            for competitor in competitors:
                entity.competitors.add(competitor)
        entity.save()
        client = EntityDetailSerializer(entity).data
        data = {'client': client}
        data = {'status': '1', 'message': '...', 'data': data}
        return Response(data)


class ClientBatchOperation(APIView):

    def _get_clients_from_matter(self, client_id):
        TEMPLATE_ID = '1'
        TEMPLATE_KEY = 'matter_client'
        TEMPLATE_MODEL = '1'
        try:
            field_id = TemplateField.objects.get(template_id=TEMPLATE_ID,
                key=TEMPLATE_KEY)
        except:
            logger.error('Get TemplateField Fail.')
            raise Http404
        tmp_values = TemplateFieldValue.objects.filter(model=TEMPLATE_MODEL,
            field_id=field_id).values('value')
        _flag = False
        for i in tmp_values:
            client_ids = i.get('value', '').split(',')
            if str(client_id) in client_ids:
                _flag = True
                _matter_name = ''
                break
        return _flag

    def post(self, request):
        user = request.user
        if not check_action_permission(user, 'entity', 'delete'):
            data = {'status': '0', 'error_message': 'No Permission.'}
            return Response(data)
        ids = request.data.get('ids')
        for i in ids:
            _flag = self._get_clients_from_matter(i)
            if _flag:
                return Response({'status': '0', 'error_message':
                    'Fail, the client has already related Matter.'})
        try:
            Entity.objects.filter(id__in=ids).delete()
        except Exception as e:
            logger.exception('Client Delete Fail.')
            return Response({'status': '0', 'error_message': 'Fail.'})
        return Response({'status': '1', 'message': 'Client Delete'})

    def put(self, request):
        user = request.user
        if not check_action_permission(user, 'entity', 'change'):
            data = {'status': '0', 'error_message': 'No Permission.'}
            return Response(data)
        clients = request.data.get('clients')
        for client in clients:
            id = client['id']
            client_obj = Entity.objects.filter(id=id).first()
            if client_obj:
                client_obj.company = client.get('company')
                if client.get('industry'):
                    client_obj.industry = Industry.objects.filter(id=client
                        .get('industry')).first()
                if not client_obj.tel and not client_obj.mobile:
                    client_obj.tel = client.get('tel')
                elif client_obj.tel:
                    client_obj.tel = client.get('tel')
                else:
                    client_obj.mobile = client.get('tel')
            client_obj.save()
        return Response({'status': '1', 'message': 'Client(s) Update!'})


class ClientQuickBuild(APIView):
    """
    快速新建接口
    """

    def post(self, request):
        user = request.user
        if not check_action_permission(user, 'entity', 'add'):
            data = {'status': '0', 'message': 'No Permission.'}
            return Response(data)
        name = request.data.get('name')
        english_name = request.data.get('english_name')
        _entity = Entity.objects.filter(name=name).first()
        if _entity:
            return Response({'status': '1', 'message': '...', 'data': {
                'client': {'id': _entity.id}}})
        del _entity
        _entity = Entity()
        _entity.name = name
        _entity.english_name = english_name
        _entity.is_opposite = False
        _entity.is_potential = True
        _entity.save()
        client = EntityDetailSerializer(_entity).data
        data = {'status': '1', 'message': '...', 'data': {'client': client}}
        return Response(data)

<mask token>


class ClientView(APIView):
    <mask token>

    @set_latest_filters('client')
    def get(self, request):
        user = request.user
        if not check_action_permission(request.user, 'entity', 'public'):
            return Response({'status': '0', 'error_message': 'No permission.'})
        SEARCH_FIELDS = ['name', 'english_name',
            'multi_joint_children_name', 'multi_joint_children_english_name']
        ORDER_FIELDS = {'number': 'number', 'name': 'name', 'industry_name':
            'sort_industry_company', 'tel': 'sort_tel_mobile', '-number':
            '-number', '-name': '-name', '-industry_name':
            '-sort_industry_company', '-tel': '-sort_tel_mobile'}
        start = request.GET.get('start', 0)
        size = request.GET.get('size', 20)
        order_by = request.GET.get('order_by', '-number')
        if order_by:
            order_by = ORDER_FIELDS.get(order_by, '-number')
        s_type = request.GET.get('s_type')
        s_keywords = request.GET.get('s_keywords')
        f_entity_type = request.GET.get('f_entity_type', None)
        f_matter_id = request.GET.get('f_matter_id', None)
        fq = {}
        sq = {}
        data = {}
        object_type = 'entity'
        f_recently = request.GET.get('f_recently', None)
        or_fq = {}
        fq['is_opposite'] = False
        if f_recently == '1':
            fq['obj_id__in'] = user.recent_items.get('client', None)
            if not fq['obj_id__in']:
                return Response({'status': '0', 'error_message':
                    'No Recently viewed data.'})
        elif f_matter_id:
            matter = Matter.objects.filter(id=int(f_matter_id)).first()
            if matter:
                sq['obj_id__in'] = [client['id'] for client in
                    get_matter_value_by_key(matter, 'matter_client')]
        elif f_entity_type:
            fq['entity_type'] = f_entity_type
        if s_type and s_keywords:
            if s_type == 'all':
                _fields = SEARCH_FIELDS
            else:
                _fields = [s_type]
            for f in _fields:
                if f == 'matter_name':
                    search_queryset = SearchQuerySet().models(Matter).filter(
                        name__contains=s_keywords).values_list(
                        'multi_client_id')
                    client_ids = []
                    for multi_client_id in search_queryset:
                        try:
                            client_ids.extend(multi_client_id[0])
                        except:
                            pass
                    sq['obj_id__in'] = list(set(client_ids))
                sq[f + '__contains'] = s_keywords
                srs = search_and_filter_objects(object_type, int(start),
                    int(size), 'OR', order_by, None, None, '2', {(f +
                    '__contains'): s_keywords}, fq)
                data[f + '_hits'] = srs['hits']
        s2 = search_and_filter_objects(object_type, int(start), int(size),
            'OR', order_by, None, None, '2', sq, fq, None, or_fq)
        for _entity in s2['data']:
            parent_ids = _entity.pop('parents', [])
            _entity['parents'] = Entity.objects.filter(id__in=parent_ids
                ).values('id', 'name', 'english_name')
        data['hits'] = s2['hits']
        data['list'] = s2['data']
        data['size'] = s2['size']
        return Response({'status': '1', 'data': data})
    <mask token>


class ClientDetail(APIView):
    """
    Client 客户
    get：获取客户详细信息
    put：1.验证是否具有更新权限。2.更新客户详细信息。
    """

    def get_object(self, pk):
        try:
            return Entity.objects.get(pk=pk)
        except ObjectDoesNotExist:
            raise Http404

    @set_recent_items('client', 20)
    def get(self, request, pk):
        entity = self.get_object(pk)
        serializer = EntityDetailSerializer(entity)
        return Response(serializer.data)

    def put(self, request, pk):
        user = request.user
        if not check_action_permission(user, 'entity', 'change'):
            data = {'status': '0', 'error_message': 'No Permission.'}
            return Response(data)
        name = request.data.get('name')
        picture = request.FILES.get('picture')
        english_name = request.data.get('english_name')
        entity_type = request.data.get('entity_type')
        company = request.data.get('company')
        industry = request.data.get('industry')
        tel = request.data.get('tel')
        mobile = request.data.get('mobile')
        fax = request.data.get('fax')
        email = request.data.get('email')
        address = request.data.get('address')
        client_members = request.data.get('client_members')
        parents = request.data.get('parents')
        child = request.data.get('child')
        website = request.data.get('website')
        tax_id = request.data.get('tax_id')
        registered_company = request.data.get('registered_company')
        bank_account = request.data.get('bank_account')
        bank_name = request.data.get('bank_name')
        registered_company_address = request.data.get(
            'registered_company_address')
        billing_period = request.data.get('billing_period')
        contacts = request.data.get('contacts')
        competitors = request.data.get('competitors')
        number = request.data.get('number', None)
        billing_tel = request.data.get('billing_tel')
        entity = self.get_object(pk)
        entity.name = name
        entity.english_name = english_name
        entity.entity_type = entity_type
        entity.company = company
        if industry is not None:
            industry = int(industry)
            industry_obj = Industry.objects.filter(id=industry).first()
            entity.industry = industry_obj
        else:
            entity.industry = None
        entity.tel = tel
        entity.mobile = mobile
        entity.fax = fax
        entity.email = email
        entity.address = address
        entity.website = website
        entity.tax_id = tax_id
        entity.registered_company = registered_company
        entity.registered_company_address = registered_company_address
        entity.bank_account = bank_account
        entity.bank_name = bank_name
        entity.billing_period = billing_period
        entity.billing_tel = billing_tel
        if number:
            entity.number = number
        if picture is not None:
            attachment = Attachment()
            attachment.name = name + '-photo'
            attachment.type_of = '2'
            attachment.file = picture
            attachment.save()
            entity.picture = attachment
        if contacts is not None:
            contacts = json.loads(contacts)
            original_contacts = Contact.objects.filter(client=entity)
            for original_contact in original_contacts:
                original_contact.client = None
                original_contact.save()
            contacts_entities = Contact.objects.filter(id__in=contacts)
            for contact in contacts_entities:
                contact.client = entity
                contact.save()
        if client_members is not None:
            client_members = json.loads(client_members)
            original_members = entity.joint_parent.all()
            for original_member in original_members:
                entity.joint_parent.remove(original_member)
            for client_member in client_members:
                entity.joint_parent.add(client_member)
        if child is not None:
            child = json.loads(child)
            original_children = entity.children.all()
            for original_child in original_children:
                entity.children.remove(original_child)
            for i in child:
                entity.children.add(i)
        if parents is not None:
            parents = json.loads(parents)
            original_parents = entity.parents.all()
            for original_parent in original_parents:
                entity.parents.remove(original_parent)
            for parent in parents:
                entity.parents.add(parent)
        if competitors is not None:
            competitors = json.loads(competitors)
            original_competitors = entity.competitors.all()
            for original_competitor in original_competitors:
                entity.competitors.remove(original_competitor)
            for competitor in competitors:
                entity.competitors.add(competitor)
        entity.save()
        client = EntityDetailSerializer(entity).data
        data = {'client': client}
        data = {'status': '1', 'message': '...', 'data': data}
        return Response(data)


class ClientBatchOperation(APIView):

    def _get_clients_from_matter(self, client_id):
        TEMPLATE_ID = '1'
        TEMPLATE_KEY = 'matter_client'
        TEMPLATE_MODEL = '1'
        try:
            field_id = TemplateField.objects.get(template_id=TEMPLATE_ID,
                key=TEMPLATE_KEY)
        except:
            logger.error('Get TemplateField Fail.')
            raise Http404
        tmp_values = TemplateFieldValue.objects.filter(model=TEMPLATE_MODEL,
            field_id=field_id).values('value')
        _flag = False
        for i in tmp_values:
            client_ids = i.get('value', '').split(',')
            if str(client_id) in client_ids:
                _flag = True
                _matter_name = ''
                break
        return _flag

    def post(self, request):
        user = request.user
        if not check_action_permission(user, 'entity', 'delete'):
            data = {'status': '0', 'error_message': 'No Permission.'}
            return Response(data)
        ids = request.data.get('ids')
        for i in ids:
            _flag = self._get_clients_from_matter(i)
            if _flag:
                return Response({'status': '0', 'error_message':
                    'Fail, the client has already related Matter.'})
        try:
            Entity.objects.filter(id__in=ids).delete()
        except Exception as e:
            logger.exception('Client Delete Fail.')
            return Response({'status': '0', 'error_message': 'Fail.'})
        return Response({'status': '1', 'message': 'Client Delete'})

    def put(self, request):
        user = request.user
        if not check_action_permission(user, 'entity', 'change'):
            data = {'status': '0', 'error_message': 'No Permission.'}
            return Response(data)
        clients = request.data.get('clients')
        for client in clients:
            id = client['id']
            client_obj = Entity.objects.filter(id=id).first()
            if client_obj:
                client_obj.company = client.get('company')
                if client.get('industry'):
                    client_obj.industry = Industry.objects.filter(id=client
                        .get('industry')).first()
                if not client_obj.tel and not client_obj.mobile:
                    client_obj.tel = client.get('tel')
                elif client_obj.tel:
                    client_obj.tel = client.get('tel')
                else:
                    client_obj.mobile = client.get('tel')
            client_obj.save()
        return Response({'status': '1', 'message': 'Client(s) Update!'})


class ClientQuickBuild(APIView):
    """
    快速新建接口
    """

    def post(self, request):
        user = request.user
        if not check_action_permission(user, 'entity', 'add'):
            data = {'status': '0', 'message': 'No Permission.'}
            return Response(data)
        name = request.data.get('name')
        english_name = request.data.get('english_name')
        _entity = Entity.objects.filter(name=name).first()
        if _entity:
            return Response({'status': '1', 'message': '...', 'data': {
                'client': {'id': _entity.id}}})
        del _entity
        _entity = Entity()
        _entity.name = name
        _entity.english_name = english_name
        _entity.is_opposite = False
        _entity.is_potential = True
        _entity.save()
        client = EntityDetailSerializer(_entity).data
        data = {'status': '1', 'message': '...', 'data': {'client': client}}
        return Response(data)

<mask token>
logger = logging.getLogger('django.request')


class ClientView(APIView):
    """
    Client 客户
    get：获取客户列表：返回基础字段信息。
    ?start=0&size=100&order_by=-date&&s_keywords=APAC&s_type=all
    post：创建客户：
    delete：删除客户：如果存在关联案件，不允许删除。（2017-12-21：案件model未定，目前直接删除）
    """

    @set_latest_filters('client')
    def get(self, request):
        user = request.user
        if not check_action_permission(request.user, 'entity', 'public'):
            return Response({'status': '0', 'error_message': 'No permission.'})
        SEARCH_FIELDS = ['name', 'english_name',
            'multi_joint_children_name', 'multi_joint_children_english_name']
        ORDER_FIELDS = {'number': 'number', 'name': 'name', 'industry_name':
            'sort_industry_company', 'tel': 'sort_tel_mobile', '-number':
            '-number', '-name': '-name', '-industry_name':
            '-sort_industry_company', '-tel': '-sort_tel_mobile'}
        start = request.GET.get('start', 0)
        size = request.GET.get('size', 20)
        order_by = request.GET.get('order_by', '-number')
        if order_by:
            order_by = ORDER_FIELDS.get(order_by, '-number')
        s_type = request.GET.get('s_type')
        s_keywords = request.GET.get('s_keywords')
        f_entity_type = request.GET.get('f_entity_type', None)
        f_matter_id = request.GET.get('f_matter_id', None)
        fq = {}
        sq = {}
        data = {}
        object_type = 'entity'
        f_recently = request.GET.get('f_recently', None)
        or_fq = {}
        fq['is_opposite'] = False
        if f_recently == '1':
            fq['obj_id__in'] = user.recent_items.get('client', None)
            if not fq['obj_id__in']:
                return Response({'status': '0', 'error_message':
                    'No Recently viewed data.'})
        elif f_matter_id:
            matter = Matter.objects.filter(id=int(f_matter_id)).first()
            if matter:
                sq['obj_id__in'] = [client['id'] for client in
                    get_matter_value_by_key(matter, 'matter_client')]
        elif f_entity_type:
            fq['entity_type'] = f_entity_type
        if s_type and s_keywords:
            if s_type == 'all':
                _fields = SEARCH_FIELDS
            else:
                _fields = [s_type]
            for f in _fields:
                if f == 'matter_name':
                    search_queryset = SearchQuerySet().models(Matter).filter(
                        name__contains=s_keywords).values_list(
                        'multi_client_id')
                    client_ids = []
                    for multi_client_id in search_queryset:
                        try:
                            client_ids.extend(multi_client_id[0])
                        except:
                            pass
                    sq['obj_id__in'] = list(set(client_ids))
                sq[f + '__contains'] = s_keywords
                srs = search_and_filter_objects(object_type, int(start),
                    int(size), 'OR', order_by, None, None, '2', {(f +
                    '__contains'): s_keywords}, fq)
                data[f + '_hits'] = srs['hits']
        s2 = search_and_filter_objects(object_type, int(start), int(size),
            'OR', order_by, None, None, '2', sq, fq, None, or_fq)
        for _entity in s2['data']:
            parent_ids = _entity.pop('parents', [])
            _entity['parents'] = Entity.objects.filter(id__in=parent_ids
                ).values('id', 'name', 'english_name')
        data['hits'] = s2['hits']
        data['list'] = s2['data']
        data['size'] = s2['size']
        return Response({'status': '1', 'data': data})

    def post(self, request):
        user = request.user
        if not check_action_permission(user, 'entity', 'add'):
            data = {'status': '0', 'message': 'No Permission.'}
            return Response(data)
        name = request.data.get('name')
        _entity = Entity.objects.filter(name=name).first()
        if _entity:
            return Response({'status': '1', 'message': '...', 'data': {
                'client': {'id': _entity.id}}})
        del _entity
        picture = request.FILES.get('picture')
        english_name = request.data.get('english_name')
        entity_type = request.data.get('entity_type')
        company = request.data.get('company')
        industry = request.data.get('industry')
        tel = request.data.get('tel')
        mobile = request.data.get('mobile')
        fax = request.data.get('fax')
        email = request.data.get('email')
        address = request.data.get('address')
        client_members = request.data.get('client_members')
        parents = request.data.get('parents')
        child = request.data.get('child')
        website = request.data.get('website')
        tax_id = request.data.get('tax_id')
        registered_company = request.data.get('registered_company')
        bank_account = request.data.get('bank_account')
        bank_name = request.data.get('bank_name')
        registered_company_address = request.data.get(
            'registered_company_address')
        billing_period = request.data.get('billing_period')
        contacts = request.data.get('contacts')
        competitors = request.data.get('competitors')
        billing_tel = request.data.get('billing_tel')
        number = request.data.get('number', None)
        new_entity = Entity()
        new_entity.name = name
        new_entity.english_name = english_name
        new_entity.entity_type = entity_type
        new_entity.company = company
        new_entity.is_active = True
        if industry:
            industry = int(industry)
            industry_obj = Industry.objects.filter(id=industry).first()
            new_entity.industry = industry_obj
        new_entity.tel = tel
        new_entity.mobile = mobile
        new_entity.fax = fax
        new_entity.email = email
        new_entity.address = address
        new_entity.website = website
        new_entity.tax_id = tax_id
        new_entity.registered_company = registered_company
        new_entity.registered_company_address = registered_company_address
        new_entity.bank_account = bank_account
        new_entity.bank_name = bank_name
        new_entity.billing_period = billing_period
        new_entity.billing_tel = billing_tel
        if number is None:
            number = get_client_number()['number']
        if len(Entity.objects.filter(number=number)) > 0:
            return Response({'status': '0', 'error_message':
                'client number is used'})
        new_entity.number = number
        if picture:
            attachment = Attachment()
            attachment.name = name + '-photo'
            attachment.type_of = '2'
            attachment.file = picture
            attachment.save()
            new_entity.picture = attachment
        new_entity.save()
        EntityAccess.objects.create(entity=new_entity, access='4', leavel='v')
        if contacts:
            contacts = json.loads(contacts)
            contacts_entities = Contact.objects.filter(id__in=contacts)
            for contact in contacts_entities:
                contact.client = new_entity
                contact.save()
        if client_members:
            client_members = json.loads(client_members)
            client_members_objs = Entity.objects.filter(id__in=client_members)
            for client_members_obj in client_members_objs:
                new_entity.joint_parent.add(client_members_obj)
        if child:
            child = json.loads(child)
            child_entities = Entity.objects.filter(id__in=child)
            for child_entity in child_entities:
                child_entity.parents.add(new_entity)
        if parents:
            parents = json.loads(parents)
            parents_entities = Entity.objects.filter(id__in=parents)
            for parents_entity in parents_entities:
                new_entity.parents.add(parents_entity)
        if competitors:
            competitors = json.loads(competitors)
            for competitor in competitors:
                new_entity.competitors.add(competitor)
        client = EntityDetailSerializer(new_entity).data
        data = {'client': client}
        data = {'status': '1', 'message': '...', 'data': data}
        new_entity.save()
        return Response(data)


class ClientDetail(APIView):
    """
    Client 客户
    get：获取客户详细信息
    put：1.验证是否具有更新权限。2.更新客户详细信息。
    """

    def get_object(self, pk):
        try:
            return Entity.objects.get(pk=pk)
        except ObjectDoesNotExist:
            raise Http404

    @set_recent_items('client', 20)
    def get(self, request, pk):
        entity = self.get_object(pk)
        serializer = EntityDetailSerializer(entity)
        return Response(serializer.data)

    def put(self, request, pk):
        user = request.user
        if not check_action_permission(user, 'entity', 'change'):
            data = {'status': '0', 'error_message': 'No Permission.'}
            return Response(data)
        name = request.data.get('name')
        picture = request.FILES.get('picture')
        english_name = request.data.get('english_name')
        entity_type = request.data.get('entity_type')
        company = request.data.get('company')
        industry = request.data.get('industry')
        tel = request.data.get('tel')
        mobile = request.data.get('mobile')
        fax = request.data.get('fax')
        email = request.data.get('email')
        address = request.data.get('address')
        client_members = request.data.get('client_members')
        parents = request.data.get('parents')
        child = request.data.get('child')
        website = request.data.get('website')
        tax_id = request.data.get('tax_id')
        registered_company = request.data.get('registered_company')
        bank_account = request.data.get('bank_account')
        bank_name = request.data.get('bank_name')
        registered_company_address = request.data.get(
            'registered_company_address')
        billing_period = request.data.get('billing_period')
        contacts = request.data.get('contacts')
        competitors = request.data.get('competitors')
        number = request.data.get('number', None)
        billing_tel = request.data.get('billing_tel')
        entity = self.get_object(pk)
        entity.name = name
        entity.english_name = english_name
        entity.entity_type = entity_type
        entity.company = company
        if industry is not None:
            industry = int(industry)
            industry_obj = Industry.objects.filter(id=industry).first()
            entity.industry = industry_obj
        else:
            entity.industry = None
        entity.tel = tel
        entity.mobile = mobile
        entity.fax = fax
        entity.email = email
        entity.address = address
        entity.website = website
        entity.tax_id = tax_id
        entity.registered_company = registered_company
        entity.registered_company_address = registered_company_address
        entity.bank_account = bank_account
        entity.bank_name = bank_name
        entity.billing_period = billing_period
        entity.billing_tel = billing_tel
        if number:
            entity.number = number
        if picture is not None:
            attachment = Attachment()
            attachment.name = name + '-photo'
            attachment.type_of = '2'
            attachment.file = picture
            attachment.save()
            entity.picture = attachment
        if contacts is not None:
            contacts = json.loads(contacts)
            original_contacts = Contact.objects.filter(client=entity)
            for original_contact in original_contacts:
                original_contact.client = None
                original_contact.save()
            contacts_entities = Contact.objects.filter(id__in=contacts)
            for contact in contacts_entities:
                contact.client = entity
                contact.save()
        if client_members is not None:
            client_members = json.loads(client_members)
            original_members = entity.joint_parent.all()
            for original_member in original_members:
                entity.joint_parent.remove(original_member)
            for client_member in client_members:
                entity.joint_parent.add(client_member)
        if child is not None:
            child = json.loads(child)
            original_children = entity.children.all()
            for original_child in original_children:
                entity.children.remove(original_child)
            for i in child:
                entity.children.add(i)
        if parents is not None:
            parents = json.loads(parents)
            original_parents = entity.parents.all()
            for original_parent in original_parents:
                entity.parents.remove(original_parent)
            for parent in parents:
                entity.parents.add(parent)
        if competitors is not None:
            competitors = json.loads(competitors)
            original_competitors = entity.competitors.all()
            for original_competitor in original_competitors:
                entity.competitors.remove(original_competitor)
            for competitor in competitors:
                entity.competitors.add(competitor)
        entity.save()
        client = EntityDetailSerializer(entity).data
        data = {'client': client}
        data = {'status': '1', 'message': '...', 'data': data}
        return Response(data)


class ClientBatchOperation(APIView):

    def _get_clients_from_matter(self, client_id):
        TEMPLATE_ID = '1'
        TEMPLATE_KEY = 'matter_client'
        TEMPLATE_MODEL = '1'
        try:
            field_id = TemplateField.objects.get(template_id=TEMPLATE_ID,
                key=TEMPLATE_KEY)
        except:
            logger.error('Get TemplateField Fail.')
            raise Http404
        tmp_values = TemplateFieldValue.objects.filter(model=TEMPLATE_MODEL,
            field_id=field_id).values('value')
        _flag = False
        for i in tmp_values:
            client_ids = i.get('value', '').split(',')
            if str(client_id) in client_ids:
                _flag = True
                _matter_name = ''
                break
        return _flag

    def post(self, request):
        user = request.user
        if not check_action_permission(user, 'entity', 'delete'):
            data = {'status': '0', 'error_message': 'No Permission.'}
            return Response(data)
        ids = request.data.get('ids')
        for i in ids:
            _flag = self._get_clients_from_matter(i)
            if _flag:
                return Response({'status': '0', 'error_message':
                    'Fail, the client has already related Matter.'})
        try:
            Entity.objects.filter(id__in=ids).delete()
        except Exception as e:
            logger.exception('Client Delete Fail.')
            return Response({'status': '0', 'error_message': 'Fail.'})
        return Response({'status': '1', 'message': 'Client Delete'})

    def put(self, request):
        user = request.user
        if not check_action_permission(user, 'entity', 'change'):
            data = {'status': '0', 'error_message': 'No Permission.'}
            return Response(data)
        clients = request.data.get('clients')
        for client in clients:
            id = client['id']
            client_obj = Entity.objects.filter(id=id).first()
            if client_obj:
                client_obj.company = client.get('company')
                if client.get('industry'):
                    client_obj.industry = Industry.objects.filter(id=client
                        .get('industry')).first()
                if not client_obj.tel and not client_obj.mobile:
                    client_obj.tel = client.get('tel')
                elif client_obj.tel:
                    client_obj.tel = client.get('tel')
                else:
                    client_obj.mobile = client.get('tel')
            client_obj.save()
        return Response({'status': '1', 'message': 'Client(s) Update!'})


class ClientQuickBuild(APIView):
    """
    快速新建接口
    """

    def post(self, request):
        user = request.user
        if not check_action_permission(user, 'entity', 'add'):
            data = {'status': '0', 'message': 'No Permission.'}
            return Response(data)
        name = request.data.get('name')
        english_name = request.data.get('english_name')
        _entity = Entity.objects.filter(name=name).first()
        if _entity:
            return Response({'status': '1', 'message': '...', 'data': {
                'client': {'id': _entity.id}}})
        del _entity
        _entity = Entity()
        _entity.name = name
        _entity.english_name = english_name
        _entity.is_opposite = False
        _entity.is_potential = True
        _entity.save()
        client = EntityDetailSerializer(_entity).data
        data = {'status': '1', 'message': '...', 'data': {'client': client}}
        return Response(data)

import json
import logging

from prm_core.models import *
from django.core.exceptions import ObjectDoesNotExist
from prm_core.serializers import *
from rest_framework.views import APIView, Response
from django.http import Http404
from prm_core.permission import *
from prm_core.solr import search_and_filter_objects
from prm_core.matter import get_matter_value_by_key
from haystack.query import SearchQuerySet, SQ
from prm_core.decorators import *
from Prime.settings import SOLR_DJANGO_CT
from haystack.query import SearchQuerySet, SQ
from haystack.utils.app_loading import haystack_get_model
from prm_core.number_generate import generate_number
from prm_core.numbers import get_client_number

logger = logging.getLogger('django.request')
# Client
#
# 创建客户和更新客户这两个接口涉及到图片附件的上传,前端需要用formdata传数据。
# formdata传数据会导致对象被转为字符串的问题,所以获取到的对象都需要做json.loads的处理。
#
class ClientView(APIView):
    """
    Client 客户
    get：获取客户列表：返回基础字段信息。
    ?start=0&size=100&order_by=-date&&s_keywords=APAC&s_type=all
    post：创建客户：
    delete：删除客户：如果存在关联案件，不允许删除。（2017-12-21：案件model未定，目前直接删除）
    """

    @set_latest_filters('client')
    def get(self, request):
        user = request.user
        if not check_action_permission(request.user, 'entity', 'public'):
            return Response({'status': '0', 'error_message': 'No permission.'})
        # LL 06282018 去除matter_name字段搜索
        SEARCH_FIELDS = ['name', 'english_name', 'multi_joint_children_name', 'multi_joint_children_english_name']
        ORDER_FIELDS = {'number': 'number', 'name': 'name', 'industry_name': 'sort_industry_company',
                      'tel': 'sort_tel_mobile', '-number': '-number', '-name': '-name',
                      '-industry_name': '-sort_industry_company', '-tel': '-sort_tel_mobile'}

        start = request.GET.get('start', 0)
        size = request.GET.get('size', 20)
        # 默认number排序;
        order_by = request.GET.get('order_by', '-number')
        if order_by:
            order_by = ORDER_FIELDS.get(order_by, '-number')
        s_type = request.GET.get("s_type")
        s_keywords = request.GET.get("s_keywords")

        # 筛选条件
        f_entity_type = request.GET.get('f_entity_type', None)
        f_matter_id = request.GET.get('f_matter_id', None)
        fq = {}
        sq = {}
        data = {}
        object_type = 'entity'
        # 过滤
        f_recently = request.GET.get('f_recently', None)
        # 过滤潜在客户:无客户号
        or_fq = {}
        # TODO: is_potential
        # or_fq['is_potential'] = None
        fq['is_opposite'] = False

        # # 最近查看
        if f_recently == '1':
            fq['obj_id__in'] = user.recent_items.get('client', None)
            if not fq['obj_id__in']:
                return Response({'status': '0', 'error_message': 'No Recently viewed data.'})
        elif f_matter_id:  # 根据案件id获取客户id
            matter = Matter.objects.filter(id=int(f_matter_id)).first()
            if matter:
                sq['obj_id__in'] = [client['id'] for client in get_matter_value_by_key(matter, 'matter_client')]
        elif f_entity_type:  # 先查出所有案件，再根据所有案件的客户字段找出所有客户的id，再进行过滤。
            fq['entity_type'] = f_entity_type
            # del or_fq['is_potential']

        # client_ids = SearchQuerySet().models(
        #     haystack_get_model('prm_core', SOLR_DJANGO_CT['matter'])).values_list('multi_client_id')
        # c_ids = []
        # for ids in client_ids:
        #     if isinstance(ids[0], list):
        #         c_ids.extend(ids[0])
        #     elif isinstance(ids[0], str):
        #         c_ids.append(ids[0])
        # fq['obj_id__in'] = set(c_ids)

        # 搜索
        if s_type and s_keywords:
            if s_type == 'all':
                _fields = SEARCH_FIELDS
            else:
                _fields = [s_type]
            for f in _fields:
                if f == 'matter_name':
                    search_queryset = SearchQuerySet().models(Matter).filter(name__contains=s_keywords).values_list(
                        'multi_client_id')
                    client_ids = []
                    for multi_client_id in search_queryset:
                        try:
                            client_ids.extend(multi_client_id[0])
                        except:
                            # should get a log.
                            pass
                    sq['obj_id__in'] = list(set(client_ids))

                sq[f + '__contains'] = s_keywords
                srs = search_and_filter_objects(object_type, int(start), int(size), 'OR', order_by, None, None, '2',
                                                {f + '__contains': s_keywords}, fq)
                data[f + '_hits'] = srs['hits']

        s2 = search_and_filter_objects(object_type, int(start), int(size), 'OR', order_by, None, None, '2', sq, fq, None, or_fq)
        # 添加母公司
        for _entity in s2['data']:
            parent_ids = _entity.pop('parents', [])
            _entity['parents'] = Entity.objects.filter(id__in=parent_ids).values('id', 'name', 'english_name')
        data['hits'] = s2['hits']
        data['list'] = s2['data']
        data['size'] = s2['size']
        
        # 返回每条数据的权限
        # ids = map(lambda x: int(x['obj_id']), data['list'])
        # auths = object_authority(user, 'entity', ids)
        # for item in data['list']:
        #     for auth in auths:
        #         if int(item['obj_id']) == auth['entity_id']:
        #             item['authority'] = auth['access']
        #             break

        return Response({'status': '1', 'data': data})

    # create Client
    def post(self, request):
        # 权限验证
        user = request.user
        if not check_action_permission(user, 'entity', 'add'):
            data = {"status": "0", "message": "No Permission."}
            return Response(data)

        name = request.data.get("name")
        # 检查名字是否重复
        # 如果重复则直接返回该对象id
        _entity = Entity.objects.filter(name=name).first()
        if _entity:
            return Response({"status": "1", "message": "...", "data": {"client": {"id": _entity.id}}})
        del _entity

        picture = request.FILES.get('picture')
        english_name = request.data.get("english_name")
        entity_type = request.data.get("entity_type")
        company = request.data.get("company")
        industry = request.data.get("industry")
        tel = request.data.get("tel")
        mobile = request.data.get("mobile")
        fax = request.data.get("fax")
        email = request.data.get("email")
        address = request.data.get("address")
        client_members = request.data.get("client_members")
        parents = request.data.get("parents")
        child = request.data.get("child")
        website = request.data.get("website")
        tax_id = request.data.get("tax_id")
        registered_company = request.data.get("registered_company")
        bank_account = request.data.get("bank_account")
        bank_name = request.data.get("bank_name")
        registered_company_address = request.data.get("registered_company_address")
        billing_period = request.data.get("billing_period")
        contacts = request.data.get('contacts')
        competitors = request.data.get('competitors')
        billing_tel = request.data.get('billing_tel')
        number = request.data.get('number', None)

        new_entity = Entity()
        new_entity.name = name
        new_entity.english_name = english_name
        new_entity.entity_type = entity_type
        new_entity.company = company
        new_entity.is_active = True
        if industry:
            industry = int(industry)
            industry_obj = Industry.objects.filter(id=industry).first()
            new_entity.industry = industry_obj

        new_entity.tel = tel
        new_entity.mobile = mobile
        new_entity.fax = fax
        new_entity.email = email
        new_entity.address = address
        new_entity.website = website
        new_entity.tax_id = tax_id                                             # 税号
        new_entity.registered_company = registered_company                     # 注册公司名称
        new_entity.registered_company_address = registered_company_address     # 公司注册地址
        new_entity.bank_account = bank_account          # 银行账户
        new_entity.bank_name = bank_name                # 开户行名称
        new_entity.billing_period = billing_period      # 账单周期
        new_entity.billing_tel = billing_tel

        if number is None:
            number = get_client_number()['number']
        if len(Entity.objects.filter(number=number)) > 0:
            return Response({'status': '0', 'error_message': 'client number is used'})
        new_entity.number = number

        # 客户图片保存
        if picture:
            attachment = Attachment()
            attachment.name = name + '-photo'
            attachment.type_of = '2'
            attachment.file = picture
            attachment.save()
            new_entity.picture = attachment

        # 保存新建client对象
        new_entity.save()

        EntityAccess.objects.create(entity=new_entity, access='4', leavel='v') #默认是view

        # 添加联系人
        if contacts:
            contacts = json.loads(contacts)
            contacts_entities = Contact.objects.filter(id__in=contacts)
            for contact in contacts_entities:
                contact.client = new_entity
                contact.save()

        # 添加账单联系人
        # if billing_contact:
        #     billing_contact = json.loads(billing_contact)
        #     billing_contacts = Contact.objects.filter(id__in=billing_contact)
        #     for billing_contact in billing_contacts:
        #         new_entity.billing_contact = billing_contact
        #         new_entity.save()

        # 如果是联合客户，添加关联
        if client_members:
            client_members = json.loads(client_members)
            client_members_objs = Entity.objects.filter(id__in=client_members)
            for client_members_obj in client_members_objs:
                new_entity.joint_parent.add(client_members_obj)

        # 关联客户子公司
        if child:
            child = json.loads(child)
            child_entities = Entity.objects.filter(id__in=child)
            for child_entity in child_entities:
                child_entity.parents.add(new_entity)

        # 添加母公司
        if parents:
            parents = json.loads(parents)
            parents_entities = Entity.objects.filter(id__in=parents)
            for parents_entity in parents_entities:
                new_entity.parents.add(parents_entity)

        if competitors:
            competitors = json.loads(competitors)
            for competitor in competitors:
                new_entity.competitors.add(competitor)

        client = EntityDetailSerializer(new_entity).data
        data = {"client": client}
        data = {"status": "1", "message": "...", "data": data}
        # 添加索引
        new_entity.save()
        return Response(data)


class ClientDetail(APIView):
    """
    Client 客户
    get：获取客户详细信息
    put：1.验证是否具有更新权限。2.更新客户详细信息。
    """

    def get_object(self, pk):
        try:
            return Entity.objects.get(pk=pk)
        except ObjectDoesNotExist:
            raise Http404

    # get Client detail
    @set_recent_items('client', 20)
    def get(self, request, pk):
        entity = self.get_object(pk)
        serializer = EntityDetailSerializer(entity)
        return Response(serializer.data)

    # put Client detail
    def put(self, request, pk):
        # 权限验证
        user = request.user
        if not check_action_permission(user, 'entity', 'change'):
            data = {"status": "0", "error_message": "No Permission."}
            return Response(data)

        name = request.data.get("name")
        picture = request.FILES.get('picture')
        english_name = request.data.get("english_name")
        entity_type = request.data.get("entity_type")
        company = request.data.get("company")
        industry = request.data.get("industry")
        tel = request.data.get("tel")
        mobile = request.data.get("mobile")
        fax = request.data.get("fax")
        email = request.data.get("email")
        address = request.data.get("address")
        client_members = request.data.get("client_members")
        parents = request.data.get("parents")
        child = request.data.get("child")
        website = request.data.get("website")
        tax_id = request.data.get("tax_id")
        registered_company = request.data.get("registered_company")
        bank_account = request.data.get("bank_account")
        bank_name = request.data.get("bank_name")
        registered_company_address = request.data.get("registered_company_address")
        billing_period = request.data.get("billing_period")
        contacts = request.data.get("contacts")
        competitors = request.data.get("competitors")
        number = request.data.get("number", None)
        billing_tel = request.data.get("billing_tel")
        # assert 1 == 2
        entity = self.get_object(pk)
        entity.name = name
        entity.english_name = english_name
        entity.entity_type = entity_type
        entity.company = company
        if industry is not None:
            industry = int(industry)
            industry_obj = Industry.objects.filter(id=industry).first()
            entity.industry = industry_obj
        else:
            entity.industry = None
        entity.tel = tel
        entity.mobile = mobile
        entity.fax = fax
        entity.email = email
        entity.address = address
        entity.website = website
        entity.tax_id = tax_id  # 税号
        entity.registered_company = registered_company  # 注册公司名称
        entity.registered_company_address = registered_company_address  # 公司注册地址
        entity.bank_account = bank_account  # 银行账户
        entity.bank_name = bank_name  # 开户行名称
        entity.billing_period = billing_period  # 账单周期
        entity.billing_tel = billing_tel
        if number:
            entity.number = number

        # # 账单联系人
        # if billing_contact is not None:
        #     billing_contact = json.loads(billing_contact)
        #     billing_contact_obj = Contact.objects.filter(id__in=billing_contact).first()
        #     if billing_contact_obj:
        #         entity.billing_contact = billing_contact_obj
        #     else:
        #         entity.billing_contact = None

        # 客户图片保存(删除操作)
        if picture is not None:
            attachment = Attachment()
            attachment.name = name + '-photo'
            attachment.type_of = '2'
            attachment.file = picture
            attachment.save()
            entity.picture = attachment

        # 更新联系人
        if contacts is not None:
            contacts = json.loads(contacts)
            # 初始化 客户-联系人关系
            original_contacts = Contact.objects.filter(client=entity)
            for original_contact in original_contacts:
                original_contact.client = None
                original_contact.save()
            # 更新 客户-联系人关系
            contacts_entities = Contact.objects.filter(id__in=contacts)
            for contact in contacts_entities:
                contact.client = entity
                contact.save()

        # 如果是联合客户，添加关联
        if client_members is not None:
            client_members = json.loads(client_members)
            original_members = entity.joint_parent.all()
            for original_member in original_members:
                entity.joint_parent.remove(original_member)
            for client_member in client_members:
                entity.joint_parent.add(client_member)

        # 关联客户子公司
        if child is not None:
            child = json.loads(child)
            original_children = entity.children.all()
            for original_child in original_children:
                entity.children.remove(original_child)
            for i in child:
                entity.children.add(i)

        # 添加母公司
        if parents is not None:
            parents = json.loads(parents)
            original_parents = entity.parents.all()
            for original_parent in original_parents:
                entity.parents.remove(original_parent)
            for parent in parents:
                entity.parents.add(parent)

        if competitors is not None:
            competitors = json.loads(competitors)
            original_competitors = entity.competitors.all()
            for original_competitor in original_competitors:
                entity.competitors.remove(original_competitor)
            for competitor in competitors:
                entity.competitors.add(competitor)
        # save
        entity.save()
        client = EntityDetailSerializer(entity).data
        data = {"client": client}
        data = {"status": "1", "message": "...", "data": data}
        return Response(data)


class ClientBatchOperation(APIView):
    # delete Client detail

    def _get_clients_from_matter(self, client_id):
        # 模板相关信息,确定当前字段ID(field_id)
        TEMPLATE_ID = '1'
        TEMPLATE_KEY = 'matter_client'
        TEMPLATE_MODEL = '1'

        try:
            field_id = TemplateField.objects.get(template_id=TEMPLATE_ID, key=TEMPLATE_KEY)
        except:
            logger.error('Get TemplateField Fail.')
            raise Http404
        tmp_values = TemplateFieldValue.objects.filter(model=TEMPLATE_MODEL, field_id=field_id).values('value')
        _flag = False
        for i in tmp_values:
            # 如果存在某个案件中则raise, 不能被删除
            client_ids = i.get('value', '').split(',')
            if str(client_id) in client_ids:
                _flag = True
                _matter_name = ''
                break
        return _flag

    def post(self, request):
        user = request.user
        if not check_action_permission(user, "entity", "delete"):

            data = {"status": "0", "error_message": "No Permission."}
            return Response(data)

        ids = request.data.get("ids")
        for i in ids:
            _flag = self._get_clients_from_matter(i)
            if _flag:
                return Response({"status": "0", "error_message": "Fail, the client has already related Matter."})

        try:
            Entity.objects.filter(id__in=ids).delete()
        except Exception as e:
            logger.exception('Client Delete Fail.')
            return Response({"status": "0", "error_message": "Fail."})
        return Response({"status": "1", "message": "Client Delete"})

    # 批量更新
    def put(self, request):
        user = request.user

        if not check_action_permission(user, 'entity', 'change'):
            data = {"status": "0", "error_message": "No Permission."}
            return Response(data)

        clients = request.data.get('clients')
        for client in clients:
            id = client['id']
            client_obj = Entity.objects.filter(id=id).first()
            if client_obj:
                client_obj.company = client.get('company')
                if client.get('industry'):
                    client_obj.industry = Industry.objects.filter(id=client.get('industry')).first()
                # 默认修改座机tel,有座机和两个电话都没的情况都更新到座机tel
                if not client_obj.tel and not client_obj.mobile:
                    client_obj.tel = client.get('tel')
                elif client_obj.tel:
                    client_obj.tel = client.get('tel')
                else:
                    client_obj.mobile = client.get('tel')
            client_obj.save()
        return Response({"status": "1", "message": "Client(s) Update!"})


class ClientQuickBuild(APIView):
    """
    快速新建接口
    """
    def post(self, request):
        # 权限验证
        user = request.user
        if not check_action_permission(user, 'entity', 'add'):
            data = {"status": "0", "message": "No Permission."}
            return Response(data)

        name = request.data.get("name")
        english_name = request.data.get("english_name")
        # 检查名字是否重复
        # 如果重复则直接返回该对象id
        _entity = Entity.objects.filter(name=name).first()
        if _entity:
            return Response({"status": "1", "message": "...", "data": {"client": {"id": _entity.id}}})
        del _entity

        _entity = Entity()
        _entity.name = name
        _entity.english_name = english_name
        _entity.is_opposite = False
        _entity.is_potential = True
        _entity.save()

        client = EntityDetailSerializer(_entity).data
        data = {"status": "1", "message": "...", "data": {"client": client}}
        return Response(data)
