Exemple #1
0
def perform_advanced_search(user_id, get_params):
    """Задача для выполнения расширенного поиска."""
    formset = get_search_form('advanced', get_params)
    # Валидация запроса
    try:
        if not formset.is_valid():
            errors = []
            errors.extend(formset.errors)
            errors.extend(formset.non_form_errors())
            return {
                'validation_errors': errors,
                'get_params': get_params
            }
    except ValidationError:
        return {
            'validation_errors': _('Некоректні умови пошуку'),
            'get_params': get_params
        }

    # Разбивка поисковых данных на поисковые группы
    search_groups = get_search_groups(formset.cleaned_data)

    # Пользователь
    user = get_user_or_anonymous(user_id)

    # Поиск в ElasticSearch по каждой группе
    s = get_elastic_results(search_groups, user)

    # Сортировка
    if get_params.get('sort_by'):
        s = sort_results(s, get_params['sort_by'][0])
    else:
        s = s.sort('_score')

    # Фильтрация, агрегация
    s, aggregations = filter_results(s, get_params)

    # Пагинация
    results_on_page = int(get_params.get('show', [10])[0])
    if results_on_page > 100:
        results_on_page = 100
    elif results_on_page < 10:
        results_on_page = 10
    res_from = results_on_page * (int(get_params['page'][0]) - 1) if get_params.get('page') else 0
    res_to = res_from + results_on_page
    items = []
    for i in s[res_from:res_to]:
        item = i.to_dict()
        item['meta'] = i.meta.to_dict()
        items.append(filter_app_data(item, user))
    results = {
        'items': items,
        'total': s.count()
    }

    return {
        'aggregations': aggregations,
        'results': results,
        'get_params': get_params
    }
Exemple #2
0
def perform_favorites_search(favorites_ids, user_id, get_params):
    """Задача для выполнения простого поиска."""
    # Формирование поискового запроса ElasticSearch
    client = Elasticsearch(settings.ELASTIC_HOST, timeout=settings.ELASTIC_TIMEOUT)

    # Пользователь
    user = get_user_or_anonymous(user_id)

    q = Q(
        'bool',
        must=[Q('terms', _id=favorites_ids)],
    )
    s = Search(using=client, index=settings.ELASTIC_INDEX_NAME).source(
        excludes=["*.DocBarCode", "*.DOCBARCODE"]
    ).query(q)

    # Сортировка
    if get_params.get('sort_by'):
        s = sort_results(s, get_params['sort_by'][0])
    else:
        s = s.sort('_score')

    # Пагинация
    results_on_page = int(get_params.get('show', [10])[0])
    if results_on_page > 100:
        results_on_page = 100
    elif results_on_page < 10:
        results_on_page = 10
    res_from = results_on_page * (int(get_params['page'][0]) - 1) if get_params.get('page') else 0
    res_to = res_from + results_on_page
    items = []
    for i in s[res_from:res_to]:
        item = i.to_dict()
        item['meta'] = i.meta.to_dict()
        items.append(filter_app_data(item, user))
    results = {
        'items': items,
        'total': s.count()
    }

    return {
        'results': results,
        'get_params': get_params
    }
Exemple #3
0
def create_favorites_results_file(user_id, favorites_ids, get_params,
                                  lang_code):
    """Возвращает url файла с результатами содержимого в избранном."""
    client = Elasticsearch(settings.ELASTIC_HOST,
                           timeout=settings.ELASTIC_TIMEOUT)
    q = Q(
        'bool',
        must=[Q('terms', _id=favorites_ids)],
    )
    s = Search(using=client, index=settings.ELASTIC_INDEX_NAME).query(q)

    if s.count() <= 5000:
        # Сортировка
        if get_params.get('sort_by'):
            s = sort_results(s, get_params['sort_by'][0])
        else:
            s = s.sort('_score')

        # Данные для Excel-файла
        user = get_user_or_anonymous(user_id)
        # Данные для Excel-файла
        data = prepare_data_for_search_report(s, lang_code, user)

        directory_path = os.path.join(
            settings.MEDIA_ROOT,
            'search_results',
        )
        os.makedirs(directory_path, exist_ok=True)
        # Имя файла с результатами поиска
        file_name = f"{get_unique_filename('favorites')}.xlsx"
        file_path = os.path.join(directory_path, file_name)

        # Формировние и сохранение Excel-файла
        create_search_res_doc(data, file_path)

        # Возврат url сформированного файла с результатами поиска
        return os.path.join(settings.MEDIA_URL, 'search_results', file_name)
    return False
