Дата приёмки: 12.08.2026. Договор эталона — «РУСЭНЕРГОСБЫТ» (Смоленск) Import_test (id 20). Эталон — Пример выгрузки готового отчета.xlsx (в репозитории reference/etalon-punc-avgust-2024.xlsx).
**Статус: принято с зафиксированными расхождениями. Отчёт ПУНЦ строится в конструкторе, скачанный файл совпал с эталонной выгрузкой по листу «август 2024» полностью — 936 из 936 проверок. Все 23 расхождения приёмки — это ровно те записи, что уже описаны реестром шага 5, новых не появилось. Ни одно из них не является ошибкой портирования: причина — отсутствие данных за сентябрь 2024 в исходном наборе 00102 (там нет ни одной строки за сентябрь по всем договорам и типам документов) и второй комплект листов эталона, правило появления которого из эталонов не выводится.**
Проверка прогонялась не «по коду», а по HTTP тем же путём, что у пользователя: accept_punc.py открывает страницу, запрашивает периоды, скачивает файл и сверяет скачанное. Сырой протокол — evidence/step6/acceptance.txt, скачанные файлы — evidence/step6/, реестр расхождений приёмки — acceptance-diffs.csv.
Смежные документы: спецификация расчёта · сверка шага 5 · реестр расхождений шага 5
| Шаг | Действие | Результат |
|---|---|---|
| 1 | Открыть конструктор, вкладка «Расчёт предельного уровня нерегулируемых цен» | HTTP 200, 24 006 байт, раздел ПУНЦ в разметке есть |
| 2 | Выбрать договор 20, раскрыть список периодов | HTTP 200, один период: «август 2024 г.» |
| 3 | Нажать «Excel по эталонному шаблону» за август 2024 | HTTP 200, 13 536 байт, валидный OOXML, имя файла «ПУНЦ «РУСЭНЕРГОСБЫТ» (Смоленск) Import_test август 2024 г..xlsx» |
| 4 | Запросить сентябрь 2024 | HTTP 400 с причиной: «за сентябрь 2024 г. по договору 20 в наборе 00102 нет строк (D_Type='АПП', R_CalcName='Текущий расчет', без «Средневзвешенный»). Периоды с данными: август 2024 г.» |
| 5 | Открыть скачанный файл | 2 листа: «август 2024» и «Сравнение»; шапка, прочерки, числовые форматы — как в эталоне |
Отдельно проверено, что отказ по сентябрю — честный, а не спрятанная ошибка выборки: прямой запрос к базе показывает 0 строк за сентябрь 2024 во всём наборе 00102 (по всем договорам и всем типам документов; единственный период данных — 2024-08, где по правилам отбора у договора 20 набирается 12 строк отчёта). Протокол — evidence/step6/db-periods.txt.
Это же поведение — важное отличие от прежней версии сервиса: на ранее развёрнутом стенде sol-msqcc8pt-2ja запрос сентября возвращает HTTP 200 и пустой бланк, то есть непосчитанный отчёт выдавался за посчитанный (проверено 12.08.2026, файл evidence/step6/live-old-aug.xlsx: один лист «август 2024 г.» размером 28×15 — собственная вёрстка, не эталонный шаблон).
Сверялись значение/формула, числовой формат и объединения ячеек — по всем листам, которые есть в обеих книгах.
| Объект | Проверок | Совпало | Расхождений |
|---|---|---|---|
| Лист «август 2024» (26×18 = 468 ячеек × значение + формат, объединения) | 936 | 936 | 0 |
| Лист «Сравнение» (143 ячейки × значение + формат, 5 объединений) | 291 | 271 | 20 |
| Состав листов книги (5 листов эталона) | 5 | 2 | 3 |
| Итого | 1232 | 1209 | 23 |
Все 23 записи совпадают с реестром шага 5 «запись в запись» (сверка множеств: расхождений, которых не было бы в реестре шага 5, — ноль). Двадцать четвёртая запись реестра шага 5 — сводная строка «состав и порядок листов книги», отдельной ячейке не соответствует.
Причина одна на все двадцать: агрегаты «Сравнения» считаются по всем листам комплекта, в эталоне это август + сентябрь, а конструктору доступен только август.
| Строка «Сравнения» | Поле | Ячейки | Эталон (август+сентябрь) | Конструктор (только август) |
|---|---|---|---|---|
| 5 в т.ч. покупка мощности | объём | B5, E5 | 9,629 | 4,605 |
| 5 в т.ч. покупка мощности | стоимость | C5, F5 | 8 368 852,07187 | 3 965 543,75955 |
| 6 в т.ч. покупка ЭЭ | объём | B6, E6 | 7 130 126 | 3 437 811 |
| 6 в т.ч. покупка ЭЭ | стоимость | C6, F6 | 12 896 242,430418974 | 5 842 311,590378701 |
| 7 Услуга по передаче | объём | B7, E7 | 7 118 689 | 3 432 410 |
| 7 Услуга по передаче | стоимость | C7, F7 | 16 872 905,76768 | 8 067 566,612380001 |
| 8 Сбытовая надбавка | стоимость | C8, F8 | 1 905 244,7550360002 | 901 881,397263 |
| 9 Инфраструктура | стоимость | C9, F9 | 34 295,90606 | 16 535,87091 |
| 10 УИРП | объём | B10, E10 | 11 437 | 5 401 |
| 10 УИРП | стоимость | C10, F10 | 6,6525799999999995 | 3,99674 |
Классификация: отличие исходных данных, не ошибка портирования. Доказано на шаге 5 подстановкой строк сентября из самой эталонной выгрузки — при этом лист «Сравнение» совпадает с эталоном полностью (0 расхождений на 286 проверках). Все формульные ячейки (D, G, H, I, J, K, L, M и итоговая строка 11) расхождений не дали ни здесь, ни на шаге 5: формулы перенесены дословно, включая H11=SUM(H5:H9) без строки УИРП.
| Лист эталона | Причина | Классификация |
|---|---|---|
| «сентябрь 2024» | в наборе 00102 нет ни одной строки за сентябрь 2024 (проверено запросом к базе: 0 строк по всем договорам и типам) | отличие исходных данных |
| «август 2024_1» | эталон содержит второй комплект листов; на шаге 5 доказано, что это побайтовая копия первого (0 различий), правило его появления из эталонного кода и шаблона не выводится | неопределённость эталона |
| «сентябрь 2024_1» | то же, плюс отсутствие данных сентября | неопределённость эталона |
Ничего не подгонялось: код после сверки не правился ни на шаге 5, ни на шаге 6.
Требование ТЗ: перенести логику точно как в эталонном коде, ничего не выдумывать — в частности, про КАПП в эталоне нет ни слова.
| Проверка | Результат |
|---|---|
Отбор строк строго D_Type='АПП' | ok — значение по умолчанию во всех точках входа |
| КАПП/КСЧФ не подмешиваются в расчёт ПУНЦ | ok — упоминаний КАПП/КСЧФ нет ни в punc_report.py, ни в punc_template.py |
| Строки «Средневзвешенный…» исключены | ok — R_Nomenclature NOT LIKE 'Средневзвешенный%' |
| Сценарий расчёта — «Текущий расчет» | ok — значение по умолчанию |
| Округления в расчёте нет | ok — round( ) встречается дважды и только при сборе множества цен для контроля их расхождения по объектам учёта, в значение отчёта не входит по ветке, которая считает цену по объёму |
| Фактическая проверка подменой типа документа | по умолчанию (АПП) — 12 строк отчёта, как в эталоне; при явном ?doc_type=КАПП — 0 строк, то есть КАПП в расчёт по умолчанию не попадает |
В интерфейсе есть выпадающие списки «Тип документа» (АПП/СЧФ/КАПП/КСЧФ) и «Сценарий расчёта» — это функциональность конструктора, а не отчёта ПУНЦ. Значения по умолчанию совпадают с эталоном, а при любом другом выборе интерфейс показывает предупреждение «Нестандартная выборка: отчёт построен не по АПП / не по «Текущему расчету». С эталоном не сверялся». Расчётные формулы ПУНЦ от этих переключателей не меняются.
Автотесты: 43 из 43 пройдены (python3 -m pytest test_punc.py test_app.py).
Проверка правил платформы по мессенджерам: собственный бот в проекте не поднимается, токенов в коде нет, обращений к api.telegram.org / botapi.max.ru нет — проверено поиском по репозиторию, совпадений ноль. Отчёт отдаётся файлом и страницей, мессенджеры не задействованы.
| Вопрос | Почему не закрыт нами | Что нужно |
|---|---|---|
| Лист «сентябрь 2024» и весь блок «Сравнение» в полном виде | В выданном наборе данных сентября 2024 нет вообще. Досчитать его нечем, а придумывать числа нельзя | Выгрузка 00102/00101 за сентябрь 2024. После загрузки лист и «Сравнение» соберутся тем же кодом — доказано подстановкой эталонных строк: 0 расхождений на 286 проверках |
| Второй комплект листов «…_1» | Правило его появления не выводится ни из эталонного кода, ни из шаблона. На данных эталона это точная копия первого комплекта | Подтвердить, нужен ли второй комплект и по какому признаку он строится (перерасчёт? второй сценарий?) |
| Округление до 10 знаков в редкой ветке | Если у компонента цены нулевой объём, цена берётся из набора уникальных значений, округлённых до 10 знаков. На августе 2024 это ветка срабатывает 5 раз и расхождений не даёт (0 из 936), но при цене с более чем 10 знаками после запятой возможно расхождение в 11-м знаке | Оставить как есть либо согласовать отказ от округления в этой ветке — на эталоне разницы нет |
Отчёт строится на данных из data.db (выгрузки заказчика) | Боевого подключения к источникам 00101/00102/00211/01112-01115 в проекте нет | Доступ к источнику данных, если нужен ежемесячный автоматический расчёт |
python3 app.py # сервис на порту 8080 (PORT — переопределяется)
python3 accept_punc.py http://127.0.0.1:8080Скрипт печатает протокол, складывает скачанные файлы в evidence/step6/ и пишет реестр расхождений evidence/step6/acceptance-diffs.csv. Ненулевой код возврата — расхождения за пределами реестра шага 5.