from __future__ import annotations from pathlib import Path from openpyxl import load_workbook from app.pipeline.mapping import FIXED_REPORT_COLUMNS from app.pipeline.report import TOP_GROUP_HEADERS, ReportRow, write_report def test_write_report_streaming_preserves_header_and_formats(tmp_path: Path) -> None: destination = tmp_path / "report.xlsx" rows = [ ReportRow( file_name="SKO115FZ_01_123456789_20260616_X00001.xml", record_id="RID-1", operation_index=1, operation_fields={"СуммаОпер": "100.50", "ДатаОпер": "2026-06-16"}, participant_fields={}, ) ] write_report(rows, destination) workbook = load_workbook(destination) sheet = workbook["Отчет"] headers = [cell.value for cell in sheet[2]] assert headers == list(FIXED_REPORT_COLUMNS) assert sheet.freeze_panes == "A3" row_values = [ sheet.cell(row=3, column=index).value for index in range(1, len(FIXED_REPORT_COLUMNS) + 1) ] assert "SKO115FZ_01_123456789_20260616_X00001.xml" in row_values date_col_idx = next( ( index for index, column in enumerate(FIXED_REPORT_COLUMNS, start=1) if "Дата" in column ), None, ) if date_col_idx is not None: assert sheet.cell(row=3, column=date_col_idx).number_format == "DD.MM.YYYY" sum_col_idx = next( ( index for index, column in enumerate(FIXED_REPORT_COLUMNS, start=1) if "Сумм" in column or "Сумма" in column ), None, ) if sum_col_idx is not None: assert sheet.cell(row=3, column=sum_col_idx).number_format == "#,##0.00" def test_write_report_contains_top_group_header_row(tmp_path: Path) -> None: destination = tmp_path / "report.xlsx" write_report([], destination) workbook = load_workbook(destination) sheet = workbook["Отчет"] assert sheet.cell(row=1, column=1).value == ( "Информация о КО, передающей сведения в уполномоченный орган" ) merged_ranges = {str(rng) for rng in sheet.merged_cells.ranges} expected_ranges = set() for header in TOP_GROUP_HEADERS: if header.start_col > len(FIXED_REPORT_COLUMNS): continue end_col = min(header.end_col, len(FIXED_REPORT_COLUMNS)) expected_ranges.add( f"{_column_letter(header.start_col)}1:{_column_letter(end_col)}1" ) assert merged_ranges == expected_ranges def _column_letter(index: int) -> str: value = index result = "" while value: value, remainder = divmod(value - 1, 26) result = chr(65 + remainder) + result return result