Exemple #4
0
def create_advanced_search_results_file(user_id, get_params, lang_code):
    """Возвращает url файла с результатами расширенного поиска."""
    formset = get_search_form('advanced', get_params)
    # Валидация запроса
    if formset.is_valid():
        # Разбивка поисковых данных на поисковые группы
        search_groups = get_search_groups(formset.cleaned_data)

        # Поиск в ElasticSearch по каждой группе
        user = get_user_or_anonymous(user_id)
        s = get_elastic_results(search_groups, user)

        # Фильтрация
        # Возможные фильтры
        filters = [
            {
                'title': 'obj_type',
                'field': 'Document.idObjType'
            },
            {
                'title': 'obj_state',
                'field': 'search_data.obj_state'
            },
            {
                'title': 'registration_status_color',
                'field': 'search_data.registration_status_color'
            },
        ]

        # Если включены платные услуги, то необходимо включить возможность фильтрации по коду MarkCurrentStatusCodeType
        paid_services_settings, created = PaidServicesSettings.objects.get_or_create()
        """ ВРЕМЕННО ОТКРЫТЬ ДОСТУП ВСЕМ """
        # if paid_services_settings.enabled:
        #     filters.append({
        #         'title': 'mark_status',
        #         'field': 'Document.MarkCurrentStatusCodeType.keyword'
        #     })
        filters.append({
            'title': 'mark_status',
            'field': 'Document.MarkCurrentStatusCodeType.keyword'
        })

        for item in filters:
            if get_params.get(f"filter_{item['title']}"):
                # Фильтрация в основном запросе
                s = s.filter('terms', **{item['field']: get_params.get(f"filter_{item['title']}")})

        if s.count() <= 5000:
            s = s.source(['search_data', 'Document', 'Claim', 'Patent', 'TradeMark', 'MadridTradeMark', 'Design', 'Geo',
                          'Certificate'])

            # Сортировка
            if get_params.get('sort_by'):
                s = sort_results(s, get_params['sort_by'][0])
            else:
                s = s.sort('_score')

            # Данные для Excel-файла
            data = prepare_data_for_search_report(s, lang_code, user)

            directory_path = os.path.join(
                settings.MEDIA_ROOT,
                'search_results',
            )
            os.makedirs(directory_path, exist_ok=True)
            # Имя файла с результатами поиска
            file_name = f"{get_unique_filename('advanced_search')}.xlsx"
            file_path = os.path.join(directory_path, file_name)

            # Формировние и сохранение Excel-файла
            create_search_res_doc(data, file_path)

            # Возврат url сформированного файла с результатами поиска
            return os.path.join(
                settings.MEDIA_URL,
                'search_results',
                file_name
            )
    return False
