diff --git a/CHANGELOG.md b/CHANGELOG.md index d7d2ec8..547de14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ - Добавлен справочник связей всех 773 журналов К1 со специальностями из Перечня ВАК на 15.09.2026, с ISSN, страницами, строками источника и датами назначений. Исключены истёкшие назначения; одинаковое название «Нефтегазовое дело» для двух ISSN помечено как неоднозначное и не используется в автоматическом подборе. - Добавлен воспроизводимый скрипт извлечения и проверенные варианты названий. Сервис читает готовый JSON без обработки PDF при запросах. +## 0.14.3 + +- Из XLSX диссертационного совета удалён столбец «Статус». Колонка «В БД» переименована в «Страница ВШЭ» на листах «Сотрудники» и «Публикации»; расчёт значений сохранён. + ## 0.14.2 - Исправлено сопоставление К1 для переименованного журнала: действующее и явно указанное в исходном PDF прежнее название распознаются как один журнал. Административное примечание хранится отдельно от названия; конфликтующие алиасы не присваиваются автоматически. diff --git a/app/services/council_export.py b/app/services/council_export.py index 5987e66..04c1589 100644 --- a/app/services/council_export.py +++ b/app/services/council_export.py @@ -22,15 +22,15 @@ def council_xlsx(result: dict) -> bytes: employees.title = "Сотрудники" publications = workbook.create_sheet("Публикации") parameters = workbook.create_sheet("Параметры") - _append(employees, ["№", "ФИО", "Учёная степень", "Q1", "Q2", "К1", "ВСЕГО", "В БД", "Все публикации", - "Статус", "Профиль ВШЭ", "Примечание"]) + _append(employees, ["№", "ФИО", "Учёная степень", "Q1", "Q2", "К1", "ВСЕГО", "Страница ВШЭ", "Все публикации", + "Профиль ВШЭ", "Примечание"]) _append(publications, ["№ сотрудника", "ФИО", "Название публикации", "Год", "Тип материала", "Источники", - "Критерии", "Q1", "Q2", "К1", "В ВСЕГО", "В БД", "DOI", "Ссылка на сайте", "Строки CSV"]) + "Критерии", "Q1", "Q2", "К1", "В ВСЕГО", "Страница ВШЭ", "DOI", "Ссылка на сайте", "Строки CSV"]) for number, candidate in enumerate(result["candidates"], 1): note = "Совпадение ФИО: публикации CSV не присвоены автоматически" if candidate["ambiguous"] else "" _append(employees, [number, candidate["name"], candidate["degree"], candidate["q1_count"], candidate["q2_count"], candidate["k1_count"], candidate["total_count"], - candidate["db_count"], candidate["count"], "Уволен" if candidate["dismissed"] else "Не отмечен как уволенный", + candidate["db_count"], candidate["count"], candidate["profile_url"], note]) for article in candidate["articles"]: _append(publications, [number, candidate["name"], article["title"], article["year"], article["type_label"], @@ -43,7 +43,7 @@ def council_xlsx(result: dict) -> bytes: ["Подбор по специальности", "Хотя бы одна публикация за пять лет в релевантном журнале К1 по Перечню ВАК на 15.09.2026; содержание статьи и исторические специальности не проверяются."], ["Начало периода", result["start"]], ["Конец периода", result["end"]], ["Поиск по ФИО", result["q"]], ["Сортировать по", {"full_name": "ФИО", "q1_count": "Q1", "q2_count": "Q2", "k1_count": "К1", - "total_count": "ВСЕГО", "db_count": "В БД", "count": "Все публикации"}[result["sort"]]], + "total_count": "ВСЕГО", "db_count": "Страница ВШЭ", "count": "Все публикации"}[result["sort"]]], ["Направление", "По возрастанию" if result["direction"] == "asc" else "По убыванию"], ["Сотрудников в выгрузке", result["matched"]], ["Всего сотрудников в списке", result["total"]], ["Отбор по степени", "Доктор наук в профиле; достаточно хотя бы одной публикации из CSV или БД"], @@ -53,11 +53,12 @@ def council_xlsx(result: dict) -> bytes: "в справочнике из ВАК категории.pdf; историческая категория не подтверждается. " "Без названия журнала К1 не подтверждён."], ["ВСЕГО", "Уникальные публикации, входящие в Q1 ИЛИ Q2 ИЛИ К1; пересечения учитываются один раз."], - ["В БД / Все публикации", "Все годы и категории; общий перечень объединяет CSV и БД без дублей."], + ["Страница ВШЭ / Все публикации", "Все годы и категории; общий перечень объединяет CSV и БД без дублей. " + "Страница ВШЭ учитывает сохранённые публикации, включая импортированные из CSV; источник указан на листе Публикации."], ]: _append(parameters, values) - for sheet, widths in [(employees, [7, 34, 40, 10, 10, 10, 12, 12, 22, 30, 45, 55]), - (publications, [16, 34, 65, 12, 40, 45, 65, 10, 10, 10, 12, 12, 45, 45, 22]), + for sheet, widths in [(employees, [7, 34, 40, 10, 10, 10, 12, 20, 22, 45, 55]), + (publications, [16, 34, 65, 12, 40, 45, 65, 10, 10, 10, 12, 20, 45, 45, 22]), (parameters, [32, 95])]: sheet.freeze_panes = "A2" sheet.auto_filter.ref = sheet.dimensions diff --git a/tests/test_council.py b/tests/test_council.py index 329bf0b..667114f 100644 --- a/tests/test_council.py +++ b/tests/test_council.py @@ -254,6 +254,14 @@ def test_xlsx_exports_all_filtered_workers_in_order_and_deduplicated_evidence(db book = load_workbook(BytesIO(response.content)) assert book.sheetnames == ["Сотрудники", "Публикации", "Параметры"] people, works = book["Сотрудники"], book["Публикации"] + assert [cell.value for cell in people[1]] == [ + "№", "ФИО", "Учёная степень", "Q1", "Q2", "К1", "ВСЕГО", "Страница ВШЭ", "Все публикации", + "Профиль ВШЭ", "Примечание" + ] + assert people["J2"].value == "https://www.hse.ru/staff/test" + assert people["K2"].value is None + assert people.max_column == 11 + assert works["L1"].value == "Страница ВШЭ" assert people.max_row == 29 and works.max_row == 29 assert people["B2"].value == "Петров 27" and people["B29"].value == "Петров 00" assert [people.cell(2, n).value for n in [4, 5, 6, 7, 8, 9]] == [1, 1, 0, 1, 1, 1]