Exemple #5
0
def create_simple_search_results_file(user_id, get_params, lang_code):
    """Возвращает url файла с результатами простого поиска."""
    formset = get_search_form('simple', get_params)
    # Валидация запроса
    if formset.is_valid():
        client = Elasticsearch(settings.ELASTIC_HOST, timeout=settings.ELASTIC_TIMEOUT)
        user = get_user_or_anonymous(user_id)
        qs = None
        for s in formset.cleaned_data:
            elastic_field = SimpleSearchField.objects.get(pk=s['param_type']).elastic_index_field
            if elastic_field:
                query = prepare_query(s['value'], elastic_field.field_type)

                if elastic_field.field_type == 'text':
                    fields = [
                        f"{elastic_field.field_name}^2",
                        f"{elastic_field.field_name}.exact^3",
                        f"{elastic_field.field_name}.*",
                    ]

                    # if '*' in query:
                    #     fields = [
                    #         # f"{inid_schedule.elastic_index_field.field_name}^2",
                    #         f"{elastic_field.field_name}.exact^2",
                    #     ]
                    # else:
                    #     fields = [
                    #         # f"{inid_schedule.elastic_index_field.field_name}^2",
                    #         f"{elastic_field.field_name}.exact^2",
                    #         f"{elastic_field.field_name}.*",
                    #     ]
                else:
                    fields = [
                        f"{elastic_field.field_name}",
                    ]

                q = Q(
                    'query_string',
                    query=query,
                    fields=fields,
                    quote_field_suffix=".exact",
                    default_operator='AND'
                )

                # Nested тип
                if elastic_field.parent:
                    q = Q(
                        'nested',
                        path=elastic_field.parent.field_name,
                        query=q,
                    )

                if qs is not None:
                    qs &= q
                else:
                    qs = q

        qs = filter_bad_apps(qs)

        s = Search(using=client, index=settings.ELASTIC_INDEX_NAME).query(qs)

        # Сортировка
        if get_params.get('sort_by'):
            s = sort_results(s, get_params['sort_by'][0])
        else:
            s = s.sort('_score')

        # Фильтрация
        # Возможные фильтры
        filters = [
            {
                'title': 'obj_type',
                'field': 'Document.idObjType'
            },
            {
                'title': 'obj_state',
                'field': 'search_data.obj_state'
            },
            {
                'title': 'registration_status_color',
                'field': 'search_data.registration_status_color'
            },
        ]

        # Если включены платные услуги, то необходимо включить возможность фильтрации по коду MarkCurrentStatusCodeType
        paid_services_settings, created = PaidServicesSettings.objects.get_or_create()
        """ ВРЕМЕННО ОТКРЫТЬ ДОСТУП ВСЕМ """
        # if paid_services_settings.enabled:
        #     filters.append({
        #         'title': 'mark_status',
        #         'field': 'Document.MarkCurrentStatusCodeType.keyword'
        #     })
        filters.append({
            'title': 'mark_status',
            'field': 'Document.MarkCurrentStatusCodeType.keyword'
        })

        for item in filters:
            if get_params.get(f"filter_{item['title']}"):
                # Фильтрация в основном запросе
                s = s.filter('terms', **{item['field']: get_params.get(f"filter_{item['title']}")})

        if s.count() <= 5000:
            s = s.source(['search_data', 'Document', 'Claim', 'Patent', 'TradeMark', 'MadridTradeMark', 'Design', 'Geo',
                          'Certificate'])

            # Данные для Excel-файла
            data = prepare_data_for_search_report(s, lang_code, user)

            directory_path = os.path.join(
                settings.MEDIA_ROOT,
                'search_results',
            )
            os.makedirs(directory_path, exist_ok=True)
            # Имя файла с результатами поиска
            file_name = f"{get_unique_filename('simple_search')}.xlsx"
            file_path = os.path.join(directory_path, file_name)

            # Формировние и сохранение Excel-файла
            create_search_res_doc(data, file_path)

            # Возврат url сформированного файла с результатами поиска
            return os.path.join(
                settings.MEDIA_URL,
                'search_results',
                file_name
            )
    return False
Exemple #6
0
def get_order_documents(user_id, id_app_number, id_cead_doc, ip_user):
    """Возвращает название файла документа или архива с документами, заказанного(ых) через "стол заказов"."""
    # Получение документа (заявки) из ElasticSearch
    client = Elasticsearch(settings.ELASTIC_HOST, timeout=settings.ELASTIC_TIMEOUT)
    q = Q(
        'bool',
        must=[Q('match', _id=id_app_number)],
    )

    user = get_user_or_anonymous(user_id)

    s = Search(index=settings.ELASTIC_INDEX_NAME).using(client).query(q).execute()
    if not s:
        return {}
    hit = s[0].to_dict()

    # Список id cead
    hit_id_cead_list = []
    if hit['Document']['idObjType'] in (1, 2, 3):
        for doc in hit['DOCFLOW']['DOCUMENTS']:
            if doc['DOCRECORD'].get('DOCIDDOCCEAD'):
                hit_id_cead_list.append(doc['DOCRECORD']['DOCIDDOCCEAD'])

        # Если это охранный документ, то нужно ещё добавить в список документы заявки
        if hit['search_data']['obj_state'] == 2:
            q = Q(
                'query_string',
                query=f"search_data.obj_state:1 AND search_data.app_number:{hit['search_data']['app_number']}",
            )
            s = Search(index=settings.ELASTIC_INDEX_NAME).using(client).query(q).execute()
            if s:
                app_hit = s[0].to_dict()
                for doc in app_hit.get('DOCFLOW', {}).get('DOCUMENTS', []):
                    if doc['DOCRECORD'].get('DOCIDDOCCEAD'):
                        hit_id_cead_list.append(doc['DOCRECORD']['DOCIDDOCCEAD'])

    elif hit['Document']['idObjType'] == 4:
        for doc in hit['TradeMark']['DocFlow']['Documents']:
            if doc['DocRecord'].get('DocIdDocCEAD'):
                hit_id_cead_list.append(doc['DocRecord']['DocIdDocCEAD'])
    elif hit['Document']['idObjType'] == 6:
        for doc in hit['Design']['DocFlow']['Documents']:
            if doc['DocRecord'].get('DocIdDocCEAD'):
                hit_id_cead_list.append(doc['DocRecord']['DocIdDocCEAD'])

    # Входит ли id_cead_doc в список документов заявки
    if isinstance(id_cead_doc, list):
        is_in_list = set(list(map(int, id_cead_doc))).issubset(set(hit_id_cead_list))
    else:
        is_in_list = id_cead_doc in hit_id_cead_list

    if is_in_list and user_has_access_to_docs(user, hit):
        # Создание заказа
        order = OrderService(
            # user=request.user,
            user_id=user_id,
            ip_user=ip_user,
            app_id=id_app_number
        )
        order.save()
        if isinstance(id_cead_doc, list):
            for item in id_cead_doc:
                OrderDocument.objects.create(order=order, id_cead_doc=item)
        else:
            OrderDocument.objects.create(order=order, id_cead_doc=id_cead_doc)
        order = get_completed_order(order.id)

        if order:
            file_zip_name = f"docs_{order.id}.zip"
            file_path_zip = os.path.join(
                settings.ORDERS_ROOT,
                str(order.user_id),
                str(order.id),
                file_zip_name
            )
            with ZipFile(file_path_zip, 'w') as zip_:
                for document in order.orderdocument_set.all():
                    zip_.write(
                        os.path.join(
                            settings.DOCUMENTS_MOUNT_FOLDER,
                            'OrderService',
                            str(order.user_id),
                            str(order.id),
                            document.file_name),
                        f"{document.file_name}"
                    )
            return os.path.join(
                settings.MEDIA_URL,
                'OrderService',
                str(order.user_id),
                str(order.id),
                file_zip_name
            )

    return False
Exemple #7
0
def perform_simple_search(user_id, get_params):
    """Задача для выполнения простого поиска."""
    formset = get_search_form('simple', get_params)
    # Валидация запроса
    try:
        if not formset.is_valid():
            errors = []
            errors.extend(formset.errors)
            errors.extend(formset.non_form_errors())
            return {
                'validation_errors': errors,
                'get_params': get_params
            }
    except ValidationError:
        return {
            'validation_errors': _('Некоректні умови пошуку'),
            'get_params': get_params
        }

    # Формирование поискового запроса ElasticSearch
    client = Elasticsearch(settings.ELASTIC_HOST, timeout=settings.ELASTIC_TIMEOUT)

    # Пользователь
    user = get_user_or_anonymous(user_id)

    qs = None
    for s in formset.cleaned_data:
        if s:
            elastic_field = SimpleSearchField.objects.get(pk=s['param_type']).elastic_index_field
            if elastic_field:
                query = prepare_query(s['value'], elastic_field.field_type)

                if elastic_field.field_type == 'text':
                    fields = [
                        f"{elastic_field.field_name}^2",
                        f"{elastic_field.field_name}.exact^3",
                        f"{elastic_field.field_name}.*",
                    ]

                    # if '*' in query:
                    #     fields = [
                    #         # f"{inid_schedule.elastic_index_field.field_name}^2",
                    #         f"{elastic_field.field_name}.exact^2",
                    #     ]
                    # else:
                    #     fields = [
                    #         f"{elastic_field.field_name}^2",
                    #         f"{elastic_field.field_name}.exact^2",
                    #         f"{elastic_field.field_name}.*",
                    #     ]
                else:
                    fields = [
                        f"{elastic_field.field_name}",
                    ]

                q = Q(
                    'query_string',
                    query=query,
                    fields=fields,
                    quote_field_suffix=".exact",
                    default_operator='AND'
                )

                # Nested тип
                if elastic_field.parent:
                    q = Q(
                        'nested',
                        path=elastic_field.parent.field_name,
                        query=q,
                    )

                if qs is not None:
                    qs &= q
                else:
                    qs = q

    # Не включать в список результатов заявки, по которым выдан патент
    qs = filter_bad_apps(qs)

    s = Search(using=client, index=settings.ELASTIC_INDEX_NAME).query(qs).source(
        excludes=["*.DocBarCode", "*.DOCBARCODE"]
    )

    # Сортировка
    if get_params.get('sort_by'):
        s = sort_results(s, get_params['sort_by'][0])
    else:
        s = s.sort('_score')

    # Фильтрация, агрегация
    s, aggregations = filter_results(s, get_params)

    results_on_page = int(get_params.get('show', [10])[0])
    if results_on_page > 100:
        results_on_page = 100
    elif results_on_page < 10:
        results_on_page = 10
    res_from = results_on_page * (int(get_params['page'][0]) - 1) if get_params.get('page') else 0
    res_to = res_from + results_on_page
    items = []
    for i in s[res_from:res_to]:
        item = i.to_dict()
        item['meta'] = i.meta.to_dict()
        items.append(filter_app_data(item, user))
    results = {
        'items': items,
        'total': s.count()
    }

    return {
        'aggregations': aggregations,
        'results': results,
        'get_params': get_params
    }
Exemple #8
0
def get_app_details(id_app_number, user_id):
    """Задача для получения деталей по заявке."""
    user = get_user_or_anonymous(user_id)
    client = Elasticsearch(settings.ELASTIC_HOST, timeout=settings.ELASTIC_TIMEOUT)
    q = Q(
        'bool',
        must=[Q('match', _id=id_app_number)],
    )
    # Фильтр заявок, которые не положено отоборажать
    q = filter_bad_apps(q)

    s = Search(index=settings.ELASTIC_INDEX_NAME).using(client).query(q).source(
        excludes=["*.DocBarCode", "*.DOCBARCODE"]
    ).execute()
    if not s:
        return {}
    hit = s[0].to_dict()

    if hit['Document']['idObjType'] in (1, 2, 3):
        hit['biblio_data'] = hit['Claim'] if hit['search_data']['obj_state'] == 1 else hit['Patent']

        # Оповещения
        transactions = hit.get('TRANSACTIONS', {}).get('TRANSACTION', [])
        if type(transactions) is dict:
            transactions = [transactions]
        hit['transactions'] = transactions

        # Документы заявки (библиографические)
        hit['biblio_documents'] = AppDocuments.get_app_documents(id_app_number)

        # Если это патент, то необходимо объеденить документы, платежи и т.д. с теми которые были на этапе заявки
        if hit['search_data']['obj_state'] == 2:
            extend_doc_flow(hit)

        hit['DOCFLOW']['DOCUMENTS'] = search_services.application_filter_documents_im_um_ld(
            hit['biblio_data'],
            hit.get('DOCFLOW', {}).get('DOCUMENTS', [])
        )

    elif hit['Document']['idObjType'] == 4:
        if hit['TradeMark'].get('DocFlow', {}).get('Documents'):
            hit['TradeMark']['DocFlow']['Documents'] = search_services.application_filter_documents_tm_id(
                hit['TradeMark'].get('DocFlow', {}).get('Documents', [])
            )

    elif hit['Document']['idObjType'] == 6:
        if hit['Design'].get('DocFlow', {}).get('Documents'):
            hit['Design']['DocFlow']['Documents'] = search_services.application_filter_documents_tm_id(
                hit['Design'].get('DocFlow', {}).get('Documents', [])
            )

    # Сортировка документов заявки по дате
    sort_doc_flow(hit)

    # Сортировка оповещений
    if hit['search_data']['obj_state'] == 2:
        search_services.application_sort_transactions(hit)

    hit['meta'] = {'id': id_app_number}

    return filter_app_data(hit, user)